我们(或者至少我)通常认为活动字符只是另一个命令,其名称恰好是字符而不是控制序列。那么为什么如果已经定义\newcommand<active character>
就不会产生错误呢?<active character>
\documentclass{article}
\begin{document}
\newcommand\newcommand{coffee} % error
\newcommand~{coffee} % no error
~
\end{document}
答案1
与任何关于 latex 的“为什么”命令一样,答案与 1985 年 (2.0x) 或 1993 年 (2e) 中可用的标记内存有关
本世纪情况有所不同
\documentclass{article}
\begin{document}
\NewDocumentCommand~{coffee} % no error
~
\end{document}
给出
! LaTeX cmd Error: Command '~' already defined.
For immediate help type H <return>.
...
l.8
?
答案2
查看源代码的答案:首先,我们有宏\@ifundefined
和\@ifdefinable
:
注意\@ifundefined
字符串(技术上是“控制序列的名称”)作为参数,而不是控制序列本身。
然而\@ifdefinable
控制序列作为输入。因此如果它想使用 \@ifundefined
在实施过程中,它必须提取名称:
不难看出,该检查仅适用于控制序列,而不适用于活动字符。
附注:假设当\escapechar
为 -1 或 32(空格字符)时没人想使用此命令,那么它将正常工作。
附注 2,\@ifundefined
与其名称所暗示的相反,它应该是(*)检查参数的含义是否任何一个undefined
任一\relax
。
尽管如此,它首先使用\ifcsname ... \endcsname
来检查它是否是undefined
第一个,然后如果不是,则用名称构造控制序列来检查它是否是\relax
,大概是为了在名称未定义时在哈希表中保存一个条目。
(我怀疑在 ε-TeX 之前的日子里,只执行了 csname-relax 检查,然后添加了 ifcsname 来保存一个条目;但为了保持向后兼容性,它仍然需要检查含义是否是 \relax——尽管我没有在旧的 LaTeX 源代码中检查这一点)
也许有人可以找到旧版本 LaTeX 的源代码,可以确认这些版本只使用 csname-\relax 检查。
(*):或者说我是这么认为的。