在我升级 Debian 并更新 texlive 后,突然出现了一个奇怪的错误。有人知道这个错误的来源吗?如何修复它?我已经使用类似的构造二十多年了,到目前为止它们看起来都很安全。如果可以避免的话,我真的不想重新连接旧的类文件。我的搜索只会出现错误的匹配结果。TIA
(编辑)最初的最小示例已由 David Carlisle 解决并在下面进行了解释。以下示例不那么简单。
% cat test.tex
\documentclass{article}
\newenvironment{testenv}{\def\foobar{1}\document}{The End\enddocument}
\begin{testenv}
Test\foorbar Test
\end{testenv}
请注意,用例是一个定义遵循相同模式的多个环境的类,并且使用 \AtBeginDocument/\AtEndDocument 并不简单。
在 Debian buster 上,它可以按预期工作
% pdflatex test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo)) (./test.aux)
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) )</usr/shar
e/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on test.pdf (1 page, 10790 bytes).
Transcript written on test.log.
在 Debian bullseye 上,我得到了
pdflatex test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Debian) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-01-09> xparse <2020-03-03>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2020/04/10 v1.4m Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
(./test.aux)
! LaTeX Error: \begin{testenv} on input line 5 ended by \end{document}.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.7 \end{testenv}
?
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) )
(\end occurred inside a group at level 1)
### semi simple group (level 1) entered at line 5 (\begingroup)
### bottom level</usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/c
mr10.pfb>
Output written on test.pdf (1 page, 10794 bytes).
Transcript written on test.log.
如果有关系的话,结果与 lualatex 或 latex 相同。
答案1
这与 TeX 或操作系统的版本无关,它是一个记录在案的更改,其中\document
进行了一些调整以适应新的挂钩系统。
以这种方式声明外部环境即使在早期版本中也是低效的,因为它会在文档周围放置一个组,导致 tex 保存文档期间设置的所有值以便在组末尾恢复。
一个没有错误并且不引入组级别的定义版本是
\documentclass{article}
\let\testenv\document
\let\endtestenv\enddocument
\begin{testenv}
Test
\end{testenv}
稍后添加扩展示例后,您可以使用钩子机制插入附加代码
\documentclass{article}
\AddToHook{begindocument/before}{\def\foorbar{1}}
\AddToHook{enddocument}{The End}
\let\testenv\document
\let\endtestenv\enddocument
\begin{testenv}
Test\foorbar Test
\end{testenv}
尽管最佳做法是只使用钩子而不重document
命名
\documentclass{article}
\AddToHook{begindocument/before}{\def\foorbar{1}}
\AddToHook{enddocument}{The End}
\begin{document}
Test\foorbar Test
\end{document}
当然,添加此类代码而不让不同的包尝试重新定义并相互绊倒是添加这些标准钩子的原因。总的来说,这已被证明是文档级别的非常兼容的更改,并且不会影响大多数包,尽管正如您所发现的,很抱歉,它确实会影响以前“手动”\document
修补的代码。\begin{document}
texdoc lthooks
有关钩子机制的更多详细信息,请参阅。