Warum wird \AtEndDocument nicht am *Ende* des Dokuments ausgeführt?

Warum wird \AtEndDocument nicht am *Ende* des Dokuments ausgeführt?

Ich muss etwas unglaublich Dummes tun, aber ich habe es so weit wie möglich reduziert, ohne Erfolg. Ich arbeite an einem Fehler, der in einem kürzlichen Commit inpagectrl @ca7dc3.

Ich habe folgendes Minimalbeispiel:

\documentclass{minimal}

\AtEndDocument{\typeout{wat}}

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

mit folgendem Protokoll

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)

Was mir viel zu viel Kummer bereitet, ist dieser Teil der Protokolldatei:

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

Ich interpretiere das so, dass wates abgetippt wird, bevor das Dokument überhaupt beginnt ( [). Was mache ich falsch?

Antwort1

Gedacht ist der \AtEndDocumentHaken vor allem für Material, das am Ende eines Dokuments abgedruckt werden soll, beispielsweise Adressen oder Notizen.

Das Paket atveryendbietet zwei weitere Hooks mit selbsterklärenden Namen:

\documentclass{minimal}
\usepackage{atveryend}

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

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

Hier ist die Ausgabe auf dem 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.

Beachten Sie, dass atveryendausgeschriebennachdie .auxDatei wurde eingelesen.

Antwort2

\AtEndDocumentAktualisierungen \@enddocumenthookinnerhalb des \enddocumentMakros. Im Folgenden wird die Position in \enddocument(vonlatex.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
   \deadcycles\z@\@@end}

Beachten Sie, dass \@enddocumenthookausgeführt wirdVor \clearpage, das den Seitenersteller startet. Als solches watwird ausgegebenVorder Seitenaufbau beginnt. Um die Seite auszugebennach\clearpagekönnen Sie patchen ( \enddocumentoder einige Richtlinien inKann ich am Ende des Dokuments einhaken, abernachDie \clearpage?):

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

Die .logBerichte:

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

Antwort3

Sie können Ihre Makros am Ende des Dokuments platzieren, \clearpageohne \patchcmddas etoolboxPaket zu verwenden. Die erste Methode kann in sehr einfachen Fällen verwendet werden:

\AtEndDocument{\clearpage\typeout{wat}}

Dies funktioniert, weil die zweite \clearpage(aus den internen LaTeX-Elementen) verarbeitet wird, wenn die vertikale Hauptliste nur verwerfbare Elemente enthält, d. h. es wird keine leere Seite erstellt. Diese Methode kann jedoch fehlschlagen, wenn andere Pakete sie verwenden \AtEndDocumentund davon ausgehen, dass ihre Makros vorher verarbeitet werden \clearpage. In diesem Fall können Sie eine robustere Methode verwenden. Definieren Sie \afterclearpageein Makro, das sein Argument nach der internen \clearpageSteuersequenz verschiebt:

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

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

verwandte Informationen