环境名称中的宏替换/扩展

环境名称中的宏替换/扩展

我注意到您可以使用宏替换环境名称:

\def\itmz{itemize}
\begin\itmz
\item Item the first
\item Item the second
\end\itmz             % works

它还可以\newcommand代替\def

但是,这不起作用(\end\itmz替换为\end{itemize}),

\def\itmz{itemize}
\begin\itmz
\item Item the first
\item Item the second
\end{itemize}         % doesn't work

我收到以下有点神秘的错误信息:

! Latex Error: \begin{itemize} (...) ended by \end{itemize}

对于编译器来说,幕后有什么不同tex

顺便说一句:我问这个问题并不是因为我想在打字时节省击键次数itemize;我想了解tex宏替换/扩展模型是如何工作的。

答案1

在 TeX 级别,\begin采用一个参数 ( <name>),然后使用该参数来查找宏,该宏是扩张<name>“字符”。所以在这里,我们正在寻找\itemize。存在,所以我们开始一个列表。<name>也保存了给定:这很重要。(数据保存在 中\@currenvir。)

在环境的末尾,\end还会抓取一个参数。然后检查抓取的参数是否与当前环境名称匹配。但是,没有进行扩展:我们正在执行与

\def\name{itemize}
\def\tempa{\name}
\def\tempb{itemize}
\ifx\tempa\tempb
  % TRUE
\else
  % FALSE
\fi

如果你运行这个示例,你会发现这是错误的:定义并不相同(尽管它们扩展为同一件事)。

打印该消息时,您会收到一条“有趣”的消息进行扩展。所以您看到的可能就是您认为自己正在做的事情!

有人可能会说,LaTeX 内核可以\edef(彻底扩展)两端的环境名称,在这种情况下,问题就会消失。但是,正式的 LaTeX 不支持将环境名称作为宏给出:这是一个技术细节。(例如,对参数进行去标记化并按原样使用它们是有效的。)

相关内容