私の目的には、各行に 1 つの要素 (ASCII で区切る\n
) があるリストがあると便利です。このようなリストを反復処理したいと思います。次のようになります。
\begin{itemize}
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST#1END}
\end{itemize}
これにより、次のようになります。
TESTfooEND
テストバー、bazEND
テストabcdefテスト終わり
私は、最初と最後の改行を無視して、上記とまったく同じように動作することを好みます\foreachperline
が、それが面倒になる場合は、次のものでも問題ありません。
\foreachperline{foo
bar, baz
abcdef \emph{test}}{\item TEST#1END}
次のように行の終わりを明示的にマークすることも許容されます(オプション2よりも好ましいですが、オプション1よりも好ましくありません)。
\foreachperline{
foo\\
bar, baz\\
abcdef \emph{test}\\
}{\item TEST#1END}
にはスペースはありませんTEST#1END
が、行の内容に応じて出力にスペースが含まれることに注意してください (bar
行を参照)。
プレースホルダーとして使用することは必須ではありません#1
。このようなものでも問題ありません。
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST\placeholder{}END}
構文が単一のマクロである必要はありません。次のようなものでも問題ありません。
\forthingy \i \in {...}{\item TEST\i{}END}
、または機能的に同等なものをどのように記述すればよいでしょうか\foreachperline
?
答え1
改行を区切り文字として使用すると、自ら足を撃つことになります。ほとんどのエディターは、ユーザーの入力を整理する方法について独自の考えを持っています。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\foreachperline}{m}
{
\cs_set_protected:Nn \__spraff_per_line_do:n { #1 }
\group_begin:
\char_set_catcode_other:n { 13 }
\char_set_catcode_active:n { 32 }
\char_set_active_eq:nN { 32 } \c_space_token
\__spraff_per_line_go:n
}
\cs_new_protected:Nn \__spraff_per_line_go:n
{
\seq_set_split:Nfn \l__spraff_per_line_input_seq { \char_generate:nn { 13 } { 12 } } { #1 }
\seq_pop_left:NN \l__spraff_per_line_input_seq \l_tmpa_tl
\seq_pop_right:NN \l__spraff_per_line_input_seq \l_tmpa_tl
\seq_map_function:NN \l__spraff_per_line_input_seq \__spraff_per_line_do:n
\group_end:
}
\seq_new:N \l__spraff_per_line_input_seq
\cs_generate_variant:Nn \seq_set_split:Nnn { Nf }
\ExplSyntaxOff
\begin{document}
\begin{itemize}
\foreachperline{\item TEST#1END}{
foo
bar, baz
abcdef \emph{test}
}
\end{itemize}
\end{document}
3 つのスペースを 1 つに圧縮しないのですか? TeX は行の先頭のスペースを無視するので、スペースが取得されないか、通常どおりに処理できないかのどちらかです。
ああ、これを別のコマンドの引数として渡そうとしないでください。特に、ネストは禁止です。