从一般的编程语言中,我习惯以以下方式调用函数:
myfunction(argument1, argument2, ..., argumentn)
好像 latex 需要这种语法
\mycommand{argument1}{argument2}...{argumentn}
使用命令。我可以使用通常的函数语法来调用命令吗(而不是为每个参数写出括号)?我希望能够这样做:
\mycommand{argument1, argument2, ..., argumentn}
答案1
其他答案已经讨论了如何在逗号处拆分,但也许更广泛的解释也很有用。首先要知道,虽然 LaTeX 可以进行一般编程,但它是一个用于排版的文档准备系统。底层语言 (TeX) 的设计也反映了同样的目标,LaTeX 在这里主要使用与 TeX 本身相同的约定。
在传递参数方面,TeX 处理的是“平衡文本”,即一些(通常)以 开头{
和结尾的任意材料}
。用于分隔“平衡文本”的字符可以更改,但我们不能改变我们需要这两个字符并且它们是不同的这一事实。这意味着我们必须以以下形式传递参数
\foo{balanced text 1}{balanced text 2}
ETC。TeX 确实允许更复杂的“分隔”参数类型,因此我们可以设置(就像大卫所做的那样) 以逗号分隔材料
\def\foo(#1,#2){Stuff with #1 and #2}
\foo(abc,def) => #1 = abc, #2 = def
但这必须在编程层面上定义:我们不能只是“切换核心语法”。此外,我刚才使用的简单定义需要输入中的逗号:如果您正在模仿其他通用语言,您可能希望参数是可选的。可以使用更复杂的编程来以可变数量的逗号进行拆分,但这始终是一层在上面核心。
要记住的一个关键点是 TeX 没有字符串数据或函数/变量分割:我们只有“标记”。重要的是,这意味着我们很可能希望在任何地方使用逗号,因此如果我们使用 \foo(abc,efg) 语法,就必须“保护”逗号:
\foo({abc,def},ghi) => #1 = abc,def; #2 = ghi
对我来说,这并不比
\baz{abc,def}{ghi}
这里还值得注意的是,使用( ... )
也会带来一些问题:它们不能出现在参数中,否则会导致问题或需要设置更复杂的代码(参见xparse
)。
答案2
一种expl3
方法(不是直接从 xparse 使用\SplitList
)通过定义命令和处理命令来对参数列表的元素执行某些操作,但这个处理器命令基本上对列表的各个元素执行相同的操作。
注意:如果许多参数具有不同含义,则一种key-value
方法更有效或至少不容易出错。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\newcommand{\foocmd}[1]{%
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
\seq_map_inline:Nn \l_tmpa_seq {%
\fooprocessorcmd{##1}%
}
}
\ExplSyntaxOn
\newcommand{\fooprocessorcmd}[1]{\fbox{#1}}
\begin{document}
\foocmd{r,o,f,y,b,i,v}
\end{document}
答案3
把一种语言中的习语强加到另一种语言中并不总是一个好主意,但例如
\documentclass{article}
\def\zz#1{\zzz#1\relax}
\def\zzz#1,#2,#3,#4\relax{\fbox{#1} \fbox{#2} \fbox{#3} \fbox{#4}}
\begin{document}
\zz{a,b,c,d}
\end{document}
请注意,与处理逗号分隔列表不同(例如)
\usepackage{array,color,longtable,booktabs}
上面定义\zz(z)
的有固定数量的参数,可以#1
使用#4
逗号语法而不是来访问{}
。
它还假设这四个参数不包括,,
或者\relax
如果需要,它们需要受到{}
保护\zz{{1,2},{3,4},{5,6},{7,8}}
答案4
这是一个非常简单的listofitems
方法。
\documentclass{article}
\usepackage{listofitems}
\newcommand\mycommand[1]{%
\readlist*\myargs{#1}%
The \myargslen{} arguments are \showitems\myargs.
The 4th argument is ``\myargs[4].''
}
\begin{document}
\mycommand{this, is, a, big, test}
\mycommand{What, would, you do, for a, Klondike, bar?}
\end{document}