13

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}

Peter Grill
  • 223,288

4 Answers4

14

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}
David Carlisle
  • 757,742
12

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}

enter image description here

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}
egreg
  • 1,121,712
5

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}

obligatory result image

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.

Guho
  • 6,115
4

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 –  Jan 03 '16 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 04 '16 at 02:25
  • I copied the example code without further ado ;-) ... ok will add one brace level in the + case. –  Jan 04 '16 at 07: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. –  Jan 04 '16 at 07:40