42

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?

40

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}
14

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}
  • Ah, but what if #1 is not equal to either a or b?... – Mico Jun 28 '12 at 20:46
  • 1
    @Mico you get zzz but you could make that a warning or error or nothing if desired – David Carlisle Jun 28 '12 at 21:17
8

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.

  • 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 Jun 29 '12 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). – Bruno Le Floch Jun 29 '12 at 5:46
  • How to add some text without using ~? – Passe Aug 13 at 18:37
  • @Passe: Under \ExplSyntaxOn, ~ means a space. – egreg Aug 13 at 19:49
6

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}
4

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 {}.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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