[Tex/LaTex] How and when is the “aux” file read and processed

auxiliary-files

Note: I've already looked at When is the aux file read and written?, but it doesn't address the issues I'm curious about.

I wrote some commands for tracking information in my document. Since I would like to have this information available from the beginning of the document, I felt the best way to store this information would be to write it the aux file. In the process of debugging, I noticed—what seemed to me—a few odd things about what was happening with the aux file.

In particular, it seems that the aux file is processed twice: once at the beginning of the document when it is read in and again at the end when it is closed. What I'm confused about is that when the aux file is closed, it appears to execute the commands I've written to the aux file.

Consider the following code:

\documentclass{article}
%% uncommenting this next line seems to affect what gets dumped into my
%% document before processing is completed.                            
% \usepackage[paperheight=3in,paperwidth=2in,margin=0.25in]{geometry}  
\usepackage{etoolbox}

\newcounter{aecounter}

\makeatletter
%% A command to retrieve the logged page number, a user into value,  
%% and a counter value from the 'aux' file.                          
%% #1=page number                                                    
%% #2=value of what was passed to \aelogdata                          
%% #3=counter value at time that  \aelogdata was called               
\def\aedocumentdata#1#2#3{%%
   \ifcsname aepage#1value\endcsname\relax
     \expandafter\xdef\csname aepage#1value\endcsname{\number\numexpr\csname aepage#1value\endcsname+#2}
     \typeout{-[#1:#2]-->\csname aepage#1value\endcsname}%%
   \else
     \typeout{--------------------------------------------------------------------}
     \typeout{-[#1:#2]-->#2}%%
     \expandafter\xdef\csname aepage#1value\endcsname{#2}%%
   \fi
}

%% logger to write information to 'aux' file.
\newcommand\aelogdata[1]{%%
  \stepcounter{aecounter}%%
  \protected@write\@auxout{}{%%
    \string\aedocumentdata{\number\value{page}}
                        {#1}
                        {\number\value{aecounter}}}%%
}
\makeatother

\newcommand\aegetloggedinformation{%%
  \ifcsname aepage\number\value{page}value\endcsname
    [page \thepage] : value is \csname aepage\number\value{page}value\endcsname
  \else
    NOT DEFINED
  \fi
}

\AtBeginDocument{\typeout{----------BEGIN DOC----------}}
\AtEndDocument{\typeout{---------- END  DOC ----------}}
%% I alter the definition 
\AtEndDocument{\def\aedocumentdata#1#2#3{DOES THIS CREEP INTO MY FILE?\par\vspace{1cm}\typeout{<<page #1-->the #3th input value was `#2'>>}}}
%% But here, I nevertheless can manage to input something into my document   
\AtEndDocument{\par\vspace{\fill}\centering\rule{0.15in}{0.4pt} HELLO WORLD \rule{0.15in}{0.4pt}\par}
\AtEndDocument{\par\vspace{\fill}\centering\rule{0.15in}{0.4pt} BYE WORLD   \rule{0.15in}{0.4pt}\par}
\begin{document}

\aegetloggedinformation

\aelogdata{2}
\aelogdata{3}
\aelogdata{1}

\pagebreak

\aegetloggedinformation

\aelogdata{5}
\aelogdata{3}
\aelogdata{2}

\pagebreak

\aegetloggedinformation

\aelogdata{1}
\aelogdata{1}
\aelogdata{1}

\end{document}

I was not expecting to see the \typeout control sequences executed at the end of the document (in fact, it took me quite a while to figure out where they were cropping up from). A bit of tweaking and I discovered that my aux file seems to be executed as if LaTeX were innocuously reading one final \input request.

A bit more playing around with the page geometry, and I got a few more surprises. If I seemed to set the geometry just right, then this final apparent \input wasn't so innocuous after all.

Could someone explain why my commands in the aux file seem to be executed before the write stream is closed (if that is what's happening)? Also, why does the input sometimes creep into my document and sometimes not?

Regarding the effect of the geometry.

With

\usepackage[paperheight=6in,paperwidth=3in,margin=0.25in]{geometry}  

my last page looks like:

enter image description here

But with

\usepackage[paperheight=3in,paperwidth=2in,margin=0.25in]{geometry}  

my last page looks like:

enter image description here

Best Answer

Yes, LaTeX does \input{filename.aux} as part of \enddocument:

% latex.ltx, line 4057:
\def\enddocument{%
   \let\AtEndDocument\@firstofone
   \@enddocumenthook
   \@checkend{document}%
   \clearpage
   \begingroup
     \if@filesw
       \immediate\closeout\@mainaux
       \let\@setckpt\@gobbletwo
       \let\@newl@bel\@testdef
       \@tempswafalse
       \makeatletter \@@input\jobname.aux
     \fi
     [...]
   \endgroup
   \deadcycles\z@\@@end}

As you see, \@enddocumenthook is executed previously, so instructions given through \AtEndDocument are processed at that point, when typesetting has not yet been inhibited; so, if you have \AtEndDocument{foo}, the word is printed. However, typesetting text with \AtEndDocument is not recommended at all: the final instruction in \enddocument essentially flushes whatever is possibly remaining in the main vertical list. If something in the vertical list, added with \AtEndDocument produces a full page, this happens before that instruction, so a page is created (but probably this is not what you want).

Typesetting text before the aux file is closed and read back in can be done with the help of the atveryend package, that provides more hooks.

LaTeX doesn't input the .aux file when \if@filesw is set to false (by the \nofiles command). Macros are processed as usual.

It's good programming disabling macros that aren't used for consistency checks (so \newlabel isn't disabled, but given a different definition) and \AtEndDocument{\renewcommand...} is the right tool for this.

Related Question