xparse 空参数

xparse 空参数

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 不同\newcommandxparse区分给定但为空的参数和未给定的参数。因此,如果您希望能够输入以下形式

\foo[][][baz]

你根本不想做NoValue测试,而是

\ExplSyntaxOn
\DeclareDocumentCommand{\foo}{ O{} O{} O{} }
  {
    \tl_if_empty:nTF {#1}
    ...
  }

使用代码级测试来测试空值。(我们目前没有设计级空值测试。)

相关内容