iterar sobre uma lista separada por nova linha

iterar sobre uma lista separada por nova linha

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 \foreachperlinefuncionasse 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#1ENDmas há espaços na saída de acordo com o conteúdo das linhas (veja a barlinha).

Não é essencial usar #1como 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 \foreachperlineou 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}

insira a descrição da imagem aqui

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.

informação relacionada