# [texhax] Fragile command problem?

Donald Arseneau asnd at triumf.ca
Thu Apr 12 21:32:33 CEST 2007

Toby Cubitt <tsc25 at cantab.net> writes:

> apologise if this turns out to be a trivial question.

Not trivial.  Not "fragile" as such, but related.

> \def\sref at type#1{%
>    \expandafter\expandafter\expandafter%
>    \sref@@type\csname r@#1\endcsname}
> \def\sref@@type#1#2{\sref@@@type#1[]}
> \def\sref@@@type{\@ifnextchar[%]
>    {\sref@@@@type}{\sref@@@@type[]}}
> \def\sref@@@@type[#1]#2[]{#1}

> This works fine until I try to use it inside \edef or (more
> importantly for my purposes) inside \csname...\endcsname.

Those are areas of macro expansion only, no typesetting or
even assignments.  \@ifnextchar uses assignments, and is not
purely expandable, so it can't work.  You should instead use
a definitive end-marker token and consume all arguments as
macro parameters.

Since the point of the \@ifnextchar seems to be to insert an
empty "type" when there is none, then why not just latch on
to the empty [] at the end...

\def\sref at type#1{%
\expandafter\expandafter\expandafter%
\sref@@type\csname r@#1\endcsname}

\def\sref@@type#1#2{\sref@@@type#1[]\delimiter}

\def\sref@@@type#1[#2]#3\delimiter{#2}

> vaguely gather that this might be a problem with the command being fragile
> (due to the \@ifnextchar?), therefore requiring the command definition to be
> protected

While purely expandable macros are indeed robust in all cases,
there are also robust commands that are not expandable.  Moreover,
no ammount of \protect will make your macro work by expansion.

--
Donald Arseneau                          asnd at triumf.ca