TeX 不使用哪些标记作为未限定的参数(除非在 { 和 } 之间)?

TeX 不使用哪些标记作为未限定的参数(除非在 { 和 } 之间)?

TeX 不使用哪些标记作为未限定的参数(除非嵌套在类别代码 1 的显式字符标记和类别代码 2 的显式字符标记之间)?

在 TeXbook 练习 20.4 之前的倒数第二个危险弯道段落中,你会发现这样的句子:

在输入 ' \def\row#1#2{...}' 之后,你可以在参数之间添加空格(例如 ' \row x n'),因为 TeX 不使用单个空格作为无限参数。

在 TeXbook 练习 20.5 之前的 double dangeorus bend 段落中,你会发现以下句子:

你可能会问,TeX 如何确定一个参数在何处结束。答案是:[...]未限定的参数紧接着⟨参数文本⟩通过参数标记,或者它出现在参数文本的最末尾;在这种情况下,相应的参数是下一个非空白标记,除非该标记是“ {”,此时参数将是{...}后面的整个组。

在 TeXbook 中,我确实没有找到“单个空格”和“非空白标记”这两个术语的精确定义。

请枚举 TeX 不用作非限定参数的所有标记(除非嵌套在类别代码 1 的显式字符标记和类别代码 2 的显式字符标记之间)。

现在我发现 TeX 不使用类别代码 10 和字符代码 32 的显式字符标记作为未限定的参数 - 您需要关注 TeX 对的\macro第二个参数所采取的方式:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A B 
\show\macrob
\bye

类别代码 10 和字符代码 32 的隐式字符标记用作未限定的宏参数:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\X=13
\uppercase{\let\space= } %
\uppercase{\letX= } %
\macro A\space B 
\show\macrob
\macro AXB
\show\macrob
\bye

显式的有趣空格被用作未限定的宏参数:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\uccode`\ =`\a
\uppercase{\macro A B}%
\show\macrob
\bye

隐式滑稽空格被用作未限定的宏参数:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\def\letcs#1#2{\let#1= #2}%
\catcode`\X=13
\uccode`\ =`\a
\uppercase{\letcs\space{ }}%
\uppercase{\letcsX{ }}%
\macro A\space B 
\show\macrob
\macro AXB
\show\macrob
\bye

类别代码 12 和字符代码 32 的隐式/显式字符标记用作未限定的宏参数:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\ =12\relax%
\let\space= %
\macro{A} {B}%
\show\macrob
\macro{A}\space{B}%
\show\macrob
\bye

控制空格用作未限定的宏参数:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A\ B
\show\macrob
\bye

因此我测试了一些情况,但测试边缘情况既不能对术语“单个空格”做出精确定义,也不能对术语“非空白标记”做出精确定义。;-)

换句话说:我不知道 TeX 不将哪些标记用作未限定的参数(除非嵌套在类别代码 1 的字符标记和类别代码 2 的字符标记之间)。

似乎数量⟨太空代币⟩不等于“单个空格”/“非空白标记”:

TeXbook 在第 24 章“垂直模式摘要”中说道:

数量⟨太空代币⟩,用于语法⟨可选空格⟩上面的 代表显式或隐式空间。换句话说,它表示类别 10 的字符标记,或者表示当前含义已通过\let或等于此类标记的控制序列或活动字符\futurelet

提到的“控制序列或活动字符”,可归入⟨太空代币⟩,将被用作未分隔的宏参数 - 上面的例子显示了这一点 - 而“单个空格”/“非空白标记”不被用作未分隔的宏参数。

可能“单个空格”/“非空白标记”是⟨太空代币⟩

如果是的话——具体是哪个子集?

答案1

TeXbook 的风格通常是说一些正确的事情,但不是完全的事实。

没有“单一空间”的正式定义,因为没有必要。

事实上,如果你尝试

\begingroup\def\\{\global\let\spacetoken= }\\ \endgroup

\def\foo#1#2{(First is #1)(Second is #2)}

\foo AB

\foo A B

\edef\two{\space\space}
\expandafter\foo\expandafter A\two B

\foo A\spacetoken B

\bye

你会得到三个实例

(第一为 A)(第二为 B)

最后一行将生成

(第一个是 A)(第二个是 )B

这个技巧是在和\expandafter之间插入多个空格。所以你看下一个练习是“更正确的”:TeX 跳过任何AB明确的寻找未限定参数时,空格标记。

最后一个例子表明隐式空格标记不会被跳过。代码中的第一行是从练习 24.6 中借用的,用于创建\spacetoken隐式空格标记,因为不能简单地像 中那样执行\let\bgroup={。如果你添加,\show\spacetoken你会得到

> \spacetoken=blank space  .

但这是不是在寻找未限定的参数时被忽略。

显式空格标记是类别代码为 10 的字符标记(正常设置下为空格或制表符;但如果您对此感兴趣,请参阅后面的更多详细信息)。正常设置下,这可能由输入中的空格或制表符生成,或者由在对输入进行标记时分配类别代码 10 的任何字符生成。


但是,有一个问题。总是有一个问题!

必须考虑到 TeX 会吸收类别代码为 10 的字符,并根据其原始字符代码为其分配字符代码 32。因此制表符与空格没有区别,因为它们一旦完成标记化,情况也是一样。

那么,问题是什么

\uccode` =`x \uppercase{\foo A B}

不忽略有趣的空间?事实上,它不同于

\catcode`*=10 \foo A*B

忽略星号,因为它的类别代码为 10。

事实上,类别代码为 10 的角色是规范化字符代码为 32在标记化过程中。但是,当\uppercase应用时,标记化已经执行,并且空格具有字符代码 32。但是之后\uppercase字符变为x10,它不再有效并且不能被忽略,因为它没有字符代码 32。

因此,只忽略字符代码 32 和类别代码 10 的字符的答案是正确的,但如果不考虑规范化,则会产生误导。

答案2

tex.web 有

begin if cur_tok=space_token then

跳过被忽略的space_token标记

@d space_token=@'5040 {$2^8\cdot|spacer|+|" "|$}

答案3

在“寻找”未限定参数的开头时,TeX 只会跳过字符代码 32 和类别 10(空格)的显式字符标记序列。


数量⟨太空代币⟩确实不等于您引用的 TeXbook 段落意义上的“单个空格”/“非空白标记”:

数量⟨一个可选空格⟩定义为:

⟨一个可选空格⟩⟨太空代币⟩|⟨空的⟩

无论何处⟨一个可选空格⟩是允许的,这也可以是一个隐式的空间标记。

例如,参见

\lowercase{\let\sptoken = } %
\edef\result{\number1234 }
\show\result
\edef\result{\number1234\sptoken}
\show\result
\let\result\sptoken\sptoken=\sptoken\TeX
\bye

(这里\lowercase 只是删除了括号。这样,您将在“=”后面获得两个字符代码为 32 的显式空格标记。第一个将被丢弃,因为使用\let-assignments 时,“=”后面的一个空格是可选的。第二个将不会被丢弃,但将成为其含义被分配给的标记\sptoken。)

\sptoken是隐式空格标记。
它在 TeX\number求值期间被丢弃,就像显式空格标记一样。
它也像任何其他空格标记一样被丢弃⟨可选空间⟩在执行第二个\let赋值时。但是 TeX在“寻找”未限定参数的开头时
不会跳过。\sptoken

所以这个例子证明了数量⟨太空代币⟩并不等于您所引用的 TeXbook 段落意义上的“单个空格”/“非空白标记”。


顺便一提:

您的问题集中在 TeX 在寻找未限定参数的开头时如何处理标记。

您的问题涉及标记化已经完成的处理阶段。

不过,值得一提的是与 .tex-input 标记过程相关的一个事实:

如果在对 .tex 输入进行标记的过程中,TeX 遇到类别代码为 10(空格)的字符,而读取设备处于状态 M(行中间),则 TeX 会将类别 10(空格)和字符代码 32 的明确字符标记附加到标记流中。也就是说,无论所讨论的输入字符的代码点有多少个数字,生成的标记都将具有字符代码 32。

例如,水平制表符(水平制表符在 ASCII 中的代码点编号为 9)通常也分配有类别代码 10。因此,对水平制表符进行标记通常会产生类别 10(空格)和字符代码 32 的明确字符标记。即,TeX 在“寻找”未定界参数的开头时跳过的那个标记。

相关内容