为什么不可展开的活动字符在 \csname...\endcsname 中不起作用?

为什么不可展开的活动字符在 \csname...\endcsname 中不起作用?

TeXbook 第 213 页对此有明确的解释\csname...\endcsname

当 TeX 扩展时,\csname它会读取匹配的标记\endcsname,并在进行过程中扩展标记;扩展完成后,只应保留字符标记。[…]

我注意到,可以通过给出如下定义来使活动字符变得不可扩展

\chardef~="16 

Then在和~等命令中将代表其自身。但为什么不起作用?\message{~}\edef\foo{~}\csname~\endcsname

答案1

标记\chardef不是一个字符,而是一个命令打印一个人物。

因此,不允许\csname...\endcsname进入特点允许使用标记(宏扩展之后)。

\edef\foo{~}产生结果是~因为\chardeftoken 不可扩展。 类似地,对于\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_typecur_cs(英文):当前状态当量cur_cs(英文):
  状态中线
  如果 当前命令outer_call 然后 检查外部有效性
  结尾

变量cur_cs0 表示字符标记,1-256 表示字符代码 0-255 的活动字符,> 256 表示真实控制序列。不幸的是,⟨ 制造控制序列名称 372⟩ 中的代码只接受具有cur_cs= 0 收集构造字符时\csname...\endcsname

\message{~}并且\edef\foo{~}工作原理基本上类似于\message{\$}\edef\foo{\$}

相关内容