免责声明在发布问题之前重读它时,我突然想到我指的是我的计算机的 LaTeX 内核 (TeXLive 2017,\fmtversion
= 2017-04-15
)。从某种意义上说,这个问题只是历史的好奇心。
我们知道,环境可以塑造群体。我在这里问的重点是
\begin{foo}
变成(经过常规检查)
\begingroup\foo
类似地
\end{foo}
基本上
\endfoo\endgroup
现在,我的问题是{document}
环境是通过直接声明\document
和来定义的\enddocument
。前者的定义是
\def\document{\endgroup
% [THE WHOLE REST ]
}
并source2e
评论第一个\endgroup
说
取消。
\begingroup
\begin
因此,由于\end{document}
将扩展为\enddocument\endgroup
,出于对称原因,我预计的定义\enddocument
将涉及不匹配的\begingroup
;但是,我没有找到:
\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
\@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}
显然团体是以某种方式平衡:如果我使用\document
而不是 ,\begin{document}
我会得到一个关于额外的 的预期错误\endgroup
,但\enddocument
直接写 而不是 则\end{document}
可以。
我在这里遗漏了什么?
答案1
\enddocument
不需要平衡组,因为\end
(2017 年是):
\def\end#1{%
\csname end#1\endcsname\@checkend{#1}%
\expandafter\endgroup\if@endpe\@doendpe\fi
\if@ignore\@ignorefalse\ignorespaces\fi}
因此\enddocument
(以及停止 TeX 的最后步骤\@@end
)在看到之前执行\endgroup
,所以不用担心。 但是\enddocument
必须\@checkend{document}
自行执行,因为从定义来看这也不会发生\end
。
事实上,通用环境钩子(例如etoolbox
或\AfterEndEnvironment{document}{<code>}
)lthooks
永远\AddToHook{env/document/after}{<code>}
不会被执行,因为它们出现在 的代码之后\enddocument
。