如何定义接受超过 9 个参数的命令

如何定义接受超过 9 个参数的命令

我有一个数学变换,它需要 16 个参数(分为 3+8+5),并且想为其创建一个乳胶命令,以便我可以在需要时轻松更改它的符号。

据我所知,\def\newcommand最多都接受 9 个参数,有没有(推荐的)方法来扩展它?

答案1

你将需要一次解析一些参数并将它们存储到临时寄存器或宏中。例如

\newcommand\foo[9]{%
    \def\tempa{#1}%
    \def\tempb{#2}%
    \def\tempc{#3}%
    \def\tempd{#4}%
    \def\tempe{#5}%
    \def\tempf{#6}%
    \def\tempg{#7}%
    \def\temph{#8}%
    \def\tempi{#9}%
    \foocontinued
}
\newcommand\foocontinued[7]{%
    % Do whatever you want with your 9+7 arguments here.
}

答案2

这是xargs 包裹,还有一些黑色 TeX 魔法keyval就我自己而言,由于习惯使用 Python,我更喜欢/xkeyval包提供的键值参数语法。

顺便提一下,如果我发现自己需要超过 9 个参数,这通常意味着我的宏/定义/代码组织不太好,我会首先尝试改进这一点。但当然,也存在 9 个参数完全没问题的合理情况 --- 尤其是当您尝试构建带有大量旋钮和调整项的定义时。

答案3

新答案

这里使用的包listofitems比我下面原来的答案更可取,因为\readlist它在捕获参数时不会扩展参数,也不依赖于不方便的罗马数字语法。

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\setsepchar{ }
\readlist\arg{1 2 3 4 5 6 7 8 9 10 11 12 FinalArgument}
There are \arglen{} arguments.  The thirteenth is \arg[13]
\end{document}

原始答案

在回应生成表时如何在命令中使用变量? 我提到了 stringstrings 包中有一个 \getargs 命令,该命令将解析在单个 { } 中传递的大量参数。总结一下那条回复,

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\getargs{1 2 3 4 5 6 7 8 9 10 11 12 FinalArgument}
There are \narg~arguments.  The thirteenth is \argxiii
\end{document}

此示例的结果是:

共有 13 个参数。第十三个是 FinalArgument


\getargs编辑:包中提供了一个更高效的版本,readarray并称为\getargsC(尊重 David Carlisle 的帮助)。因此,可以使用以下方法更快地完成相同的任务

\documentclass{article}
\usepackage{readarray}
\begin{document}
\getargsC{1 2 3 4 5 6 7 8 9 10 11 12 FinalArgument}
There are \narg~arguments.  The thirteenth is \argxiii
\end{document}

答案4

首先,我们定义命令\foo。它包含一个用于参数扩展的嵌套命令定义。注意它是使用声明的\neworrenewcommand,如果未定义则定义命令,如果已定义则重新定义命令。*

带有一个破折号的参数绑定到第一个命令,而带有两个破折号的参数绑定到第二个命令。MWE:

\documentclass{article}

% Provide a way to declare and renew a command in one command
\newcommand{\neworrenewcommand}[1]{\providecommand{#1}{}\renewcommand{#1}}

\newcommand{\foo}[9]{
    \neworrenewcommand{\ffoo}[1]{
        #1 #2 #3 #4 #5 #6 #7 #8 #9 ##1
    }
    \ffoo
}

\begin{document}
    \foo{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}

    \foo{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}
\end{document}

结果预览:

预览

\foo*这是必要的,因为多次调用会重新定义嵌套命令。这个\neworrenewcommand技巧进一步解释这里

相关内容