87

Some actions (such as generating the Table of Contents) require two passes of the TeX compiler: during the first pass, some data get written to an auxiliary file, only to be retrieved during the second pass. Here are a few TeX.SE questions that require two-pass solutions:

Two-pass stuff has piqued my interest; I have a few questions:

  1. Can I write (append) custom data to an existing auxiliary file (e.g. .aux)? Is that even a good idea? If not, can I generate my own auxiliary file (with a custom extension) to store/retrieve some data?
  2. What are good sources for learning the basics of writing to & reading from auxiliary files?
4
  • It's not so hard to write something to the aux file: \immediate\write\@auxout{<something expandable>} or \write\@auxout{<something expandable>}. The aux file is automatically read in at begin document.
    – cgnieder
    May 24, 2013 at 11:58
  • 3
  • might also want to consider VerbatimOut as provided by fancyvrb. there's a nice discussion in the companion of how it was used for the side-by-side examples in the book. May 24, 2013 at 13:02
  • 1
    A word of warning: A downside when writing to other files is that often abortion of a compilation can lead to errors the "next time round", forcing you to delete all "half-written" versions of files you created during that run through. This can be quite tedious and while some UIs allow you to automatically delete the aux file, usually they don't check for other files that were created and cause an error in the next run-through (which is imho a plus for writing to the aux file and not create more files ...)
    – Jonathan
    Aug 21, 2013 at 18:59

1 Answer 1

88

You can write to the aux file with

\write\@auxout{\gdef\string\testa{hello}}

or

\immediate\write\@auxout{\gdef\string\testb{hello2}}

or

\protected@write\@auxout{}{\gdef\string\testc{hello3}}

Depending on requirements.

\immediate\write writes to the specified file at that point, expanding the supplied tokens (like \edef) so fragile commands will do the wrong thing.

\write does not write at that point it puts a write node into the current vertical or horizontal list and if that list is shipped out to make a page then the write happens. This is needed to get page numbers correct. (If the write is inside a box and that box is never used on the main page then nothing is written to the file.)

\protected@write is a LaTeX-defined macro that uses \write but arranges that \protect works as required in LaTeX to protect fragile commands. The extra argument unused above allows you to locally insert extra definitions to make more commands be safe or have special definition in the write, see for example the definition of \index or \addtocontents.

It is safe to write to the aux file, however you have to be aware that the file will be read back at least at the begin and end of the document, so you need to write lines that are safe in that context.

If you want to write to your own file then you just need to do

\newwrite\myfile
\immediate\openout\myfile=\jobname.foo

in the preamble and then replace \@auxout by \myfile when writing.

Have a look at the way \tableofcontents or \listoftables or \listoffigures work in latex.ltx or documented in source2e. They basically all use

\def\@starttoc#1{%
  \begingroup
    \makeatletter
    \@input{\jobname.#1}%
    \if@filesw
      \expandafter\newwrite\csname tf@#1\endcsname
      \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
    \fi
    \@nobreakfalse
  \endgroup}
6
  • 3
    Please mention that closing your own file requires \immediate\closeout\myfile. Thanks. Feb 9, 2015 at 17:33
  • 4
    @FaheemMitha you only need to close it explicitly if you are going to input it or write a different file on the same stream, if you do nothing the file will be closed automatically at end document. Also it should be \closeout not \immediate\closeout if there are any non-immediate \write pending. Oct 2, 2018 at 12:39
  • The "hello..." raw strings are just placeholders for real code. Typesetting as is would result in a LaTeX Missing \ begin {document} error, which is expected because aux files contents are executed at the end of the preamble. Sep 16, 2021 at 7:33
  • @JérômeLAURENS er yes good point actually, I could change the examples to be a more typical \gdef\zz{hello} ? Sep 16, 2021 at 8:17
  • Such an explicit example would certainly be welcome. It would illustrate both the trickery related to expansion and the necessity of the global changes. Moreover, it won't really make the answer less readable. Sep 16, 2021 at 11:43

You must log in to answer this question.

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