如果显示的方程式接近页面底部,TeX 会插入分页符,即使当前段落在方程式后只包含一行,例如
... it follows that
\[
a_n = ...
\]
for all $n\in\N$.
(尽管当前页面有足够的空间,但这种情况仍然会发生。)问题似乎是 TeX 不把显示方程式后面的孤行视为孤行。
因为我不喜欢这种行为,所以我想出了以下解决方法:我\avoidbreak
在结束之前写入\]
,其中\avoidbreak
定义为
\newcommand{\avoidbreak}{\postdisplaypenalty=100}
当然,现在我必须在每次出现可能“不好”的分页符时都进行书写,这很麻烦\avoidbreak
。我不想全局定义\postdisplaypenalty=100
因为这会阻止在显示方程式后分页,即使在段落末尾也是如此:对于新段落显示之后立即从下一页开始也是完全没问题的(即使它只包含一行,另请参阅下面的 MWE)。
现在我的问题是:是否有一个干净的解决方案,无需手动添加类似的东西\avoidbreak
?我很感激一些可以添加到我的序言中的代码。
\documentclass{article}
%Remove the following % to get "one line of text" onto the first page:
%\postdisplaypenalty=100
\setlength\textheight{3.65cm}
\setlength\textwidth{4cm}
\begin{document}
Two lines of text followed by a formula
\[a=b\]
Two lines of text followed by a formula
\[a=b\]
%With my code, there will be no change if you put an empty line at this place!
%If "one line of text" below starts a new paragraph, then
%that paragraph should be allowed (even encouraged) to start on a new page.
%I only want to try and avoid the page break if no new paragraph is started here.
one line of text
New paragraph
\end{document}
(让我提一下,TeX 有一个\displaywidowpenalty
参数,但这个参数是关于寡妇的前显示的方程式。
答案1
我看不出设置有什么问题\postdisplaypenalty
全局设置有什么问题——如果你遇到任何问题,它们可能是软件包错误的迹象。默认值可能对 Knuth 来说没问题;但这些设置是作为参数实现的,因为你应该定制它们。
答案2
好的,我不知道这是一个多么糟糕的黑客行为,但这是一个尝试\par
在末尾重新定义的尝试\]
,以便它可以检测它是否直接出现在显示的数学之后。
\documentclass{article}
\usepackage{etoolbox}
%Remove the following % to get "one line of text" onto the first page:
\postdisplaypenalty=100
\setlength\textheight{3.65cm}
\setlength\textwidth{4cm}
\makeatletter
\patchcmd\]{\ignorespaces}
{%
% We are in horizontal mode here again!
% Insert a penalty so we can recognize whether \par comes directly
% after.
\penalty6666
% This might conflict with \par redefinitions in lists, so only
% proof of concept!
\def\par
{%
% check whether we are directly behind formula
\@tempcnta=\lastpenalty\unpenalty
\@par
% in that case - insert negative penalty!
\ifnum6666=\@tempcnta\addpenalty\m@ne\fi
}%
\ignorespaces
}{}{}
\makeatother
\begin{document}
\tracingoutput1
\showboxdepth1000
\showboxbreadth1000
Two lines of text followed by a formula
\[a=b\]
Two lines of text followed by a formula
\[a=b\]
%With my code, there will be no change if you put an empty line at this place!
%If "one line of text" below starts a new paragraph, then
%that paragraph should be allowed (even encouraged) to start on a new page.
%I only want to try and avoid the page break if no new paragraph is
%started here.
one line of text
New paragraph
\end{document}
这可能充其量只是概念的初步证明,但至少你可以基于此开始进行真正的测试。
答案3
如果您确实不想postdisplaypenalty
全局设置该值,您可以创建一个新环境,修改环境内的显示惩罚,并在离开之前重置它。
\makeatletter
\newenvironment{tighten}{
\let\pen@old\postdisplaypenalty
\postdisplaypenalty=100
}{
\let\postdisplaypenalty=\pen@old
}
\makeatother
修改后的MWE代码:
\documentclass{article}
\makeatletter
\newenvironment{tighten}{
\let\pen@old\postdisplaypenalty
\postdisplaypenalty=100
}{
\let\postdisplaypenalty=\pen@old
}
\makeatother
%Remove the following % to get "one line of text" onto the first page:
%\postdisplaypenalty=100
\setlength\textheight{3.65cm}
\setlength\textwidth{4cm}
\begin{document}
\begin{tighten}
Two lines of text followed by a formula
\[a=b\]
Two lines of text followed by a formula
\[a=b\]
\end{tighten}
%It doesn't matter if you have a new line at this place or not!
%I only want to avoid the page break if no new paragraph is started here.
one line of text
New paragraph
\end{document}