假设我想定义一个用于排版 (a+b)^2 的命令:
\newcommand{\sumsquare}[2]{\ensuremath{(#1+#2)^2}}
我怎样才能修改它以便\sumsquare{a}{0}
产生 a^2?
答案1
我建议您将语法更改为\sumsquare{a}{}
:
可以用以下方式编码:
\newcommand{\sumsquare}[2]{%
\ifx\\#2\\%
\ensuremath{#1^2}}%
\else
\ensuremath{(#1+#2)^2}}%
\fi
}
或者:
\newcommand{\sumsquare}[2]{%
\begingroup
\def\tempvar{#2}%
\ifx\tempvar\empty
\endgroup
\ensuremath{#1^2}}%
\else
\endgroup
\ensuremath{(#1+#2)^2}}%
\fi
}
如果你真的想要0
无操作指标,你可以像这样定义它:
\newcommand{\sumsquare}[2]{%
\begingroup
\def\tempvara{#2}%
\def\tempvarb{0}%
\ifx\tempvara\tempvarb
\endgroup
\ensuremath{#1^2}}%
\else
\endgroup
\ensuremath{(#1+#2)^2}}%
\fi
}
(我这样命名临时变量是为了避免\makeatletter
。通常使用\@tempa
和。)\@tempb
解释:
如果下一个标记具有相同的定义,则该\ifx
命令将比较下一个标记(例如宏、字符等)。在最后一个示例中,和都0
定义#2
为一个宏,然后进行比较。这需要赋值,因此不可扩展,即在 中不起作用\edef
。
在第一个代码中,\ifx\\#2\\
用于测试是否#2
为空。如果#2
包含某些内容,\ifx
则将其中的第一个标记与进行比较,如果不以开头,\\
则不匹配。然后,所有其他标记都简单地作为#2
\\
真的部分并简单地将其丢弃。如果\\
是有效的值,则#2
只需使用其他宏(如\relax
或)\@nnil
代替。
但是,如果#2
为空,则表达式简化为\ifx\\\\
,即\ifx
比较两个\\
,它们当然定义相同。
答案2
使用的解决方案xparse
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\sumsquare{mg}{%
\IfNoValueTF{#2}
{\ensuremath{#1^2}}
{\ensuremath{(#1+#2)^2}}
}
答案3
它也可以通过可选的第二个参数来完成,但它并不比输入它更短
\documentclass{article}
\newcommand{\sumsquare}[2]{\ensuremath{\ifx\relax#2\relax#1\else(#1+#2)\fi^2}}
\begin{document}
\sumsquare{a}{b} \sumsquare{a}{}
\end{document}