9

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

  • Commands are executed both in the first reading and at end document. – egreg Jan 3 '16 at 18:54
  • @egreg So is there a way to inhibit that behavior at the end of the document (other than make sure the commands work rather innocuously)? – A.Ellett Jan 3 '16 at 19:01
  • @egreg Or perhaps a better question is: why is this the preferred approach at the end of the document? (I can easily work around it by \letting my commands to \relax in the \AtEndDocument hook.) – A.Ellett Jan 3 '16 at 19:04
7

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.

  • Any idea about why the different output depending upon my page geometry? – A.Ellett Jan 3 '16 at 19:09
  • @A.Ellett I see nothing particularly strange; what are you referring to? – egreg Jan 3 '16 at 19:11
  • If I uncomment my \usepackage[...]{geometry} line, I get different output from the aux file, but not for every page geometry. – A.Ellett Jan 3 '16 at 19:13
  • I've updated the question to show the different geometries I've experimented with and the resulting last page of the document. – A.Ellett Jan 3 '16 at 19:17
  • package atveryend provides convenient hooks into \enddocument. – user4686 Jan 3 '16 at 19:47
4

latex is not expecting the aux file to typeset text, it is input to check cross references after the final \clearpage that flushes all text and floats.

So any text that is typeset to the main vertical list is likely to be lost unless (as with your short page version) you typeset enough to trigger a "natural" page break in which case (just) the text before the page break will be output.

  • That is useful to know. – A.Ellett Jan 3 '16 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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