32
  1. I'd like to know when the aux file is read. I know it happens after the preamble, but does it come before or after the \AtBeginDocument hook?

  2. I'd like to know when the aux file (or any other helper file) is actually written. I tried to trace the writing process by placing an undefined command after something should have been written to the aux file, and run pdflatex in interactive mode, like so:

    \documentclass{article}
    \begin{document}
    \section{S}\label{s}% write something to the aux file
    
    \foo% unknown command
    \end{document}
    

    but to my surprise the aux file is still empty when pdflatex stops at the error. I guess there is some buffering happening, but how would I resolve the synchronization issue? Say, when \foo is command that wants to read from the aux file?

mafp
  • 19,096

1 Answers1

30

The .aux file is read as part of the \document macro (\begin{document}) but before the \AtBeginDocument hook is used. (You can check this by inserting some 'test code' into the .aux file and the hook.)

Writing to the .aux file takes place both 'immediately' and at shipout. The latter is important to get for example the correct page numbers for cross-references, so things like \label take place in a delayed fashion, using the \protected@write 'wrapper' around the \write primitive. Thus for example

\documentclass{article}

\begin{document}
\makeatletter
\immediate\write\@auxout{\string\foo}
\protected@write\@auxout{}{\string\baz}

\end{document}

only places \foo in the .aux file: \baz is never written as there is no page shipout. In your example, shipout occurs after \foo, so you see nothing in the .aux file at that point although a shipout does occur later.

Note that TeX keeps the .aux file open until the end of the run, so you cannot be sure that any particular \write will appear in the partial .aux file during a run. As such, the only safe time to check on what gets written to the file is after the run completes. In particular, badly-terminated jobs may leave the .aux file in an incomplete state even if the crash occurs after writes 'should' have taken place.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • Thanks. But even when I do a \clearpage after the \label, and pdflatex tells me it shipped out the first page before running into the error, I still don't see anything in the aux file. Why? – mafp Jun 25 '13 at 10:30
  • @mafp A \clearpage does nothing if there's no material to build a page. – egreg Jun 25 '13 at 10:36
  • 2
    Because the file is still open for writing. It is closed only at \end{document} – Ulrike Fischer Jun 25 '13 at 10:38
  • @egreg But the section title is there, is that not enough? I mean, it says [1{/var/lib/texmf/fo nts/map/pdftex/updmap/pdftex.map}] ! Undefined control sequence. l.8 \foo, that is the shipout of the first page, no? – mafp Jun 25 '13 at 10:39
  • @mafp: No, the page shipout routine of Tex runs asynchronously. So even if the page is finished, it is not processed immediately. – Daniel Jun 25 '13 at 11:15
  • 2
    @Daniel: The problem bothering @mafp has imho nothing to do with asynchronously output. The file is still open and so its content - even if it belongs to previous pages lurks still around in memory and you don't see it if you open the file. If one would add \makeatletter\immediate\closeout\@mainaux before the error it would appear. – Ulrike Fischer Jun 25 '13 at 11:26
  • @UlrikeFischer: Well, that is asynchronous output on another level, isn't it :-) If tex has already invoked the operating system's write() syscall, it may well be the case that the file system is buffering the content until the final close(). However, this depends on the OS and using another file system could change this behaviour. However, if tex itself does some internal buffering (I don't know the implementation details) and delays the write() syscall until the \closeout\@mainaux, I would consider it as asynchronous output by tex. – Daniel Jun 25 '13 at 13:13
  • Joseph -- please add the information to your answer that tex doesn't close the .aux file until the very end. as it stands now, unless someone reads @UlrikeFischer's comments, they might still think that they should be able to see a partial .aux file if their job crashes 99% of the way through a long job, but they can't. – barbara beeton Jun 25 '13 at 13:33
  • If the people who rejected my edit understood a 10th of this helpful post, they would have realized that even if a page were shipped out, the code in the answer as of 2019-04-14 wouldn't write \baz to the .aux file. This is because \protected@write is quite different from \write. \protected@write takes 3 args and the 3rd one is subject to \edef before \write. One could write \baz with \protected@write\@auxout{}{\protect\baz} (+ put a box on page). – frougon Apr 14 '19 at 06:31
  • 1
    @frougon I'e made the edit: sorry about the missing argument – Joseph Wright Apr 14 '19 at 06:46
  • 1
    @frougon I've kept both arguments as \noexpand as the idea is to show as little difference as possible – Joseph Wright Apr 14 '19 at 06:49
  • @Joseph Wright Thanks, I was going to point out the problem with \noexpand (i.e., if the page were non-empty, \protected@write would write the expansion of \baz but not the \baz token), but if it's on purpose, okay. :) – frougon Apr 14 '19 at 06:51