跟踪 LaTeX 分页惩罚的错误,调整 KOMAscript 中的橡胶长度跳过

跟踪 LaTeX 分页惩罚的错误,调整 KOMAscript 中的橡胶长度跳过

我使用 KOMAscript 的scrbook类。我对梅花/寡妇非常挑剔。有趣的是,大多数梅花和寡妇主要出现在具有多个流程、显示数学环境和/或标题的页面上。我认为这很了不起,因为所有这些元素及其可伸缩的垂直跳跃都应该为 LaTeX 提供足够的灵活性以避免梅花/寡妇。

目前,某个页面让我抓狂,这让我认为我对橡胶长度和惩罚机制存在概念上的误解(见下图)。不幸的是,我无法重现 MWE。这个有问题的页面是第 70 页。

无论如何,为了摆脱俱乐部,我在序言中添加了以下内容

\clubpenalty=9000           % Default:   150
\widowpenalty=9000          % Default:   150
\displaywidowpenalty=3000   % Default:    50
\setlength\floatsep       {12\p@ \@plus 6\p@ \@minus 2\p@}   % Default: 12\p@ \@plus 2\p@ \@minus 2\p@ (scrsize10pt.clo)
\setlength\textfloatsep   {20\p@ \@plus 10\p@ \@minus 4\p@}  % Default: 20\p@ \@plus 2\p@ \@minus 4\p@ (scrsize10pt.clo)
\setlength\intextsep      {12\p@ \@plus 6\p@ \@minus 2\p@}   % Default: 12\p@ \@plus 2\p@ \@minus 2\p@ (scrsize10pt.clo)
\setlength\dblfloatsep    {12\p@ \@plus 6\p@ \@minus 2\p@}   % Default: 12\p@ \@plus 2\p@ \@minus 2\p@ (scrsize10pt.clo)
\setlength\dbltextfloatsep{20\p@ \@plus 10\p@ \@minus 4\p@}  % Default: 20\p@ \@plus 2\p@ \@minus 4\p@ (scrsize10pt.clo)

但什么都没变。如果我算得没错的话,我允许了 4pt ( \floatsep) 和 8pt ( \textfloatsep) 额外的可伸缩跳过的盈余。仅凭这一点(总共 12pt)就足以让 LaTeX 在页面底部挥舞棍棒了。

看来 LaTeX 认为球杆的危害程度比拉伸橡胶长度要小。拉伸/收缩橡胶长度也会受到惩罚吗?如果是,惩罚程度是多少?

只是,如果我将\clubpenalty=10000即设置为“无穷大”,俱乐部就会消失。但是,我在某处读到,设置无穷大不是一个明智的选择,因为如果遇到几个同样糟糕的解决方案,LaTeX 可能会选择一个非常丑陋的解决方案。

有没有办法在计算过程中回溯惩罚计算并记录当前值?

附言:完全不同的是,我想知道我对惩罚和长度的重新定义是否“符合 KOMA”。我知道,KOMA 在许多方面都有自己的界面,例如设置字体或更改标题。因此,我也考虑了我的重新定义被忽略的可能性。

末尾有一个棍棒的不听话的页面: 尽管有两个浮动和一个标题,但页面仍带有一个棍棒

答案1

免责声明:此答案是由 TeX 新手撰写的,应谨慎考虑

这里的信息基于“TeXbook”和“LaTeX 2e 来源”以及我从启用的调试输出中得出的结论\tracepages=1

要理解 TeX 如何决定分页符,以下术语很重要。

坏处: 糟糕之处b页面布局(或更准确地说,垂直框列表)的“粘连必须拉伸或收缩以形成所需大小的 [框] 的比率的立方乘以 100”。最初,此定义是针对水平框和段落行给出的(参见 TeXbook 第 14 章第 97 页),但“垂直不良度的计算规则与水平不良度相同”(TeXbook 第 15 章第 111 页)。

惩罚:惩罚是与断点关联的整数值。例如,如果在段落之间分页,则为零;\clubpenalty如果分页会导致出现分节符,则为 (使用上面的例子)。

插入惩罚:插入惩罚是一种与插入文本分割相关的特殊惩罚。插入文本是 TeX 术语,指任何无序放置的垂直框。LaTeX 只识别在 TeX 插入文本之上实现的浮点数和脚注。在 TeX 中,插入文本可以跨页面分割,但在 LaTeX 中只有脚注可以分割,而普通浮点数则被实现为不可分割。分割脚注的惩罚由 参数化\floatingpenalty

成本: 成本C是在特定点分页的总成本,TeX 在决定最佳分页点时会尽量减少页面成本。成本通常计算为

c=b+p+q

带着恶意b, 惩罚并插入惩罚如上所述。我写“通常”,因为真正的公式稍微复杂一些,并且是按照逐案方式定义的,当其中一个值为无限时,确实会处理特殊情况(参见 TeXbook 第 15 章第 111 页)。

观察/猜测 1:在计算分页符的成本时,TeX 确实考虑了垂直粘连的可拉伸部分,即b-component(不良分量)。如果具有足够的可拉伸性,使得拉伸的垂直框堆栈的不良性小于惩罚那么 TeX 应该做出反对俱乐部的决定并扩展页面的内容。

更多定义:

球门高度:球门高度G是需要用垂直框列表填充的页面的期望高度。对于没有插入内容的页面,G等于\textheight

总页数:页面总数是页面上所有垂直框的高度,并且还具有收缩/拉伸分量(由各个垂直框的拉伸/收缩分量产生)。

为了构建页面,TeX 会逐步向页面添加更多垂直框。在每个步骤中,TeX 都会计算成本C根据上面的公式。当页面总数大于目标高度G, 即使缩小到最小,即尽可能多地将内容挤到页面上。然后 TeX 从产生最低成本的步骤中选择一组垂直框。

然而,如果插入内容(又称 LaTeX 浮动内容)发挥作用,就会发生一些有趣的事情。插入内容不会添加到垂直框列表中,从而增加页面总数,但插入内容的自然高度会从页面目标中减去G换句话说,TeX 试图填充更小的页面(减少了插入内容所占用的空间)。

让我们看一下上面所描绘页面的调试输出。记住我们设置了\clubpenalty=9000\widowpenalty=9000,在这种情况下页面高度等于 \textheight = 582.19865pt

%% goal height=582.19865, max depth=5.5
%% goal height=381.98903, max depth=5.5
%% goal height=173.92876, max depth=5.5
% t=0.0 g=173.92876 b=10000 p=0 c=100000#
% t=40.64388 plus 1.93948 g=173.92876 b=10000 p=0 c=100000#
% t=56.96384 plus 2.93948 g=173.92876 b=10000 p=9100 c=100000#
% t=73.2838 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=73.2838 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=73.2838 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=73.2838 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=89.60376 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=105.92372 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=122.24368 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=138.56364 plus 2.93948 g=173.92876 b=10000 p=9000 c=100000#
% t=154.8836 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=171.20357 plus 3.93948 g=173.92876 b=33 p=9000 c=9033#
% t=187.52353 plus 3.93948 g=173.92876 b=* p=0 c=*

对于普通页面(无插入页),只有一个以双百分比 ( %%) 开头的顶行。但此处我们在页面顶部有两个插入页,它们一起将目标高度降低至 173.92876pt。

然后 TeX 陆续将“正常”行添加到剩余的页面,可以通过增加值。请注意,页面总数具有灵活性,但唯一的灵活性(加号部分)来自标题(上图中的“4.2.1 注册”)和待办事项框。同一段落的行与行之间没有灵活性。

倒数第四行,显示惩罚值p = 9000如果页面在“输出到新页面”之前被破坏,则这是寡妇的惩罚(参见上图)。

倒数第三行再次显示零惩罚,因为第一段已完成。这将在“新注册的一方”之后创建分页符(参见上图)。

倒数第二行再次显示惩罚值p = 9000。这是俱乐部的惩罚,我们想取消它。

最后一行显示編號 0 編號。这是 TeX 表示无法在页面上添加额外行的方式,即页面总数大于页面目标G

有趣的是

% t=154.8836 plus 2.93948 g=173.92876 b=10000 p=0 c=100000#
% t=171.20357 plus 3.93948 g=173.92876 b=33 p=9000 c=9033#

我们想避免俱乐部。尽管俱乐部的惩罚是 9000,但计算出的成本是 9033,这仍然小于第一段后分页的成本。为什么?让我们来算一下。

页面目标等于 173.92876pt。如果只将第一个段落放到页面上,页面总高度(即自然高度)为 154.8836pt。这导致缺失内容的增量为 19.04616pt。允许的可伸缩性为 2.93948pt。(请记住,这只是部分标题的可伸缩性。)结果为 100*(19.04616pt/2.93948pt)^3 = 27,198 的不良率。TeX 将此值截断为 10,000,这就是我们在第一行中看到的。

对第二行进行同样的计算,我们可以确认 100*( (173.92876pt-171.20357pt)/3.93948pt)^3 = 33 为不良率。加上俱乐部惩罚,我们得到总成本 9033。请注意,由于段落间可伸缩性,我们的可伸缩性也略高一些,即 3.93948pt。

结论:TeX 在计算分页符的成本时会考虑垂直可拉伸性,但会忽略插入。

这自然会引出一个问题:参数\floatsep\textfloatsep\intextsep有什么用处?如果有用的话。在深入研究了 LaTeX 源代码后,似乎只有 LaTeX 会使用它们(TeX 不会使用)。如果页面被弹出,TeX 会调用输出例程,该例程也用于打印页码和类似的东西。LaTeX 会挂接到这个例程中,并在那里考虑插入/浮动的垂直粘贴(参见第 65 章《LaTeX 2e 源代码》)。

个人感言:与我的直觉相反,插入(浮动)不会增加页面的灵活性,实际上反而会降低灵活性,因为页面目标值会降低。最重要的是,这种方法与输出例程非常不一致,因为其中考虑了额外的粘合。

相关内容