\hbox
我正在尝试删除或后面的空格\vbox
。
例子:
\def\w#1{%
\vbox{%
\hbox to #1{%
\vrule width 1pt
\kern -1pt
\vbox to #1 {%
\hrule width #1 height 1pt
\vfil
\hrule width #1 height 1pt
}%
\vrule width 1pt
\kern -1pt
}%
}%
}
\vrule width 1pt height 3cm \w{1cm} \vrule width 1pt height 3cm
我正在尝试消除\w
和之间的空格\vrule
。
谢谢您的任何建议。
答案1
您混淆了 TeX 的两个方面。
第一遍:标记化
您的输入\vrule width 1pt height 3cm \w{1cm} \vrule
将转换为以下标记序列
\vrule•w•i•d•t•h•⍽•1•p•t•⍽•h•e•i•g•h•t•⍽•3•c•m•⍽•\w•{•1•c•m•}•⍽•\vrule
笔记:•
将标记彼此分开,⍽
表示空格标记。
请注意,后面没有空格标记\vrule
。
第二遍:命令处理和扩展
第一个标记是一个基元,后面可以跟一串关键字和值;这五个标记w•i•d•t•h
被识别为一个关键字,然后 TeX 会查找维度,找到⍽•1•p•t
规则忽略空格的位置(在本例中为搜索 ⟨optional signs⟩ 的一部分)。规则也会忽略维度规范后面的空格。
对于 也类似•h•e•i•g•h•t•⍽•3•c•m•⍽
。
现在 TeX 来到了\w
一个单参数宏;由于以下标记是{
,TeX 会查找匹配的}
括号并将参数传递1•c•m
给扩展处理器:插入替换文本,并#1
用 替换1•c•m
。
请注意,此时, 的处理\vrule
尚未完成。一旦 TeX 重新开始检查标记,它就会完成,在这种情况下,它会发现\vbox
不能成为 的规范的一部分\vrule
,因此会执行命令并丢弃 到 为止的标记\vbox
。
现在确定了 的内容\vbox
(故事很长,我就略过不谈了),结束于}
。\vbox
构造 ,将其添加到正在处理的水平列表中,并丢弃标记。 接下来是空格标记,它被传递到水平列表中。 然后 TeX 找到\vrule
并继续执行前面的操作。
评论
在标记化过程中,“控制序列后忽略空格”和“命令处理过程中忽略空格标记”之间存在很大差异。在第一种情况下,空格永远不会到达嘴TeX(从技术角度来说,它不会生成任何标记)。
在命令处理过程中,一些空格标记可能会被忽略:关键字前面的空格、维度规范前面的空格、常量后面的空格(当 TeX 寻找数字时)以及其他几种情况。
一个非常重要的情况是,当 TeX 正在寻找未限定的参数到一个宏。
如果你这样做\def\macro#1#2{-#1-#2-}
,那么调用
\macro{a}{b}
\macro{a} {b}
\macro ab
\macro a b
完全等价。但这是因为\macro
定义为具有二未限定的参数。第二个参数后的空格标记不会被忽略。
在您的情况下\w
只有一个参数,因此后面的空格\w{3cm}
不会被忽略。
如果你不想要它,就不要输入它:
\vrule width 1pt height 3cm \w{1cm}\vrule
最后评论
上文中的“Space token”表示“显式空间token”,即类别代码为10的字符token。
你需要注意上述所有怪癖吗?如果你只是个普通用户,那不需要。如果你想编写 TeX 程序,你应该注意这些细节。例如,
\vbox{
abc
}
并\vbox{abc}
会产生相同的结果。相反,
\hbox{
abc
}
不会。为什么?长版本被标记为
\vbox•{•⍽•a•b•c•}
和
\hbox•{•⍽•a•b•c•}
所以它们看起来很相似,不是吗?嗯,是也不是。在这种\vbox
情况下,第一个空格标记是在垂直模式下遇到的,它什么也不做(它没有被忽略);第二个空格标记实际上会生成一个空格,但由于\par
结尾处隐式添加,因此该空格会被删除\vbox
。
在这种\hbox
情况下,两个空格标记在水平模式下被发现,并且都在水平列表中生成一个粘合节点。
答案2
我找到了错误。这是 后面的空格\w{1cm}
。TeX 忽略不会忽略格式中带有参数的宏后面的空格{}
。更正版本:
\vrule width 1pt height 3cm \w{1cm}\vrule width 1pt height 3cm