\ifmmode 的正确用法

\ifmmode 的正确用法

似乎使用中有一些\ifmmode我不知道的微妙之处。出于某种原因,使用:

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

与以下内容不完全相同:

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

我将\ifmmode测试从外部移到宏的内部。

两者都可以,除了align\hlcodeB没有问题但\hlcodeA产生警告的环境中:

LaTeX 字体警告:命令 \small 在输入行 26 的数学模式下无效

笔记:

  • 在环境中使用时未报告任何问题equation

  • 下面的 MWE 产生警告,但在环境中\hlcodeA{y2}替换,没有报告任何警告。\hlcodeB{y2}align

  • 这个例子并不是为了在数学模式下产生正确的输出,但看来我滥用我的真实示例中的环境align。这是我的内部文档的旧代码,现在我知道我应该使用tabular它——2011 年初我开始写这个文档时,我并没有意识到这一点 :-) ,现在我正试图清除一些警告。

代码:

\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

在对齐单元格的开始处,TeX 会扩展宏来寻找\omit\multicolumn),但此时单元格模板中的数学开始尚未添加,因此\ifmmode始终为假。

您需要\relax在它前面放置以终止预扫描\omit或使包含此构造的命令变得健壮,以便它不会在此上下文中扩展(使用 LaTeX\DeclareRobustCommand或 eTeX \protected


为了展示各种方法,这个简单的 eTeX 文件

\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

生产

enter image description here

(0)丢失 ffi 连字符。

(1)就是你想要的。

(2)非鲁棒无保护命令获得了 ffi 连字符,但搞乱了 if 数学测试。

(3)etex\protected宏的作用与(1)相同。

(4)使用\relax(在这种情况下与在 LaTeX 中使用相同\DeclareRobustCommand)可以使数学测试正确,但会丢失 ffi 连字符。

相关内容