I have some text that I would like to preprocess using xstring's \StrSubstitute method (basically replacing certain keywords by simple commands such as foobar by \emph{foobar}). There are two side conditions which make this tough (at least I haven't been able to figure out how to do this). On the one hand, I need to run \StrSubstitute in noexpandarg mode, on the other I would like to use active spaces in order to print out the input obeying spaces. I know there are environments such as listings or verbatim but these won't work for what I have in mind: in the very end the thus preprocessed string should go into an (amsmath) align environment.
So here is what I have
\documentclass{article}
\usepackage{xstring}
\begingroup
\catcode`\@=\active
\lccode`\@=`\ % At-sign is a space
\lowercase{%
\endgroup
\newenvironment{withspaces}{%
\catcode`\ =\active % Space active
\let@=~%
}{
}}
\begin{document}
\def\foo{foo}
\begin{withspaces}
There is space before \foo foo
\end{withspaces}
\begin{withspaces}
\StrSubstitute{There is space before \foo foo}{foo}{bar}
\end{withspaces}
\noexpandarg % in order to first run the string substitution and only then expand \foo
\StrSubstitute{There is space before \foo foo}{foo}{bar}
% The following breaks down to the noexpandarg flag
\begin{withspaces}
%\StrSubstitute{There is space before \foo foo}{foo}{bar}
\end{withspaces}
\end{document}
The withspaces environment (adapted from Joseph's answer Environment that obeys spaces) seems to work fine both in text mode and in math mode. The first use of \StrSubstituteworks as it is in fullyexpandmode. The result then, however, is that first \foo is expanded and then replaced by \StrSubstitute which is why I think I need to use noexpandarg: \StrSubstitute should do the substitution without expanding \foo.
This also works fine in isolation. That is,
\noexpandarg % in order to first run the string substitution and only then expand \foo
\StrSubstitute{There is space before \foo foo}{foo}{bar}
yields the desired result but without active spaces. Once I try to combine the two (uncommenting out the last \StrSubstitute in the MWE) I am stuck at
Argument of \@xs@behindspace has an extra }.
<inserted text>
\par
l.33 \end
{withspaces}
And here is where I am lost.

\noexpandargto the definition ofwithspaces? – egreg Mar 26 '15 at 09:05\noexpandarg(i.e. full expansion mode) but not with it. If I add it to thewithspacesenvironment then already the firstStrSubstitutefails. – Arno Mittelbach Mar 26 '15 at 09:21xstringbe acceptable? – egreg Mar 26 '15 at 09:34\highlight{foobar}. Currently I am implementing this with a sequence of StrSubstitutes but anything that provides the functionality (i.e. str replacement without expansion + spacing) is fine. – Arno Mittelbach Mar 26 '15 at 09:39