でこの郵便受けリストを処理するための便利なトリックを見つけました。以下のコードでは、オプションのセパレーター引数を使用してリストを印刷できます。
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
\def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
\renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}
\printlist
ただし、コマンド内で を\author
改行と組み合わせて使用すると\\
、正しく動作しません。改行はリストの最初の要素に対してのみ設定されます。他のすべての要素では、改行は無視されます。
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][;]{%
\def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
\renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\title{Test}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
\begin{document}
\maketitle
\end{document}
たとえば、改行なしの区切り文字を使用すると::
、上記は期待どおりに機能します。
\\
コマンドに改行を追加して\author
も、期待どおりの結果が得られます。
\author{\printlisti[::]{abc,def,ghi}\\123\\456\\789}
\printlist
改行との組み合わせが\\
問題を引き起こしているようです。なぜでしょうか?
答え1
への引数\author
は にタイプセットされますtabular
。各セルは独自のグループを形成するため、 の内部定義\itemdelim
と の定義は\do
最初の行では保持されません。
本質的には、次のようなことが起こっています:
\begin{tabular}{c}
\def\itemdelim{test} \\
\itemdelim
\end{tabular}
についても同様です\do
が、2 行目の は の外部と同じ定義になりtabular
、エラー メッセージは表示されません。
\itemdelim
(最初のエントリ以外) と\do
グローバルの定義を行う必要があります。
\newcommand{\printlist}[2][;]{%
\def\itemdelim{\gdef\itemdelim{#1}}%
\gdef\do##1{\itemdelim##1}%
\docsvlist{#2}}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
ただし、directly を使用して、 \itemdelim
for\do
と skip を直接実行する「トリック」を適用できます。\itemdelim
#1
\newcommand{\printlist}[2][;]{%
\def\do##1{##1\gdef\do####1{#1####1}}%
\docsvlist{#2}}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
次のような別の補助マクロを使用すると、グローバル\defdo
定義を回避できます\do
(ただし、ドキュメント全体で定義された別のマクロが必要になります)。
\newcommand*\defdo[1]{%
\def\do##1{#1\defdo{#1}##1}}%
\newcommand{\printlist}[2][;]{%
\def\do##1{##1\defdo{#1}}%
\docsvlist{#2}}%
\author{\printlist[,\\]{abc,def,ghi,jkl}}
これにより、行から行への の定義が の\do
後ろに忍び込み\\
、次の行で使用できるようになります。
あるいは、リストを前処理して、それを次のように転送することもできます\author
。
\newcommand{\savelist}[3][;]{%
\renewcommand*\do[1]{%
\newcommand*#3{##1}%
\renewcommand*\do[1]{%
\appto#3{#1####1}%
}%
}%
\docsvlist{#2}}
\savelist[,\\]{abc,def,ghi,jkl}\authors
\author{\authors}
この場合、 の定義は\do
ドキュメントの最上位レベルで定義されているため、「グローバル」でもあります。
グローバルを定義して\do
も競合は発生しません。グローバルを使用する他のすべてのコードは、\do
定義を前提とせずにグローバル自身を定義しているはずです。グローバルとローカルの割り当て/定義を混在させる面倒になるかもしれないただし、 を使用する方\savelist
が望ましいかもしれません。
を超えてetoolbox
、LaTeX3 のl3clist
パッケージは、リストのエントリの間に何か ( = )\clist_use:Nn
を配置するだけで定義を必要としない を提供します。#1
,\\
\documentclass{article}
\ExplSyntaxOn
\DeclareDocumentCommand{\printlist}{ O{;} m}{
\clist_set:Nn \l_tmpa_clist {#2}
\clist_use:Nn \l_tmpa_clist {#1}
}
\ExplSyntaxOff
\author{\printlist[,\\]{abc,def,ghi,jkl}}
\title{Test}
\begin{document}
\maketitle
\end{document}