Para meus propósitos, é conveniente ter uma lista fornecida com um elemento em cada linha (separada por ASCII \n
). Quero iterar essa lista. Algo assim:
\begin{itemize}
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST#1END}
\end{itemize}
Isso produziria:
TESTEfooEND
Barra de TESTE, bazEND
TESTEabcdeftesteFIM
Eu preferiria que \foreachperline
funcionasse exatamente como acima, com a primeira e a última nova linha ignoradas, mas se isso ficar confuso, o seguinte também seria aceitável
\foreachperline{foo
bar, baz
abcdef \emph{test}}{\item TEST#1END}
Também seria aceitável (preferível à opção 2, mas não preferível à opção 1) marcar explicitamente os finais das linhas, algo como isto
\foreachperline{
foo\\
bar, baz\\
abcdef \emph{test}\\
}{\item TEST#1END}
Observe que não há espaços, TEST#1END
mas há espaços na saída de acordo com o conteúdo das linhas (veja a bar
linha).
Não é essencial usar #1
como espaço reservado. Algo assim também estaria bem.
\foreachperline{
foo
bar, baz
abcdef \emph{test}
}{\item TEST\placeholder{}END}
Não é essencial que a sintaxe seja uma macro única. Algo assim também estaria bem.
\forthingy \i \in {...}{\item TEST\i{}END}
Como escrevo \foreachperline
ou algo funcionalmente equivalente?
Responder1
Você vai se arriscar usando novas linhas como delimitadores: a maioria dos editores tem suas próprias ideias sobre como organizar as entradas dos usuários.
\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}
Nenhuma compressão dos três espaços em um? Bem, você sabe que o TeX ignora espaços no início das linhas, então ou você não os entende ou não pode ser tratado como de costume.
Ah, nem tente alimentar isso como argumento para outro comando; em particular, sem aninhamento.