5

I want to define a macro that does different things depending on the number of (optional) arguments given to it. Is this possible? How?

\documentclass{standalone}
\usepackage{xparse}

\DeclareDocumentCommand{\MyCommand}{ g g g }{
% if 1 parameter
   thing for 1 parameter #1
% else if 2 parameters
   thing for 2 parameters #1 #2
% else if 3 parameters
   thing for 3 parameters #1 #2 #3
}

\begin{document}
\MyCommand{one}
\MyCommand{one}{two}
\MyCommand{one}{two}{three}
\end{document}
  • I assume you know this is not recommended, as while we provide the g argument in xparse it's non-standard LaTeX syntax. – Joseph Wright Feb 18 '13 at 21:40
  • right, yeah, it should probably be { o o o } I guess – flamingpenguin Feb 18 '13 at 21:46
10

The short answer is yes. You can use \IfNoValueTF as a switch.

It's probably better to go with o instead of g.

I think the code is actually cleaner using \ExplSyntaxOn. Some might say easier to read (not all the distracting % to read)--- others might not. ;)

With \ExplSyntaxOn you will have to use ~ for spacing.

\documentclass{article}
\usepackage{xparse}
\pagestyle{empty}
\ExplSyntaxOn
\NewDocumentCommand{\testing}{ ooo }
    {
        \IfNoValueTF {#1} { \texttt{Hello ~ World} }{
            \IfNoValueTF {#2} { \textit{#1} }{
                \IfNoValueTF {#3}  { \textbf{#1}:\textsf{#2} }
                    { \textbf{#3}:\textit{#2}:\textsf{#1} }
            }}
    }
\ExplSyntaxOff
\begin{document}

\testing[One][Two][Three]

\testing[One][Two]

\testing[One]

\testing
\end{document}

A LaTeX3 Solution

\documentclass{article}
\usepackage{xparse}
\pagestyle{empty} 
\ExplSyntaxOn
\int_new:N \g__my_options_count_int
\int_gset:Nn \g__my_options_count_int {3}
\NewDocumentCommand{\testing}{ ooo }
    {
        \IfNoValueT {#3}{  \int_gdecr:N \g__my_options_count_int }
        \IfNoValueT {#2}{  \int_gdecr:N \g__my_options_count_int }
        \IfNoValueT {#1}{  \int_gdecr:N \g__my_options_count_int }
        \int_case:nnn { \g__my_options_count_int }
            {
                {  3  }{\textbf{#3}:\textit{#2}:\textsf{#1}}
                {  2  }{\textbf{#1}:\textsf{#2}}
                {  1  }{\textit{#1}}
            }{
                \texttt{Hello ~ World}
            }
        \int_gset:Nn \g__my_options_count_int {3}
    }

\ExplSyntaxOff
\begin{document}

\testing[One][Two][Three]

\testing[One][Two]

\testing[One]

\testing
\end{document}

All the above produce:

enter image description here

| improve this answer | |
  • »not all the distracting % to read)« - one can get used to them ;) – cgnieder Feb 18 '13 at 22:02
  • @cgnieder true. But with \ExplSyntaxOn you also don't have to worry about whether you forgot any %. – A.Ellett Feb 18 '13 at 22:05
  • 1
    If there's no first optional argument there's no second and third either. I'd go from the first to the third: try it and you'll see that the order is more natural. – egreg Feb 18 '13 at 22:06
  • @egreg So right. :( And it would be cleaner. – A.Ellett Feb 18 '13 at 22:20

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.