\documentclass[a4paper]{article}
\usepackage{lipsum}
\begin{document}
\lipsum[1-4]\filbreak
\textbf{This should fit on page 1}~\lipsum[5]\filbreak\lipsum[6-10]\filbreak
\textbf{This should not fit on page 2}~\lipsum[11-12]\filbreak\lipsum[13-19]
\end{document}
问题在于最后的 \filbreak
在这个例子中。它会刷新\lipsum[13-19]
到下一页。我想\filbreak
用命令替换最后一个\stopfilbreak
,这样由于\lipsum[11-12]
实际上不适合放在第 2 页,所以它会\lipsum[11-12]
放在第 3 页上,然后放在第 3 页上\lipsum[13-19]
(第 3 页)。现在它设置\lipsum[13-19]
在第 4 页。
我想要一个命令\stopfilbreak
,让 LaTeX 解释“如果可能,将内容放在和 之间\filbreak
,\stopfilbreak
放在同一页上,否则就在这里分页,放到新页上”。后面的内容\stopfilbreak
不应该受到影响。
也就是说:我想要一个在使用后恢复正常流程的命令\filbreak
请注意,介于\filbreak
和之间的内容可能\stopfilbreak
会大于页面宽度,因此minipage
不起作用。
以下是一些我认为可能有助于回答我的问题的背景信息:
背景信息
目的\filbreak
TeXbook 表示,这\filbreak
大致意味着
“在此处分页并用空白填充底部,除非还有空间容纳更多后面跟着 \filbreak 的副本。”
也就是说,如果我们考虑被\filbreak
s “包围”的内容,如果页面上有空间,它会插入该内容,但如果没有空间,它会转到下一页。
\filbreak
在实践中
\filbreak
由 定义\par\vfil\penalty-200\vfilneg
。据我了解,这会结束当前段落,然后用可拉伸的空白填充页面,然后在页面底部/新页面顶部显示此处“中断”很便宜。如果程序随后决定在此处中断,则 不会执行\vfilneg
任何操作,因为没有\vfil
“否定”,但如果没有,则会\vfilneg
将“光标”放回原位。
我没有\filbreak
按照预期使用它。我的 VC 示例中的所有内容都按预期工作,这表明我可能问错了问题?
答案1
我之前发布过一个完全错误的答案,随后又删除了它;现在我用下面的答案替换它,它不仅至少有一定道理,而且似乎也能按预期工作!(:-)
% 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}
\makeatletter
\@ifdefinable\@My@filbreak@counter{\newcount\@My@filbreak@counter}
\global \@My@filbreak@counter = 0
\@ifdefinable\@My@filbreak@mark{\newmarks\@My@filbreak@mark}
\renewcommand*\filbreak{%
\par
\global \advance \@My@filbreak@counter \@ne
\marks\@My@filbreak@mark{\number\@My@filbreak@counter}%
\vfil
\penalty -200
\vfilneg
}
\newcommand*\@My@finish@stopfilbreak{}
\newcommand*\stopfilbreak{%
\par
\ifnum \prevdepth >\@m \else \prevdepth \z@ \fi
\nobreak \null
\nobreak \vskip -\baselineskip
\penalty \z@
\begingroup
\output{%
% \typeout{>>> \topmarks\@My@filbreak@mark
% \space vs \number\@My@filbreak@counter}%
\typeout{t: \the\pagetotal, g: \the\pagegoal}%
\unvbox\@cclv
\ifnum 0\topmarks\@My@filbreak@mark <\@My@filbreak@counter
% the last "\filbreak" is still on the current page
\gdef\@My@finish@stopfilbreak{%
\vfil\break % force page break
}%
\else
% the page has changed since the last "\filbreak"
\gdef\@My@finish@stopfilbreak{%
\penalty\z@ % allow page break but don't force it
}%
\fi
}%
\break
\endgroup
\@My@finish@stopfilbreak
}
\makeatother
\newcommand*{\mylipsum}[1]{\par\textbf{#1}~-- \lipsum*[#1]\par}
% \tracingpages = 1
\begin{document}
\mylipsum{1}
\filbreak
\mylipsum{2}
\filbreak
\mylipsum{3}
\filbreak
\mylipsum{4}
\filbreak
\mylipsum{5}
\filbreak
\mylipsum{6}
\filbreak
\mylipsum{7}
\filbreak
\mylipsum{8}
\mylipsum{9}
\mylipsum{10}
% \mylipsum{11}
\indent One.\par
\indent Two.\par
\indent Three.\par
\indent Four.\par
% \indent Five.\par
% \indent Six.\par
% \mylipsum{12}
\stopfilbreak
\mylipsum{13}
\mylipsum{14}
\mylipsum{15}
\mylipsum{16}
\end{document}
尝试取消注释以下行% \mylipsum{11}
或以下行% \indent Five.\par
。
现在,我太累了,无法详细解释代码的工作原理;也许我明天会复习这个答案,现在我只是暗示一下大概的想法。我们使用一个自定义\marks
系统,即\marks\@my@filbreak@mark
,来检测最后一个\filbreak
before是否\stopfilbreak
与后者出现在同一页上,如果是,我们强制分页;否则,\stopfilbreaks
只插入一个允许断点。
我把这个答案的先前版本留在编辑列表中,以便每个人都能思考它是多么的愚蠢……