# [texhax] Fragile command problem?

Toby Cubitt tsc25 at cantab.net
Thu Apr 12 02:21:12 CEST 2007

Hi,

I've used LaTeX for many years, but am fairly new to (La)TeX hacking, so
I apologise if this turns out to be a trivial question. I've tried
reading the FAQ, Tex-by-topic, and the documented LaTeX2e source, but
still don't fully understand what's going wrong.

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". 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.

Can anyone put me out of my misery? I'd very much appreciate an
explanation of what's going wrong, as well as a solution.

Thanks very much,

Toby Cubitt