为什么当我使用没有换行符的内联数学运算时 \hbox 会溢出

为什么当我使用没有换行符的内联数学运算时 \hbox 会溢出

为了防止方程式内出现换行符,我使用以下 LaTeX 命令:

${r^2 = x^2 + y^2}$.

不幸的是,它给了我Overfull \hbox (12.4459pt too wide)警告。为什么 LaTeX 没有将整个方程式移到下一行?

答案1

使用${....}$确实可以防止公式跨行,但代价是冻结公式内的所有间距。如果您写入,$a=b+c$则 LaTeX 会为您生成以下列表:

\mathon
\OML/cmm/m/it/10 a
\glue(\thickmuskip) 2.77771 plus 2.77771
\OT1/cmr/m/n/10 =
\penalty 500
\glue(\thickmuskip) 2.77771 plus 2.77771
\OML/cmm/m/it/10 b
\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
\OT1/cmr/m/n/10 +
\penalty 700
\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
\OML/cmm/m/it/10 c
\mathoff

如您所见,此列表具有许多可以拉伸(也可能收缩)的“粘合”项目,并且还显示了两个断点,相关惩罚分别为 500 和 700。

相反如果你这样做${a=b+c}$你会得到

\hbox(0.0+0.0)x15.0
\mathon
\hbox(6.94444+0.83333)x39.46046
.\OML/cmm/m/it/10 a
.\glue(\thickmuskip) 2.77771 plus 2.77771
.\OT1/cmr/m/n/10 =
.\glue(\thickmuskip) 2.77771 plus 2.77771
.\OML/cmm/m/it/10 b
.\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
.\OT1/cmr/m/n/10 +
.\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
.\OML/cmm/m/it/10 c
\mathoff

看上去很像,但实际上不是。现在断点消失了(TeX 将它们放在水平盒子内),整个公式位于一个定义大小的盒子中。因此,即使粘合项仍然存在,它们也不再有帮助,因为这个水平盒子的大小被冻结了。

简而言之,如果段落行稍微被拉伸,正常的公式也会被拉伸,当行被挤压时也是如此。但在第二种情况下,公式将保持其自然宽度不变。

我应该补充一点,在公式中使用建议${...}$最初是由 Don Knuth 提出的,可以在 TeX 书中找到。然而,从印刷术的角度来看,这是一个值得怀疑的建议(或更糟),因为它严重破坏了 TeX 通常试图实现的目标:文本材料的统一和高质量外观。

不存在此缺陷的替代方法是将生成断点的两个参数设置为不同的值:

\newcommand\nomathlinebreaks{\relpenalty=10000
                             \binoppenalty=10000 } % the space in the def is deliberate

在公式内部使用可防止在公式内部换行,在公式外部使用可防止在后面的公式中换行。\allowbreak可用于在公式内部提供明确的换行可能性并可\nobreak防止换行,例如,$a=b+\nobreak c$

现在为什么要让 TeX 变成一个溢出行,而不是将整个公式移到下一行?这只是段落拆分算法工作的标准方式。如果它找不到满足其当前设置等的解决方案,\tolerance它将产生一个溢出行,而不是使段落更长。基本原因是这是处理有问题的对象大于整行的情况的唯一方法。如果移动它,下一行也会发生同样的问题……最终您将得到一个由无数行组成的空白段落。

因此答案是:如果需要,更改段落参数以允许更大的灵活性。一个可能的候选是\emergencystretch,但允许稍微高一点的值通常\tolerance会改善整体结果而不会产生真正糟糕的影响。不过需要注意的是:段落算法非常复杂,有很多花哨的东西,开始更改其参数设置时应小心谨慎,并且只有在详细研究算法之后才能进行。

相关内容