\@for no compone con \StrSubstitute

\@for no compone con \StrSubstitute

Quiero dividir una cadena delimitada por espacios en partes y generar código para cada parte. Aparentemente, TeX funciona con cadenas delimitadas por comas de forma nativa, así que intenté escribir una adaptación.

\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

ingrese la descripción de la imagen aquí

La primera línea de salida de una cadena delimitada por comas es correcta. La segunda línea de salida que muestra una cadena delimitada por espacios que se transforma en la cadena correspondiente delimitada por comas es correcta.

Sin embargo, en la tercera línea, la segunda \@for, la cadena no se divide.

¿Por qué no y cómo soluciono esto?

Respuesta1

\StrSubstitutetiene múltiples argumentos opcionales y no se puede expandir, por lo que no es posible usar la salida \StrSubstitutey volver a introducirla en el flujo de entrada de TeX.

Es posible almacenar el resultado en \StrSubstituteuna macro temporal y utilizar 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}

ingrese la descripción de la imagen aquí

Respuesta2

Si el requisito es recorrer una lista separada por espacios, no es necesario reemplazar los espacios por comas y recorrer una lista separada por comas. La implementación de ese reemplazo probablemente ya requiera la capacidad de iterar sobre los espacios.

Por ejemplo, esto itera sobre las palabras separadas por espacios y coloca cada una en un fbox.

ingrese la descripción de la imagen aquí

\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}

Respuesta3

El listofitemspaquete puede analizarse en función de una multiplicidad de caracteres especificada, aquí indicada como un espacio y una coma ,. Por tanto, una definición de \setsepcharresuelve todos los casos, sin el uso de xstring. EDITADO para incorporar la solución en la 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}

ingrese la descripción de la imagen aquí

información relacionada