# [texhax] Fragile command problem?

Toby Cubitt tsc25 at cantab.net
Thu Apr 12 16:32:38 CEST 2007

I should also have said...[see below]

Toby Cubitt wrote:
> I have a series of macros defined as:
>
> \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}
>
> (I guess it's probably possible to collapse this down to one or two
> macros once I can get them working correctly.) The \r@#1 commands expand
> to something of the form {[type]a}{b}, and I want \sref at type{#1} to
> return the "type".

The \r@#1 commands sometimes expand to something of the form {a}{b}
instead, hence the whole \@ifnextchar stuff.

> This works fine until I try to use it inside \edef or
> (more importantly for my purposes) inside \csname...\endcsname. E.g.
> assuming \r at ref expands as just described,
>
>    \def\sref at tmpa#1{\sref at type{ref}}
>
> throws an "Argument of \sref@@type has an extra }" error, followed by a
> "TeX capacity exceeded" error. On the other hand, the line
>
>
> throws "Missing \endcsname inserted" followed by "Extra \endcsname". I
> 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 and any \edef to be replaced by
> \protected at edef or some such. But naively protecting the macros doesn't
> work, and I still don't understand how to achieve what I need: a way to
> use the "type" part of r@#1 inside a \csname...\endcsname in order to
> construct a new command sequence from it.