57

Suppose I want to define a command, say, \tree with, say, two arguments. I would like \tree to do different things depending on what my first argument is. For example,

if #1 = a, then return $\sqrt{#2}$

if #1 = b, then return "Hi"

Is it possible to realise the above pseudocode? If so, how can I?

5 Answers 5

50

You can also use \IfEqCase from the xstring package which can easily be extended to add more cases:

enter image description here

Notes:

  • Besides being able to easily extend to more cases, this also has the benefit that it will produce a \PackageError if an unknown option is passed in.

Code:

\documentclass{article}
\usepackage{xstring}

\newcommand{\tree}[2]{%
    \IfEqCase{#1}{%
        {a}{$\sqrt{#2}$}%
        {b}{Hi}%
        % you can add more cases here as desired
    }[\PackageError{tree}{Undefined option to tree: #1}{}]%
}%
\begin{document}
\tree{a}{4}

\tree{b}{4}

%\tree{c}{4}
\end{document}
3
  • What about if I need to use multiple conditions/variables for the same case, for example CASE1: if a=1 and/or b=2 : then do this and so on. Identifying multiple variables in the same case
    – Silva
    Commented Feb 20, 2020 at 21:07
  • @Silva: In general, you should be able to nest the cases, or perhaps make use of Modified \IfStrEqCase with multiple matches per case. But, without seeing more details I can't give you an exact answer. If you are unable to locate the answer on this site, I'd suggest you ask a new question and include a MWE that illustrates the problem including the \documentclass and the appropriate packages. If this question is relevant you should link to it. Commented Feb 20, 2020 at 21:45
  • tex.stackexchange.com/questions/529341/…
    – Silva
    Commented Feb 20, 2020 at 21:59
18

ifthen package then

  \newcommand\tree[2]{\ifthenelse{\equal{#1}{a}}{$\sqrt{#2}$}{Hi}}

actually I mis read your condition so I suppose the full version is

 \newcommand\tree[2]{\ifthenelse{\equal{#1}{a}}%
                     {$\sqrt{#2}$}{\ifthenelse{\equal{#1}{b}}{Hi}{zzz}}}

I think all the answers given so far (including mine above) are not expandable which means that you can't to the test in places like a \write or \edef see the \typeout below. Given your \sqrt example that probably doesn't matter, but the following is a version using expandable tests that is almost certainly the quickest version posted so far, although rather expensive in terms of command name use.

\documentclass{article}

\makeatletter
\@namedef{tree@a}#1{$\sqrt{#1}$}
\@namedef{tree@b}#1{h1}
\def\tree#1{\expandafter\ifx\csname tree@#1\endcsname\relax
\expandafter\@gobble\else
\csname tree@#1\expandafter\endcsname
\fi}

\makeatother


\begin{document}
\tree{a}{2}

\typeout{[[[\tree{b}{2}]]]}

\tree{b}{xyz}

\tree{x}{Uh!}

\end{document}
2
  • Ah, but what if #1 is not equal to either a or b?...
    – Mico
    Commented Jun 28, 2012 at 20:46
  • 1
    @Mico you get zzz but you could make that a warning or error or nothing if desired Commented Jun 28, 2012 at 21:17
10

The easiest implementation is with expl3:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\tree}{ m m }
 {
  \seaton_tree:nn { #1 } { #2 }
 }
\cs_new:Npn \seaton_tree:nn #1 #2
 {
  \str_case:nnF { #1 }
   {
    { a } { $\sqrt{ #2 }$ }
    { b } { Hi }
    % other possible strings
   }
   {
    I~don't~know~what~to~do~with~`#1'
   }
 }
\ExplSyntaxOff

\begin{document}
\tree{a}{2}

\tree{b}{xyz}

\tree{x}{Uh!}

\end{document}

The list of admissible strings can be arbitrarily long.

4
  • Thank you very much for the solution (+1). However, as I am not very well versed in Latex, some of the of parameters above are beyond me.
    – JSeaton
    Commented Jun 29, 2012 at 2:12
  • The \prg_case_str:nnn command is in the process of being renamed to \str_case:nnn as part of the LaTeX3 'small bang' (July 2012). Commented Jun 29, 2012 at 5:46
  • How to add some text without using ~?
    – PascalS
    Commented Aug 13, 2019 at 18:37
  • @Passe: Under \ExplSyntaxOn, ~ means a space.
    – egreg
    Commented Aug 13, 2019 at 19:49
7

Another variation on the theme flowing through the answers is to use the etoolbox; same idea, just different syntax.

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\tree}[2]{%
    \ifstrequal{#1}{a}%
        {$\sqrt{#2}$}%
        {\ifstrequal{#1}{b}{Hi}{\PackageError{tree}{Undefined option to tree command}{}}}%
        }
\begin{document}
\tree{a}{4}

\tree{b}{4}

% this one throws an error
%\tree{c}{4}
\end{document}
6

You don't mention what a and b are supposed to be, so I'll assume that they are character strings (possibly of unit length). The following construct, which makes use of the \ifthenelse macro of the ifthen package, should work for you:

\newcommand{\tree}[2]{%
    \ifthenelse{\equal{#1}{a}}{$\sqrt{#2}$}{%
    \ifthenelse{\equal{#1}{b}}{"Hi."}{}}}

Notice that you don't appear to specify what should be done if #1 is not equal to either a or b. I've therefore set the outcome for that case to {}.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .