# A macro has a pesky global effect when used in several environments

I was using a cool macro to write some nice matrices inside a particular math environment, from this question:

Ugly matrices to fix

But then I wanted to use the same macro to fix some other matrices which have nothing to do with the ones in the previous question (in another chapter of the same document). I just noticed that the macro gives the same column spacings for all matrices, even when they aren't in the same environment. The macro appears to have a global effect, which I certainly don't want.

How can I make that macro to work locally only, in a given environment, without having any affect on other environments?

Here's a MWE which shows the problem:

\documentclass[11pt,letterpaper,twoside]{book}
\usepackage{lmodern}
\usepackage{microtype}
\usepackage{amsfonts}
\usepackage{mathtools}

\usepackage{eqparbox}
\newcommand{\squash}[2][M]{\eqmakebox[#1]{$#2$}}

\begin{document}

These matrices are affected by the last matrices, which is bad:
\begin{align}
A &=
\begin{bmatrix}
0 & \squash{\sigma_2} \\[1em]
\squash{\sigma_2}& 0
\end{bmatrix},
\\
B &=
\begin{bmatrix}
\squash{-i \sigma_3} & 0 \\[1em]
0 & \squash{-i \sigma_3}
\end{bmatrix},
\end{align}
These matrices are affecting the first matrices which is bad:
\begin{align}
C &=
\begin{bmatrix}
0 & \squash{1} \\[1em]
\squash{r \sin \vartheta \cos \varphi} & 0
\end{bmatrix},
\\
D &=
\begin{bmatrix}
\squash{-\, r^2} & 0 \\[1em]
0 & \squash{-\, r^2}
\end{bmatrix},
\end{align}

\end{document}


Preview with the problem shown in red:

The definition of \squash is wrong, in the sense that it doesn't make clear that the optional argument is actually mandatory.

The syntax of \eqmakebox is

\eqmakebox[<tag>][<alignment>]{<material>}


where the <tag> is an arbitrary label that should be common to all constructs that need to have the same width.

Since you're using \squash in different contexts, but never use the optional argument, you get the same width for all such boxes throughout the document.

\documentclass[11pt,letterpaper,twoside]{book}
\usepackage{lmodern}
\usepackage{microtype}
\usepackage{amsfonts}
\usepackage{mathtools}

\usepackage{eqparbox}
\newcommand{\squash}[2][M]{\eqmakebox[#1]{$#2$}}

\begin{document}

These matrices are affected by the last matrices, which is bad:
\begin{align}
A &=
\begin{bmatrix}
0 & \squash[A]{\sigma_2} \\[1em]
\squash[A]{\sigma_2}& 0
\end{bmatrix},
\\
B &=
\begin{bmatrix}
\squash[A]{-i \sigma_3} & 0 \\[1em]
0 & \squash[A]{-i \sigma_3}
\end{bmatrix},
\end{align}
These matrices are affecting the first matrices which is bad:
\begin{align}
C &=
\begin{bmatrix}
0 & \squash[B]{1} \\[1em]
\squash[B]{r \sin \vartheta \cos \varphi} & 0
\end{bmatrix},
\\
D &=
\begin{bmatrix}
\squash[B]{-\, r^2} & 0 \\[1em]
0 & \squash[B]{-\, r^2}
\end{bmatrix},
\end{align}

\end{document}


I'd make the argument mandatory and add an optional argument for the alignment, for greater flexibility:

\newcommand{\squash}[3][c]{\eqmakebox[#2][#1]{$#3$}}


The calls in the document should become like

\squash{A}{\sigma_2}


Full code

\documentclass[11pt,letterpaper,twoside]{book}
\usepackage{lmodern}
\usepackage{microtype}
\usepackage{amsfonts}
\usepackage{mathtools}

\usepackage{eqparbox}
\newcommand{\squash}[3][c]{\eqmakebox[#2][#1]{$#3$}}

\begin{document}

These matrices are affected by the last matrices, which is bad:
\begin{align}
A &=
\begin{bmatrix}
0 & \squash{A}{\sigma_2} \\[1em]
\squash{A}{\sigma_2}& 0
\end{bmatrix},
\\
B &=
\begin{bmatrix}
\squash{A}{-i \sigma_3} & 0 \\[1em]
0 & \squash{A}{-i \sigma_3}
\end{bmatrix},
\end{align}
These matrices are affecting the first matrices which is bad:
\begin{align}
C &=
\begin{bmatrix}
0 & \squash{B}{1} \\[1em]
\squash{B}{r \sin \vartheta \cos \varphi} & 0
\end{bmatrix},
\\
D &=
\begin{bmatrix}
\squash{B}{-\, r^2} & 0 \\[1em]
0 & \squash{B}{-\, r^2}
\end{bmatrix},
\end{align}

\end{document}


The optional argument to \squash should be a letter from lcr (meaning “left”, “center” and “right”, default is c).

Just by way of example, if you change all \squash{A}{...} into \squash[l]{A}{...} and all \squash{B}{...} into \squash[r]{B}{...}, you get

Not really useful in the present case, but you might find it useful in other circumstances.

• Your last suggestion doesn't work, I don't know why. You're missing a bracket } but it's still not working. – Cham Jun 26 at 16:42
• @Cham Yes, sorry: a } was missing – egreg Jun 26 at 16:49
• @Cham I added a full example – egreg Jun 26 at 16:52
• It appears to work great now. Thanks! – Cham Jun 26 at 17:04
• @Cham Added the example – egreg Jun 26 at 17:41