TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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}
share|improve this question
up vote 13 down vote accepted

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}
share|improve this answer
    
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}

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}
share|improve this answer
    
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
            \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.

share|improve this answer

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}
share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.