包含美元符号 (\$) 的 LaTeX 宏中的格式化字符串

包含美元符号 (\$) 的 LaTeX 宏中的格式化字符串

我正在编写一个宏,根据 LaTeX 报告中的字符串值来格式化字符串。我遇到了一个问题,其中包含美元符号 (\$) 的字符串会导致错误。这是一个最小工作示例:

\documentclass{article}
\usepackage{color}
\usepackage{xstring}

\newcommand{\ChgFmt}[1]{\IfSubStr{#1}{-}{{\color{red} #1}}{ {\color{green} #1}}}

\begin{document}
This number is printed in green: \ChgFmt{1\%}
This number is printed in red: \ChgFmt{-1\%}
\end{document} 

如果将上面的 1\% 替换为 \$1 million,则我会收到消息“TeX 容量超出”,并且不会产生任何输出。我读到一种解决方案是将上面的 \newcommand 的参数括在 \ensuremath 中,如下所示:

\documentclass{article}
\usepackage{color}
\usepackage{xstring}

\newcommand{\ChgFmt}[1]{\ensuremath{\IfSubStr{#1}{-}{{\color{red} #1}}{ {\color{green} #1}}}}

\begin{document}
This number is printed in green: \ChgFmt{\$1 million}
\end{document} 

但是,这会将“百万”格式化为数学符号而不是字符串。我尝试按照下面的建议使用@gobble,但我的代码还有额外的复杂性,因为我使用了动态变量。具体来说,这是一个最小示例:

\documentclass{article}
\usepackage{color}

\newcommand{\FirstDollarAmount}{\$1 million}
\newcommand{\SecondDollarAmount}{-\$1 million}
\newcommand{\inputnum}[2]{\expandafter\csname #1#2\endcsname}

\makeatletter
\newcommand{\ChgFmt}[1]{{\@ifnextchar{-}{\color{red}$-$\@gobble}{\color{green}}#1}}
\makeatother

\begin{document}
This number should be printed in green: \ChgFmt{\inputnum{First}{DollarAmount}}

This number should be printed in red: \ChgFmt{\inputnum{Second}{DollarAmount}}
\end{document}

虽然输出没有错误,但两个数字都打印成绿色。还有其他想法吗?

答案1

您需要\fullexpandarg,但\$\text无法幸免;后一个命令是在普通类型中设置“百万”所必需的。

因此,我首先中\$和并使它们在测试期间\text等同;在测试决定是否遵循真实路径或错误路径后进行替换。\relax

其他宏可能需要类似的处理;并不是\%因为它非常强大且能够存活下来\edef

\documentclass{article}
\usepackage{amsmath}
\usepackage{color}
\usepackage{xstring}

\makeatletter
\newcommand{\ChgFmt}[1]{%
  \ensuremath{%
    \begingroup\fullexpandarg
    \let\$\relax \let\text\unexpanded
    \IfSubStr{#1}{-}
      {\endgroup\@firstoftwo}
      {\endgroup\@secondoftwo}%
    {\begingroup\color{red}#1\endgroup}
    {\begingroup\color{green}#1\endgroup}%
  }%
}
\makeatother

\newcommand{\FirstDollarAmount}{\$1\text{ million}}
\newcommand{\SecondDollarAmount}{-\$1\text{ million}}
\newcommand{\inputnum}[2]{\expandafter\csname #1#2\endcsname}

\begin{document}
This number is printed in green: \ChgFmt{\$1 \text{ million}}

This number is printed in red: \ChgFmt{-\$1 \text{ million}}

This number should be printed in green: \ChgFmt{\inputnum{First}{DollarAmount}}

This number should be printed in red: \ChgFmt{\inputnum{Second}{DollarAmount}}
\end{document} 

在此处输入图片描述

相关内容