# How can I test if a command is followed by an argument?

Imagine I have two commands defined as

\def\witharg#1{something with #1}
\def\without{something without arg}


and I want to define a new command \mycmd that behaves as \witharg if it's followed by an argument (not necessarily enclosed in braces), and behaves like \without if it is not followed by an argument. In fact, the later case can only be true if \mycmd is followed by the token }. To make things slightly more clear, I want

{\mycmd\token\mycmd}


to expand to something similar to the expansion of

{\witharg{\token}\without}


How can I achieve this?

Note that, in fact, trying to evaluate something like {\witharg} fails with TeX complaining that there is an extra }, i.e. the argument to \witharg is missing.

-
Are you looking for a solution that is strictly in basic TeX? I.E. is LaTeX allowed? – Sharpie Aug 3 '10 at 3:18
tex-guts is a really ugly term to use. Can we use tex-only or plain-tex instead? – Will Robertson Aug 3 '10 at 6:07
I was trying, you can re-tag of course :) – Juan A. Navarro Aug 3 '10 at 7:01
@SSharpie, I was looking for a TeX answer, but a LaTeX one would also be welcome – Juan A. Navarro Aug 3 '10 at 7:02
I thought the consensus was tex-core? – Konrad Rudolph Aug 6 '10 at 9:28

Whenever you need to check what comes next after a macro, the primitive to use is generally \futurelet (see TeX by Topic for a good reference). In this case, you'd write something like

\def\mycmd{%
\futurelet\mytoken\myargparse
}


which will \let the following token to \mytoken and then expand \myargparse. Define \myargparse to be conditional on what \mytoken is, and that's it:

\def\myargparse{%
\ifx\mytoken\closingbracetoken
\expandafter\without
\else
\expandafter\witharg
\fi
}
\let\closingbracetoken=}


Finally, check that it works:

\def\witharg#1{something with #1}
\def\without{something without arg}
\def\token{TOK}
{\mycmd\token\mycmd}

-
More or less what I was about to write :-) – Joseph Wright Aug 3 '10 at 6:04
You would have written your explanations more clearly :) – Will Robertson Aug 3 '10 at 6:08
Excellent, thanks! I found about \futurelet but somehow I couldn't figure out how to test for } or put all of it together. This works nicely! – Juan A. Navarro Aug 3 '10 at 7:05

xparse can test for explicit brace-delimited arguments (or other delimiters, see documentation):

\documentclass{article}
\usepackage{xparse}% http://www.ctan.org/pkg/xparse

\NewDocumentCommand\mycmd{g}{%
\IfValueTF{#1}{(something with #1)}{(something without arg)}%
}

\def\token{TOK}
\begin{document}

\mycmd{Hello}

\mycmd

{\mycmd\token\mycmd}

Blah, \mycmd{Hello}, blah, \mycmd, blah

\end{document}


-
but in the {\mycmd\token\mycmd} case, I wanted \token to be used as an argument to the first \mycmd. Here it seems that the argument is taken only if enclosed by braces? – Juan A. Navarro Mar 7 '13 at 20:49
@JuanA.Navarro: Correct, This approach requires braces when you want to pass an argument, Will's \futurelet approach requires braces when you do not want to pass an argument. Use whichever you find more natural (for my code, I find the "braces when arg wanted" semantics more natural). – Dean Serenevy Mar 13 '13 at 18:18