20

I’m struggling with getting \ifmmode to work correctly when used inside an array environment which is inside a displaymath environment.

Here is a minimal example:

\documentclass{article}

\newcommand{\signal}[1]{%
  \ifmmode
    1#1
  \else
    2$#1$
  \fi
}

\begin{document}
\begin{displaymath}
  \begin{array}{cc}
    \signal{a} \signal{b} & \signal{c} \signal{d} \\
  \end{array}
\end{displaymath}
\end{document}

This example generates the following output:

2a 1 _b_ 2c 1 _d_

Why doesn’t all invokations of \signal detect math-mode?

1 Answer 1

24

At the start of an alignment cell, TeX is looking for an \omit or \noalign, rather than being in math mode. The way to deal with this is to insert a \relax.

\documentclass{article}

\newcommand{\signal}[1]{%
  \relax
  \ifmmode
    1#1
  \else
    2$#1$
  \fi
}

\begin{document}
\begin{displaymath}
  \begin{array}{cc}
    \signal{a} \signal{b} & \signal{c} \signal{d} \\
  \end{array}
\end{displaymath}
\end{document}

Now, the issue with that is that it will mess up kerning if used in other places (it puts a \relax in even when it's not needed). In some LaTeX3 work, we've experimented with an approach to 'pick up' the alignment cell using e-TeX. At one point we had something very elaborate to test for this

\documentclass{article}

\newcommand{\signal}[1]{%
  \ifnum\currentgrouptype = 6 %
    \ifnum\lastnodetype = 0 %
    \else
      \ifnum\lastnodetype = 7 %
      \else
        \relax
      \fi
    \fi
  \fi
  \ifmmode
    1#1
  \else
    2$#1$
  \fi
}

\begin{document}
\begin{displaymath}
  \begin{array}{cc}
    \signal{a} \signal{b} & \signal{c} \signal{d} \\
  \end{array}
\end{displaymath}
\end{document}

This uses the various diagnostics from e-TeX to pick up the start of a cell. However, this is really not a good idea as it pretends to be expandable but does insert \relax: not expandable! A much cleaner approach is to use \protected

\documentclass{article}

\protected\def\signal#1{%
  \ifmmode
    1#1
  \else
    2$#1$
  \fi
}

\begin{document}
\begin{displaymath}
  \begin{array}{cc}
    \signal{a} \signal{b} & \signal{c} \signal{d} \\
  \end{array}
\end{displaymath}
\end{document}

as e-TeX does not expand protected macros here.

1
  • 1
    Joseph, we're not in math mode: that will be started when TeX inserts the u part for the cell (in the terminology of the TeXbook) and ended with the v part. Saying \omit won't give math mode, for example; LaTeX takes precautions to add again the $ characters when \multicolumn is used in an array. But this is almost splitting hairs, I guess. :)
    – egreg
    Sep 5, 2011 at 21:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .