Ich habe eine durch Kommas getrennte Zeichenfolge. Darauf möchte ich jedes Element abrufen und einen Befehl anwenden. Ich habe Folgendes, was funktioniert.
\documentclass[12pt]{article}
\usepackage[trim]{tokenizer}
\newcommand{\cadd}[1]{
\def\Source{#1}
\whiledo{\not\equal{\Source}{}}
{
\GetTokens{TokenOne}{TokenTwo}{\Source}
\textbf{\TokenOne}
\let\Source\TokenTwo
}
}
\begin{document}
\cadd{a,b,c}
\end{document}
Aber ich hätte gerne folgendes
\documentclass[12pt]{article}
\usepackage[trim]{tokenizer}
\newcommand{\cadd}[1]{
\whiledo{\not\equal{#1}{}}
{
\GetTokens{TokenOne}{TokenTwo}{#1}
\textbf{\TokenOne}
\let\#1\TokenTwo
}
}
\begin{document}
\cadd{a,b,c}
\end{document}
Aber es \let\#1\TokenTwo
wird ein Fehler ausgegeben. Wie kann ich #1
mit\let
Antwort1
#1
wird beim ersten Aufruf des Makros ersetzt. Wenn Makro\cadd
\newcommand{\cadd}[1]{
\whiledo{\not\equal{#1}{}}
{
\GetTokens{TokenOne}{TokenTwo}{#1}
\textbf{\TokenOne}
\let\#1\TokenTwo
}
}
heißt \cadd{a,b,c}
, dann wird es zu:
<space>
\whiledo{\not\equal{a,b,c}{}}<space>
{<space>
\GetTokens{TokenOne}{TokenTwo}{a,b,c}<space>
\textbf{\TokenOne}<space>
\let\#1\TokenTwo
}<space>
- Die Zeile
\let\#1\TokenTwo
besteht aus der\let
Zuweisung\let\#=1
und\TokenTwo
.#1
wird nur bei der Makroerweiterung durch das erste Argument ersetzt. Es gibt viele Leerzeichen (verursacht durch das Zeilenende):
- Der erste wird im vertikalen Modus ignoriert, da der Absatz noch nicht begonnen hat.
- Das zweite wird ignoriert, wenn
\whiledo
der Schleifenkörper als nicht begrenztes Argument gelesen wird. - Die dritte und vierte Zahl werden in der Ausgabe vorhanden sein.
- Der Letzte wird wegen des Absatzendes entfernt.
Leerzeichen am Zeilenende können durch die Verwendung von Kommentarzeichen vermieden werden, wie im folgenden Beispiel zu sehen ist.
Es gibt viele Parser für durch Kommas getrennte Listen. Einer davon wird vom Paket bereitgestellt kvsetkeys
:
\documentclass[12pt]{article}
\usepackage{kvsetkeys}
\makeatletter
\newcommand{\cadd}[1]{%
\comma@parse{#1}{\caddentry}%
}
\newcommand*{\caddentry}[1]{%
\textbf{[#1]}%
}
\makeatother
\begin{document}
\cadd{a,b,c}
\cadd{ a , b , c }
\cadd{abc, def, ghi}
\cadd{{ with spaces }, {a b c}}
\end{document}
Antwort2
Heiko hat die Details hier gut beschrieben. Der Vollständigkeit halber eine Lösung mit der LaTeX3-Kommalisten-Mapping-Funktion\clist_map_inline:nn
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \cadd } { m }
{ \clist_map_inline:nn {#1} { [ \textbf {##1} ] } }
\ExplSyntaxOff
\begin{document}
\cadd{a,b,c}
\cadd{ a , b , c }
\cadd{abc, def, ghi}
\cadd{{ with spaces }, {a b c}}
\end{document}
Die zugrunde liegende Idee ist weitgehend dieselbe wie in Heikos Antwort: Anstatt die Zuordnung manuell vornehmen zu müssen, verwenden Sie einen vorgefertigten Befehl, der das Ende der Liste findet.