我有一个装饰性标志来分隔子章节,定义如下:
\def\divider{
\vskip2em plus.2em minus1em
\hbox to\hsize{\hss ... \hss}
\vskip2em plus.2em minus1em
}
如果分页符位于分隔线后面,我希望分隔线后面的 \vskip 拉伸得更多 - 如果分隔线位于页面底部,我更希望它不规则,而不是拉伸该页面上的段落间空间。我该怎么做?
答案1
(最后,这和@Gustavo Mezzetti 的答案相同,但我开始时并不知道,因为我还没有读过那个答案。无论如何,用多种方式解释事情可能是有价值的……)
如果我理解正确的话,你想要的垂直粘连是无限的,如果后面有分页符(这样页面底部就会参差不齐),\vskip2em plus.2em minus1em
否则就是一个特定的有限值()。做这样的事情的方法散布在 TeXbook 中,在我看来,最好从 Knuth–Plass 论文中学习将段落分成几行。
不过,您的情况特别简单:用三重表示胶水(ideal, stretch, shrink)
,我会使用以下序列:
- 胶水(0,∞,0)
- 惩罚
- 胶水(0,-∞,0)
- 胶水(2em,.2em,1em)
这个想法是
- 如果没有发生分页,那么无限胶合就会相互抵消,其效果正是你想要的有限胶合,而
- 如果选择了分页符(在惩罚之后),那么所有后续的粘连都会被丢弃,因此效果就是无限粘连。
你可以将惩罚设置为负值或正值,具体取决于你想在多大程度上鼓励或阻止分页。有关更多信息,请参阅以下问题的答案:理解needspace
。
特别是,plain.tex
定义\filbreak
为\def\filbreak{\par\vfil\penalty-200\vfilneg}
(这在 LaTeX 中保留),因此您可以使用\filbreak
后跟您的\vskip2em plus.2em minus1em
,或者您可以更改惩罚值。
下面是一个例子(放入 saydivider.tex
并用 进行编译pdftex divider.tex
),首先使用您现有的定义(建议的更改被注释掉):
\hsize=5in \vsize=4in % Small page just to keep screenshot small
\parskip=0pt plus 100pt % Stretch exaggerated to be easier to see
\def\divider{
\vskip2em plus.2em minus1em
\hbox to\hsize{\hss \S \hss}
% \vfil
% \penalty 0
% \vfilneg
\vskip2em plus.2em minus1em
}
\input plipsum
\lipsum{1}
\divider
\lipsum{2-3}
\divider
\lipsum{5-6}
\bye
生产
(请注意段落之间的拉伸)并在取消注释这三行之后,产生参差不齐的底部而不是拉伸:
你可以阅读古斯塔沃的回答以进行更多改进。
答案2
难道这个好用的\filbreak
命令不能解决问题吗?还是我遗漏了什么?该命令及其工作原理的描述在第 111 页TeXbook,第三个“危险弯道”;也许,它只需要通过改变值来适应你的情况\penalty
。
以下是我用 LaTeX 编写的完整、可编译的示例,仅仅是为了方便(\usepackage{lipsum}
等等),但\divider
宏的定义仅使用普通的 TeX 结构。
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{lipsum}
\newcommand*{\divider}{
\par % to begin with...
\nobreak % I assume you don't want to allow a page break _before_ the
% divider
\vskip 2ex plus.2ex minus1ex
\hbox to\hsize{\hss $***$\hss}
% Comment out the following lines, from "\nobreak" to "\vfilneg"
% (inclusive) and compare results:
\nobreak
\vfil
\penalty 50 % adjust as you see it fits; but keep in mind that we are
% offering, in exchange, infinite stretchability for this page
\vfilneg
\vskip 2ex plus.2ex minus1ex
}
\flushbottom % we want to see if it works or not!
\begin{document}
\lipsum[1]\divider
\lipsum[2]\divider
\lipsum[3-4]\divider
\begingroup
\centering
\parbox[c][8\baselineskip]{.75\textwidth}{
\centering
\hrule
\vfill
Unbreakable box.
\vfill
\hrule
}\par
\endgroup
\divider
\lipsum[5]
\end{document}
答案3
\vskip2em plus.2em minus1em
请使用代替 \vspace*{2em plus.2em minus1em}
,如不符合要求请确认