Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I just want a good way to make a backslash character (or whatever character(s) any given format uses as escape characters), suitable to \write to a file or pass to a pdfTeX primitive.

Let me emphasize that getting it to typeset is not the point of the question. In fact, if using cmr10/11/12, what I want would not be usable to typeset a backslash, since these fonts use that slot for something else for some reason.

An acceptable answer will say how to do this in general, not just in LaTeX, though format-specific techniques are also of interest (and will be upvoted).

Bonus points for explaining how to do this for all characters with special catcodes. (Not literal bonus points, only figurative ones. At least, not from me; I only have 296 rep at the moment!)

share|improve this question
    
FYI, my personal motivation for wanting to do this was that I needed a backslash for a directory separator in order to give a working implementation in my answer to a question about how make a PDF hyperlink open a given file in a particular application, with the concrete example task "open c:\figure.bmp in MS Paint". –  SamB Dec 25 '10 at 6:21
    
What I actually used there was taken from @TH.'s answer to a less targetted question, and is nearly the same as @Hendrik's answer here, except with curly braces instad of \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
    
You've just posted a question. The question would look better if your accept rate was abobe 0%. I think here you have a good point where you can start improving your accept rate! –  Hendrik Vogt Jan 21 '11 at 15:15
    
@Hendrik: True. I've been meaning to accept one, but hadn't felt ready to decide which to accept. I hope that's changed, because I've just accepted one :-). –  SamB Jan 21 '11 at 17:34

4 Answers 4

up vote 16 down vote accepted

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{!}}
share|improve this answer
    
excellent answer! –  Yiannis Lazarides Dec 19 '10 at 12:57
    
That is nice and tidy. Now, you say I get to pick the catcode, but do I get to pick any catcode? As Hendrik and TH. mention, I can pick from at least 11 and 12 with the other technique already, so what options does this technique offer that that one does not? –  SamB Dec 25 '10 at 6:13
1  
@SamB: With the \expandafter\@gobble\string method you are limited to catcode 12. With the lccode method, you can obtain the catcodes of $, &, ^, _, ~ and of course 11 and 12. With the \catcode method, you can pick whichever catcode you want. But, unlike catcodes, lccode changes work inside the argument of a command so that's another advantage over the other methods. –  Philippe Goutet Dec 26 '10 at 19:51
    
I just tried \@backslashchar, and while it works great with \write (what I needed it for), then it seems to crash my file on second run of pdflatex - failing on \\ linebreaks (which previously worked as normal) with the error: "! Use of \\ doesn't match its definition." ... Any suggestions how I'd address this? Thanks - cheers! –  sdaau May 17 '11 at 16:46
    
@myself :) - ok, turns out I had an error, that effectuated itself once this \@backslashchar started working - and that ended up spitting a "gdef\\..." in the .aux file, which redefined the usual \\ ... So all seems to be fine now :) –  sdaau May 17 '11 at 17:33

Here's one possible way with changing catcodes (just saw that TH. proposed almost the same in this answer):

\begingroup
\catcode`\@=0
\catcode`\\=11
@global@def@backslash{\}
@endgroup

Note that I first give @ catcode 0 so that I can use it in place of \. For other special characters it's in fact easier; you don't need the @.

As Philippe pointed out, the drawback of the above approach is the use of \global. Here's another nice trick that avoids this:

\begingroup
\catcode`\@=0
\catcode`\\=11
@def@makeliteralbackslash{@def@backslash{\}}
@expandafter@endgroup@makeliteralbackslash

The macro @makeliteralbackslash is expanded before the end of the group; one expansion happens while the catcode changes are still active. The definition of \backslash itself then is executed outside the group. I'm not claiming that this is the best possible approach: It's just to give an example of interesting TeX core tricks.

share|improve this answer
    
It probably doesn't make much difference, but I'd probably go with 12 instead of 11. –  TH. Dec 19 '10 at 3:03
    
@TH.: I've thought about that, but indeed I didn't really see why I should prefer which. Of course the code work's with either. –  Hendrik Vogt Dec 19 '10 at 7:26
    
Yeah, I'm not sure I can give a convincing reason for other over letter. Best I've got is \ isn't a letter. –  TH. Dec 19 '10 at 13:04

LaTeX core appears to do this:

\catcode`\@=11
...
\long\def\@gobble#1{}
\edef\@backslashchar{\expandafter\@gobble\string\\}

I don't properly understand how this works, but it does seem to do what you want in \write.

share|improve this answer
    
It doesn't seem to matter if <code>\\</code> is a macro or not. –  TH. Dec 18 '10 at 23:37
    
You know what, that was from a previous iteration of experimenting, when I set the catcode of @ wrong; the complaint I got was "Argument of \\ has an extra }." Fixed. –  Zack Dec 18 '10 at 23:48

There are many ways to do it depending on what you want to do. You don't always need to change the catcode. Some examples:

\textbackslash will simply typeset \

For writing a macro to a file use \string\macro. This can also be used to just typeset it, also.

You can also define it by using:

\newcommand{\bs}{\symbol{'134}} % a backslash in tt type in OT1/T1

The \lccode trick and changing \catcode has been explained by the other posters and I haven't added it.

And a minimal with these:

\documentclass[11pt]{article} 
\begin{document}
\newcommand{\bs}{\symbol{'134}}% a backslash in tt type in OT1/T1
\newcommand{\BS}{\texttt{\symbol{`\\}}}

\BS, \texttt{\string\test}, \texttt{\bs}
\end{document}
share|improve this answer
    
Hi @Yiannis Lazarides, thanks for the tip on \textbackslash! Just a small note: \typeout{==\textbackslash==} for me outputs "==\textbackslash ==" instead of ==\==. Cheers! –  sdaau May 17 '11 at 16:19
    
@sdaau: Yiannis did only say that \textbackslash would typeset a backslash, so, what did you expect? –  SamB May 17 '11 at 17:18
    
@SamB - that's correct, sorry, I wasn't paying too much attention when I read at first.. –  sdaau May 17 '11 at 17:35
    
@sdaau: (Belated, I know.) Hmm, I may need to work on "don't bite"; I wouldn't want to accidentally bite newcomers ... –  SamB Mar 24 at 17:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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