为什么 \if 可以位于基数和文字整数的数字之间,而 \relax 不可以?

为什么 \if 可以位于基数和文字整数的数字之间,而 \relax 不可以?

如果我写

\count10=\iftrue'\fi10 \the\count10

那么答案就是 8,因为“if”子句添加了一个',导致10被解释为八进制。

如果我这样写,答案也是8:

\count10='\iftrue\fi10
\the\count10

但是,如果我将“if”子句换成另一个可扩展的子句,比如说\relax

\count10='\relax10
\the\count10

然后失败了:

! Missing number, treated as zero.
<to be read again> 
                   \relax 
l.16 \count10='\relax
                     10

有什么区别呢?

答案1

在扫描原始命令的参数时,有些上下文会\relax被忽略,但这不是其中之一。

TeXbook 将 ⟨filler⟩ 定义为任何空格和\relax标记序列;当扫描 时{,⟨filler⟩ 会被忽略。但请注意,TeXbook 使用{来表示类别代码为 1 的显式或隐式字符标记。因此,在标记寄存器赋值或操作中查找参数时,⟨filler⟩ 会被忽略\lowercase(参见让狮子跑来跑去。简洁地一个特殊的方面)。

被忽略的另一种情况\relax是当它用于结束要传递给\numexpr\dimexpr\glueexpr的表达式时\muexpr

当 TeX 想要确定寄存器赋值的参数时\count,它会查找可选的标记=,然后扩展标记(当然,如果可扩展的话),只要它找到可以解释为整数的东西(可能包括基数的前缀)。在第一个不能被解释为所选基数中的数字的有效输入的标记处,搜索停止,并评估该数字以供存储。

重要例外:当 TeX 确定整数是字母格式时,即前缀为`(反引号) 时,它会停止扩展标记,并将下一个字符标记或长度为一个控制序列的控制序列作为字母常量,将其转换为 ASCII 码(或 Unicode,对于 Unicode 引擎)。如果输入不正确,则会引发错误。

让我们检查一下你的尝试

\count10=\iftrue'\fi10 \the\count10
\count10='\iftrue\fi10 \the\count10
\count10='\relax10

在第一种情况下,TeX 在后面找到可扩展的内容=并将其扩展。好吧,的扩展\iftrue为空,然后'被扫描,因为它是“真实文本”的一部分;现在 TeX 知道它想要寻找一个八进制常数。接下来,它找到\fi,其扩展为空,然后是10最后是一个空格,结束扫描过程。计算数字并将值存储在寄存器中;忽略空格并继续处理,在这种情况下打印存储在寄存器中的值。

第二种情况完全类似。但第三种情况有一个问题'\relax不是忽略。它是一个不可扩展的标记,不能被解释为八进制数字,并且 TeX 会因错误而停止,因为基数前缀不是有效的数字。

出于好奇,这里是另一个失败的案例:

\chardef\foo=10
\count10='\foo

A\chardef可以在数字上下文中使用,但不能与基数前缀一起使用:它是一个“抽象”数字,就像

\count10=\count255

前缀'"只能用在明确的数字(即适当范围内的数字序列)前面。

相关内容