[Tex/LaTex] Vertical Spacing within align environment accounting for fractions

amsmathmath-modespacing

The default vertical spacing within an align environment seems very tight when there are fractions in the lines.

enter image description here

I am aware of three manual tweaks that can be applied:

  1. Adjust the value \jot.
  2. Add a vertical space on each line where necessary via \\[<amount>].
  3. Use the spreadlines environment from the mathtools package.

enter image description here

Solutions 1 and 3 add vertical space even between the lines that don't need them, so if the set of equations has lines without fractions (and lines with fractions), the spacing is not quite right.

Question:

Is there not some automated solution to always leave the appropriate vertical space between the bottom of one line and the top of the next?

References:

Code:

\documentclass{article}
\usepackage{mathtools}% includes amsmath

\begin{document}
\begin{minipage}[t]{0.20\linewidth}
\textbf{Nice}
\begin{align*}
 x &= 73 \times 2\\
   &= 146
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.25\linewidth}
\textbf{Not so nice}
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%


\bigskip\par\noindent
\textbf{Manual Tweak Options:}
\medskip\par\noindent
\begin{minipage}[t]{0.25\linewidth}
\textbf{Tweak jot}
\setlength{\jot}{8pt}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\textbf{Add vertical space}
\begin{align*}
 x &= \frac{146}{10}\\[5pt]% tweak
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\textbf{spreadlines}
\begin{spreadlines}{0.8em}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{spreadlines}
\end{minipage}%
\end{document}

Testing Proposed fix:

I tested the proposed fix, and it does seem to fix the "Not so nice" section:

enter image description here

Not sure I like the additional vertical space at the top.

But furthermore, it also adds spacing where it is not needed as was the case in the section that was previously "Nice":

enter image description here

In cases where there are manual adjustments, they should probably not be extended (or only extended if the spacing is not sufficient. Personally I can work without this, but perhaps a method of disabling it would be good:

enter image description here

Code:

\documentclass{article}
\usepackage{mathtools}% includes amsmath

\begin{document}
\par\noindent
%---------------------------------------- Oringally "Nice"
\begin{minipage}[t]{0.30\linewidth}
\textbf{Nice}
\begin{align*}
 x &= 73 \times 2\\
   &= 146
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\makeatletter
    \def\align@preamble{%
       &\hfil
        \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \tabskip\z@skip
       &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \hfil
        \tabskip\alignsep@
    }%
\makeatother
%
%
\textbf{With 2012-05-09 fix:}
\begin{align*}
 x &= 73 \times 2\\
   &= 146
\end{align*}
\end{minipage}%

\bigskip\par\noindent
%---------------------------------------- Oringally "Not so Nice"
\begin{minipage}[t]{0.30\linewidth}
\textbf{Not so nice}
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\makeatletter
    \def\align@preamble{%
       &\hfil
        \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \tabskip\z@skip
       &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \hfil
        \tabskip\alignsep@
    }%
\makeatother
%
\textbf{With 2012-05-09 fix:}
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%



\bigskip\par\noindent
\textbf{Manual Tweak Options:}
\medskip\par\noindent
%---------------------------------------- Adjust \jot
\begin{minipage}[t]{0.30\linewidth}
\textbf{Tweak jot}
\setlength{\jot}{8pt}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\makeatletter
    \def\align@preamble{%
       &\hfil
        \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \tabskip\z@skip
       &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \hfil
        \tabskip\alignsep@
    }%
\makeatother
%
\textbf{With 2012-05-09 fix:}
\setlength{\jot}{8pt}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%

%---------------------------------------- Adding Vertical Space
\bigskip\par\noindent
\begin{minipage}[t]{0.30\linewidth}
\textbf{Add vertical space}
\begin{align*}
 x &= \frac{146}{10}\\[5pt]% tweak
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\makeatletter
    \def\align@preamble{%
       &\hfil
        \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \tabskip\z@skip
       &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \hfil
        \tabskip\alignsep@
    }%
\makeatother
%
\textbf{With 2012-05-09 fix:}
\begin{align*}
 x &= \frac{146}{10}\\[5pt]% tweak
   &= \frac{73}{5}
\end{align*}
\end{minipage}%


%---------------------------------------- Spreadlines
\bigskip\par\noindent
\begin{minipage}[t]{0.30\linewidth}
\textbf{spreadlines}
\begin{spreadlines}{0.8em}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{spreadlines}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\makeatletter
    \def\align@preamble{%
       &\hfil
        \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \tabskip\z@skip
       &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
        \ifdim\ht\z@<\ht\strutbox@
        \ht\z@\ht\strutbox@
        \dimen@\ht\strutbox@
        \advance\dimen@.15em
        \ht\strutbox@\dimen@
        \fi
        \strut@
        \ifmeasuring@\savefieldlength@\fi
        \set@field
        \hfil
        \tabskip\alignsep@
    }%
\makeatother
%
\textbf{With 2012-05-09 fix:}
\begin{spreadlines}{0.8em}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{spreadlines}
\end{minipage}%
\end{document}

Best Answer

AMS alignments box and measure each cell anyway so you can check if the cell height is larger than a strut you can locally increase the strut height.

enter image description here

Code updated to use > instead of < so it opens up big entries not small ones:-) Also does not do anything on first row to avoid adding space above the display.

\documentclass{article}
\usepackage{mathtools}% includes amsmath

\makeatletter

\newlength\minalignvsep


\def\align@preamble{%
   &\hfil
    \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
    \ifnum\row@>\@ne
    \ifdim\ht\z@>\ht\strutbox@
    \dimen@\ht\z@
    \advance\dimen@\minalignvsep
    \ht\strutbox\dimen@
    \fi\fi
    \strut@
    \ifmeasuring@\savefieldlength@\fi
    \set@field
    \tabskip\z@skip
   &\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
    \ifnum\row@>\@ne
    \ifdim\ht\z@>\ht\strutbox@
    \dimen@\ht\z@
    \advance\dimen@\minalignvsep
    \ht\strutbox@\dimen@
    \fi\fi
    \strut@
    \ifmeasuring@\savefieldlength@\fi
    \set@field
    \hfil
    \tabskip\alignsep@
}
\makeatother

\minalignvsep.15em

\begin{document}

\begin{minipage}[t]{0.20\linewidth}
\textbf{Nice}
\begin{align*}
 x &= 73 \times 2\\
   &= 146
\end{align*}
\end{minipage}%


%
\begin{minipage}[t]{0.25\linewidth}
\textbf{Not so nice}
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%


\bigskip\par\noindent
\textbf{Manual Tweak Options:}
\medskip\par\noindent
\begin{minipage}[t]{0.25\linewidth}
\textbf{Tweak jot}
\setlength{\jot}{8pt}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\textbf{Add vertical space}
\begin{align*}
 x &= \frac{146}{10}\\[5pt]% tweak
   &= \frac{73}{5}
\end{align*}
\end{minipage}%
%
\begin{minipage}[t]{0.30\linewidth}
\textbf{spreadlines}
\begin{spreadlines}{0.8em}% tweak
\begin{align*}
 x &= \frac{146}{10}\\
   &= \frac{73}{5}
\end{align*}
\end{spreadlines}
\end{minipage}%
\end{document}