Nas linguagens de programação gerais, estou acostumado a chamar funções da seguinte maneira:
myfunction(argument1, argument2, ..., argumentn)
Parece que o látex requer esta sintaxe
\mycommand{argument1}{argument2}...{argumentn}
para usar comandos. Posso chamar comandos usando a sintaxe de função usual (em vez de escrever colchetes para cada argumento)? Eu quero ser capaz de fazer isso:
\mycommand{argument1, argument2, ..., argumentn}
Responder1
Outras respostas trataram de como se pode dividir entre vírgulas, mas talvez alguma explicação mais ampla também seja útil. É importante começar com o fato de que embora o LaTeX possa ser programado de maneira geral, ele é um sistema de preparação de documentos para composição tipográfica. O design da linguagem subjacente (TeX) também reflete o mesmo objetivo, e o LaTeX usa amplamente as mesmas convenções do próprio TeX aqui.
Em termos de passagem de argumentos, o TeX lida com 'texto balanceado', que é algum material arbitrário (normalmente) começando {
e terminando com }
. Os caracteres utilizados para delimitar o 'texto balanceado' podem ser alterados, mas não o fato de que precisamos dos dois e de serem distintos. Isso significa que temos que passar argumentos na forma
\foo{balanced text 1}{balanced text 2}
etc.O TeX permite um tipo de argumento 'delimitado' mais complexo, então podemos configurar (como David como feito) para dividir o material entre vírgulas
\def\foo(#1,#2){Stuff with #1 and #2}
\foo(abc,def) => #1 = abc, #2 = def
mas isso tem que ser definido na camada de programação: não podemos simplesmente 'mudar a sintaxe central'. Além disso, a definição simples que acabei de usarrequeruma vírgula na entrada: se você estiver modelando em outras linguagens gerais, provavelmente espera que os argumentos sejam opcionais. Pode-se usar uma programação mais elaborada para dividir em números variáveis de vírgulas, mas isso sempre será uma camadaem cimado núcleo.
Um ponto importante a ter em mente é que o TeX não possui dados de string ou uma divisão de função/variável: temos apenas 'tokens'. É importante ressaltar que isso significa que podemos esperar que uma vírgula seja usada em qualquer lugar e, portanto, temos que 'proteger' as vírgulas se usarmos a sintaxe \foo(abc,efg):
\foo({abc,def},ghi) => #1 = abc,def; #2 = ghi
que (para mim) não é mais claro do que
\baz{abc,def}{ghi}
Também vale a pena notar aqui que using ( ... )
também traz alguns problemas: eles não podem aparecer nos argumentos sem causar problemas ou sem uma configuração de código mais complexa (veja Recursos xparse
).
Responder2
Uma expl3
maneira (não usando \SplitList
diretamente do xparse) definindo o comando e um comando de processamento que faz algo com os elementos da lista de argumentos, mas esse comando do processador basicamente faz a mesma operação nos elementos individuais da lista.
Nota: No caso de muitos argumentos com significados diferentes, uma key-value
abordagem é mais eficaz ou pelo menos menos propensa a erros.
\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}
Responder3
Nem sempre é uma boa ideia forçar expressões idiomáticas de uma língua para outra, mas por exemplo
\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}
Observe que, diferentemente do processamento de uma lista separada por vírgula (como por exemplo)
\usepackage{array,color,longtable,booktabs}
o \zz(z)
definido acima tem um número fixo de argumentos, acessados como, #1
mas #4
usando uma sintaxe de vírgula em vez de {}
.
Também assume que os quatro argumentos não incluem ,
ou, \relax
se necessário, precisam ser protegidos por {}
isso.\zz{{1,2},{3,4},{5,6},{7,8}}
Responder4
Aqui está uma listofitems
abordagem muito simples.
\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}