Ich verwende etoolbox
insbesondere zur Listenverarbeitung \forcsvlist
.
Wenn ich die durch Kommas getrennte Liste direkt an übergebe \forcsvlist
, kann es jedes Element in der Liste analysieren. Wenn ich die Listenvariable jedoch woanders definiere, \forcsvlist
kann es nicht zwischen den einzelnen Elementen in der Liste unterscheiden und nimmt sie als ein ganzes Argument.
Z.B:
\newcommand\doforme[1]{#1 \\}
\forcsvlist\doforme{a,b,c}
Der obige Code funktioniert einwandfrei, indem am Ende jedes Elements eine neue Zeile eingefügt wird. Aber der folgende Code funktioniert nicht
\newcommand\doforme[1]{#1 \\}
\def\@authors{a,b,c}
\forcsvlist\doforme{\@authors}
Das bringt mich auf den Gedanken, dass es eine andere Möglichkeit geben muss, die Liste zu definieren, die \forcsvlist
interpretiert werden kann.
Antwort1
Das Problem bei der Verwendung der variablen Form war ihre frühere Erweiterung, die dann das Ganze als eine Einheit betrachtete a,b,c
. Mit einer Einheit meine ich das einzige einzelne Element in der Liste.
Um dieses Problem zu lösen, müssen wir hier zunächst doppelte Klammern verwenden. So {a,b,c}
wird {{a,b,c}}
, der Grund dafür wird am Ende dieser Antwort klar.
\expandafter
Das Primitiv erweitert das ihm nach dem nächsten gegebene Argument. Wenn beispielsweise \def\foo{A}, \def\bar{B}
und vorhanden sind \expandafter\foo\bar
, wird es zuerst zu \foo B
und dann schließlich zu AB
.
In ähnlicher Weise kann ich das obige Problem in der Frage wie folgt lösen:
noindent\expandafter\forcsvlist\expandafter\doforme\authors
Wenn wir uns den obigen rekursiven Ausdruck ansehen, geht das erste expandafter zu seinem ersten Argument (\forcsvlist), überspringt es für eine Weile und versucht, das Argument daneben zu erweitern, das in diesem Fall wieder ist \expandafter
. Das zweite \expandafter
überspringt also wieder \doforme
eine Weile und erweitert dann \authors.
\authors
ist derzeit {{a,b,c}}
. Nach der Erweiterung wird es {a,b,c}
. Der endgültige Ausdruck wird also jetzt
\noident\forcsvlist\doforme{a,b,c}
Dies entspricht der Übergabe des Arguments wie im ersten Fall in der Frage und führt daher zu denselben Ergebnissen.
Antwort2
Das Paket etoolbox
definiert einen speziellen Befehl zur Handhabung interner Listen: \forlistloop
. Diese Listen verwenden ein Sonderzeichen als internen Listentrenner. Sie müssen also \listadd
(oder ähnliche Befehle verwenden - sieheetoolbox
Dokumentation), um einer solchen Liste ein Element hinzuzufügen.
\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand\doforme[1]{#1 \\}
\forcsvlist{\listadd\authors}{a,b,c}
\noindent\forlistloop\doforme{\authors}
\end{document}