# Why won't \AtEndDocument execute at the *end* of the document?

I must be doing something incredibly stupid, but I've boiled it down just as far as it can go with no luck. I'm working on a bug that's cropped up in a recent commit in pagectrl @ca7dc3.

I have the following minimal example:

\documentclass{minimal}

\AtEndDocument{\typeout{wat}}

\begin{document}
hello, world
\end{document}


with the following log

This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdflatex 2014.12.7)  9 DEC 2014 22:03
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**\input success-6.tex
(./success-6.tex (/usr/local/texlive/2014/texmf-dist/tex/latex/base/minimal.cls
Document Class: minimal 2001/05/25 Standard LaTeX minimal class
)
No file success-6.aux.
\openout1 = success-6.aux'.

LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 5.
LaTeX Font Info:    ... okay on input line 5.
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 5.
LaTeX Font Info:    ... okay on input line 5.
LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 5.
LaTeX Font Info:    ... okay on input line 5.
LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 5.
LaTeX Font Info:    ... okay on input line 5.
LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 5.
LaTeX Font Info:    ... okay on input line 5.
LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 5.
LaTeX Font Info:    ... okay on input line 5.
wat
[1{/usr/local/texlive/2014/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./success-6.aux) )
Here is how much of TeX's memory you used:
17 strings out of 493109
369 string characters out of 6135004
52967 words of memory out of 5000000
3574 multiletter control sequences out of 15000+600000
3640 words of font info for 14 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
14i,4n,10p,120b,92s stack positions out of 5000i,500n,10000p,200000b,80000s
</usr/local/texlive/2014/texmf-dist/fonts/type1/public/amsfo
nts/cm/cmr10.pfb>
Output written on success-6.pdf (1 page, 11394 bytes).
PDF statistics:
12 PDF objects out of 1000 (max. 8388607)
7 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)


What is causing me way too much grief is this portion of the log file:

wat
[1{/usr/local/texlive/2014/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]


I'm interpreting this to mean that wat is being typed out before the document even begins ([). What am I doing wrong?

• While my log file looks fine. It seems that wat is getting typed out at the end of the document. Test this with \typeout{---> the end?} just before the \end{document} and you'll set that wat is written to the log after ---> the end? is written. – A.Ellett Dec 10 '14 at 3:33
• @A.Ellett You are correct. What's more, I did a git bisect to find the bug – it's absolutely vanished. I'm a little frightened, but I won't argue voodoo magic that works in my favor. – Sean Allred Dec 10 '14 at 3:38
• @A.Ellett If you post an answer explaining the relevant output of the logfile, I'll accept it so that this embarrassment can be buried in time as quickly as possible. :) – Sean Allred Dec 10 '14 at 3:39
• Seems like you understand better than me what happened. I'm not sure my comment really warrents an answer. :( – A.Ellett Dec 10 '14 at 3:41
• @A.Ellett I can write one up then :) It will have to wait until tomorrow, though. – Sean Allred Dec 10 '14 at 4:00

The \AtEndDocument hook has been thought mainly for material to be printed at the end of a document, addresses or notes, for instance.

The package atveryend provides two more hooks, with self explaining names:

\documentclass{minimal}
\usepackage{atveryend}

\AtEndDocument{\typeout{atend}}
\AfterLastShipout{\typeout{afterlastshipout}}
\AtVeryEndDocument{\typeout{atveryend}}

\begin{document}
hello, world
\end{document}


Here's the output on the terminal:

This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./veryend.tex
LaTeX2e <2014/05/01>
Babel <3.9l> and hyphenation patterns for 79 languages loaded.
(/usr/local/texlive/2014/texmf-dist/tex/latex/base/minimal.cls
Document Class: minimal 2001/05/25 Standard LaTeX minimal class
) (/usr/local/texlive/2014/texmf-dist/tex/latex/oberdiek/atveryend.sty)
(./veryend.aux)
atend
[1{/usr/local/texlive/2014/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
afterlastshipout
(./veryend.aux)
atveryend
)</usr/local/texlive/2014/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on veryend.pdf (1 page, 11397 bytes).
Transcript written on veryend.log.


Note that atveryend is typed out after the .aux file has been read in.

\AtEndDocument updates \@enddocumenthook within the \enddocument macro. The following shows its location in \enddocument (from latex.ltx):

\def\enddocument{%
\let\AtEndDocument\@firstofone
\@enddocumenthook% <---- Hook for \AtEndDocument
\@checkend{document}%
\clearpage% <---- Starts the final page builder
\begingroup
\if@filesw
\immediate\closeout\@mainaux
\let\@setckpt\@gobbletwo
\let\@newl@bel\@testdef
\@tempswafalse
\makeatletter \@@input\jobname.aux
\fi
\@dofilelist
\ifdim \font@submax >\fontsubfuzz\relax
\@font@warning{Size substitutions with differences\MessageBreak
up to \font@submax\space have occurred.\@gobbletwo}%
\fi
\@defaultsubs
\@refundefined
\if@filesw
\ifx \@multiplelabels \relax
\if@tempswa
\@latex@warning@no@line{Label(s) may have changed.
Rerun to get cross-references right}%
\fi
\else
\@multiplelabels
\fi
\fi
\endgroup


Note that \@enddocumenthook is executed before \clearpage, which starts the page builder. As such, wat is output before the page building starts. To have it output after the \clearpage, you can patch \enddocument (or follow some guidelines in Can I hook into the end of the document but after the \clearpage?):

\documentclass{article}
\usepackage{etoolbox}
\patchcmd{\enddocument}% <cmd>
{\clearpage}% <search>
{\clearpage\typeout{wat}}% <replace>
{}{}% <success><failure>
\begin{document}
hello, world
\end{document}


The .log reports:

[1{/usr/local/texlive/2014/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
wat

• That's some top-notch information! Thanks :) – Sean Allred Dec 10 '14 at 4:42
• This doesn't guarantee the code is executed after the last page has been shipped out, in case of pending floats. – egreg Dec 10 '14 at 11:35
• In the interest not duplicating code / modular design, egreg has stolen your tick – there is still very good information here! :) – Sean Allred Dec 10 '14 at 14:32
• @SeanAllred: That's truly unfortunate, but it's the name of the game. – Werner Dec 10 '14 at 15:23

You can place your macros at end document after \clearpage without using \patchcmd from etoolbox package. First method can be used at very simple cases:

\AtEndDocument{\clearpage\typeout{wat}}


This works because the second \clearpage (from LaTeX internals) is processed when the main vertical list includes only discardable items, i.e. no empty page is created. But this method can fail when another packages use \AtEndDocument and they suppose that their macros will be processed before \clearpage. Then you can use more robust method. Define \afterclearpage macro which shifts its argument after internal \clearpage control sequence:

\documentclass{article}
\def\afterclearpage#1#2\clearpage{#2\clearpage#1}
\AtEndDocument{\afterclearpage{\typeout{wat}}}

\begin{document}
hello, world
\end{document}
`