別のコマンドの出力を処理する場合、\author で改行が失われます。

別のコマンドの出力を処理する場合、\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
\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}

失敗したケース

たとえば、改行なしの区切り文字を使用すると::、上記は期待どおりに機能します。

テスト1成功

\\コマンドに改行を追加して\authorも、期待どおりの結果が得られます。

\author{\printlisti[::]{abc,def,ghi}\\123\\456\\789}

テスト2成功

\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 を使用して、 \itemdelimfor\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}

関連情報