(注:\parindent
为了外观更好,设置为0。)
\noindent\hrulefill\par %With one single \hrulefill I get nothing.
a\hrulefill b\par %As desired.
\noindent\hrulefill b\par %As desired.
a\hrulefill\par %The "a" is there, but \hrulefill is not.
\hbox to\hsize{\hrulefill} %As desired
上面 5 个例子中的行为\hrulefill
确实让我感到困惑。我以为 TeX 应该在所有情况下将整行(当然\parfillskip
)打包到宽度为 的水平盒子中\hsize
,但上面的结果告诉我我一定是错的。到底发生了什么?
答案1
\hrulefill
我猜你使用的是纯 TeX。让我们看看第 707 行的定义plain.tex
:
\def\hrulefill{\leaders\hrule\hfill}
如果你这样做会发生什么
a\hrulefill\par
就像你的第三个例子一样?好吧,标准行为\par
适用,这在 TeXbook 第 286 页有解释。
▪
\par
。原始\par
命令(在纯 TeX 中也称为\endgraf
)在受限水平模式下不执行任何操作。但它会终止水平模式:通过执行 结束当前列表\unskip\penalty10000\hskip\parfillskip
,然后将其分解为行(如第 14 章所述),TeX 返回封闭垂直或内部垂直模式。段落的行将附加到封闭垂直列表中,中间穿插有行间粘连和行间惩罚,以及水平列表中的垂直材料的迁移。然后 TeX 执行页面生成器。
自从\hrulefill
是胶水,则可以通过 去除\unskip
。
如果您查看 TeXbook 的源代码,您会发现它只\hrulefill
用于框中,无论是明确构建的\line
还是表格材料中的。
与 LaTeX 的定义比较:
% latex.ltx, line 616:
\def\hrulefill{\leavevmode\leaders\hrule\hfill\kern\z@}
如果必要的话,启动\leavevmode
水平模式;\par
由于不移除字距,所以\unskip
不会移除引线。
在普通 TeX 中,如果在垂直模式下使用,\hrulefill
则会出现错误
! Leaders not followed by proper glue.
<to be read again>
\hfill
因为它不会启动水平模式。如果紧接着\par
它就会消失。
那么,为什么 TeX 在结束一个段落时会删除粘连呢?结束一个段落的通常方法不是附加\par
,而是留下一个空行:
This is a paragraph.
This is another one.
按照规则,空白行将转换为\par
标记,因此我们得到相当于
This is a paragraph. \par
This is another one.
并且必须删除行尾转换产生的尾随空格,否则会影响换行。在某些情况下,\parfillskip
当最后一行几乎已满时,它可能会导致只包含粘连的不必要的空白行。