# Defining a command that scans every arguments' macro “looking for” a token

Knowing that every command declaration with conditionally optional arguments, as \foo{...} expanding into \foo[default]{...} can be defined by \newcommand\foo[1][default]{...} or the safer version of:

\newcommand\foo{\@ifnextchar[{\@foo}{\@foo[default]}}
\def\@foo[#1]#2{do something with #1 and #2}


this kind of "test" however fails if the optional argument is declared after the mandatory one. Therefore (knowing that the order of argument declaration of \@foo cannot be changed):

\newcommand\foo{\@ifnextchar[{\@foo}{\@foo{}[default]}}
\def\@foo#1[#2]{do something with #1 and #2}


will generate errors.

More generally, if \@bar is defined such that has to contain two (or more, but the general case is left aside) arguments, but only the optional #2 that doesn't appear just after the control sequence name:

\def\@bar#1[#2]{#1 and #2}


then, how is it possible to define \bar such that this condition:

\bar{a}[b] % returns "a and b"
\bar{a}    % returns "a and default"


will be met? In this case an internal command inside the definition of \bar would scan all of the argument tokens of \bar until it finds a [; if it doesn't find any, then it'll just declare \@bar#1[default].

This behaviour should be similar to \@ifnextchar (say \@iftoksexist) with the difference that it will be sufficient for char to just exist as argument token:

\documentclass{article}
\makeatletter
\def\@iftoksexist#1#2#3{...} %
\def\mybar{%
\@iftoksexist{[} % or \@iftoksexist[{...}{...}
{
%use "\@mybar#1[#2]"
}
{
%use "\@mybar#1[default]"
}%
}
\def\@mybar#1[#2]{#1 and #2\par}
\makeatother
%
\begin{document}
%
\mybar{lorem}[ipsum]
\mybar{dolor}
\mybar{sit}[amet]
%
\end{document}


In this case, \@iftoksexist will search for [ inside every \mybar..., yielding this output:

Yet again, after a sufficient number of trials, and looking this and that, I haven't had much success.

• You should have a look at xparse – egreg Sep 14 '14 at 16:30
• @egreg Right in the weak spot... Unfortunately I haven't put my eye on its documentation for a long time, although it may save some difficulties with the plain TeX understanding of this problem. – alandella Sep 14 '14 at 16:32

Just absorb the mandatory argument and “remember” it:

\makeatletter
\newcommand{\foo}[1]{%
\@ifnextchar[{\foo@aux{#1}}{\foo@aux{#1}[default]}%
}
\def\foo@aux#1[#2]{%
mandatory is #1', optional is #2'%
}
\makeatother


of course this is not very robust and \DeclareRobustCommand should be used.

A syntax like \foo{a}[b]{c} where the optional argument has a default value can be defined in a similar way:

\makeatletter
\newcommand{\foo}[1]{%
\@ifnextchar[{\foo@aux{#1}}{\foo@aux{#1}[default]}%
}
\def\foo@aux#1[#2]#3{%
first mandatory is #1', optional is #2', second mandatory is #3'%
}
\makeatother


Alternatively:

\usepackage{xparse}

\NewDocumentCommand{\foo}{mO{default}}{%
mandatory is #1', optional is #2'%
}


which is automatically robust. But as a general advice, avoid trailing optional arguments. The \foo{a}[b]{c} syntax is just

\NewDocumentCommand{\foo}{mO{default}m}{%
first mandatory is #1', optional is #2', second mandatory is #3'%
}


Note that in the first case spaces will be ignored after \foo{a} if no optional argument is present (the reason is how \@ifnextchar works).

• The [default] should be in the false branch I guess: \@ifnextchar[{\foo@aux{#1}}{\foo@aux{#1}[default]} – clemens Sep 14 '14 at 16:38
• @cgnieder You're perfectly right – egreg Sep 14 '14 at 16:40
• @egreg Needless to say, excellent answer as usual. I'll definitely look up xparse now that I have plenty of time ;) – alandella Sep 14 '14 at 20:40
• @AndreaL. Exam session ended? – egreg Sep 14 '14 at 20:46
• @egreg Yeah! But I finished in July; right now I'm preparing some Linear Algebra exercise sheets for my colleagues (with the occasion, I took two birds with one stone) :-) – alandella Sep 14 '14 at 21:02