macros,arguments – Command Not Able to Unravel Argument in LaTeX

argumentsmacros

I am trying to define some new commands to be able to define default values for some of the things I will be using over and over again in order to centralize where the style and the typical letter used should be defined.

The things that I have so far and that gives some trouble is the following

\newcommand{\Prob}[1]{%
    \IfEqCase{#1}{%
        {1}{p}%
        {2}{q}%
        {3}{r}%
    }[#1]%
}%
\newcommand{\RandomVar}[1]{%
    \IfEqCase{#1}{%
        {1}{X}%
        {2}{Y}%
        {3}{Z}%
    }[#1]%
}%

And an example of use is

$p_{\RandomVar1, \RandomVar2}$, $\Prob{p_{\RandomVar1,\RandomVar2}}$

The goal of all this is to be able to have default values for probability distributions, default values for random variables, and to also be able to provide a different value than the default ones if needed. Here the first code works and produces $p_{X,Y}$, the second one doesn't and produce the following error

I've run across a `}' that doesn't seem to match anything. For example, `\def\a#1{...}' and `\a}' would produce this error.

I think that the problem is similar to that of this post but I couldn't work around a solution, I tried putting braces around things without really understanding what I was doing. Any help would be welcome.


Complete example

\documentclass{article}
\usepackage{xstring}

\newcommand{\Prob}[1]{%
    \IfEqCase{#1}{%
        {1}{p}%
        {2}{q}%
        {3}{r}%
    }[#1]%
}%
\newcommand{\RandomVar}[1]{%
    \IfEqCase{#1}{%
        {1}{X}%
        {2}{Y}%
        {3}{Z}%
    }[#1]%
}%

\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$

$\Prob{p_{\RandomVar1,\RandomVar2}}$

\end{document}

The first line of the document yields

$p$, $q$, $p_{X,Y}$, $p_{X,Y}$

The last line should yield

$p_{X,Y}$

but instead gives an error.

Best Answer

Seems making commands robust by defining via \NewDocumentCommand instead of \newcommand does the trick.

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

\NewDocumentCommand{\Prob}{m}{%
    \IfEqCase{#1}{%
        {1}{p}%
        {2}{q}%
        {3}{r}%
    }[{#1}]%
}%
\NewDocumentCommand{\RandomVar}{m}{%
    \IfEqCase{#1}{%
        {1}{X}%
        {2}{Y}%
        {3}{Z}%
    }[{#1}]%
}%

\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$

$\Prob{p_{\RandomVar1,\RandomVar2}}$

\end{document}

The last line yields p_{\RandomVar1,\RandomVar2} which in turn yields p_{X,Y}.

enter image description here


A better approach might be using expandable \str_case:nnTF:

\documentclass{article}

\ExplSyntaxOn
\cs_new:Npn \Prob #1 {%
  % \exp_args:Ne fully expands the argument passed to \str_case:nnTF.
  \exp_args:Ne
  \str_case:nnTF {#1}
    {
      {1} {p}
      {2} {q}
      {3} {r}
    }
    {}
    {#1}
}
\cs_new:Npn \RandomVar #1 {%
  % \exp_args:Ne fully expands the argument passed to \str_case:nnTF.
  \exp_args:Ne
  \str_case:nnTF {#1}
    {
      {1} {X}
      {2} {Y}
      {3} {Z}
    }
    {}
    {#1}
}
\ExplSyntaxOff

\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$

$\Prob{p_{\RandomVar1,\RandomVar2}}$

\end{document}

enter image description here

Related Question