我想定义以下宏。
\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
。