为什么 \newcommand 对已经定义的活动字符不会产生错误?

为什么 \newcommand 对已经定义的活动字符不会产生错误?

我们(或者至少我)通常认为活动字符只是另一个命令,其名称恰好是字符而不是控制序列。那么为什么如果已经定义\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字符串(技术上是“控制序列的名称”)作为参数,而不是控制序列本身。

然而\@ifdefinable控制序列作为输入。因此如果它想使用 \@ifundefined在实施过程中,它必须提取名称:

ifdefinable 的源代码

不难看出,该检查仅适用于控制序列,而不适用于活动字符。

附注:假设当\escapechar为 -1 或 32(空格字符)时没人想使用此命令,那么它将正常工作。

附注 2,\@ifundefined与其名称所暗示的相反,它应该是(*)检查参数的含义是否任何一个undefined任一\relax
尽管如此,它首先使用\ifcsname ... \endcsname来检查它是否是undefined第一个,然后如果不是,则用名称构造控制序列来检查它是否是\relax,大概是为了在名称未定义时在哈希表中保存一个条目。
(我怀疑在 ε-TeX 之前的日子里,只执行了 csname-relax 检查,然后添加了 ifcsname 来保存一个条目;但为了保持向后兼容性,它仍然需要检查含义是否是 \relax——尽管我没有在旧的 LaTeX 源代码中检查这一点)

ifundefined 的源代码

也许有人可以找到旧版本 LaTeX 的源代码,可以确认这些版本只使用 csname-\relax 检查。

(*):或者说我是这么认为的。

相关内容