2

xstring: I want something like this \StrSubstitute{abc,cde}{,}{\newline}, but it doesn't work.

1

This works:

\documentclass{article}
\usepackage{xstring}

\begin{document}

\noindent
\StrSubstitute{abc,def}{,}{\noexpand\noexpand\noexpand\newline}

\end{document}
1

The xstring package documentation alludes to this (section 3.1.1 The commands \fullexpandarg, \expandarg and \noexpandarg):

The command \fullexpandarg is called by default, so all the arguments are fully expanded (an \edef is used) before the the macro works on them. In most of the cases, this expansion mode avoids chains of \expandafter and allows lighter code. Of course, the expansion of argument can be canceled to find back the usual behaviour of TeX with the commands \noexpandarg or \normalexpandarg.

In the following list, [...] the arguments colored in purple will possibly be expanded, according to the expansion mode:

enter image description here

You're placing \newline in <stringB>, which is causing the issue when trying to be expanded. Adding \normalexpandarg after loading xstring works:

enter image description here

\documentclass{article}

\usepackage{xstring}
\normalexpandarg

\begin{document}

\StrSubstitute{abc,cde}{,}{;}

\StrSubstitute{abc,cde}{,}{\newline}

\end{document}
1

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}

enter image description here


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}

enter image description here

1

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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.