
Я хочу разделить строку, разделенную пробелами, на части и сгенерировать код для каждой части. Видимо, TeX изначально работает со строками, разделенными запятыми, поэтому я попытался написать адаптацию
\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
Первая строка вывода для строки, разделенной запятыми, верна. Вторая строка вывода, показывающая преобразование строки, разделенной пробелами, в соответствующую строку, разделенную запятыми, верна.
Однако в третьей строке, во второй \@for
, строка не разделяется.
Почему нет и как это исправить?
решение1
\StrSubstitute
имеет несколько необязательных аргументов и не может быть расширен, поэтому невозможно использовать вывод \StrSubstitute
и снова подать его во входной поток TeX.
Можно сохранить результат \StrSubstitute
во временном макросе и использовать этот макрос в качестве входных данных для \@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}
решение2
Если требуется выполнить цикл по списку, разделенному пробелами, нет необходимости заменять пробелы запятыми и выполнять цикл по списку, разделенному запятыми. Реализация этой замены уже, вероятно, требует возможности итерации по пробелам.
Например, это позволяет перебрать слова, разделенные пробелами, и поместить каждое из них в fbox.
\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}
решение3
Пакет listofitems
может выполнять синтаксический анализ на основе указанного множества символов, здесь заданных как пробел и запятая
,
. Таким образом, одно определение \setsepchar
решает все случаи, без использования xstring
. ОТРЕДАКТИРОВАНО для воплощения решения в макросе \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}