# How to specify an optional final argument with \newcommand?

I'm writing my first package, and I'm trying to work out how to create a new command with an optional final argument. In this instance, if an argument is omitted, it defaults to blank. This is problematic because it assumes that the two arguments passed in this case are #2 and #3.

\newcommand{\sfsx}[3][]{\wrapper{#1}{#2}{#3}}


Unfortunately, I would like it the other way around, where if only two arguments are given, they are assumed to be #1 and #2. Is there a simple way to do this that doesn't invoke other packages?

(\wrapper in this case is just another command that takes on various forms depending on package options).

-

Try the new xparse package, which is built on top of LaTeX3. With this package you can specify arbitrary combinations of mandatory and optional arguments. This case would be as easy as

\DeclareDocumentCommand \sfsx { m m o } { \wrapper{#1}{#2}{#3} }


If you want to have your own default value, use O{value} instead of o.

-
That works pretty well, with the breaking change that the optional argument loses its formatting. Consider the following: \newcommand{\wrapper}[3]{\ensuremath{\mathrm{\uppercase{#1}}_{#2#3}}}: running \sfsx{c}{2}{v} will produce the expected behaviour for the first two characters but the third will be set in normal sized roman rather than subscript italic. –  Richard Terrett Oct 5 '11 at 14:44
@RichardTerrett: [v] :-) –  Andrey Vihrov Oct 5 '11 at 14:50
Problem solved, thankyou. –  Richard Terrett Oct 5 '11 at 14:57
If you want the final argument in a TeX group ({...}), you could use the G or g argument specification. –  Joseph Wright Oct 5 '11 at 15:07

This can't be done using \newcommand directly. One way is to read the first mandatory arguments, store them in a temporary macro and then call another macro which has only one optional argument and reads the other ones from the temporary macro. An easier way would be to use the xparse package which allows for several optional arguments at any position (see Andrey's answer).

\documentclass{article}

\makeatletter
\newcommand{\sfsx}[2]{%
\def\sfsx@args{{#1}{#2}}%
\sfsx@
}
\newcommand{\sfsx@}[1][]{%
\expandafter\wrapper\sfsx@args{#1}%
}
\makeatletter

\newcommand{\wrapper}[3]{%
I got (#1), (#2) and (#3).
}

\begin{document}

\sfsx{A}{B}

\sfsx{A}{B}[C]

\end{document}


This can be made a little more efficient if you use the internal \@testopt macro directly which is used by LaTeX to test for the optional argument:

\documentclass{article}

\makeatletter
\newcommand{\sfsx}[2]{%
\@testopt{\sfsx@{#1}{#2}}{}%
}
\def\sfsx@#1#2[#3]{%
\wrapper{#1}{#2}{#3}%
}
\makeatletter

\newcommand{\wrapper}[3]{%
I got (#1), (#2) and (#3).
}

\begin{document}

\sfsx{A}{B}

\sfsx{A}{B}[C]

\end{document}

-
Instead of the empty brace group after \@testopt you can write {xyz}, and xyz will be the default value for the optional argument. –  egreg Oct 5 '11 at 14:48
I appreciate the detailed response. As I'm not well versed in the answer syntax, I'm further investigating xparse, as whilst it does introduce a dependency, it also seems the most parsimonious method. (:P) –  Richard Terrett Oct 5 '11 at 14:49