\@for não compõe com \StrSubstitute

\@for não compõe com \StrSubstitute

Quero dividir uma string delimitada por espaço em partes e gerar código para cada parte. Aparentemente, o TeX funciona nativamente com strings delimitadas por vírgulas, então tentei escrever uma adaptação

\usepackage{xstring}    
\makeatletter
\@for\next:=foo,bar,baz\do{X \next Y} \\
\StrSubstitute{foo bar baz}{ }{,} \\
\@for\next:=\StrSubstitute{foo bar baz}{ }{,}\do{X \next Y}
\makeatother

insira a descrição da imagem aqui

A primeira linha de saída de uma string delimitada por vírgula está correta. A segunda linha da saída mostrando uma string delimitada por espaço sendo transformada na string delimitada por vírgula correspondente está correta.

Porém, na terceira linha, a segunda \@for, a string não está sendo dividida.

Por que não e como faço para corrigir isso?

Responder1

\StrSubstitutetem vários argumentos opcionais e não pode ser expansível, portanto não é possível usar a saída \StrSubstitutee alimentá-la novamente no fluxo de entrada do TeX.

É possível armazenar o resultado de \StrSubstituteuma macro temporária e usar esta macro como entrada para \@for\next....

\documentclass{article}

\usepackage{xstring}   

\begin{document} 
\makeatletter
\@for\next:=foo,bar,baz\do{X \next Y} \\
\StrSubstitute{foo bar baz}{ }{,} \\
\StrSubstitute{foo bar baz}{ }{,}[\@stuff]
\@for\next:=\@stuff\do{X \next Y}
\makeatother
\end{document}

insira a descrição da imagem aqui

Responder2

Se o requisito for percorrer uma lista separada por espaços, não há necessidade de substituir espaços por vírgulas e percorrer uma lista separada por vírgulas. A implementação dessa substituição provavelmente já requer a capacidade de iterar nos espaços.

Por exemplo, isso itera sobre as palavras separadas por espaço, colocando cada uma em um fbox.

insira a descrição da imagem aqui

\documentclass{article}

\def\zz#1{\zzz#1 \! }

\def\zzz#1 {\ifx\!#1\else\fbox{#1} \expandafter\zzz\fi}
\begin{document}

\zz{foo bar baz}

\end{document}

Responder3

O listofitemspacote pode ser analisado com base em uma multiplicidade especificada de caracteres, aqui fornecidos como espaço e vírgula ,. Assim, uma definição de \setsepcharresolve todos os casos, sem o uso de xstring. EDITADO para incorporar a solução na macro \processlist.

\documentclass{scrartcl}
\usepackage{listofitems}
\setsepchar{ ||,}%
\newcommand\processlist[1]{%
  \readlist\mylist{#1}%
  \foreachitem\next\in\mylist{X \next Y}%
}
\begin{document}
\processlist{foo,bar,baz}

\processlist{foo bar baz}
\end{document}

insira a descrição da imagem aqui

informação relacionada