How to use lineno with amsmath align?

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}%
  \cspreto{end#1}{\endlinenomath}%
  \cspreto{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}%
  \cspreto{end#1}{\endlinenomath}%
  \cspreto{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}%
  \cspreto{end#1}{\endlinenomath}%
  \cspreto{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


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