考虑一下这个摘录电子书:
练习 7.5 用 TEX 做实验,看看
\string
当它后面跟着一个活动字符(如 )时会发生什么~
。(活动字符的行为类似于控制序列,但它们没有以转义符为前缀。)有什么简单的方法可以在线进行此类实验? 你可以在后面放什么控制序列\string
来获得单个字符标记\ 12
?
答案如下:
如果你输入‘
\message{\string~}
’和‘\message{\string\~}
’,TEX 将分别响应‘~
’和‘\~
’。
当 Knuth 尝试在这里使用 \~ 时,他的推理流程是什么?我的意思是,我们如何从练习中逻辑地推断出我们必须尝试 \~,而那里只提到了 ~?
此外,为什么在下一个摘录中使用了“因此”这个词?我的意思是,我们如何从“ \string\~ experiment
”得出结论,我们必须创建\
一个主动角色?我可以理解“ ”的相关性\string~
,但为什么是“ \string\~
”?
因此,要从 \string获取内容
\ 12
,您需要将反斜杠变为活动字符。
此外,也可以将其设为“其他”,这在 TeXbook 中没有提及:
{\catcode`/=0 \catcode`\\=12 /message{/string\}}
顺便说一句,为什么 catcode 更改不能直接放入 \message,而不需要额外的分组(即使使用原始的 Knuth 的活动字符示例),即为什么如果我们更改原始
{\catcode`/=0 \catcode`\\=13 /message{/string\}}
进入
\message{\catcode`/=0 \catcode`\\=13 /string\}
那么它就停止工作了?
答案1
该命令\message
非常类似于\write
的工作原理它的扩张在终端上;不可扩展的标记以其名称显示,如果它们是控制字,则后面跟着一个空格。
不命令是执行,特别是任务没有执行。所以你尝试
\message{\catcode`/=0 \catcode`\\=13 /string\}
由于多种原因,它注定会失败。
的参数
\message
必须以代码中没有的显式右括号结束;TeX 将继续扫描输入以查找<right brace>
匹配的{
后\message
一个,但可能找不到。即使你输入了,
\message{\catcode`/=0 \catcode`\\=13 /string\ }
你也得不到你想要的内容,因为类别代码\
没有改变。你所得到的是因为,嗯,
plain.tex
其特点是定义\\
为一个带有分隔参数的宏;但即使你在终端上得到的\let\\=\relax
只是\message
\catcode `/=0 \catcode `\\=13 /string\
并且事后反斜杠的类别代码仍然为 0,即使该参数在
\message
技术上不构成一个组。
请注意\expandafter
办法解决这个问题,因为扩张, 不是执行:这些是 TeX 中的不同概念,并且在不同的阶段执行。
那么,为什么 Knuth 会将\string~
其与进行比较呢\string\~
?可能是因为有人认为\string
处理字符标记的方式与字母常量类似,因此
\char`~
\char`\~
\char126
是等价的。然而,对于 来说,情况并非如此\string
。
为什么 Knuth 说\
必须激活吗?我不知道;除 0、5、9、10、14、15 之外的任何字符代码都可以正常工作。
那么,如何获得宏 \backslashstring
其扩展是\
12?
有几种方法:
\begingroup\catcode`/=0 \catcode`\\=12 /gdef/backslashstring{\}\endgroup
\begingroup\escapechar=-1 \xdef\backslashstring{\string\\}\endgroup
\begingroup\lccode`?=`\\ \lowercase{\endgroup\def\backslashstring{?}}
每个人都使用不同的想法。
使用 LuaTeX(0.75 或更高版本)还可以
\edef\backslashstring{\Uchar`\\}
XeTeX 0.99992(2015 年 6 月中旬与 TeX Live 一起推出)增加了更多可能性
\edef\backslashstring{\Ucharcat`\\ 12}
并且该\Uchar
方法也有效。