18

Is there a way to have lineno show line numbers for a paragraph that uses the align environment?

In the following example, the (first) paragraph that ends with \begin{align} ... \end{align} does not have the desired line numbers, whereas the (second) paragraph that separates the text with a single new line contains the line numbers.

\documentclass{article}

\usepackage{amsmath}
\usepackage[mathlines]{lineno}
\usepackage{lipsum}

\linenumbers
\title{My Document}
\author{Anonymous Anteater}

\begin{document}
\maketitle

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
culpa qui officia deserunt mollit anim id est laborum.
\begin{align}
x = 2
\end{align}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis

\begin{align}
x = 2
\end{align}

\end{document}

missing line numbers with lineno and align

jII
  • 497

2 Answers2

26

The lineno package is not compatible with the amsmath environments, but the two can be made to work together. Without the mathlines option to lineno (which turns on line numbering inside equations) this is pretty simple, but if you want the lines inside equations to be numbered it becomes a little more difficult.

Manual fix (without mathlines only)

The documentation for lineno describes how to get the equation numbering around a display equation right:

lineno.sty does not work well with display math. The parts of a paragraph preceeding a display math will not get line numbers. The reason is that the paragraph is not finished, but the part above the display is broken into lines anyway.

[…]

lineno.sty defines a {linenomath} environment, which can be wrapped around a display math to make the line numbering work. This will work with any kind of display math, even if you use explicit $$ pairs. There is a *-form {linenomath*} which also numbers the lines of the display itself, as good as it can.

This works fine as long as you don't provide the mathlines option to lineno (which turns on line numbering inside equations) or use the starred form.

\begin{linenomath}
    \begin{align}
        …
    \end{align}
\end{linenomath}

Doing this for every equation is a bit of a hassle, though.

Automatic fix (without mathlines)

Instead of manually doing this for every equation, it is more convenient to patch the AMS math environments instead. This can be done by adding the following (or some variation of it) to the preamble.

\usepackage{lineno}   %% <- no mathlines option
\usepackage{amsmath}  %% <- after lineno
\usepackage{etoolbox} %% <- for \cspreto, \csappto

%% Patch 'normal' math environments: \newcommand\linenomathpatch[1]{% \cspreto{#1}{\linenomath}% \cspreto{#1}{\linenomath}% \csappto{end#1}{\endlinenomath}% \csappto{end#1*}{\endlinenomath}% }

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

This also won't work well if the mathlines option to lineno is used (see below).

Note: The choice to load lineno before amsmath was intentional because lineno also patches the equation environment (but not equation*), as well as \[+\] (somewhat improperly), while amsmath redefines them completely. If the packages are loaded in the opposite order, equation and \[+\] end up being patched twice (which is harmless) and \[+\] ends up no longer being robust. Since \[ and \] are defined as shorthands for \begin{equation*} and \end{equation*}, these do work fine for this order.

Automatic fix (with or without mathlines)

If you are using the mathlines option to lineno because you also want the lines of the equations themselves to be numbered, there are some problems with this approach. An additional line number will be printed just below all amsmath equation environment, and multline will additionally receive an extra line number at the top. I posted a way to avoid both of these extraneous line numbers in this answer to another question.

You'll need to add the following to the preamble of your document. If the mathlines options is removed this will still work, but lines inside equations will no longer be numbered.

\usepackage[mathlines]{lineno} %% <- with [mathlines] to number lines in equations
\usepackage{amsmath}           %% <- after lineno
\usepackage{etoolbox}          %% <- for \cspreto, \csappto and \patchcmd

%% 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}

% Disable line numbering during measurement step of multline \makeatletter \patchcmd{\mmeasure@}{\measuring@true}{ \measuring@true \ifnum-\linenopenaltypar>\interdisplaylinepenalty \advance\interdisplaylinepenalty-\linenopenalty \fi }{}{} \makeatother

An explanation of why all of this is necessary and why this works can be found here.


Demonstration

Here is a sample document for the last solution.

\documentclass{article}

\usepackage[mathlines]{lineno} %% <- remove [mathlines] to omit equation line numbers \usepackage{amsmath}

\usepackage{etoolbox} %% <- for \pretocmd, \apptocmd and \patchcmd

%% 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}

\linenumbers \title{My Document} \author{Anonymous Anteater}

\begin{document} \maketitle

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor culpa qui officia deserunt mollit anim id est laborum. \begin{align} \nabla \cdot E &= \frac{\rho}{\varepsilon_0} & \nabla \times E &= - \frac{\partial B}{\partial t} \ \nabla \cdot B &= 0 & \nabla \times B &= \mu_0 J + \mu_0 \varepsilon_0 \frac{\partial E}{\partial t} \end{align} Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis

\begin{equation} (\mathrm{id}{C} \otimes \Delta ) \circ \Delta = (\Delta \otimes \mathrm{id}{C}) \circ \Delta \end{equation}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor, [ \bigwedge_{i=1}^{\dim(V)} A(v_i) = \det(A) \bigwedge_{i=1}^{\dim(V)} v_i, ] culpa qui officia deserunt mollit anim id est laborum.

\end{document}

output

Circumscribe
  • 10,856
  • Awesome! Is there a way to extend this to work with \[ ... \] display math as well? – Peter Grill Nov 21 '18 at 21:02
  • @PeterGrill I modified the answer to obey (the presence/absence of) the mathlines option. With this option \[…\]-equations are also counted as lines. – Circumscribe Nov 21 '18 at 22:34
  • Oh I see. I didn't notice that you had removed the mathlines option in your MWE. – Peter Grill Nov 21 '18 at 22:35
  • @PeterGrill I thought it was no longer necessary, but I had forgotten about \[…\]. – Circumscribe Nov 21 '18 at 22:44
  • Just noticed that you are missing the trailing % in the \linenomathpatch@, \linenomathpatch@AMS and the usage of \linenomathpatch. These don't matter if the patching is all done in the preamble, but if for some reason a user decides to apply the patch to only a portion of the doc, they will be spurious spaces. – Peter Grill Nov 21 '18 at 22:48
  • @PeterGrill good point, I fixed it. – Circumscribe Nov 21 '18 at 22:56
  • They are also needed after each \linenomathpatch{}% – Peter Grill Nov 22 '18 at 00:31
  • @PeterGrill I don't quite agree that this is necessary. These would be different from the line breaks I just commented out because they are not inside a definition. Adding a % after each \linenomathpatchAMS{…} would be similar to appending a % to every \newcommand in your preamble, which I think only very few people do. It only matters if someone copies these lines and places them somewhere mid-paragraph without removing or commenting out line breaks. – Circumscribe Nov 22 '18 at 01:30
  • Ok. That makes sense. – Peter Grill Nov 22 '18 at 07:46
  • 1
    example would be improved by a multi-line align. align isn't meant to be used for single-line formulas. – barbara beeton Nov 22 '18 at 16:04
  • @barbarabeeton I changed the example to include a multi-line align environment. – Circumscribe Nov 22 '18 at 16:23
  • @Circumscribe -- thanks. seeing a line number on both lines is something i haven't seen before. i'll have to try it out with the other amsmath multi-line environments. – barbara beeton Nov 22 '18 at 17:53
  • This seems to work with align but not alignat – kevinkayaks Aug 29 '19 at 22:05
  • 1
    You need to also patch equation if amsmath is loaded because then equation gets changed (and equation* was never patched before) – Frank Mittelbach Dec 29 '20 at 18:15
  • @FrankMittelbach: Thanks, you're right. I hadn't realised equation* wasn't already patched by lineno. I've updated my answer. – Circumscribe Dec 30 '20 at 09:11
  • @Circumscribe there is that but also equation is no longer patched (I think) if amsmath is loaded after lineno – Frank Mittelbach Dec 30 '20 at 14:27
  • @FrankMittelbach: Before my edit earlier today I was loading amsmath before lineno precisely for that reason, but I swapped the order to avoid patching equation twice since I'm patching equation myself now. – Circumscribe Dec 30 '20 at 15:20
  • Very nice and useful suggestion.... – MadyYuvi Dec 31 '20 at 13:17
  • The last two \cspreto in \linenomathpatch should be \csappto, as the \linenomathpatchAMS below. Otherwise this may cause some unexpected Overfull \vbox in the document. – Jinwen Apr 04 '21 at 01:16
  • @Jinwen, you're absolutely right, I've fixed it now. – Circumscribe Apr 06 '21 at 05:23
4

One way is to replace the align by

\[
  \begin{aligned}
    x = 2
  \end{aligned}
\]

or by

\begin{equation}
 \begin{aligned}
   x = 2
 \end{aligned}
\end{equation}

if you want numbered version.

enter image description here

Sigur
  • 37,330