Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
1  
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
    
@MartinScharrer: Please see additional answer. You could have posted that as answer yourself. +1 to your comment. –  Stephen Nov 14 '11 at 18:04

4 Answers 4

up vote 10 down vote accepted

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.

share|improve this answer

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

share|improve this answer
1  
\symbol{37} won't write %, but rather \char37. –  egreg Nov 10 '11 at 19:03
1  
Also \char is unexpandable –  egreg Nov 10 '11 at 20:43
1  
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.)

share|improve this answer

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).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.