An example "borrowing" \@ifnextchar from latex.ltx:
\catcode`\@=11\relax
\long\def\@ifnextchar#1#2#3{%
\let\reserved@d=#1%
\def\reserved@a{#2}%
\def\reserved@b{#3}%
\futurelet\@let@token\@ifnch}
\def\@ifnch{%
\ifx\@let@token\@sptoken
\let\reserved@c\@xifnch
\else
\ifx\@let@token\reserved@d
\let\reserved@c\reserved@a
\else
\let\reserved@c\reserved@b
\fi
\fi
\reserved@c}
\def\:{\let\@sptoken= } \: % this makes \@sptoken a space token
\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
\def\foo{%
\@ifnextchar[%]
{\foo@}
{\foo@[]}
}
\def\foo@[#1]#2{%
First argument = #1, second argument = #2}
\catcode`\@=12\relax
\foo{stuff}
\foo[more]{stuff}
\bye
Joseph Wright
but it seems doesn't work
Who can help me on this?
Thanks in advance
> I've tried \def\foo[#1]#2{.....}
>
> but it seems doesn't work
>
> Who can help me on this?
Basically, you need to scan the next argument and see if it is equal to [.
If so, you execute one macro with [..] in its definition, otherwise, a
different macro with no [...] in its definition.
Suppose you have a macro \doifnextcharelse that checks the next token.
Then something like this will work.
\def\foo{\doifnextcharelse[\dofoooptional\dofoodefault}
\def\dofoodefault#1{No Optional argument. Required argument: #1}
\def\dofoooptional[#1]#2{Optional argument: #1. Req M7uired argument: #2}
Then something like this will work.
\foo{required}
\foo[optional]{required}
Now, plain tex does not have a macro similar to \doifnextcharelse. But
both LaTeX and ConTeXt have one. So, the easiest thing to do it to copy
the macro from either of these. This is how ConTeXt defines
doifnextcharelse
http://source.contextgarden.net/tex/context/base/syst-gen.tex?search=%5C%5Cdef%5C%5Cdoifnextchar)
Or just \input miniltx and then \@ifnextchar is automatically
defined. Also @ is a letter and \makeatother is defined to restore
its \catcode:
\input miniltx
> \def\foo{%
> \@ifnextchar[%]
> {\foo@}
> {\foo@[]}
>
> }
>
> \def\foo@[#1]#2{%
> First argument = #1, second argument = #2}
\makeatother
> \foo{stuff}
>
> \foo[more]{stuff}
>
> \bye
miniltx also provides \@ifstar and \@for and other useful
(and some not-so-useful) commands for plain TeX.
Dan