xstring: I want something like this \StrSubstitute{abc,cde}{,}{\newline}, but it doesn't work.
- 2,755
4 Answers
The xstring package documentation alludes to this (section 3.1.1 The commands \fullexpandarg, \expandarg and \noexpandarg):
The command
\fullexpandargis called by default, so all the arguments are fully expanded (an\edefis used) before the the macro works on them. In most of the cases, this expansion mode avoids chains of\expandafterand allows lighter code. Of course, the expansion of argument can be canceled to find back the usual behaviour of TeX with the commands\noexpandargor\normalexpandarg.In the following list, [...] the arguments colored in purple will possibly be expanded, according to the expansion mode:
You're placing \newline in <stringB>, which is causing the issue when trying to be expanded. Adding \normalexpandarg after loading xstring works:
\documentclass{article}
\usepackage{xstring}
\normalexpandarg
\begin{document}
\StrSubstitute{abc,cde}{,}{;}
\StrSubstitute{abc,cde}{,}{\newline}
\end{document}
This works:
\documentclass{article}
\usepackage{xstring}
\begin{document}
\noindent
\StrSubstitute{abc,def}{,}{\noexpand\noexpand\noexpand\newline}
\end{document}
- 1,121,712
A listofitems approach
Limitation: the separator cannot be parsed inside a group (i.e., the comma cannot be inside the \textbf argument and be converted to a newline)
\documentclass{article}
\usepackage{listofitems}
\newcommand\subnewlines[2]{%
\setsepchar{#1}%
\readlist\parsethis{#2}%
\foreachitem\z\in\parsethis[]{%
\ifnum\zcnt=1\relax\else\newline\fi
\z
}%
}
\begin{document}
\subnewlines{,}{abc,def,a test of \textbf{big}, proportions}
\end{document}
A tokcycle approach
This approach is unique in that it allows the separator inside of groups, with no loss of functionality:
\documentclass{article}
\usepackage{tokcycle}
\newcommand\subnewlines[2]{%
\tokcycle
{\ifx##1#1\addcytoks{\newline}\else\addcytoks{##1}\fi}
{\processtoks{##1}}
{\addcytoks{##1}}
{\addcytoks{##1}}
{#2}%
\the\cytoks%
}
\begin{document}
\subnewlines{,}{abc,def,a test of \textbf{big,ly} proportions}
\end{document}
- 237,551
Using expl3 and xparse:
\documentclass[]{article}
\usepackage{xparse} % also loads expl3
\ExplSyntaxOn
\tl_new:N \l__schneider_substitute_tl
\cs_new_protected:Npn \schneider_substitute:nnn #1 #2 #3
{
\tl_set:Nn \l__schneider_substitute_tl { #1 }
\tl_replace_all:Nnn \l__schneider_substitute_tl { #2 } { #3 }
\l__schneider_substitute_tl
}
\NewDocumentCommand \substitute { +m +m +m }
{
\schneider_substitute:nnn { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\substitute{abc,cde}{,}{\newline}
\end{document}
- 60,462




