2

I am using

\usepackage{lineno}

to print line numbers on my document. My document has lots of equations. I use

\usepackage{mathtools}

and frequently use environments such as align, multline and flalign to name a few (I also use their starred * equivalents). There exists an option called mathlines

\usepackage[mathlines]{lineno}

which as far as I can see only prints numbers for the equation environment.

I have read that to get line numbers working for all math environments you need to wrap every environment in

\begin{linenomath*}
  \begin{align} % or equation,multline,flalign etc 
    .
    .
  \end{align} 
\end{linenomath*}

and remove the option mathlines. See this answer from Why doesn't lineno number a paragraph when it is followed by an indented equation?. This is sort of working for me, but I have two problems:

  1. It is giving me 'extra' numbers on the last line of some equations;
  2. I have hundreds of equations in my document. It is impossible for me to individually go through and add begin{linenomath*} around every equation.

Are there any solutions to these issues? This is what my output looks like. Notice the bunched up numbers (4 , 5), (7 , 8) and (11 , 12).

enter image description here

Code

\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}
9
+50

Problem 1:

The lineno package prints a line number at the end of every display equation, as well between any two lines within the equation (on the first of these two lines). For the amsmath environments, it however also prints an "interdisplay" line number after the last line, so you should suppress the "postdisplay" line number.

The package works by decreasing penalties by a large amount to force (and then abort) page breaks. The linenomath* environment calls \linenomathWithnumbers, which contains the line \advance\postdisplaypenalty\linenopenalty. Deleting this line from the definition would remove the spurious line number, but it would also remove the only line number for the equation environment.

You could add \postdisplaypenalty=0 (which is the default value) after \begin{linenomath*} and before \begin{<multline/align/flalign>} in your MWE and this would solve problem 1.

Problem 2:

Patching the math environments to include the effect of linenomath* is not too difficult. I have defined a command \linenomathpatch that does this below. It also has a starred version, which doesn't change \postdisplaypenalty and should be used for the amsmath environments. (Note: \linenomathpatch{<math env>} patches both <math env> and <math env>*)

Code:

The following code does both of the things described above:

\documentclass[12pt,a4paper]{report}
\usepackage{amsmath} %% <- N.B., mathtools also loads this
\usepackage{lineno}
\linenumbers

\usepackage{etoolbox} %% <- for \pretocmd and \apptocmd
\makeatletter %% <- make @ usable in macro names
\newcommand*\linenomathpatch{\@ifstar{\linenomathpatch@AMS}{\linenomathpatch@}}
\newcommand*\linenomathpatch@[1]{
  \expandafter\pretocmd\csname #1\endcsname {\linenomathWithnumbers}{}{}
  \expandafter\pretocmd\csname #1*\endcsname{\linenomathWithnumbers}{}{}
  \expandafter\apptocmd\csname end#1\endcsname {\endlinenomath}{}{}
  \expandafter\apptocmd\csname end#1*\endcsname{\endlinenomath}{}{}
}
\newcommand*\linenomathpatch@AMS[1]{
  \expandafter\pretocmd\csname #1\endcsname {\linenomathWithnumbersAMS}{}{}
  \expandafter\pretocmd\csname #1*\endcsname{\linenomathWithnumbersAMS}{}{}
  \expandafter\apptocmd\csname end#1\endcsname {\endlinenomath}{}{}
  \expandafter\apptocmd\csname end#1*\endcsname{\endlinenomath}{}{}
}
\let\linenomathWithnumbersAMS\linenomathWithnumbers
\patchcmd\linenomathWithnumbersAMS{\advance\postdisplaypenalty\linenopenalty}{}{}{}
\makeatother %% revert @

\linenomathpatch{equation}
\linenomathpatch*{gather}
\linenomathpatch*{multline}
\linenomathpatch*{align}
\linenomathpatch*{alignat}
\linenomathpatch*{flalign}

\begin{document}

\begin{equation}
    F=ma
\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}

enter image description here

(I'm not sure why the multline environment has an additional line number at the top. The extra number is caused by a third interdisplay penalty, not a a predisplay penalty)


Explanation:

The lineno package is rather complicated and I should note that I do not fully understand how it works. This is what I believe to understand:

  1. \linenumbers decreases the penalty for a page break between two lines in a paragraph by 100000. Since the penalty normally lies somewhere between –10000 and +10000 (one 0 fewer), this is normally pretty much guaranteed to force a page break between any two lines (any value below –10000 forces a page break).

  2. The package also hooks into the output routine. Whenever a page is about to be shipped, it tests whether the penalty is below –32000 (which would normally never happen). If it is, it prints a number, increases the penalty by 100000 (undoing the earlier decrease) and essentially tells TeX to reconsider the page break. If it isn't below –32000, the page is shipped as normal.

  3. The linenomath* environment decreases the penalties for page breaks above/below an equation and between lines within an equation by 100000. For normal equations, only the "postdisplay" and "predisplay" penalties are relevant, but the "interdisplay" penalty also occurs between any two lines of the amsmath environments (including after the last line).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.