我有以下命令:
\newcommand{\plusbinomial}[3][2]{(#2 + #3)^{#1}}
该命令接受3个参数,第一个参数的默认值为2。
如果我不想使用默认值,那么我会这样调用:
\[ \plusbinomial[4]{y}{y} \]
我的问题是,如何定义所有参数的默认值以及如何调用它?
答案1
编辑:
我同意 David Carlisle 的观点,即通常情况下,使用多个具有默认值的可选参数是一种不好的做法。如果要为最后一个参数赋予值,还必须提供前面的参数。对于这类宏,使用结构来表示key=<value>
参数可能更清楚。以下示例使用pgf
此结构:
\documentclass{article}
\usepackage{pgf}
\pgfkeys{
/plus binomial/.cd,
a/.initial={5},
b/.initial={8},
c/.initial={2},
}
\newcommand{\plusbinomial}[1][]{%
\pgfkeys{/plus binomial/.cd,#1}%
(\pgfkeysvalueof{/plus binomial/a} + \pgfkeysvalueof{/plus binomial/b})^{\pgfkeysvalueof{/plus binomial/c}}%
}
\begin{document}
\( \plusbinomial \)
\( \plusbinomial[c=9] \)
\( \plusbinomial[c=9,b=1] \)
\( \plusbinomial[c=9,b=1,a=3] \)
\( \plusbinomial[c=9,a=3] \)
\end{document}
其结果如下,更加直观:
如果没有包,可以按如下方式完成:
\documentclass{article}
\makeatletter
\def\plusbinomial{%
\@ifnextchar[{%
\plusbinomial@i%
}{%
\plusbinomial@i[2]% Default is 2
}%
}
\def\plusbinomial@i[#1]{%
\@ifnextchar[{%
\plusbinomial@ii{#1}%
}{%
\plusbinomial@ii{#1}[5]% Default is 5
}%
}
\def\plusbinomial@ii#1[#2]{%
\@ifnextchar[{%
\plusbinomial@iii{#1}{#2}%
}{%
\plusbinomial@iii{#1}{#2}[8]% Default is 8
}%
}
\def\plusbinomial@iii#1#2[#3]{(#2 + #3)^#1}
\makeatother
\begin{document}
\( \plusbinomial \)
\( \plusbinomial[9] \)
\( \plusbinomial[9][1] \)
\( \plusbinomial[9][1][3] \)
\( \plusbinomial[9][][3] \)
\end{document}
但如果你愿意加入xparse
包,这变成了很多更简单:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\plusbinomial}{O{2} O{5} O{8}}{(#2 + #3)^{#1}}
\begin{document}
\( \plusbinomial \)
\( \plusbinomial[9] \)
\( \plusbinomial[9][1] \)
\( \plusbinomial[9][1][3] \)
\( \plusbinomial[9][][3] \)
\end{document}
结果完全相同:
答案2
您可以测试任何参数是否为星号 ( ) *
,并在出现这种情况时替换默认值。 工作原理如下:(默认值为2
、1
和\delta
,#1
以及#2
)#3
\documentclass{article}
\newcommand\defaultifstar[2]{\ifx*#1 #2\else #1\fi}
%% \defaultifstar{#1}{#2} --> #2 if #1 is a *, and --> #1 otherwise
\newcommand*\plusbinomial[3][2]{(\defaultifstar{#2}{1}+\defaultifstar{#3}{\delta})^{#1}}
\begin{document}
$\plusbinomial{x}{y}$,
$\plusbinomial*{y}$,
$\plusbinomial{x}*$,
$\plusbinomial[3]{x}{y}$,
$\plusbinomial[3]*{y}$,
$\plusbinomial[3]{x}*$
\end{document}
注意:上述方法实际上只测试 的第一个标记是否#1
为*
,因此当您传递一个恰好以 开头的实际参数时,它会失败*
。因此,如果可能发生这种情况,请不要使用它。
(要测试参数是否等于,*
你可以用 pdfLaTeX、XeLaTeX 和LuaLaTeX 替换(最后一个\ifx*#1
需要\ifnum\pdfstrcmp{*}{#1}=0
\ifnum\strcmp{*}{#1}=0
\ifnum\pdf@strcmp{*}{#1}
pdftexcmds
包裹)。)
您还可以测试参数是否为空,然后使用默认值。
\documentclass{article}
\newcommand\defaultifempty[2]{\if\relax\detokenize{#1}\relax #2\else #1\fi}
%% \defaultifempty{#1}{#2} --> #2 if #1 is empty, and --> #1 otherwise
\newcommand*\plusbinomial[3][2]{(\defaultifempty{#2}{1}+\defaultifempty{#3}{\delta})^{#1}}
\begin{document}
$\plusbinomial{x}{y}$,
$\plusbinomial{}{y}$,
$\plusbinomial{x}{}$,
$\plusbinomial[3]{x}{y}$,
$\plusbinomial[3]{}{y}$,
$\plusbinomial[3]{x}{}$
\end{document}
⟨ 输出结果相同 ⟩