当我浏览 TeXbook 第 225 页左右并解决其中的练习 21.6 时出现了这些问题:
在 中和本质上
\leaders
是 相同的吗?换句话说,在 中和有什么区别?\vrule
\hrule
\vrule
\hrule
\leaders
为什么 和 都
\vrule
可以\hrule
用\leaders
?我想知道 下的水平模式被限制了\leaders
。为什么 两个规则都可以用?有什么特别的原因吗?
答案1
在 中使用时,
\vrule
和之间绝对没有区别,除了默认值(默认宽度为 0.4pt 和“连续”高度和深度,以及默认高度+深度为 0.4pt+0pt 和“连续”宽度)。换句话说,如果您明确指定宽度、高度和深度,则完全没有区别。\hrule
\leaders
\vrule
\hrule
关于“我想知道它是否是受限水平模式
\leaders
”:里面的规范\leaders
不是受限水平模式;它只是一个盒子规范。水平/垂直模式的问题仅适用于如何将盒子组合在一起。关于“为什么在一般用法中将规则区分为 \vrule 和 \hrule”:这只是为了方便表明您的意图或避免错误,例如在垂直模式下 a
\hrule
停留在同一个列表中,但 a\vrule
开始一个新段落,而在水平模式下 a\vrule
停留在同一个列表中,但 a\hrule
显示错误。我想这也回答了“为什么可以在那里使用这两种规则”:因为\leaders
错误范围较小,或者想要“错误”类型的规则不那么奇怪,等等。(正如TeXbook您在第 225 页上提到:“这种情况\hrule
在水平模式下是有意义的,因为它在文本中给出了水平规则。”)
详细说明上面的(1):如果你看一下 TeX 的源代码,这一点就很清楚了。(调用texdoc tex.pdf
或获取 B 卷计算机和排版。)源代码的组织方式不太容易“证明”这一点,但以下内容基于阅读所有出现“vrule”或“hrule”字符串的部分及其依赖项。基本上,它的工作原理如下:
- TeX 定义了内部命令代码
vrule
和hrule
(在“第 15 部分:命令代码”的第 208 节中)。原语\vrule
和\hrule
被定义为具有这些命令代码(在“第 18 部分:哈希表”的第 265 节中)。因此,当在输入中看到\vrule
或时,TeX 会将其分别转换为内部命令或。\hrule
vrule
hrule
- 类似地,TeX 为 、 和定义了内部命令代码
leader_ship
(可能是双关语,因为它同时用于领导者和\shipout
,以及“领导力”一词)。\shipout
\leaders
\cleaders
\xleaders
这些命令(vrule
和hrule
)可以在两种情况下遇到。
当 TeX 在主控制循环中遇到水平模式 / 垂直模式 / 数学模式下的
vrule
或hrule
命令时,它采取的操作如下:- 对于
mmode + hrule
:在§1046中(insert_dollar_sign
即显示错误并重新同步), - 对于(常见情况)
vmode + hrule
,或hmode + vrule
,或mmode + vrule
:§1056(只需调用scan_rule_spec
即可获取规则节点,并附加到当前列表的尾部)。 - 对于
vmode + vrule
:在§1090中(开始新的段落并备份输入,即转到上一个案例), - 对于
hmode + hrule
:在§1094(显示错误等)。
- 对于
另一种情况是领导者的情况。当 TeX 在主控制循环中遇到任何这些“领导者”命令时,它采取的操作如下:
- 对于
any_mode(leader_ship)
:在 §1073 中(scan_box
使用标志调用,说明哪种领导者或 shipout)。此scan_box
过程在 §1084 中定义:它也(在领导者和当前命令为 vrule/hrule 的情况下)调用scan_rule_spec
,然后调用box_end
(根据当前模式查找 §1078 中的尾随\hskip
或\vskip
)。
- 对于
总结一下目前为止案例的控制流程:
因此,主要情况是对 的调用。scan_rule_spec
此函数在 §463 中定义,并且它是唯一与 相关的(除了上面 (1) 中的顶级情况之外):vrule
hrule
在这里,如您所见,新创建的规则节点以默认的“运行”维度开始(即“按照 §138 和 §139 运行规则直到最内层封闭框的边界”),但根据命令是“hrule”还是“vrule”,会分配不同的宽度/高度/深度。但任何后续指定的宽度、高度或深度都会立即覆盖这些默认值,因此只要指定了它们,无论命令最初是“vrule”还是“hrule”,效果都是完全相同的。
答案2
完全不一样。首先我们来分析一下垂直模式下会发生什么。
调用将使用when\leaders\vrule
的默认值,或者未提供。例如,\vrule
height
depth
width
\def\init{\hsize=3cm\parindent=0pt x\par}
\vbox{\init\leaders\vrule width1pt\vskip1cm}
\bigskip
\vbox{\init\leaders\vrule height1pt\vskip1cm}
\bye
将绘制 1cm 高规则,第一条 1pt 宽,第二条 0.4pt 宽。相反,
\def\init{\hsize=3cm\parindent=0pt x\par}
\vbox{\init\leaders\hrule width1pt\vskip1cm}
\bigskip
\vbox{\init\leaders\hrule height1pt\vskip1cm}
\bye
将打印两个 1cm 高的规则,第一个 1pt 宽,第二个 3cm 宽(一个丑陋的大黑色矩形),因为默认使用封闭框的宽度,因为\init
排版了一个段落,所以结果为 3cm。
您可以尝试在水平模式下观察差异。