当我使用创建宏时\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