5

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?

5

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.