\AtEndDocument がドキュメントの *最後* で実行されないのはなぜですか?

\AtEndDocument がドキュメントの *最後* で実行されないのはなぜですか?

私はとんでもなく馬鹿げたことをやっているに違いないが、それをできるだけ絞り込んでみたが、うまくいかなかった。私は最近のコミットで発生したバグに取り組んでいる。pagectrl @ca7dc3

次のような最小限の例があります。

\documentclass{minimal}

\AtEndDocument{\typeout{wat}}

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

次のログ

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)

私にとって非常に大きな悲しみを引き起こしているのは、ログ ファイルのこの部分です。

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

watこれは、文書が始まる前に が入力されているという意味だと解釈しています( [)。何が間違っているのでしょうか?

答え1

フック\AtEndDocumentは、主に文書の最後に印刷される資料、たとえば住所やメモなどのために考えられてきました。

パッケージにはatveryend、わかりやすい名前が付いた 2 つのフックがさらに用意されています。

\documentclass{minimal}
\usepackage{atveryend}

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

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

ターミナルの出力は次のとおりです。

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.

atveryend入力されていることに注意してくださいファイル.auxが読み込まれました。

答え2

\AtEndDocument\@enddocumenthookマクロ内の更新\enddocument。以下は、\enddocument(から)内のその場所を示しています。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
   \deadcycles\z@\@@end}

\@enddocumenthook実行されることに注意してください前に \clearpageはページビルダーを起動します。そのため、wat出力は次のようになります。前にページの構築が始まります。出力させるには\clearpage、パッチを当てることができます\enddocument(または、文書の最後にフックすることはできますか?\clearpage):

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

報告.log

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

答え3

fromパッケージを\clearpage使用せずに、ドキュメントの最後にマクロを配置できます。最初の方法は非常に単純な場合に使用できます。\patchcmdetoolbox

\AtEndDocument{\clearpage\typeout{wat}}

\clearpageこれは、メインの垂直リストに破棄可能な項目のみが含まれている場合、つまり空のページが作成されていない場合に、2 番目 (LaTeX 内部から) が処理されるため機能します。ただし、他のパッケージが を使用し\AtEndDocument、それらのマクロが より前に処理されると想定している場合、この方法は失敗する可能性があります\clearpage。その場合は、より堅牢な方法を使用できます。内部制御シーケンス\afterclearpageの後に引数をシフトするマクロを定義します。\clearpage

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

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

関連情報