如何创建以下宏?

如何创建以下宏?

我想定义以下宏。

\newcommand{\NC}{\ensuremath{\mathbf{NC}}}
\newcommand{\NC}[1]{\ensuremath{\mathbf{NC^{#1}}}}

但是 LaTeX 会抱怨\NC已经定义了。因此,我仅\NC使用可选参数进行定义,如下所示。

\newcommand{\NC}[1][\phantom{0}]{\ensuremath{\mathbf{NC^{#1}}}}

现在\NC可以工作了,但是\NC1没有按预期工作。

答案1

有两种方法可以解决您的问题:如果您愿意输入\NC[1]等,那么以下方法有效

\newcommand{\NC}[1][]{{\def\NCexponent{#1}%
  \ifx\NCexponent\empty{\ensuremath{\mathbf{NC}}}\else
    \ensuremath{\mathbf{NC^{#1}}}\fi}}

这里,\ifx\exponent\empty测试可选参数是否存在,然后\mathbf{NC^{#1}}如果参数存在则使用,\mathbf{NC}否则使用。这使得和都\NC\NC[1]预期工作。(额外的括号层{{...}}是为了防止辅助宏\NCexponent泄漏到这个宏之外。)对于所有 TeX 宏,宏后的空格会被 TeX 吞掉,因此您需要使用类似这样的结构来\NC\ and\NC[1]在后面获取空格\NC

如果你坚持要能够\NC像 一样打字\NC1,那么这也是可以做到的,但是解决方案更复杂。下面是一个完整的示例:

\noexpand#2(已更新以按照@egreg 的建议使用)

\documentclass{article}

\def\NC{\NCa{}}
\def\NCa#1#2{\def\next{\NCa{#1#2}}%
  % test whether #2 is a digit:
  \if0\noexpand#2\else\if1\noexpand#2\else\if2\noexpand#2\else
  \if3\noexpand#2\else\if4\noexpand#2\else\if5\noexpand#2\else
  \if6\noexpand#2\else\if7\noexpand#2\else\if8\noexpand#2\else
  \if9\noexpand#2\else
  \def\next{\NCb{#1}#2}%
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\next}
\def\NCb#1{{\def\exponent{#1}\ifx\exponent\empty
    \ensuremath{\mathbf{NC}}\else\ensuremath{\mathbf{NC^{#1}}}\fi}}

\begin{document}
There is \NC, \NC1, \NC 2\ and \NC345, as well as \NC a and again
\NC.
\end{document}

此版本的宏\NC检查以下所有标记:只要它们是数字,就将它们合并到指数中,第一个非数字停止参数。为此,使用了两个辅助宏。 \NCa构造指数;它接受两个参数,到目前为止构造的指数(#1)和输入流中的下一个标记(#2)。如果下一个标记等于 0、1、...、9,我们\NCa再次调用,并将#2添加到指数。否则,我们调用\NCb排版(如上所述测试空指数)并将其放回到#2扩展后的输入流中\NCb(通过写入\NCb{#1}#2)。

第二种解决方案的一个怪癖是全部遇到的空格\NCa会被 TeX 解析器忽略。因此,\NC 1 2 3与 相同\NC123

相关内容