我注意到您可以使用宏替换环境名称:
\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 不支持将环境名称作为宏给出:这是一个技术细节。(例如,对参数进行去标记化并按原样使用它们是有效的。)