我创建了一个带有 3 个可选参数的命令。
以下是 MWE:
\documentclass[10pt,a4paper,french]{article}
\usepackage{mathtools}
\usepackage{babel}
\usepackage[warnings-off={mathtools-colon,mathtools-overbracket},math-style=french]{unicode-math}
\usepackage[scale={0.75,0.8},footskip=1.5cm,heightrounded]{geometry}
\NewDocumentCommand{\pliste}{O{x} O{1} O{n}}{(#1_{#2},\dotsc,#1_{#3})}
\begin{document}
$\pliste$,\quad$\pliste[y]$,\quad$\pliste[z][2]$,\quad$\pliste[a][][p]$
\end{document}
它运行正常,但在这种情况下$\pliste[a][][p]$
,第二个参数的默认值(此处为 1)没有出现。所以也许只使用可选参数不是一个好主意?我做错了什么吗?
答案1
插入默认参数仅有的当未指定可选参数时。指定[]
意味着可选参数将被替换为空。
可选参数不是问题,坏主意是在它们彼此独立时使用多个参数。
举个例子,\makebox
有两个可选的初始参数,但只有在指定第一个参数时第二个参数才有意义:
\makebox{x}% natural width
\makebox[2cm]{x}% 2cm wide (centered by default)
\makebox[2cm][l]{x}% 2cm wide left aligned
以下类型的作品
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\NewDocumentCommand{\pliste}{O{x} O{1} O{n}}{%
(\IfBlankTF{#1}{x}{#1}_{\IfBlankTF{#2}{1}{#2}},\dots,\IfBlankTF{#1}{x}{#1}_{#3})%
}
\begin{document}
$\pliste$,
$\pliste[y]$,
$\pliste[z][2]$,
$\pliste[a][][p]$
\end{document}
但这真的很尴尬。
您可以将变量名称设为必需的,并更改可选参数的顺序:
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\NewDocumentCommand{\pliste}{O{1} m O{n}}{(#2_{#1},\dots,#2_{#3})}
\begin{document}
$\pliste{x}$,
$\pliste[2]{y}$,
$\pliste{z}[p]$,
$\pliste[2]{a}[p]$
\end{document}
可以使用不同的方法生成相同的输出,其中有一个接受键值语法的单个(可选)参数。
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\ExplSyntaxOn
\keys_define:nn { didier/pliste }
{
v .tl_set:N = \l_didier_pliste_variable_tl,
s .tl_set:N = \l_didier_pliste_start_tl,
e .tl_set:N = \l_didier_pliste_end_tl,
}
% defaults
\tl_new:N \l_didier_pliste_initial_tl
\keys_precompile:nnN { didier/pliste } { v=x, s=1, e=n } \l_didier_pliste_initial_tl
\NewDocumentCommand{\pliste}{O{}}
{
\group_begin:
\tl_use:N \l_didier_pliste_initial_tl
\keys_set:nn { didier/pliste } { #1 }
(
\l_didier_pliste_variable_tl\sb{\l_didier_pliste_start_tl}
,\dots,
\l_didier_pliste_variable_tl\sb{\l_didier_pliste_end_tl}
)
\group_end:
}
\ExplSyntaxOff
\begin{document}
$\pliste$,
$\pliste[v=y,s=2]$,
$\pliste[e=p,v=z]$,
$\pliste[s=2,v=a,e=p]$
\end{document}
这里的优点是,你不需要记住参数的顺序,而只需要记住键名称。
v
“变量”s
“开始”e
代表“结束”
另外,如果\dots
后面跟着逗号,则amsmath
自动使用\dotsc
。此命令主要被认为是在无法猜测以下字符时使用的,例如
$x_{1},x_{2},\dots,x_{n},x_{n+1},\dotsc$
答案2
我同意 @egreg 的观点,应该避免这种情况,但只是为了避免这种情况,这显示了使用 的ltcmd
参数处理器的另一种可能性。这个想法很简单,只需默认将它们设置为空,如果它们是空的/空白的,则使用参数处理器将它们更改为真正的默认值。
\documentclass{article}
\usepackage{mathtools}
\newcommand\ProcessOdefault[2]
{%
\IfBlankTF{#2}
{\edef\ProcessedArgument{\unexpanded{#1}}}
{\edef\ProcessedArgument{\unexpanded{#2}}}%
}
\NewDocumentCommand{\pliste}
{>{\ProcessOdefault{x}}O{} >{\ProcessOdefault{1}}O{} O{n}}
{(#1_{#2},\dotsc,#1_{#3})}
\begin{document}
$\pliste$,\quad$\pliste[y]$,\quad$\pliste[z][2]$,\quad$\pliste[a][][p]$
\end{document}
另一种可能性是插入原本未使用的可选星号,必要时您可以跳过不需要的可选参数:
\documentclass{article}
\usepackage{mathtools}
\NewDocumentCommand{\pliste}
{O{x} s O{1} s O{n}}
{(#1_{#3},\dotsc,#1_{#5})}
\begin{document}
$\pliste$,\quad$\pliste[y]$,\quad$\pliste*[2]$,\quad$\pliste[a]*[p]$,\quad$\pliste**[p]$
\end{document}