# How to implement \ifxcase: case equivalent of \ifx

I am looking for a case equivalent of \ifx. So, when I have nested uses of \ifx it would be cleaner to specify it in some sort of syntax similar to:

\newcommand*{\ColorSymbol}[1]{%
\ifxcase#1{%
{\exists}{\color{red}#1}%
{\ge}{\mathrel{\color{orange}#1}}%
{\le}{\mathrel{\color{blue}#1}}%
}[#1\footnote{Unknown symbol: \string#1}]%
}%


instead of nesting \ifxs as is done in the MWE.

## Notes:

• Don't require the syntax to be identical to that, just something easier to read than the MWE.

## MWE:

\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{xcolor}

\newcommand*{\ColorSymbol}[1]{%
\ifx#1\exists
{\color{red}#1}%
\else
\ifx#1\ge
\mathrel{\color{orange}#1}%
\else
\ifx#1\le
\mathrel{\color{blue}#1}%
\else
#1%
\footnote{Unknown symbol: \string#1}%
\fi
\fi
\fi
}%

%%% Would prefer some case like syntax:
%\newcommand*{\ColorSymbol}[1]{%
%    \ifxcase#1{%
%        {\exists}{\color{red}#1}%
%        {\ge}{\mathrel{\color{orange}#1}}%
%        {\le}{\mathrel{\color{blue}#1}}%
%    }[#1\footnote{Unknown symbol: \string#1}]%
%}%

\begin{document}

$\ColorSymbol\exists x$

$A \ColorSymbol= B$

$a \ColorSymbol\ge n$,
$x \ColorSymbol\le z$

\end{document}

-

I'd use a different syntax (a hash table lookup rather than a nested switch) that allows the coloured symbols to be declared separately, potentially at different points in the code.

\documentclass{article}
\usepackage{mathtools}

\usepackage{xcolor}

\newcommand*{\ColorSymbol}[1]{%
\expandafter\ifx\csname CS-\string#1\endcsname\relax
#1\footnote{Unknown symbol: \string#1}%
\else
\csname CS-\string#1\expandafter\endcsname
\fi}

\newcommand\defColorSymbol[3][]{%
\expandafter\def\csname CS-\string#2\endcsname{%
#1{\color{#3}#2}}}

\defColorSymbol\exists{red}
\defColorSymbol[\mathrel]\ge{orange}
\defColorSymbol[\mathrel]\le{blue}

\begin{document}

$\ColorSymbol\exists x$

$A \ColorSymbol= B$

$a \ColorSymbol\ge n$,
$x \ColorSymbol\le z$

\end{document}

-
Interesting. Hadn't thought about that. – Peter Grill Jan 4 at 2:28

You're loading xstring that already provides the feature:

\documentclass{article}
\usepackage{xcolor}
\usepackage{xstring}

\newcommand{\ColorSymbol}[1]{%
\IfStrEqCase*{#1}{%
{\exists}{\textcolor{red}{#1}}%
{\ge}{\mathrel{\textcolor{orange}{#1}}}%
{\le}{\mathrel{\textcolor{blue}{#1}}}%
}[#1\footnote{Unknown symbol: \string#1}]%
}

\begin{document}

$\ColorSymbol\exists x$

$A \ColorSymbol= B$

$a \ColorSymbol\ge n$,

$x \ColorSymbol\le z$

\end{document}


With xparse it's similar:

\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\ColorSymbol}{m}
{
\str_case:nnF { #1 }
{
{\exists}{\textcolor{red}{#1}}
{\ge}{\mathrel{\textcolor{orange}{#1}}}
{\le}{\mathrel{\textcolor{blue}{#1}}}
}
{#1\footnote{Unknown symbol: \string#1}}
}
\ExplSyntaxOff

\begin{document}

$\ColorSymbol\exists x$

$A \ColorSymbol= B$

$a \ColorSymbol\ge n$,

$x \ColorSymbol\le z$

\end{document}

-
Yes that is what I have been doing, but I thought \ifx was the correct way to compare macros as per How to test if two macros have identical definition. – Peter Grill Jan 4 at 2:18
@PeterGrill One could implement an \ifx based comparison along those lines. I'm not seeing particular benefits. I'll ask for a \token_case:NNTF function. – egreg Jan 4 at 11:36

Yet another option, here's an approach loosely based on C syntax.

\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{xcolor}

\makeatletter
\newcommand\switch[3][\ifx]{%provide switch-case structure with an if
\def\@parsed@ifs{}%contains the arguments recast to standard \if\else\fi
\def\@allfis{}%contains all of the \fis
\def\case@with@option[##1]##2##3{%process a case with optional relation ##1
\def\case{\@ifnextchar[{\case@with@option}{\case@with@option[]}}%
#3\expandafter\@parsed@ifs\@allfis%
}
\makeatother

%%% Would prefer some case like syntax:
\newcommand*{\ColorSymbol}[1]{%
\switch{#1}{%
\case{\exists}{{\color{red}#1}}%
\case{\ge}{\mathrel{\color{orange}#1}}%
\case{\le}{\mathrel{\color{blue}#1}}%
\default{#1\footnote{Unknown symbol: \string#1}}}
}%

\begin{document}

$\ColorSymbol\exists x$

$A \ColorSymbol= B$

$a \ColorSymbol\ge n$,
$x \ColorSymbol\le z$

\end{document}


The conditional is left as an option (\if, \ifx, \ifnum, and \ifdim all work). To support those using a relation, \case is defined with an optional parameter. For example, two is the result from:

\def\testnumber{2}%
\def\anothernumber{5}%
\switch[\ifnum]{\testnumber}{%
\case[=]{0}{zero}%
\case[=]{1}{one}%
\case[=]{2}{two}%
\case[=]{\anothernumber}{another number}%
\default{not 0, 1, or 2}}


Obviously this will fail spectacularly if \case or \default are defined elsewhere and used as arguments in the \case and \default statements (e.g., \case{\exists}{\default\case}). For the same reason, nesting \switch calls would be problematic as well. As such, this approach is limited.

-

Something with a slightly different syntax (I feel I already had an answer on this site quite like an \ifxcase but I can't find it now ...)

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\long\def\xintdothis #1#2\xintorthat #3{\fi #1}%
\makeatletter
\let\xintorthat \@firstofone
\makeatother
\newcommand*{\ColorSymbol}[1]{%
\ifx#1+\xintdothis{\mathbin{\color{red}+}}\fi
\ifx#1\ge\xintdothis{\mathrel{\color{orange}\ge}}\fi
\ifx#1\le\xintdothis{\mathrel{\color{blue}\le}}\fi
\xintorthat{#1\footnote{Unknown symbol: \string#1}}%
}%
\begin{document}
$a\ColorSymbol+ b$, $a\ColorSymbol\ge b$, $a\ColorSymbol\le b$, $a\ColorSymbol\infty b$
\end{document}

-
The expandable \eqifcase is discussed in an answer by @wipet and also an answer of mine – jfbu Jan 3 at 22:24
This has a grouping issue: Try \$a \ColorSymbol+ b where the b is not supposed to have the color applied. – Peter Grill Jan 4 at 2:25
I copied the example code without further ado ;-) ... ok will add one brace level in the + case. – jfbu Jan 4 at 7:24
forgot to explicitly mention to the passer by that this is expandable, although in this context that doesn't mean anything really useful, but could be useful in other contexts where one wants expandability. – jfbu Jan 4 at 7:40