例如,如果我想定义一个命令来产生具有给定名称的函数,我使用以下代码:
\NewDocumentCommand \fun { m e{\sp\sb} O{} }
{
\operatorname{\mathrm{#1}}
\IfNoValueTF{#2}{}{\sp#2}
\IfNoValueTF{#3}{}{\sb#3}
\ifblank{#4}{}
{\left(#4\right)}
}
或以下内容:
\NewDocumentCommand \fun { m e{^_} O{} }
{
\operatorname{\mathrm{#1}}
\IfNoValueTF{#2}{}{\sp#2}
\IfNoValueTF{#3}{}{\sb#3}
\ifblank{#4}{}
{\left(#4\right)}
}
但是它们存在问题:第一个只接受一个字符作为参数#2
和#3
,而后者将所有后续字符(包括那些应该被视为参数 的字符#4
)作为参数#2
或#3
。
如何解决这个问题?
答案1
您需要将参数括在括号中,否则 TeX 将仅使用下标/上标中的第一个参数。此外,\IfValueT{#2}{\sp{#2}}
比 更容易\IfNoValueTF{#2}{}{\sp{#2}}
,我还\IfBlankTF
使用定义了一个expl3
:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_eq:NN \IfBlankTF \tl_if_blank:nTF
\ExplSyntaxOff
\NewDocumentCommand \fun { m e{^_} O{} }
{%
\operatorname{#1}%
\IfValueT{#2}{\sp{#2}}%
\IfValueT{#3}{\sb{#3}}%
\IfBlankTF{#4}{}
{\left(#4\right)}%
}
\begin{document}
\(\fun{blub}_{foo}^{bar}[zzz]\)
\end{document}
此外,在下一次xparse
更新(TL'20)中,当您将标记定义为分隔符时,如下所示:
\NewDocumentCommand \fun { e{\sp\sb} } { ... }
那么只有当文档中e
有文字标记\sp
和(即)时,参数才会匹配,但如果有其他具有相同含义的标记(如),则不会匹配。如果您定义以下内容,情况也一样:\sb
\fun\sp{arg1}\sb{arg2}
\fun^{arg1}_{arg2}
\NewDocumentCommand \fun { e{^_} } { ... }
那么函数将匹配\fun^{arg1}_{arg2}
,但是不是 \fun\sp{arg1}\sb{arg2}
。