TeX 提供了命令\vfil
和\vfill
(以及它们对应的水平版本\hfil
和\hfill
)。
这些命令实际上定义如下:
\vskip 0cm plus 1fil
\vskip 0cm plus 1fill
其中 'fil' 和 'fill'(以及事实上filll
)是无限胶合的单位,其数量级不断增加。以下是 TeXBook(第 71 页)中的一段引文:
TeX 实际上可以识别几种无穷大,其中一些无穷大比其他无穷大“更无穷”。你可以同时说
\vfil
和\vfill
;第二种无穷大比第一种更强。换句话说,如果没有其他无限可拉伸性,\vfil
会扩展以填充剩余空间;但如果\vfil
和\vfill
同时存在, 会\vfill
有效地阻止\vfil
拉伸。你可以认为\vfil
具有一英里的可拉伸性,而\vfill
具有一万亿英里的可拉伸性。
至少在理论上我知道这么多,并且我还知道我可以使用fil
和fill
版本的间距命令来获得不同的效果。
我不太清楚的是,为什么这些命令以这种方式工作,以及“无限粘合”的整个概念实际上意味着什么。
那么有人可以帮忙解释一下 Knuth 的引言吗?
答案1
让我们看看最简单的情况
\hbox to \hsize{<horizontal material>}
其中<horizontal material>
还会有粘合、隐式(即空格标记)或显式(\hskip
命令)。
TeX 维护两个四维向量来计算粘合率,例如五为了伸展和瓦为了萎缩. 胶水如
\hskip 4pt plus 2pt minus 1pt
为第一部分贡献 2pt五并将 1pt 添加到第一个组件瓦. 胶水如
\hskip 6pt plus 1fil minus 0.5fill
对第二个部分贡献 1五并将 0.5 添加到第三个分量瓦.最后我们将得到
五=(有限,一阶无限,二阶无限,三阶无限)
同样地瓦,其中组件是所有贡献的总和。TeX 还维护了 中的字符、框和粘连的自然宽度的总和<horizontal material>
。
当 TeX 收集完 的材料后\hbox
,它会将自然宽度与所需框宽度(在我们的示例中为\hsize
)进行比较,并决定要做什么。如果自然宽度等于所需宽度,它会排版框。否则,它会决定必须拉伸或收缩粘连。在前一种情况下,它会查看五后者瓦。
让我们看看拉伸的情况(另一个类似)。如果五为零,则几乎无能为力:没有胶水或胶水全部相互抵消:盒子将会不满。
否则,五不同于零;TeX 将选择最右边的非零分量。这是无穷大的顺序,胜利(可能是“有限”组件)。然后,要填充的多余空间按比例分配给贡献那无穷大阶。
让我们看一些例子
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fil minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
盒子必须拉伸 3 厘米(这是进行此类实验的方便语法),因此我们必须计算五=(2pt,3,0,0)。一阶无穷大获胜,因此多余的空间将被分割,在 B 和 C 之间增加 1cm,在 C 和 D 之间增加 2cm;A 和 B 之间将有一个 4pt 宽的空间(不拉伸)。结果是(表示最终的空间)
A<4pt>B<4pt+1cm>C<4pt+2cm>D
让我们看看
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fill minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
这里五=(2pt,2,1,0),因此二阶无穷大获胜,3cm 宽的空间将位于 B 和 C 之间:
A<4pt>B<4pt+3cm>C<4pt>D
三阶无穷大很少使用,但是当必须取消二阶无穷大时,它们可用于紧急情况。
前面的系数fil(ll)
应为绝对值小于 16384 的十进制数(必须有一个)。最小非零值为2^(-16)=0.000015
,因此说0.000014filll
相当于说0filll
(当然是无用的)。
TeX 有一些与胶水规范等效的原语:
\hfil = \hskip 0pt plus 1fil minus 0pt
\hfilneg = \hskip 0pt plus -1fil minus 0pt
\hss = \hskip 0pt plus 1fil minus 1fil
\hfill = \hskip 0pt plus 1fill minus 0pt
收缩时使用相同的算法,但是任何粘连都不会被拉伸到小于其自然宽度,而所有粘连都可用于拉伸(可能导致盒子未充满)。垂直盒子也是如此。
答案2
同意,TeXbook 在解释这些宏和关键字时有点晦涩难懂fil
。首先它指的是胶水这是用词不当弹性因为它可以扩张和收缩。
请考虑下图,您可以通过以下最少的操作获得该图表:
\def\abox#1#2{
\vbox{\hrule
\hbox
{\vrule
\hskip#1
\vbox{\vskip#1\relax
#2%
\vskip#1}%
\hskip#1
\vrule}
\hrule}}
\def\testbox#1{\abox{0.2cm}{\hbox{#1}}}
\hskip 2cm\abox{0.4cm}{\hbox{
\vbox to 4cm{\vfil\testbox A}
\vrule\ \vbox to 4cm{\testbox B\vfil}
\vrule\ \vbox to 4cm{\vfil \testbox C \vfil}
\vrule\ \vbox to 4cm{\vfil \testbox D \vfil\vfil}
\vrule\ \vbox to 4cm{\vfil \testbox E \vfill}}}
\bye
fil
实际上是一种度量,也是 TeX 的少数关键字之一,其他关键字包括“plus”、“height”、“pt”等,即关键字而非宏。在原始 Pascal 程序中,这些度量可能导致无穷大,我猜这就是为什么 Knuth 一直将它们称为无限胶水。
把它们想象成弹簧,即使它们被称为“胶水”,研究上面的图表和代码,希望它们会变得更加清晰。
答案3
Martin Scharrer 已经说过,还有一点fil
需要补充:
\hbox to \hsize{\hfil x\hfil\hfil x\hfil}
所有的\hfil
s 将延伸到相同数量x
这意味着两者之间的空间将是左右两侧空间的两倍。
答案4
正如您给出的引文所述:fill
覆盖。fil
想想fil
X为了X到无穷大,fill
则X2(或者也许XX?)。
在我看来,其背后的想法是应该使用普通格式宏fil
,它将无限拉伸到例如中心材料。无限拉伸因子只是填充剩余空间。它们仅在现有空间是预定义的(例如使用\vbox to ...{...}
或)时才起作用\hbox to ...{...}
。多个fil
共享剩余空间,可用于居中材料。如果需要,用户或包作者可以fill
手动添加拉伸以覆盖普通的fil
。这样,在这种情况下仍然可以使用普通格式宏。