Für meine Zwecke ist es praktisch, eine Liste mit einem Element pro Zeile (durch ASCII getrennt \n
) zu haben. Ich möchte über eine solche Liste iterieren. Etwa so:
\begin{itemize}
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST#1END}
\end{itemize}
Dies würde ergeben:
TESTfooENDE
TEST-Leiste, bazEND
TESTabcdefprüfenENDE
Ich würde es vorziehen, wenn \foreachperline
es genau wie oben funktioniert, wobei die erste und letzte Zeilenumbruchzeile ignoriert wird. Wenn das jedoch zu kompliziert wird, wäre Folgendes auch in Ordnung
\foreachperline{foo
bar, baz
abcdef \emph{test}}{\item TEST#1END}
Es wäre auch akzeptabel (vorzuziehen gegenüber Option 2, aber nicht vorzuziehen gegenüber Option 1), die Zeilenenden explizit zu markieren, etwa so
\foreachperline{
foo\\
bar, baz\\
abcdef \emph{test}\\
}{\item TEST#1END}
Beachten Sie, dass in keine Leerzeichen enthalten sind, TEST#1END
in der Ausgabe jedoch entsprechend dem Zeileninhalt (siehe Zeile bar
) Leerzeichen vorhanden sind.
Es ist nicht zwingend erforderlich, es #1
als Platzhalter zu verwenden. So etwas wäre auch ok.
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST\placeholder{}END}
Es ist nicht zwingend erforderlich, dass die Syntax aus einem einzigen Makro besteht. So etwas wäre auch ok.
\forthingy \i \in {...}{\item TEST\i{}END}
Wie schreibe ich \foreachperline
oder etwas funktional Äquivalentes?
Antwort1
Wenn Sie Zeilenumbrüche als Trennzeichen verwenden, schießen Sie sich ins eigene Bein: Die meisten Redakteure haben ihre eigenen Vorstellungen davon, wie die Eingaben der Benutzer zu organisieren sind.
\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}
Keine Komprimierung der drei Leerzeichen auf eins? Nun, Sie wissen, dass TeX Leerzeichen am Zeilenanfang ignoriert, also erhalten Sie sie entweder nicht oder sie können nicht wie gewohnt behandelt werden.
Versuchen Sie nicht einmal, dies als Argument an einen anderen Befehl weiterzugeben. Insbesondere keine Verschachtelung.