Another way to do this kind of thing is to use a \lccode
trick:
\begingroup\lccode`!=`\\\lowercase{\endgroup\def\@backslashchar{!}}
This avoids any need to change catcodes thanks to the special properties of \lowercase
. Compared to the \expandafter\@gobble\string
method, it's a bit more flexible as you can choose the catcode of the resulting character inside your macro. Compared to a change of catcodes, you don't have to use \global
because of how \lowercase
interacts with \endgroup
.
Here's the detail of the code. The \begingroup
is here to keep the lccode changes local. The
\lccode`!=`\\
means that when lowercasing !
you will get the backslash \
(the choice of !
is arbitrary, you just need a normal
character which will not appear elsewhere inside the \lowercase
). The important thing is that the lowercase version of !
wille be a normal character since \lowercase
doesn't change catcodes.
The code \lowercase{\endgroup\def\@backslashchar{!}}
is thus equivalent to \endgroup\def\@backslashchar{\}
but with \
not being special (so \
followed by }
won't be interpreted as \}
but as two separate entities).
At the end, the result is that you have defined \@backslashchar
to be a \
with normal catcode. It can thus be used inside a \write
command without causing the same problems as \
does.
This lccode trick works with all other special characters. For example if you want a space character (of course, for spaces, the macro \space
works fine):
\begingroup\lccode`!=`\ \lowercase{\endgroup\def\@spacechar{!}}
If ever you break the code on two lines, just be careful with the end of lines and put a %
after the \
:
\begingroup\lccode`!=`\ %
\lowercase{\endgroup\def\@spacechar{!}}
\begingroup
and@endgroup
, but that seems to have no actual impact on the meaning in this case, as far as I can see. – SamB Dec 25 '10 at 6:28