![リスト変数を定義する](https://rvso.com/image/309876/%E3%83%AA%E3%82%B9%E3%83%88%E5%A4%89%E6%95%B0%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%99%E3%82%8B.png)
etoolbox
具体的には、リスト処理に を使用しています\forcsvlist
。
カンマ区切りのリストを に直接渡すと\forcsvlist
、リスト内の各項目を解析できます。ただし、リスト変数を別の場所で定義すると、 は\forcsvlist
リスト内の各項目を区別できず、1 つの引数として受け取ります。
例えば:
\newcommand\doforme[1]{#1 \\}
\forcsvlist\doforme{a,b,c}
上記のコードは各項目の末尾に改行を追加すると完璧に機能します。しかし、次のコードは機能しません
\newcommand\doforme[1]{#1 \\}
\def\@authors{a,b,c}
\forcsvlist\doforme{\@authors}
\forcsvlist
このことから、解釈できるリストを定義する別の方法があるはずだと考えます。
答え1
変数形式を使用する際の問題は、その前の展開によって全体がa,b,c
1 つのエンティティとして扱われることです。1 つのエンティティとは、リスト内の唯一の要素を意味します。
この問題を解決するには、まずここで二重括弧を使用する必要があります。したがって、 は{a,b,c}
になります{{a,b,c}}
。その理由は、この回答の最後で明らかになります。
\expandafter
プリミティブは、次の引数の後に与えられた引数を展開します。たとえば、\def\foo{A}, \def\bar{B}
とがある場合\expandafter\foo\bar
、最初は になり\foo B
、最終的には になりますAB
。
同様に、上記の問題は次のようにして解決できます。
noindent\expandafter\forcsvlist\expandafter\doforme\authors
上記の再帰式を見ると、最初の expandafter は最初の引数 (\forcsvlist) に行き、しばらくそれをスキップし、その次の引数 (この場合再び ) を展開しようとします\expandafter
。したがって、2 番目はしばらく\expandafter
スキップしてから、現在はを展開します。展開後は になります。したがって、最終的な式は次のようになります。\doforme
\authors.
\authors
{{a,b,c}}
{a,b,c}
\noident\forcsvlist\doforme{a,b,c}
これは、質問の最初のケースのように引数を渡すのと同じであり、したがって同じ結果が生成されます。
答え2
パッケージはetoolbox
内部リストを処理するための特別なコマンドを定義します: \forlistloop
。これらのリストは内部リスト区切り文字として特別な文字を使用します。したがって、\listadd
(または同様のコマンドを使用する必要があります。etoolbox
ドキュメンテーション) を使用して、そのようなリストに項目を追加します。
\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand\doforme[1]{#1 \\}
\forcsvlist{\listadd\authors}{a,b,c}
\noindent\forlistloop\doforme{\authors}
\end{document}