# Flexible \IfStrEqCase statement

I am trying to use xstring's \IfStrEqCase to switch between cases. It seems to work fine except for the case where the parameter for the switch is a macro with an optional parameter:

\MySwitch{$\MyMacro[optional]{a - b}$}


The problematic line is commented out in the MWE. Once this works as desired, the last line in the output should be duplicated:

The code within the \MySwitch is used often for different cases.

## Code:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xstring}
\usepackage{xparse}

\NewDocumentCommand{\MyMacro}{o m}{\IfNoValueTF{#1}{#2}{\text{#1: } #2}}%

\newcommand*{\MySwitch}[1]{%
\IfStrEqCase{#1}{%
{plain text}{text: #1}%
{$x^2$}{math a: #1}%
{$\MyMacro{a - b}$}{math b: #1}%
{$\MyMacro[optional]{a - b}$}{math c: #1}%
}[Error: Invalid input: #1]%
}

\begin{document}
\MySwitch{plain text}

\MySwitch{$x^2$}

\MySwitch{$\MyMacro{a - b}$}

math c: $\MyMacro[optional]{a - b}$%% <-- Following should produce this output

%\MySwitch{$\MyMacro[optional]{a - b}$}% <--- This is the problem

\end{document}


The problem you have is a 'classic' one: the definition of optional arguments used by the LaTeX kernel (and most hand-written code) doesn't count up' square brackets. You therefore need to make sure that any place where optional arguments are nested is done with 'protection':

\documentclass{article}
\usepackage{amsmath}
\usepackage{xstring}
\usepackage{xparse}

\NewDocumentCommand{\MyMacro}{o m}{\IfNoValueTF{#1}{#2}{\text{#1: } #2}}%

\newcommand*{\MySwitch}[1]{%
\IfStrEqCase{#1}{%
{plain text}{text: #1}%
{$x^2$}{math a: #1}%
{$\MyMacro{a - b}$}{math b: #1}%
{$\MyMacro[optional]{a - b}$}{math c: #1}%
}[{Error: Invalid input: #1}]% CHANGE IS HERE
}

\begin{document}
\MySwitch{plain text}

\MySwitch{$x^2$}

\MySwitch{$\MyMacro{a - b}$}

math c: $\MyMacro[optional]{a - b}$%% <-- Following should produce this output

\MySwitch{$\MyMacro[optional]{a - b}$}% <--- This is the problem

\end{document}


Notice that I've added a pair of braces inside the optional argument so that #1 is 'safe' even if it itself contains [ ... ].

Where everything is set up by xparse this issue doesn't arise as it uses a definition for optional arguments that does match up square brackets: as a result, no extra steps are required.

• Is there a simple fix to use \mathrm as in \MySwitch{$\MyMacro[optional]{\mathrm{a} - b}$}. I am getting a \GenericError. – Peter Grill Dec 28 '16 at 11:07
• @PeterGrill That's a different question and is because \IfStrEqCase is trying to \edef something containing \mathrm. Easiest solution is \usepackage{etoolbox}\robustify\mathrm, as this makes the command engine robust. – Joseph Wright Dec 28 '16 at 12:06