命令定义中没有参数

命令定义中没有参数

假设我想定义一个用于排版 (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} 

相关内容