的文件环境包裹说
使用环境的优点是它们的内容不被视为宏参数,因此对其中存在的内容的限制更少,并且可以更有效地处理长篇文档文本。
然而,有时“扫描”大量代码、解析它们并“不执行任何操作”(除非满足某些条件)可能会很有用。在这样做时,重要的是要知道这是否会对其余代码施加限制。
具体来说,请考虑以下文档:
\documentclass{minimal}
\long\def\everything#1end@of@everything{#1}
\def\test{test1}
\begin{document}
\everything
Hello World!
\test
%%% Some
%%% other
%%% code
end@of@everything
\end{document}
这工作正常,但是使用这种宏的“危险”是什么?在“其他代码”中什么可以发生,什么不能发生?
我想到两件事:
任何用 定义的东西
\outer
都会抛出错误(参见什么时候适合使用 \outer?)可能会有内存问题,但是这些问题有多严重,例如参数的长度是否有限制?
编辑:@Joseph Wright 指出了嵌套和(重新)标记化问题(这可能是\collect@body
为什么数学和环境比我的宏更微妙地工作)。
不过,我仍然对“效率”方面感兴趣。这个例子来自@Yiannis Lazarides,我发现
\documentclass{minimal}
\long\def\everything#1end@of@everything{#1}
\usepackage{lipsum}
\begin{document}
\everything
\newcount\n
\n=0
\def\message{I can count to }
\loop
\ifnum\n<37000
\advance\n by1
\message\number\n : \lipsum[1-2]
\repeat
end@of@everything
\end{document}
仍然有效(产生了惊人的 11563 页输出 :)),这让我想知道是否真的有任何限制数量作为参数传递的数据。
答案1
这里的两个典型限制是逐字材料和嵌套。
如果您将材料作为宏参数抓取,则 TeX 会对其进行标记。即使使用 e-TeX(或写入外部文件),我们稍后重新标记的能力也是有限的。因此
\begin{foo}
Some normal content
\verb=%=
\end{foo}
(通常)可以很好地处理,而
\foo
\verb=%=
@endfoo
不会。
在嵌套方面,使用分隔宏 TeX 将在第一个匹配处停止
\foo
\foo
stuff
@endfoo
morestuff
@endfoo
因此不会按预期运行,
\begin{foo}
\begin{foo}
stuff
\end{foo}
more stuff
\end{foo}
将要。
(我在这里使用了类似 LaTeX 的环境,但你当然也可以用纯 TeX、ConTeXt 来定义环境,ETC。具有同样的含义。