# Starred macro with delimited arguments?

My goal is to define a starred and a non-starred version of a macro \foo that will be called as \foo arg {actual argument} or \foo* arg {actual argument}.

So I tried the following:

\makeatletter
\def\foo{\@ifstar\withstar\withoutstar}
\makeatother

\def\withstar arg #1{%
With star: #1
}

\def\withoutstar arg #1{%
Without star: #1
}

\foo* arg {actual argument}
\foo arg {actual argument}


but I get the error

! Use of \withstar doesn't match its definition.
l.67 \foo*
arg {actual argument}


However, if I change the definition of \withstar and \withoutstar to

\def\withstar #1{%
With star: #1
}

\def\withoutstar #1{%
Without star: #1
}


Then the calls \foo* {actual argument} and \foo {actual argument} work as expected. Why does this happen?

There is a space between the start * and arg:

\foo* arg {actual argument}


But the parameter text of \withstar directly starts with arg:

\def\withstar arg #1{...}


because the space inbetween ends the command sequence \withstar.

Fix:

\makeatletter
\def\foo{\@ifstar\withstar\withoutstar}

\@firstofone{\def\withstar} arg #1{%
\typeout{With star: #1}%
}
\makeatother

\def\withoutstar arg #1{%
\typeout{Without star: #1}
}

\foo* arg {actual argument}
\foo arg {actual argument}

% End TeX job
\makeatletter\@@end


The space after curly braces is not ignored. \@firstofone is defined in the LaTeX kernel as such:

\long\def\@firstofone#1{#1}


It is used as trick to insert the space after the command sequence \withstar.

Result:

With star: actual argument
Without star: actual argument

• But \withstar arg {some argument} works fine. I guess I don't completely understand how spacing affects the macro parsing? – dow May 6 '18 at 20:50
• @dow A space after a command sequence (\withstar) is ignored. But a space is not ignored after other tokens like the start *. – Heiko Oberdiek May 6 '18 at 20:58
• Would you mind elaborating on the use of \@firstofone in this case ? – dow May 6 '18 at 21:00
• @dow Answer is updated. – Heiko Oberdiek May 6 '18 at 21:10
• Thank you. On line 7, I believe you meant to say \makeatother (I would have fixed it myself, but it won't let me make edits that are less than 6 characters). – dow May 6 '18 at 21:11