练习 20.7 答案中的具体例子电子书指的是答案的以下部分吗?
未显示类别代码,但类别 6 的字符始终连续出现两次。替换文本中的参数标记使用参数文本中最后一个参数的字符代码。
答案1
该部分答案指的是 的输出\tracingmacros=1
。它也包含一个错误。 (编辑:我被答案中的另一个矛盾所吸引。原帖指出了正确的解释;这句话没有错误。)
第 205 页的练习 20.7 标有双“危险弯道”符号,要求:
假设“
[
”、“]
”和“!
”的类别代码分别为 1、2 和 6,而“{
”、“}
”和“#
”的类别代码也分别为 1、2 和 6。看看您是否能猜出以下定义的含义:\def\!!1#2![{!#]#!!2}
\! x{[y]][z}
扩展“ ”后会产生什么标记列表?
如第 37 页所述,catcode 1 表示“组的开始”(如{
)。Catcode 2 表示“组的结束”(如}
)。Catcode 6 表示参数(如#
)。因此,首先回答这个问题:
\def\!!1#2![{!#]#!!2}
┗━┳┛┗┫┗┫┗┫┃┃┃┗┫┃┗┫┗┫┃
┃ ┃ ┃ ┃┃┃┃ ┃┃ ┃ ┃┃
┗━━╋━╋━╋╋╋╋━╋╋━╋━╋╋━━━━━ \def primitive defines a macro.
┗━╋━╋╋╋╋━╋╋━╋━╋╋━━━━━ \! means that the command being defined is \! (like the \foo in \def\foo{bar} etc).
┗━╋╋╋╋━╋╋━╋━╋╋━━━━━ !1 is like #1 and means parameter 1, the first parameter passed to the macro when used.
┗╋╋╋━╋╋━╋━╋╋━━━━━ #2 means parameter 2, the second parameter passed to the macro when used.
┗╋╋━╋╋━╋━╋╋━━━━━ ! (as it's of catcode 6 and followed by a catcode 1 token) means, by the special rule mentioned after 20.5,
┃┃ ┃┃ ┃ ┃┃ that a token [ namely catcode 1, char 91 is inserted at end of both parameter text and replacement text.
┗╋━╋╋━╋━╋╋━━━━━ [ as it has catcode 1 is like { so this marks end of parameter text / start of replacement text of the macro
┗━╋╋━╋━╋╋━━━━━ { means the token { namely catcode 1, char 123
┗╋━╋━╋╋━━━━━ !# as it is two consecutive chars with catcode 6, means the token # namely catcode 6, char 35 -- HERE THE LATTER CHAR IS USED
┗━╋━╋╋━━━━━ ] means the token ] namely catcode 2, char 93
┗━╋╋━━━━━ #! as it is two consecutive chars with catcode 6, means the token ! namely catcode 6, char 33 -- HERE THE LATTER CHAR IS USED
┗╋━━━━━ !2 is like #2 and means parameter 2, the second parameter passed to the macro when used.
┗━━━━━ } marks the end of the replacement text and macro definition, but recall there's a { at end, by the special rule.
如果您的浏览器无法正确显示:
当你调用问题中提到的扩展时,例如
\catcode`[=1
\catcode`]=2
\catcode`!=6
\def\!!1#2![{!#]#!!2}
\tracingmacros=1
\message{Expansion gives \! x{[y]][z} ok?}
\end
您将第一个参数设置为x
,然后将第二个参数设置为[y]
(即{[y]]
没有周围的 begin-group / end-group 标记),并且 被[
使用,并且所有这些都被替换为标记序列{
, #
, ]
, !
, [y]
, [
。日志文件显示
\!!1#2[->{##]!!#2[
!1<-x
#2<-[y]
(#1<-x
不像练习中提到的那样:这是一个 TeX 或TeXbook,不确定 DEK 会认为它是哪一个)。在这里,在此\tracingmacros
输出中:
“类别代码未显示,但类别 6 的字符总是连续出现两次。” — 例如,显示的
##
和,每个代表一个!!
单身的catcode-6 标记的字符代码分别为#
和!
。“替换文本中的参数标记使用参数文本中最后一个参数的字符代码。” — 这指的是第一个日志行(在 的右侧
->
)中的输出参数\!!1#2[->{##]!!#2[
显示为#2
而不是!2
。 如果有\def\foo#1!2{#1#2}
,则我们会看到\foo #1!2->!1!2
,如果有 ,\def\foo!1#2{#1#2}
则我们会看到\foo !1#2->#1#2
。 也就是说,替换文本中显示的每个参数标记都\tracingmacros
使用最后的catcode-6 字符,用于宏定义的参数文本部分中的参数。[编辑:此解释由 OP 指出;删除了此处的错误解释。]
答案2
这项练习是关于解释
\def\!!1#2![{!#]#!!2}
当[
、]
和!
分别具有类别代码 1、2 和 6 时。
引用的段落之前的内容如下
顺便说一句,如果你用显示它
\tracingmacros=1
,TeX 会说\!!1#2[->{##]!!#2[ #1<-x #2<-[y]
类别代码 6 个字符的重复在顶行中很明显:扩展\!
显示为
{##]!!#2
这意味着输入流将接收
{
1#
6]
2!
6[
1y
11]
2
并且需要一个左括号。