![转义字符的 catcode 变化范围?](https://linux22.com/image/237995/%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E7%9A%84%20catcode%20%E5%8F%98%E5%8C%96%E8%8C%83%E5%9B%B4%EF%BC%9F.png)
在下面的宏中,我将转义字符()的类别代码更改\
为“其他”(12):
\def\xxA{\begingroup
\catcode`\\ = 12
\gdef\xxB ##1z{\tt ##1\endgroup}
\xxB}
这到底是怎么回事?似乎在我重新定义之后\
,其余的定义就不应该解析了。然而输入:
\xxA\bar\ba\xxAz
产生输出:
\bar\ba\xxA
显然,转义字符在参数中没有被解释。这是怎么回事?
答案1
当 TeX 扫描定义时,它不会扩展任何控制序列,也不会执行任何赋值。每个标记都会被吸收并以内部形式进行转换,而内部形式与任何外部字符表示无关。
当您使用\xxA
TeX 时,它会确定它是一个无参数的宏,因此它会用替换文本替换它:
|begingroup|catcode`|\=12 |gdef|xxB#1z{|tt #1|endgroup} |xxB
在这里,我用它们的“外部形式”来表示标记;为了区分 TeX 已经读取的符号标记,我使用管道,但它只是以某种方式写入它们:字符并不真正存在。
现在 TeX 打开该组并执行类别代码分配,并全局定义标记,|xxB
如下所示。最后,TeX 找到一个空格(传递给 胃),然后是 ,|xxB
并确定它是一个带有分隔参数的宏,因此它继续扫描更多标记。在您的示例中,它找到了 ,\bar\ba\xxAz
但现在反斜杠的类别代码为 12,因此 的参数|xxB
是\bar\ba\xxA
(所有字符),因此它删除宏和参数(直到z
),并将它们替换为
|tt \bar\ba\xxA|endgroup
(再次,管道符位于已读取的符号标记之前)。打印字符,关闭组并恢复反斜杠的类别代码。