How to implement \ifxcase: case equivalent of \ifx
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}
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}
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
\g@addto@macro\@allfis{\fi}%
\g@addto@macro\@parsed@ifs{#1#2##1##2##3\else}}%
\def\case{\@ifnextchar[{\case@with@option}{\case@with@option[]}}%
\def\default##1{\g@addto@macro\@parsed@ifs{##1}}%
#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.