¿Por qué no se ejecuta \AtEndDocument al *final* del documento?

¿Por qué no se ejecuta \AtEndDocument al *final* del documento?

Debo estar haciendo algo increíblemente estúpido, pero lo he reducido al máximo sin suerte. Estoy trabajando en un error que surgió en una confirmación reciente enpagectrl @ca7dc3.

Tengo el siguiente ejemplo mínimo:

\documentclass{minimal}

\AtEndDocument{\typeout{wat}}

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

con el siguiente registro

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)

Lo que me está causando demasiado dolor es esta parte del archivo de registro:

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

Estoy interpretando que esto significa que watse está escribiendo antes de que el documento comience ( [). ¿Qué estoy haciendo mal?

Respuesta1

El \AtEndDocumentgancho ha sido pensado principalmente para material que se va a imprimir al final de un documento, direcciones o notas, por ejemplo.

El paquete atveryendproporciona dos ganchos más, con nombres que se explican por sí solos:

\documentclass{minimal}
\usepackage{atveryend}

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

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

Aquí está la salida en la 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.

Nota que atveryendestá escritadespuésel .auxarchivo ha sido leído.

Respuesta2

\AtEndDocumentactualizaciones \@enddocumenthookdentro de la \enddocumentmacro. A continuación se muestra su ubicación en \enddocument(desdelatex.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}

Nota que \@enddocumenthookse ejecutaantes \clearpage, que inicia el creador de páginas. Como tal, watse produceantescomienza la construcción de la página. Para que salgadespuésel \clearpage, puedes parchear\enddocument (o seguir algunas pautas en¿Puedo engancharme al final del documento pero?despuésel \clearpage?):

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

Los .loginformes:

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

Respuesta3

Puede colocar sus macros al final del documento después de \clearpageno usarlas \patchcmddesde etoolboxel paquete. El primer método se puede utilizar en casos muy simples:

\AtEndDocument{\clearpage\typeout{wat}}

Esto funciona porque el segundo \clearpage(de los elementos internos de LaTeX) se procesa cuando la lista vertical principal incluye sólo elementos descartables, es decir, no se crea ninguna página vacía. Pero este método puede fallar cuando se utilizan otros paquetes \AtEndDocumenty suponen que sus macros serán procesadas antes \clearpage. Entonces puedes usar un método más robusto. Defina \afterclearpagela macro que cambia su argumento después de \clearpagela secuencia de control interno:

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

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

información relacionada