Take the 2-minute tour ×
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.

I've got a define such as \def\doctype{SomeString}. \doctype can take on one of five values. I want to do something like a switch statement in a programming language, i.e. (pseudocode):

switch (\doctype) {
    case 'SomeString1': some text here
    case 'SomeString2': some different text here
    ...
}

(I don't need a default/else/otherwise case.) I tried doing this in LaTeX with:

\documentclass{article}

\usepackage{etoolbox}

\def\doctype{SomeString1}

\newenvironment{switchdoctype}[0]{%
  \newcommand{\case}[2]{\ifdefequal{\doctype}{##1}{##2}{}}%
}{}

\begin{document}

\begin{switchdoctype}
  \case{SomeString1}{some text here}
  \case{SomeString2}{some different text here}
\end{switchdoctype}

\end{document}

This gives an error: ERROR: Argument of \@secondoftwo has an extra }. I gather this is some sort of problem with using \ifdefequal. How can I make this work? I suspect it's some trick of expansion but I can't make this work with my limited knowledge of [La]TeX; I'm interested in learning something from making this work.

MacTeX 2010 here, which is based on TeX Live 2010 AFAIK. Thanks!

P.S.: boolexpr has a \switch but I can't use it because it conflicts badly with etoolbox (and BibLaTeX depends on etoolbox as far as I can tell). I have reported this incompatibility to the author listed in boolexpr's documentation.

share|improve this question
add comment

4 Answers

up vote 12 down vote accepted

From your description, I think you want \ifdefstring, as you need to compare one macro with one definition of a macro. \ifdefequal is for testing two macros for equivalence.

share|improve this answer
1  
Holy crap that is embarrassing. You are right. I knew of the existence of both of these commands in my head, but I obviously got them switched around in the course of coming up with this code. Thanks! –  dsedivec Nov 8 '10 at 22:06
add comment

Just for future reference, expl3 has nice switch/case statement constructs:

\str_case:nnF {\doctype}
{
   {SomeString1} {some~ text~ here}
   {SomeString2} {some~ different~ text~ here}
}
{else~ clause}

Variations are also provided with integers, dimensions, and token lists; e.g.,

\int_case:nnF{2*5}{
  {5}{Small}
  {4+6}{Medium}
  {-2*10}{Negative}
}{Other}
share|improve this answer
    
Nice indeed! Is there a reason for all those ~s? –  Hendrik Vogt Nov 11 '10 at 9:19
1  
In expl3 code, spaces are ignored, so if you want to print a string, ~ is used as a space. –  Will Robertson Nov 11 '10 at 11:20
    
Thank you very much! I skimmed expl3 the other day but didn't see anything that would help me. texdoc l3prg was just bringing up expl3.pdf. I have since learned to ask for source3 which appears to be a very comprehensive reference document. I'm excited to see all this stuff, especially all the standardized names. (And ignoring spaces also seems very kind to people writing commands.) If anyone in a position to do so reads this: it might be nice to mention the existence of source3 in the expl3 document. (My PDF reader didn't find that string.) –  dsedivec Nov 11 '10 at 19:23
    
@dsedivec Thanks for the feedback; I've added a pointer like you suggest. –  Will Robertson Nov 13 '10 at 13:07
add comment

For switching on identifiers, it's simplest to use the primitive \ifcase:

\documentclass{article}

\usepackage{etoolbox}

\def\typeone{1}
\def\typetwo{2}

\begin{document}

\let\doctype=\typeone

\ifcase\doctype
  \or some text here %matches \typeone
  \or some different text here % matches \typetwo
\else you didn't want an else case, but it's no trouble to put in
\fi

\end{document}

If you want to convert strings into your type numbers, you can use \csname ...\endcsname; e.g., \csname typeone\endcsname will expand into 1, matching the first case.

share|improve this answer
    
Thanks, this is pretty good looking. I may have to play with this in the future. –  dsedivec Nov 8 '10 at 22:06
2  
No need for etoolbox here, I believe. –  Bruno Le Floch Apr 2 '11 at 18:13
    
@Brune: Or indeed Latex. (Only just noticed your comment) –  Charles Stewart Mar 29 '12 at 12:00
add comment

Case statements can also be implemented with the xstring package:

enter image description here

\documentclass{article}
\usepackage{xstring}

\newcommand{\CheckCase}[1]{%
    \par\noindent%
    \IfEqCase*{#1}{%
    {Some String 1}{matched case 1}%
    {Some String 2}{matched case 2}%
    {Some String 3}{matched case 3}%
    {Some String 4}{matched case 4}%
    {Some String 5}{matched case 5}%
    }[Did not match any given case!!]%
}%

\begin{document}
    \CheckCase{Some String 1}
    \CheckCase{Some String 2}
    \CheckCase{Some String 3}
    \CheckCase{Some String 4}
    \CheckCase{Some String 5}
    \CheckCase{Some String 6}
\end{document}
share|improve this answer
add comment

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.