我在用
\usepackage{lineno}
在我的文档上打印行号。我的文档有很多方程式。我使用
\usepackage{mathtools}
并经常使用诸如align
、multline
和flalign
等环境(我也使用它们带星号的*
等效环境)。有一个名为mathlines
\usepackage[mathlines]{lineno}
据我所知,它仅打印环境数字equation
。
我已经读过,为了让行号适用于所有数学环境,你需要将每个环境包装在
\begin{linenomath*}
\begin{align} % or equation,multline,flalign etc
.
.
\end{align}
\end{linenomath*}
并删除该选项mathlines
。请参阅这个答案从为什么当段落后面跟着缩进的公式时,lineno 不会对段落进行编号?。这对我来说是可行的,但我有两个问题:
- 它给我一些等式的最后一行“额外”的数字;
- 我的文档中有数百个方程式。我不可能逐一浏览并添加
begin{linenomath*}
每个方程式。
这些问题有解决方案吗?这是我的输出。请注意成堆的数字 (4 , 5)、(7 , 8) 和 (11 , 12)。
代码
\documentclass[12pt,a4paper]{report}
\usepackage{mathtools}
\usepackage{lineno}
\linenumbers
\begin{document}
\begin{linenomath*}
\begin{equation}
F=ma
\end{equation}
\end{linenomath*}
\begin{linenomath*}
\begin{multline}
p(x) = 3x^6 + 14x^5y + 590x^4y^2 + 19x^3y^3\\
- 12x^2y^4 - 12xy^5 + 2y^6 - a^3b^3
\end{multline}
\end{linenomath*}
\begin{linenomath*}
\begin{align}
2x - 5y &= 8 \\
3x + 9y &= -12
\end{align}
\end{linenomath*}
\begin{linenomath*}
\begin{flalign}
a &= b+c &\\
&= 1+1 &\\
&= 2 &
\end{flalign}
\end{linenomath*}
\end{document}
答案1
问题 1:
该lineno
包在每个显示方程的末尾打印一个行号,以及方程内任何两行之间的行号(在这两行中的第一行)。amsmath
然而,对于环境,它还会在最后一行之后打印一个“显示间”行号,因此您应该隐藏“显示后”行号。
该包通过大量减少惩罚来强制(然后中止)分页。linenomath*
环境调用\linenomathWithnumbers
,其中包含行\advance\postdisplaypenalty\linenopenalty
。从定义中删除此行将删除虚假的行号,但也会删除环境的唯一行号equation
。
您可以在 MWE 中添加\postdisplaypenalty=0
(默认值)after\begin{linenomath*}
和 before ,这将解决问题 1。\begin{<multline/align/flalign>}
问题2:
修补数学环境以包含的效果linenomath*
并不太难。我已定义命令\linenomathpatch
和,\linenomathpatchAMS
它们在下面执行此操作。第一个命令用于基本数学环境(equation
和eqnarray
),后者用于amsmath
环境。这些环境的带星号和不带星号的版本都已修补。我使用\patchcmd
了etoolbox
\linenopenalty
包中删除不需要的更改\linenomath
。
代码:
以下代码完成了上面描述的两件事:
\documentclass[12pt,a4paper]{report}
\usepackage[mathlines]{lineno} %% <- mathlines turns on line numbering in equations
\usepackage{amsmath} %% <- N.B., mathtools also loads this
\linenumbers
\usepackage{etoolbox} %% <- for \cspreto, \csappto, \patchcmd, \pretocmd, \apptocmd
%% Patch 'normal' math environments:
\newcommand*\linenomathpatch[1]{%
\cspreto{#1}{\linenomath}%
\cspreto{#1*}{\linenomath}%
\csappto{end#1}{\endlinenomath}%
\csappto{end#1*}{\endlinenomath}%
}
%% Patch AMS math environments:
\newcommand*\linenomathpatchAMS[1]{%
\cspreto{#1}{\linenomathAMS}%
\cspreto{#1*}{\linenomathAMS}%
\csappto{end#1}{\endlinenomath}%
\csappto{end#1*}{\endlinenomath}%
}
%% Definition of \linenomathAMS depends on whether the mathlines option is provided
\expandafter\ifx\linenomath\linenomathWithnumbers
\let\linenomathAMS\linenomathWithnumbers
%% The following line gets rid of an extra line numbers at the bottom:
\patchcmd\linenomathAMS{\advance\postdisplaypenalty\linenopenalty}{}{}{}
\else
\let\linenomathAMS\linenomathNonumbers
\fi
\linenomathpatch{equation}
\linenomathpatchAMS{gather}
\linenomathpatchAMS{multline}
\linenomathpatchAMS{align}
\linenomathpatchAMS{alignat}
\linenomathpatchAMS{flalign}
\begin{document}
\begin{equation}
F = m a
\end{equation}
\begin{multline}
p(x) = 3x^6 + 14x^5y + 590x^4y^2 + 19x^3y^3\\
- 12x^2y^4 - 12xy^5 + 2y^6 - a^3b^3
\end{multline}
\begin{align}
2x - 5y &= 8 \\
3x + 9y &= -12
\end{align}
\begin{flalign}
a &= b + c &\\
&= 1 + 1 &\\
&= 2 &
\end{flalign}
\end{document}
注意:我是amsmath
在之后加载的lineno
,但另一种顺序也可以。如果使用另一种顺序,equation
和\[
最终将被修补两次(因为lineno
也会修补它们),这不是很优雅,但完全无害。
附录:multline
正如你在上面的截图中看到的,multline
这是唯一一个运行不正常的 ASM 环境,因为它在右侧有一个额外的行号多于方程。这个额外的数字是由额外的显示间惩罚(而不是预显示惩罚)引起的,它发生在“测量”阶段,当amsmath
排版组成方程的单元格只是为了确定环境的每个列应该有多宽时。我真的不知道有什么不同/为什么multline
不同。
可以通过修补amsmath
内部命令来修复此问题\measure@
,如下所示。以下内容需要添加到 之后的任意位置的前言中\usepackage{amsmath}
。
% Disable line numbering in measurement phase for multline
\makeatletter
\patchcmd{\mmeasure@}{\measuring@true}{
\measuring@true
\ifnum-\linenopenaltypar>\interdisplaylinepenalty
\advance\interdisplaylinepenalty-\linenopenalty
\fi
}{}{}
\makeatother
我没有在上面的演示中包含这一点,因为我相信multline
没有太多人使用它。
解释:lineno
底层是如何工作的
这个lineno
包相当复杂,我应该指出,我并不完全理解它的工作原理。以下是我认为可以理解的内容:
\linenumbers
将段落中两行之间的分页符惩罚值减少 100000。由于惩罚值通常介于 -10000 和 +10000 之间(少一个 0),这通常几乎可以保证强制在任意两行之间分页(任何低于 -10000 的值都会强制分页)。该包还挂接到输出例程中。每当要发送页面时,它都会测试惩罚是否低于 -32000(通常不会发生这种情况)。如果是,它会打印一个数字,将惩罚增加 100000(取消之前的减少),并实质上告诉 TeX 重新考虑分页符。如果不低于 -32000,则页面将正常发送。
该
linenomath*
环境将方程式上方/下方分页符和方程式内行之间的惩罚减少了 100000。对于普通方程式,只有“显示后”和“显示前”惩罚是相关的,但“显示间”惩罚也会发生在环境中的任意两行之间amsmath
(包括最后一行之后)。
这是由显示后惩罚引起的伪分页符,它会产生额外的不需要的数字,因此将该值设置回零(或从一开始就不改变它)可以解决您的问题。