TeXbook 第 213 页对此有明确的解释\csname...\endcsname
:
当 TeX 扩展时,
\csname
它会读取匹配的标记\endcsname
,并在进行过程中扩展标记;扩展完成后,只应保留字符标记。[…]
我注意到,可以通过给出如下定义来使活动字符变得不可扩展
\chardef~="16
Then在和~
等命令中将代表其自身。但为什么不起作用?\message{~}
\edef\foo{~}
\csname~\endcsname
答案1
标记\chardef
不是一个字符,而是一个命令打印一个人物。
因此,不允许\csname...\endcsname
进入特点允许使用标记(宏扩展之后)。
\edef\foo{~}
产生结果是~
因为\chardef
token 不可扩展。 类似地,对于\message{~}
。
TeX 为活动字符分配特殊内部代码这一事实无关紧要。相关方面是活动字符的定义是否是宏。如果是宏,则展开;否则不是,并且其行为取决于上下文。
例如,如果你有
\chardef~="16
\csname\ifnum~="16 \string~\else foo\fi\endcsname
非常好,最终会得到。但这当然\~
不是真正的“~
在 内部使用”。\csname...\endcsname
另一方面,\&
定义为\chardef\&="26
并且\&
是不是允许“裸露”在里面\csname...\endcsname
,就像~
它是一个\chardef
令牌一样。
另一个类似的问题是隐式字符标记。如果你这样做
\let~=a
你是不是也允许~
在内部使用。\csname...\endcsname
答案2
第 47 页,共TeXbook指出
如果 TeX 发现类别 1、2、3、4、6、8、11、12 或 13 的字符,或者类别 7 的字符(该字符不是上述特殊序列的第一个字符),它会通过附加类别代码将该字符转换为标记,并进入状态米。
但这是善意的谎言。第 13 类字符实际上通过 tex.web 中的以下代码转换为一种特殊的控制序列:
353. ⟨ 处理活动字符控制序列并设置状态←中线353 ⟩ ≡
开始 cur_cs←当前状态+active_base;当前命令←eq_type(cur_cs(英文):当前状态←当量(cur_cs(英文):
状态←中线;
如果 当前命令≥outer_call 然后 检查外部有效性;
结尾
变量cur_cs0 表示字符标记,1-256 表示字符代码 0-255 的活动字符,> 256 表示真实控制序列。不幸的是,⟨ 制造控制序列名称 372⟩ 中的代码只接受具有cur_cs= 0 收集构造字符时\csname...\endcsname
。
\message{~}
并且\edef\foo{~}
工作原理基本上类似于\message{\$}
和\edef\foo{\$}
。