在 Plain TeX 中,下面的代码编译没有错误
Hello\footnote*{\tt\catcode92=12 \world}!
\bye
LaTeX 中的模拟
\documentclass{article}
\begin{document}
Hello\footnote{\ttfamily\catcode92=12 \world}!
\end{document}
失败并显示错误消息
ERROR: Undefined control sequence.
--- TeX said --- <argument> ...ces \ttfamily \catcode 92=12 \world
\@finalstrut \strutbox l.4 Hello\footnote{\ttfamily\catcode92=12 \world}
!
这只是说\world
仍被视为未定义的控制序列。因此,这就像 (强制) 参数被\footnote
视为与宏参数一样,结果是无法\verb
在 LaTeX 脚注中使用。
是什么样的基本原理或实施限制导致了\footnote
LaTeX 中这个概念的贫乏(在这方面)?
答案1
LaTeX 一直都是这样做的。当然,在 LaTeX2e 中,我们有意识地决定不改变它。记录的行为是,\verb
在另一个命令的参数中不起作用。如果你让它工作,\footnote
你必须解释为什么它不起作用,\marginpar
或者在\footnote
里面\textrm{...}
或任何其他地方它会失败。基本上,LaTeX 不支持在文档中间更改 catcodes。几乎总是有更好更强大的技术可以使用,例如\footnote{\ttfamily\string\world}
在 LaTeX 中工作,即使它已经在另一个宏的参数中。
答案2
值得一提的是,此代码片段在 ConTeXt 中有效。
\starttext
Hello\footnote{\tt\catcode92=12 \world}!
\stoptext
但是,正如 David 所指出的,它失败了\inmargin
(这是 ConTeXt 的等价物\marginpar
)。这并不奇怪;所有 catcode 更改都会因解析其参数的宏而失败。话虽如此,在 ConTeXt 中处理 catcode 更改的标准方法是使用缓冲区。
\starttext
\startbuffer[catcode]
\catcode92=12 \world
\stopbuffer
Hello\inmargin{\tt\getbuffer[catcode]}!
\stoptext
在 MkII 和 MkIV 中都可以正常工作。在 LaTeX 中,filecontents
环境最接近缓冲区。(参见LaTeX 相当于 ConTeXt 缓冲区)。