3

I'd like to make a document which looks different each time it is built. I thought this would be pretty easy to do using the aux file; however, it seems I am misunderstanding something very basic. For a small proof-of-concept, here is a document that I thought would produce something different on its second run than on its first:

\documentclass{article}
\def\a{never ran}
\begin{document}
\a
\makeatletter\protected@write\@auxout{}{\string\def\string\a{ran}}\makeatother
\end{document}

After running pdflatex test, I can see that test.pdf indeed contains "never ran", and test.aux contains:

\relax 
\def\a{ran}

However, running pdflatex test a second time changes neither file. Why not? What should I change so that the document contains ran on the second run?

2
  • 2
    Don't define single letter macros - especially not without checking whether they already exist!!
    – cfr
    Commented Oct 16, 2015 at 0:34
  • See tex.stackexchange.com/a/273116/4427
    – egreg
    Commented Oct 16, 2015 at 8:52

2 Answers 2

9

You need \gdef as the .aux file is read in inside a group. At least, I think that's why. Certainly, \gdef works.

I changed the name of the command to avoid the complications which ensued from overwriting an existing one. In general, very short macro names - especially single letters - are unsafe and unwise. At the very least, you should ensure that they do not already exist rather than simply redefining them.

\documentclass{article}
\def\abacus{never ran}
\begin{document}
\abacus
\makeatletter
\protected@write\@auxout{}{\string\gdef\string\abacus{ran}}
\makeatother
\end{document}
6

Make it a global definition:

\documentclass{article}
\def\hasruncheck{never ran}
\begin{document}
    \hasruncheck
    \makeatletter\protected@write\@auxout{}{\string\gdef\string\hasruncheck{ran}}\makeatother
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .