移动可选参数

移动可选参数

当我使用创建宏时\newcommand,我通常会提供默认变体,以部分应用风格设置一些第一个参数

\newcommand\five[5]{#1,#2,#3,#4,#5}
\newcommand\letters{\five{a}{b}{c}}
\newcommand\numbers{\five{1}{2}{3}}

因此人们可以说\numbers{8}{9}并得到1,2,3,8,9

现在我想对带有可选参数的命令执行此操作,为第一个设置默认值强制的参数。据我所知,\newcommand它只接受一个可选参数,并且该参数始终必须是第一个。因此,如果我想使用新命令预定义一些参数,我必须将可选参数进一步向下移动以使其通过。以下最小工作示例展示了我如何实现这一点。

\documentclass{scrartcl}
\newcommand\five[5][f]{#1,#2,#3,#4,#5}
\newcommand\reordered{}
\newcommand\thirdoptional[2]{\renewcommand\reordered[3][f]{\five[##1]{##2}{##3}{#1}{#2}}\reordered}
\newcommand\letters{\thirdoptional{a}{b}}
\newcommand\numbers{\thirdoptional{1}{2}}

\begin{document}
\begin{itemize}
  \item \numbers[3]{4}{5}
  \item \letters[c]{d}{e}
  \item \thirdoptional{v}{w}[x]{y}{z}
  \item \thirdoptional{6}{7}{8}{9}
\end{itemize}
\end{document}

但是,我对将辅助程序导出到外部并不满意\reordered。最重要的是,如果的默认参数发生\five变化,这不会传播到\thirdoptional。还有其他方法可以重新排序参数吗?

我知道 pgfkeys 和 keyval 等软件包提供了更复杂的参数处理。但我定义的命令必须在比此示例显示的更复杂的环境中工作,尤其是其中一些命令是通过 TikZ 全局定义的\foreach,所以我想尝试放弃使用其他软件包。

答案1

您可以测试是否给出了可选参数(或者只是测试无论是空的) 并以此为条件。xparse提供一个简单的界面:

在此处输入图片描述

\documentclass{article}
\newcommand\five[5][f]{#1,#2,#3,#4,#5}
\newcommand\reordered{}
\newcommand\thirdoptional[2]{\renewcommand\reordered[3][f]{\five[##1]{##2}{##3}{#1}{#2}}\reordered}
\newcommand\letters{\thirdoptional{a}{b}}
\newcommand\numbers{\thirdoptional{1}{2}}

\usepackage{xparse}% http://ctan.org/pkg/xparse
\NewDocumentCommand{\numbersA}{o m m}{%
  \IfNoValueTF{#1}% Condition on whether the optional argument is
    {\five{1}{2}{#2}{#3}}%... empty, or...
    {\five[#1]{1}{2}{#2}{#3}}%... not.
}

\begin{document}
\begin{itemize}
  \item \numbers[3]{4}{5}
  \item \letters[c]{d}{e}
  \item \thirdoptional{v}{w}[x]{y}{z}
  \item \thirdoptional{6}{7}{8}{9}
  \item \numbersA{4}{5}
  \item \numbersA[3]{4}{5}
\end{itemize}
\end{document}

上述 MWE 定义了\numbersA[<opt>]{<stuff>}{<stuff>}将可选参数插入<opt>到需要的正确位置。可以\five对进行类似的定义。\lettersA

相关内容