Desde los lenguajes de programación generales, estoy acostumbrado a llamar funciones de la siguiente manera:
myfunction(argument1, argument2, ..., argumentn)
Parece que el látex requiere esta sintaxis.
\mycommand{argument1}{argument2}...{argumentn}
para usar comandos. ¿Puedo llamar comandos usando la sintaxis de función habitual (en lugar de escribir llaves para cada argumento)? Quiero poder hacer esto:
\mycommand{argument1, argument2, ..., argumentn}
Respuesta1
Otras respuestas han tratado sobre cómo se pueden dividir las comas, pero quizás también sea útil alguna explicación más amplia. Es importante comenzar con el hecho de que, si bien LaTeX se puede programar en general, es un sistema de preparación de documentos para composición tipográfica. El diseño del lenguaje subyacente (TeX) también refleja el mismo objetivo, y LaTeX utiliza en gran medida las mismas convenciones que el propio TeX aquí.
En términos de paso de argumentos, TeX trata con 'texto balanceado', que es algún material arbitrario (normalmente) que comienza {
y termina con }
. Los caracteres utilizados para delimitar el 'texto equilibrado' se pueden modificar, pero no el hecho de que necesitemos los dos y que sean distintos. Eso significa que tenemos que pasar argumentos en la forma
\foo{balanced text 1}{balanced text 2}
etc.TeX permite un tipo de argumento 'delimitado' más complejo, por lo que podemos configurar (como David como hecho) para dividir el material por comas
\def\foo(#1,#2){Stuff with #1 and #2}
\foo(abc,def) => #1 = abc, #2 = def
pero esto debe definirse en la capa de programación: no podemos simplemente "cambiar la sintaxis central". Además, la definición simple que acabo de usarrequiereuna coma en la entrada: si está modelando en otros lenguajes generales, probablemente espere que los argumentos sean opcionales. Se puede utilizar una programación más elaborada para dividir en un número variable de comas, pero esto siempre será una capa.en la parte superiordel núcleo.
Un punto clave a tener en cuenta es que TeX no tiene datos de cadena ni una división función/variable: solo tenemos 'tokens'. Es importante destacar que esto significa que bien podríamos esperar que se use una coma en cualquier lugar, por lo que tenemos que 'proteger' las comas si usamos la sintaxis \foo(abc,efg):
\foo({abc,def},ghi) => #1 = abc,def; #2 = ghi
lo cual (para mí) no es más claro que
\baz{abc,def}{ghi}
También vale la pena señalar aquí que el uso ( ... )
también conlleva algunos problemas: no pueden aparecer en los argumentos sin causar problemas o sin una configuración de código más compleja (consulte xparse
).
Respuesta2
Una expl3
forma (sin usar \SplitList
directamente desde xparse) definiendo el comando y un comando de procesamiento que hace algo con los elementos de la lista de argumentos, pero este comando del procesador básicamente hace la misma operación en los elementos individuales de la lista.
Nota: En caso de que haya muchos argumentos que tengan significados diferentes, un key-value
enfoque es más eficaz o al menos menos propenso a errores.
\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}
Respuesta3
No siempre es una buena idea forzar modismos de un idioma a otro, pero por ejemplo
\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}
Tenga en cuenta que, a diferencia del procesamiento de una lista separada por comas (como por ejemplo)
\usepackage{array,color,longtable,booktabs}
lo \zz(z)
definido anteriormente tiene un número fijo de argumentos, a los que se accede como #1
pero #4
usando una sintaxis de coma en lugar de {}
.
También supone que los cuatro argumentos no incluyen ,
o, \relax
si es necesario, deben estar protegidos {}
por\zz{{1,2},{3,4},{5,6},{7,8}}
Respuesta4
Aquí hay un listofitems
enfoque muy simple.
\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}