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

1 Answer 1

up vote 10 down vote accepted

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

share|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

 
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.