\enddocument 定义中缺少(?)\begingroup

\enddocument 定义中缺少(?)\begingroup

免责声明在发布问题之前重读它时,我突然想到我指的是我的计算机的 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

相关内容