# Correct usage of \ifmmode

Seems that there is some subtlety in using \ifmmode that I am not aware of. For some reason, using:

\newcommand{\hlcodeA}[1]{\ifmmode\else\small\fi\texttt{\hilight{#1}}}%


is not quite identical to:

\newcommand{\hlcodeB}[1]{\texttt{\hilight{\ifmmode\else\small\fi#1}}}%


where I moved the \ifmmode test to the inner level of the macro from the outer.

Both are ok, except in an alignenvironment where \hlcodeB has no problems, but \hlcodeA yields a warning:

LaTeX Font Warning: Command \small invalid in math mode on input line 26

## Notes:

• No problems are reported when used in an equation environment.

• The MWE below yields a warning, but replacing \hlcodeA{y2} with \hlcodeB{y2} in the align environment, no warnings are reported.

• This example is not really intended to produce proper output in math mode, but it seems that I am abusing the align environment in my real example. This is old code for my internal documentation where I now know that I should have used tabular instead -- this was not obvious to me in early 2011 when I started this document :-) , and am just now trying to clean up some of the warnings.

## Code:

\documentclass{article}
\usepackage{xcolor}
\usepackage{amsmath}

\newcommand{\hilight}[1]{\colorbox{yellow}{#1}}%

\newcommand{\hlcodeA}[1]{%
\ifmmode\else\small\fi\texttt{\hilight{#1}}%
}%

\newcommand{\hlcodeB}[1]{%
\texttt{\hilight{\ifmmode\else\small\fi#1}}%
}%

\begin{document}
\hspace*{5.0cm}\hlcodeA{y} = \hlcodeA{x}%   This is ok (no warnings)

\begin{equation*}%         This is ok (no warnings)
\hlcodeA{y1} = \hlcodeA{x1}
\end{equation*}

\begin{align*}%         This is NOT ok (warnings but only from \hlcodeA)
\hlcodeA{y2} = \hlcodeB{x2}
\end{align*}
\end{document}

-

## 1 Answer

At the start of an alignment cell TeX expands macros looking for \omit (\multicolumn) the math start in the cell template has not been added at this point so \ifmmode is always false.

You need to put \relax in front of it to kill the pre-scan for \omit or make the command containing this construct be robust so it doesn't expand in this context (using LaTeX \DeclareRobustCommand or eTeX \protected)

To show the various approaches, this plain eTeX file

\def\foo{\ifmmode \phi\else fi\fi}
\protected\def\pfoo{\ifmmode \phi\else fi\fi}
\def\rfoo{\relax\ifmmode \phi\else fi\fi}

\halign{#)&$#$\hfill&\quad dif#cult\cr
0&\omit $\phi$\hfill&\omit \quad dif{f}icult\cr
1&\omit $\phi$\hfill&\omit \quad difficult\cr
2&\foo&\foo\cr
3&\pfoo&\pfoo\cr
4&\rfoo&\rfoo\cr
}

\bye


produces

(1) is what you want.

(0) loses the ffi ligature.

(2) the non robust unprotected command gets the ffi ligature but messes up the if math test.

(3) the etex \protected macro does the same as (1).

(4) using \relax (which would be the same as using \DeclareRobustCommand in LaTeX in this context) gets the math test correct but loses the ffi ligature.

-
Yep, using \newcommand{\hlcodeA}[1]{\relax\ifmmode\else\small\fi\texttt{\hilight{#1}}} yields no errors. So it seems I would have had this problem even with tabular. Hmmm, it appears I can't quite accept this answer yet -- probably need to get more rep to accept answers quicker. –  Peter Grill Nov 14 '12 at 0:06
But then under what conditions should I not use \relax\immode? Clearly there must be such a case, otherwise it would have been built into \ifmmode? –  Peter Grill Nov 14 '12 at 0:17
when \relax would be a bad idea. –  David Carlisle Nov 14 '12 at 0:26
:-) Ok, so when could \relax be a bad idea before a \immode? If it is complicated, I can post another question? –  Peter Grill Nov 14 '12 at 0:30
With e-TeX, you can simply use \protected\def to create a macro that is not expanded by TeX at the start of a cell. This then does not need \relax to get the correct result. –  Joseph Wright Nov 14 '12 at 7:06