2

Feeding

\documentclass{article}
\usepackage{mathtools}%%% or amsmath
\begin{document}
\begin{gather*}
  \ifmmode Math\else Text\fi
\end{gather*}
\end{document}

to any of the four LaTeX processors (latex, pdflatex, xelatex, lualatex) prints “Text”. The same holds if \ifmmode starts the body of a macro called right after \begin{gather*}. The same holds if \begin{gather*} is replaced with \begin{align*}, \[\begin{aligned}, or even \[\begin{aligned}[t], or even \[\begin{aligned}[t] stuff &, each time properly terminated, of course.

Why? Who is the culprit and what to do?

  • 1
    At the beginning of an alignment cell, \ifmmode is always false. Add \relax in front of it. – egreg Jul 14 '22 at 12:03
  • 1
    @user202729 Thanks! The answer in the question you mentioned (namely, prepend \protected to \def) works if \ifmmode is hidden inside the macro, and, of course, that question itself specifically mentions both an array and a macro, therefore being not a duplicate of my original post. –  Jul 14 '22 at 12:53
  • I am reopening the question because StackExchange's interface said “This question already has an answer here: https://tex.stackexchange.com/questions/27592/ifmmode-doesnt-seem-to-work-correctly-inside-an-array-environment”. Clearly, this is not the case: the linked post is related but does not contain an answer to the current question. The real answer to the current question is provided by @egreg in https://tex.stackexchange.com/a/650863 . –  Jul 14 '22 at 13:07

1 Answers1

2

All alignment display environment of amsmath are defined in terms of the primitive \halign with suitable templates for the column cells.

By design, as soon as TeX starts examining a new cell in an \halign it is in “restricted horizontal mode” and recursively expands the first token it finds, in order to see whether \omit appears at the beginning, which would trigger not to use the specified template; usually, \omit is followed by \span in order to merge cells, but that's not mandatory.

In your case, TeX expands \ifmmode and this conditional turns out to be false, because TeX is not in math mode. It would only be true after the u part (what should go before the cell text) has been inserted.

Add \relax in front of \ifmmode. But of course your conditional text would be inserted by a macro: use \DeclareRobustCommand for defining it.

Thus either

\newcommand{\mymacro}{\relax\ifmmode Math\else Text\fi}

or

\DeclareRobustCommand{\mymacro}{\ifmmode Math\else Text\fi}

The latter is preferable if \mymacro can also appear in moving arguments. It works because a macro defined by \DeclareRobustCommand expands to something preceded by \protect and, in typesetting contexts, \protect is the same as \relax.

As an aside, for macros without argument using \newcommend or \newcommand* is irrelevant. The difference shows only for macros with arguments, where the *-form disallows \par (or empty lines) in any argument. The same applies to \DeclareRobustCommand.

egreg
  • 1,121,712
  • Thx! Would \DeclareRobustCommand* have the same property as \DeclareRobustCommand in this respect? –  Jul 14 '22 at 12:43
  • 1
    @GeekestGeek With the *-form, \par or empty lines are not allowed in the argument (if any). Otherwise, there's no difference. – egreg Jul 14 '22 at 12:44
  • For whatever it's worth, \DeclareRobustCommand* changed the visual appearance compared to \newcommand* in a larger, non-minimal example. However, the change was so small that I couldn't see the difference, although diffpdf drew my attention to its existance. –  Jul 14 '22 at 12:58
  • @GeekestGeek A macro defined with \newcommand (with or without *) is expandable and you incur in the untimely expansion of \ifmmode unless you precede it with \relax. I added explanations. – egreg Jul 14 '22 at 13:01