# classicthesis StrSubstitute and accented character

I have a "second order" incompatibility problem between: classicthesis, StrSubstitute and accented characters. Here is a MWE:

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage[nochapters]{classicthesis}
\usepackage{xstring}

\begin{document}
Il modello associa un valore di \StrSubstitute{verità}{x}{y}\
\end{document}


The compilation gives the following error:

! Argument of \MT@res@a has an extra }.


But if I remove the classicthesis package, or remove the StrSubstitute command or remove the accented character: then the compilation works without errors!

• this isn't really related to classicthesis other than it loads microtype May 28, 2018 at 10:46

xstring functions use \edef which means that any commands that do not work by pure expansion are likely to fail. You get the same error with this simplified input

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage{microtype}

\begin{document}
Il modello associa un valore di
\edef\foo{verità}

\end{document}


You could use

 {\def\protect{\noexpand\protect\noexpand}\StrSubstitute{verità}{x}{y}}


which makes no error, but drops the accent, depending on the actual requirement it is probably easiest to use an expandable string replace function rather than xstring.

this for example replaces x by y while preserving the accented a

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage{microtype}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\repl{mmm}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_once:nnN { #2 } { #3 } \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\begin{document}
Il modello associa un valore di \repl{vxerità}{x}{y}
\end{document}

• Can you suggest an expandable string replace function? I need to replace the "!" character used in the \index command with a space. May 28, 2018 at 11:04
• @EmanuelePaolini updated answer May 28, 2018 at 11:13
• maybe \usepackage{l3regex} is required? May 28, 2018 at 11:32
• @EmanuelePaolini oh only if you have an old installation, I tested the answer as posted, regex has been a part of core expl3 for some time May 28, 2018 at 12:12
• @moewe I shall summon the culprit to come back and fix it! May 28, 2018 at 14:15

The problem, as you discovered, is that \StrSubstitute executes \edef on its arguments. However, this can be avoided.

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage[nochapters]{classicthesis}
\usepackage{xstring}

\begin{document}

Il modello associa un valore di
\saveexpandmode\noexpandarg
\StrSubstitute{virità}{i}{e}
\restoreexpandmode\

\bigskip

\saveexpandmode\noexpandarg
\StrSubstitute{viritò}{ò}{à}
\restoreexpandmode\

\end{document}


If you never need other modes (check the manual, section 3.1.1), you can issue \noexpandarg in the preamble and forget about saving and restoring it.

An easier method might be to use an expl3 implementation (currently classicthesis raises an error, which you can safely ignore).

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage[nochapters]{classicthesis}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\xStrSubstitute}{mmmo}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { #2 } { #3 }
\IfNoValueTF{#4}
{ \tl_use:N \l_tmpa_tl }
{ \tl_set_eq:NN #4 \l_tmpa_tl }
}
\ExplSyntaxOff

\begin{document}

Il modello associa un valore di
\xStrSubstitute{virità}{i}{e}\

\bigskip

\xStrSubstitute{viritò}{ò}{à}

\end{document}


listofitems to the rescue.

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage[nochapters]{classicthesis}
\usepackage{listofitems}
\newcommand\loiStrSubstitute[3]{%
\setsepchar{#2}%
\foreachitem\x\in\mylist{\ifnum\xcnt=1\else#3\fi\x}%
}
\begin{document}
Il modello associa un valore di \loiStrSubstitute{verità}{e}{x}\

\loiStrSubstitute{verità}{à}{x}

\loiStrSubstitute{verititità}{i}{o}
\end{document}


If you need a star version of the macro that only substitutes the first occurrence,

\documentclass[italian]{article}
\usepackage[utf8]{inputenc}
\usepackage[nochapters]{classicthesis}
\usepackage{listofitems}
\makeatletter
\newcommand\loiStrSubstitute{%
\@ifstar{\loiStrSubstitutefirst}{\loiStrSubstituteall}}
\makeatother
\newcommand\loiStrSubstituteall[3]{%
\setsepchar{#2}%
\foreachitem\x\in\mylist{\ifnum\xcnt=1\else#3\fi\x}%
}
\newcommand\loiStrSubstitutefirst[3]{%
\setsepchar{#2}%