3

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:

enter image description here

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}
5

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

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.