xparse
我已经使用as定义了一个命令
\DeclareDocumentCommand\mymacro{o o o}
我想用不同数量的参数来调用它(最多 3 个)
\mymacro, \mymacro[test][two], \mymacro[][][test]
ETC...
问题是它[]
似乎没有返回一个\NoValue
而是一个空令牌,因为我使用的测试\IfNoValueTF
从未返回 false。
有没有办法将参数设置为“空”,就像\mymacro[]
当它是一个空字符串时#1
一样?\NoValue
本质上我需要设置“空”参数才能\NoValue
使我的代码正常工作。
我总是可以做到
\mymacro[\NoValue][test][\NoValue]
但这当然违背了简化的目的。
在我的代码中我使用了\IfNoValueTF{#n}
很多但是为了使其在空参数上工作我需要类似的东西\IfNoValueOrEmptyTF
。
答案1
使用混合物xparse
以及\ifx
可以测试空参数的条件:
\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\makeatletter
\DeclareDocumentCommand\mymacro{o o o}{
\def\@tempa{#1}Arg 1 is \ifx\@tempa\@empty\relax empty\else #1\fi. \par
\def\@tempa{#2}Arg 2 is \ifx\@tempa\@empty\relax empty\else #2\fi. \par
\def\@tempa{#3}Arg 3 is \ifx\@tempa\@empty\relax empty\else #3\fi.
}
\makeatother
\begin{document}
\verb|\mymacro|:\par\mymacro
\verb|\mymacro[test][two]|: \par\mymacro[test][two]
\verb|\mymacro[][][test]|: \par\mymacro[][][test]
\verb|\mymacro[][][]|: \par\mymacro[][][]
\verb|\mymacro[one][][three]|: \par\mymacro[one][][three]
\end{document}
答案2
这是一个\IfNoValueOrEmpty
宏:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfNoValueOrEmptyTF}{mmm}
{
\IfNoValueTF{#1}{#2}
{
\tl_if_empty:nTF {#1} {#2} {#3}
}
}
\ExplSyntaxOff
\NewDocumentCommand{\mymacro}{ooo}{%
\IfNoValueOrEmptyTF{#1}{\typeout{\#1 is empty}}{\typeout{\string#1 is `#1'}}%
\IfNoValueOrEmptyTF{#2}{\typeout{\#2 is empty}}{\typeout{\string#2 is `#2'}}%
\IfNoValueOrEmptyTF{#3}{\typeout{\#3 is empty}}{\typeout{\string#3 is `#3'}}%
}
\mymacro
\mymacro[a]
\mymacro[a][b]
\mymacro[a][b][c]
\mymacro[][b]
\mymacro[][][c]
\mymacro[][][]
但是,带有三个可选参数的命令很难管理,因为需要记住哪个是哪个。键值语法可能更容易使用。
答案3
空参数和NoValue
参数 1 并不相同(实际上,\NoValue
直接使用不受支持,因为我们很快就会更改定义)。与 LaTeX2e 不同\newcommand
,xparse
区分给定但为空的参数和未给定的参数。因此,如果您希望能够输入以下形式
\foo[][][baz]
你根本不想做NoValue
测试,而是
\ExplSyntaxOn
\DeclareDocumentCommand{\foo}{ O{} O{} O{} }
{
\tl_if_empty:nTF {#1}
...
}
使用代码级测试来测试空值。(我们目前没有设计级空值测试。)