# Variable number of arguments in a command

Code

\documentclass{article}
\newcommand*\test[2]{#1\textsuperscript{#2}}
\begin{document}
The player ended as no.~\test{1}{} and her friend came in \test{2}{nd}.
\end{document}


Output

Question

How can I change the \test command so that I'm abel to switch between one or two arguments?

(I would like to be abel to write \test{1} instead of \test{1}{}.)

• Optional arguments for LaTeX2e commands are given in square brackets! – Joseph Wright Jan 17 '16 at 10:53
• @JosephWright Sorry. I mixed things up; I'll rephrase my question. – Svend Tveskæg Jan 17 '16 at 10:54
• @SvendTveskæg You might want to be able to use \test{1} and \test{2}{nd}, but I'm recommending not to. – egreg Jan 17 '16 at 11:03
• @SvendTveskæg Joseph already told you: if an argument is optional, treat it as such. – egreg Jan 17 '16 at 11:05
• While it is possible to do this it is a really bad idea to do it in a latex2e context. LaTeX2e commands never take a variable number of {} arguments. A major aim of the system is to give a consistent interface to arguments. If an argument is optional it should be in square brackets. – David Carlisle Jan 17 '16 at 11:12

With xparse the feature can be done easily with the g optional argumen t specifier, but optional arguments should be done with [...], i.e. use o rather, in my point of view!

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\test}{mg}{#1\IfValueT{#2}{\textsuperscript{#2}}}
\begin{document}
The player ended as no.~\test{1} and her friend came as \test{2}{nd}.
\end{document}

• I would like to be abel to write \test{1} and \test{2}{nd} (or \test{5} and \test{8}{th}, ect.). – Svend Tveskæg Jan 17 '16 at 11:00
• @SvendTveskæg: That's easy: Use g instead of o as optional argument specifier! – user31729 Jan 17 '16 at 11:02
• I actually like Werner approach better (even though I asked for the solution you have given). – Svend Tveskæg Jan 17 '16 at 17:37
• @SvendTveskæg: You asked for this and I provided this -- now you unaccept. I am sure you know that is not kosher at all. – user31729 Jan 17 '16 at 19:14
• I didn't knew that but we can't have that you are upset about it. – Svend Tveskæg Jan 17 '16 at 19:41

I'd suggest an alternative interface using * (say):

\documentclass{article}

\usepackage{fmtcount}

\makeatletter
\newcommand{\@test}[1]{#1}
\newcommand{\@@test}[1]{\ordinalnum{#1}}
\newcommand{\test}{\@ifstar\@test\@@test}
\makeatother

\begin{document}

\test{1} \test*{1}

\test{2} \test*{2}

\test{11} \test{12} \test{21}
\end{document}


The above command definition is also possible using xparse:

\usepackage{xparse}
\NewDocumentCommand{\test}{s m}
{\IfBooleanTF{#1}{#2}{\ordinalnum{#2}}}

• Great! What if I want the starred version to give the ordinal number? – Svend Tveskæg Jan 17 '16 at 17:50
• @SvendTveskæg: Then use \newcommand{\test}{\@ifstar\@@test\@test} or \NewDocumentCommand{\test}{s m}{\IfBooleanTF{#1}{\ordinalnum{#2}}{#2}}. – Werner Jan 17 '16 at 17:55
• @SvendTveskæg: You can accept any answer that helped you the most. – Werner Jan 17 '16 at 19:57
• Okay. I think that Christian is rather childish so I'll let him have the 15 points reward but I'll remember your advise for next time. – Svend Tveskæg Jan 18 '16 at 14:37
• @SvendTveskæg: :) – Werner Jan 18 '16 at 14:49
\documentclass[a4paper]{article}
\newcommand\test[2][]{#2\ifx\relax#1\relax\else\textsuperscript{#1}\fi}
\begin{document}
The player ended as no.~\test{1} and her friend came ind \test[nd]{2}.
\end{document}