0

I'm using \StrSubstitute from the xstring package, and it appears that the .tex file does not compile if any of the arguments to \StrSubstitute contain math operators that I have declared with \DeclareMathOperator. A minimal failing example:

% mfe.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\DeclareMathOperator{\myop}{MyOp}

\begin{document}
$\StrSubstitute{a(B)}{a}{\myop}$
\end{document}

Running pdflatex mfe.tex fails to produce a .pdf file, with mfe.log stating

! TeX capacity exceeded, sorry [input stack size=5000].
\@spaces ->\space 
                  \space \space \space 
l.10 $\StrSubstitute{a(B)}{a}{\myop}
                                    $
If you really absolutely need more capacity,
you can ask a wizard to enlarge me.


Here is how much of TeX's memory you used:
 1067 strings out of 494953
 12733 string characters out of 6180978
 173300 words of memory out of 5000000
 4419 multiletter control sequences out of 15000+600000
 4094 words of font info for 16 fonts, out of 8000000 for 9000
 14 hyphenation exceptions out of 8191
 5000i,3n,4003p,244b,52s stack positions out of 5000i,500n,10000p,200000b,80000s
!  ==> Fatal error occurred, no output PDF file produced!

By contrast, I can get the output I want by making \myop just use \mathrm. A minimal working example:

% mwe.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\newcommand{\myoprm}{\mathrm{MyOp}}

\begin{document}
$\StrSubstitute{a(B)}{a}{\myoprm}$
\end{document}

Which produces the following output:

output from <code>pdflatex mwe.tex</code>

Any idea what's going on here, and how I might get \StrSubstitute to cooperate with my operators? I've been given to understand that \DeclareMathOperator{\foo}{foo} is better practice than \newcommand{\foo}{\mathrm{foo}}, but I need these commands to cooperate with \StrSubstitute.

  • \StrSubstitute, by default, use \edef on all its arguments and anything defined with \DeclareMathOperator doesn't survive it. As you discovered, \noexpandarg will work. – egreg Sep 4 '18 at 22:47
0

I found a workaround that works: in the documentation for xstring, it mentions that the commands read their arguments "syntax unit by syntax unit," suggesting that throwing in a \noexpandarg will affect its behavior.

I don't know what the mechanism is here, but the following edit makes mfe.tex work as expected:

% mfe_redeemed.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\DeclareMathOperator{\myop}{MyOp}

\begin{document}
$\noexpandarg\StrSubstitute{a(B)}{a}{\myop}$
\end{document}

which produces the following output:

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.