3

I need the ability to switch color for all subsequent "cells" with a single macro command. (I also don't want the far spread-out justification h-spacing of align when I have many parts of an equation). If someone has a better alternative, please let me know; but for now, its equationarray.

\documentclass[10pt]{memoir}

\usepackage{xcolor}
\usepackage{eqnarray}

\providecommand{\mathfgcolor}{}

\NewDocumentEnvironment{eq}{b}{%
   \begin{equationarray*}{*{16}{ >{\mathfgcolor} c } }
     #1
   \end{equationarray*}%
   \ignorespacesafterend%
 }{}

\showoutput

\begin{document}

\setlength{\abovedisplayskip}{2pt plus 0pt minus 0pt}
\setlength{\belowdisplayskip}{3pt plus 0pt minus 0pt}

This is my first equation to show off good spacing
\begin{eq}
  (1+r_{0.5}) &=& (1 + r_{1})^{0.5} &=& (1+5\%)^{0.5} &\approx& 1+2.4695\% &=& 1.024695
\end{eq}
ok --- compounding 2.4695\% over two (6-month) periods indeed yields 5\%
\begin{eq}
  (1+2.4695\%)\cdot(1+2.4695\%) &=& 1.024695^{2} &\approx& (1+5\%)
  \gdef\mathfgcolor{\color{blue}}
  \\
  (1 + r_{0,1}) \cdot (1+r_{1,2}) &=& (1+r_1)^2 &=& (1+r_{0,2})
\end{eq}

\end{document}

Unfortunately, this produces a puzzling vertical space before the second equation:

puzzling vspace on 2nd eqn

Now that I know about \showoutput, I looked at the log, but I do not recognize what creates this additional space, and more importantly, how I can ask LaTeX not to insert it. (I am guessing that the reason is that LaTeX at some point [for long enough a line] really wants to push the line to the right margin, at which point it then also decides that it has something on the following line [though it is empty] and leaves this line blank, thereby pushing the equation one line beyond it. In this case, it would be a \parfillskip before maybe...?)

Thanks everyone (D!) for indulging my problems here.

UPDATES: 1 I made the example more detailed, showing why I bother with eqnarray to begin with. 2 I think I am using the standard eqnarray.sty 1.3 from /usr/local/texlive/2022/texmf-dist/tex/latex/eqnarray/eqnarray.sty. [3] Please ignore spacing around '&' --- I tinker with this elsewhere, but am omitting this in the example.

regards, /iaw

9
  • 1
    hmm you are using some non standard equationarray env which is unrelated to the standard eqnarray environment. (that may be fine, I do not know the package, but means your initial text is misleading) Jun 15 at 22:36
  • 1
    @egreg will be so happy to see this in your log ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 ....\glue 3.33333 plus 1.66666 minus 1.11111 Jun 15 at 22:51
  • 2
    "I believe that eqnarray is deprecated in favor of align. Nevertheless, I have an unusual need for it:` is still misleading as you refer to commens about the eqnarray evironmnent that you are not using. \glue 3.33333 plus 1.66666 minus 1.11111 is a standard interword space which implies the macros have spuriousbad space tokns somewhere, but too late to trace this evening. Most likely the cause of your visible space as that is not vertical space it is an all-white line of paragraph text Jun 15 at 23:08
  • 2
    You can surely note that the line preceding the second display is spread out to the full textwidth, which it shouldn't.
    – egreg
    Jun 15 at 23:11
  • 2
    eqnarray is a standard latex evironment built into the format not requiring any package. This is some contributed package defining a different evironmnent. Looking at your image it seems to have horizontal space around = even worse than eqnarray (which already makes it unusably large) Jun 15 at 23:22

1 Answer 1

7

Why not using array?

And why the b argument specifier? It's a standard environment, no need for it.

Now let's look at the problem. The output log shows for the line before the first display

....\OT1/cmr/m/n/10 s
....\OT1/cmr/m/n/10 p
....\OT1/cmr/m/n/10 a
....\OT1/cmr/m/n/10 c
....\OT1/cmr/m/n/10 i
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 g
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\glue 3.33333 plus 1.66666 minus 1.11111
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil

which means that seventeen spaces are added before starting a display. That line can accommodate them, the line before the second display cannot, so a line consisting of only spaces is output.

Two spurious spaces come from the code for \equationarray and \@equationarray and are easily fixed. The other 15 obviously are due to the 16 declared columns.

And, guess what? It's memoir! The bug lives at line 5670

   5664 \let\m@mold@addamp\@addamp
   5665 \newcommand*{\m@m@addamp}{%
   5666   \if@firstamp
   5667     \@firstampfalse
   5668     \global\@curtab\@ne
   5669   \else
   5670     \@addtopreamble{&}
   5671     \global\advance\@curtab\@ne
   5672   \fi}
   5673 \let\@addamp\m@m@addamp

Now the fixes.

\documentclass[10pt]{memoir}

\usepackage{xcolor}
\usepackage{eqnarray}

\makeatletter
% fix the spurious space by memoir
\renewcommand*{\@addamp}{%
  \if@firstamp
    \@firstampfalse
    \global\@curtab\@ne
  \else
    \@addtopreamble{&}% <---
    \global\advance\@curtab\@ne
  \fi}
% fix the spurious spaces by equationarray
\def\equationarray{%
 \col@sep\arraycolsep
 \def\d@llarbegin{$\displaystyle}%
 \def\d@llarend{$}%
 \stepcounter{equation}%
 \let\@currentlabel=\theequation
 \set@eqnsw \global\@eqcnt\z@ \global\@eqargcnt\z@
 \let\@classz\@eqnclassz
 \def\multicolumn##1##2##3{\@eqnmulticolumn{##1}{##2}{##3}%
                           \global\advance\@eqcnt##1\relax
                           \global\advance\@eqcnt\m@ne}%
 \def\eqnnum##1{\global\@eqnswfalse\gdef\@eqnarrnum{##1}}% <---
 \def\@halignto{to\displaywidth}%
 \@ifnextchar[{\@equationarray}{\@equationarray[.]}}
\def\@equationarray[#1]#2{%
     \eqnarr@opts
     \@tempdima \ht \strutbox
     \advance \@tempdima by\extrarowheight
     \setbox\@arstrutbox=\hbox{\vrule
               \@height\arraystretch \@tempdima
               \@depth\arraystretch \dp \strutbox
               \@width\z@}%
     \gdef\advance@eqargcnt{\global\advance\@eqargcnt\@ne}%
     \begingroup
     \@mkpream{#2}%
     \xdef\@preamble{%
      \if #1l\tabskip\z@ \else\if #1r\tabskip\@centering
                         \else\if #1c\tabskip\@centering
                         \else\tabskip\eqnarr@left \fi\fi\fi
      \halign \@halignto
      \bgroup \tabskip\z@ \@arstrut \@preamble
      \if #1l\tabskip\@centering \else\if #1r\tabskip\z@
                                 \else\tabskip\@centering \fi\fi
      \@amper\llap{\@sharp}\tabskip\z@\cr}%
     \endgroup
     \gdef\advance@eqargcnt{}%
     \bgroup
     \let\@sharp##% <---
     \let\protect\relax
     \m@th   \let\\=\@equationcr
     \let\par\@empty
     $$%                            % $$ BRACE MATCHING HACK
     \lineskip \z@
     \baselineskip \z@
     \@preamble}
\makeatother


\providecommand{\mathfgcolor}{}

\NewDocumentEnvironment{eq}{}
  {\begin{equationarray*}{*{16}{>{\mathfgcolor}c}}}
  {\end{equationarray*}\ignorespacesafterend}

\begin{document}

\setlength{\abovedisplayskip}{2pt plus 0pt minus 0pt}
\setlength{\belowdisplayskip}{3pt plus 0pt minus 0pt}

This is my first equation to show off good spacing
\begin{eq}
  (1+r_{0.5}) &=& (1 + r_{1})^{0.5} &=& (1+5\%)^{0.5} &\approx& 1+2.4695\% &=& 1.024695
\end{eq}
ok --- compounding 2.4695\% over two (6-month) periods indeed yields 5\%
\begin{eq}
  (1+2.4695\%)\cdot(1+2.4695\%) &=& 1.024695^{2} &\approx& (1+5\%)
  \gdef\mathfgcolor{\color{blue}}
  \\
  (1 + r_{0,1}) \cdot (1+r_{1,2}) &=& (1+r_1)^2 &=& (1+r_{0,2})
\end{eq}

\end{document}

enter image description here

How to really do it?

\documentclass[10pt]{memoir}

\usepackage{amsmath}
\usepackage{array}
\usepackage{xcolor}

\makeatletter
% fix the spurious space from memoir
\renewcommand*{\@addamp}{%
  \if@firstamp
    \@firstampfalse
    \global\@curtab\@ne
  \else
    \@addtopreamble{&}% <---
    \global\advance\@curtab\@ne
  \fi}
\makeatother


\providecommand{\mathfgcolor}{}
\newcolumntype{A}{>{\mathfgcolor}c@{}}
\newcolumntype{B}{>{\mathfgcolor{}}c<{{}}@{}}

\NewDocumentEnvironment{eq}{}
  {\begin{equation*}\begin{array}{@{} A *{8}{B}}}
  {\end{array}\end{equation*}\ignorespacesafterend}

\begin{document}

This is my first equation to show off good spacing
\begin{eq}
  (1+r_{0.5}) &=& (1 + r_{1})^{0.5} &=& (1+5\%)^{0.5} &\approx& 1+2.4695\% &=& 1.024695
\end{eq}
ok --- compounding 2.4695\% over two (6-month) periods indeed yields 5\%
\begin{eq}
  (1+2.4695\%)\cdot(1+2.4695\%) &=& 1.024695^{2} &\approx& (1+5\%)
  \gdef\mathfgcolor{\color{blue}}
  \\
  (1 + r_{0,1}) \cdot (1+r_{1,2}) &=& (1+r_1)^2 &=& (1+r_{0,2})
\end{eq}

\end{document}

enter image description here

5
  • 2
    The maintainer of memoir has been informed.
    – egreg
    Jun 16 at 15:38
  • Magnifico, Professore. I was struggling with this for a long time, cluelessly of course. I need to put a special thanks to David, Ulrike, and you into my (free) finance textbook. I don't think I could have put it together without you.
    – ivo Welch
    Jun 16 at 16:28
  • (PS: I also have a hack in there that puts an equation number on only when there is a label. This makes a lot of sense --- one presumably wants the numbers primarily for referring to them. It reduces clutter.)
    – ivo Welch
    Jun 16 at 16:28
  • Stupid Question --- would it make sense to switch the default behavior while defining macros to ignore spaces? If one needs a space, one would then have to add it specifically. There are a large number of questions/problems/bugs caused by spurious unintended spaces.
    – ivo Welch
    Jun 16 at 16:33
  • 1
    @ivoWelch That's one of the reasons why in the expl3 programming environment spaces are ignored. See tug.org/TUGboat/tb36-2/tb113gregorio.pdf
    – egreg
    Jun 16 at 16:53

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.