Aus allgemeinen Programmiersprachen bin ich es gewohnt, Funktionen folgendermaßen aufzurufen:
myfunction(argument1, argument2, ..., argumentn)
Es scheint, als ob Latex diese Syntax erfordert
\mycommand{argument1}{argument2}...{argumentn}
Befehle verwenden. Kann ich Befehle mit der üblichen Funktionssyntax aufrufen (anstatt für jedes einzelne Argument Klammern zu schreiben)? Ich möchte Folgendes tun können:
\mycommand{argument1, argument2, ..., argumentn}
Antwort1
In anderen Antworten wurde darauf eingegangen, wie man an Kommas trennen kann, aber vielleicht ist auch eine ausführlichere Erklärung hilfreich. Zunächst einmal ist es wichtig, dass LaTeX zwar allgemein programmiert werden kann, aber ein Dokumentvorbereitungssystem für den Schriftsatz ist. Das Design der zugrunde liegenden Sprache (TeX) spiegelt dasselbe Ziel wider, und LaTeX verwendet hier weitgehend dieselben Konventionen wie TeX selbst.
Was die Übergabe von Argumenten betrifft, so arbeitet TeX mit „ausgewogenem Text“, also beliebigem Material, das (normalerweise) mit beginnt {
und endet }
. Die Zeichen, die zur Abgrenzung des „ausgewogenen Textes“ verwendet werden, können geändert werden, nicht jedoch die Tatsache, dass wir die beiden benötigen und dass sie unterschiedlich sind. Das bedeutet, dass wir Argumente in der Form übergeben müssen
\foo{balanced text 1}{balanced text 2}
usw.TeX erlaubt einen komplexeren 'abgegrenzten' Argumenttyp, daher können wir (wie David es getan hat), um Material an Kommas zu trennen
\def\foo(#1,#2){Stuff with #1 and #2}
\foo(abc,def) => #1 = abc, #2 = def
aber das muss auf der Programmierebene definiert werden: wir können nicht einfach „die Kernsyntax ändern“. Außerdem ist die einfache Definition, die ich gerade verwendet habeerfordertein Komma in der Eingabe: Wenn Sie andere allgemeine Sprachen modellieren, erwarten Sie wahrscheinlich, dass die Argumente optional sind. Man kann eine ausgefeiltere Programmierung verwenden, um bei unterschiedlichen Kommazahlen zu teilen, aber dies wird immer eine Schicht seinoben draufdes Kerns.
Ein wichtiger Punkt, den man im Hinterkopf behalten sollte, ist, dass TeX weder String-Daten noch eine Funktion/Variablen-Aufteilung hat: Wir haben nur „Token“. Das bedeutet, dass wir durchaus erwarten können, dass überall ein Komma verwendet wird, und daher Kommas „schützen“ müssen, wenn wir die \foo(abc,efg)-Syntax verwenden:
\foo({abc,def},ghi) => #1 = abc,def; #2 = ghi
was (für mich) nicht klarer ist als
\baz{abc,def}{ghi}
Hier ist auch zu beachten, dass die Verwendung ( ... )
auch einige Probleme mit sich bringt: Sie können nicht in den Argumenten erscheinen, ohne Probleme zu verursachen oder ohne einen komplexeren Code-Aufbau (siehe xparse
).
Antwort2
Eine expl3
Möglichkeit (die nicht \SplitList
direkt von xparse verwendet wird) besteht darin, den Befehl und einen Verarbeitungsbefehl zu definieren, der etwas mit den Elementen der Argumentliste macht, aber dieser Prozessorbefehl führt im Grunde dieselbe Operation für die einzelnen Elemente der Liste aus.
Hinweis: Bei vielen Argumenten mit unterschiedlichen Bedeutungen key-value
ist ein Ansatz effektiver oder zumindest weniger fehleranfällig.
\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}
Antwort3
Es ist nicht immer eine gute Idee, Redewendungen von einer Sprache in eine andere zu übertragen, aber zum Beispiel
\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}
Beachten Sie, dass im Gegensatz zur Verarbeitung einer durch Kommas getrennten Liste (wie zum Beispiel)
\usepackage{array,color,longtable,booktabs}
Die \zz(z)
oben definierte Version hat eine feste Anzahl von Argumenten, #1
auf die wie zu zugegriffen wird #4
, jedoch mit einer Kommasyntax statt mit {}
.
Es wird auch angenommen, dass die vier Argumente nicht enthalten ,
oder, \relax
falls erforderlich, durch {}
solche geschützt werden müssen\zz{{1,2},{3,4},{5,6},{7,8}}
Antwort4
Hier ist ein sehr einfacher listofitems
Ansatz.
\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}