# How can I write % into a file?

How can I write % into an auxiliary file? % will not work, because LaTeX thinks that I start a comment with it (in the main file, not in the auxiliary file!), and \% will write \% into the file. How can it be accomplished?

\documentclass{article}
\begin{document}
\newwrite\outfile
\immediate\openout\outfile=example.dat
\immediate\write\outfile{%}% will not work, of course, but neither \%
\immediate\closeout\outfile
\end{document}

-
Have a look at my answer to How can I provide a verbatim (unescaped) commandline for executing with \write18? which should also answer this question. – Martin Scharrer Nov 10 '11 at 20:33

There is \@percentchar that expands to a literal % character. You need to enclose your writing operation in a \makeatletter \makeatother pair

\makeatletter
\newwrite\outfile
\immediate\openout\outfile=example.dat
\immediate\write\outfile{\@percentchar}
\immediate\closeout\outfile
\makeatother


An alternative with escaping the % inspired by an example where

git log -1 --pretty=format:"%h-%ad" --date=short > /tmp/temp.dat


needs to be passed to \write18

\makeatletter
\newcommand\dosystem{%
\@ifstar{\@tempswafalse\do@system}{\@tempswatrue\do@system}%
}
\newcommand\do@system[1]{%
\begingroup
\let\%\@percentchar
\if@tempswa\expandafter\immediate\fi
\write18{#1}%
\endgroup
}
\makeatother


so the command above can be executed by saying

\dosystem{git log -1 --pretty=format:"\%h-\%ad" --date=short > /tmp/temp.dat }


With \dosystem* the \write is delayed at the next shipout (because \immediate is not executed).

Other characters can be escaped using the same idea, adding other \let instructions. If also braces and # are needed, an extended definition would be

\makeatletter
\newcommand\dosystem{%
\@ifstar{\@tempswafalse\do@system}{\@tempswatrue\do@system}%
}
\edef\@hashmark{\string#}\edef\@lbrace{\string{}\edef\@rbrace{\string}}
\newcommand\do@system[1]{%
\begingroup
\let\%\@percentchar
\let\#\@hashmark
\let\{\@lbrace
\let\}\@rbrace
\if@tempswa\expandafter\immediate\fi
\write18{#1}%
\endgroup
}
\makeatother


and in the argument also \#, \{ and \} can be used for escaping those characters.

-

use \@percentchar or \charxxx where xxx is the decimal number of %

-
\symbol{37} won't write %, but rather \char37. – egreg Nov 10 '11 at 19:03
Also \char is unexpandable – egreg Nov 10 '11 at 20:43
And being unexpandable I can't use it. – Stephen Nov 14 '11 at 18:04

Following the comment of Martin Scharrer I read up on his newverbs package. With this the following is possible:

\documentclass{article}
\usepackage{newverbs}
\Verbdef\verbpercent{%}
\begin{document}
\newwrite\outfile
\immediate\openout\outfile=example.dat
\immediate\write\outfile{\verbpercent}
\immediate\closeout\outfile
\end{document}


Comparison with the use of \@percentchar:

• Advantage: \Verbdef can generally be used for any verbatim text, and doesn't require \makeatletter \makeatother.

• Disadvantage: It uses more of TeX's memory and more time to compile (both: slightly), and theoretically there could be an incompatibility between package newverbs and some other package.

(Therefore I use \@percentchar, but reference to the newverbs package surely is useful for the general case.)

-

As other answers note, you need one way or another to output the string %. For users not using LaTeX, something like

\def\percentchar#1{}
\edef\percentchar{\expandafter\percentchar\string\%}


will generate a macro \percentchar which can be used for this purpose. (I've used \percentchar twice rather than define a 'gobble' command: just to avoid 'name waste'. Many people will have something of that sort set up anyway.) Thus for example with the above

\immediate\write-1{\percentchar}


will write % to the log file.

Another alternative is to alter the category code of %

\begingroup
\catcode\%=12
\immediate\write-1{%}\relax
\endgroup


although this does require a bit more care terminating lines correctly (for example, the \relax` above is needed if we cannot assume vertical mode).

-