10

Consider this extract from TeXbook:

EXERCISE 7.5 Experiment with TEX to see what \string does when it is followed by an active character like ~. (Active characters behave like control sequences, but they are not prefixed by an escape.) What is an easy way to conduct such experiments online? What control sequence could you put after \string to obtain the single character token \ 12 ?

The answer reads:

If you type ‘\message{\string~}’ and ‘\message{\string\~}’, TEX responds with ‘~’ and ‘\~’, respectively.

What was Knuth's flow of reasoning when he tried to use \~ here? I mean, how can we logically deduce from the exercise that we must try \~ when it is told there only about ~?

Further, why the word "therefore" in the next extract is used? I mean, how can we conclude from "\string\~ experiment" that we must make \ an active character? I can understand the relevance of "\string~", but why "\string\~"?

To get \ 12 from \string you therefore need to make backslash an active character.

Besides, it is possible to make it "other" also, which is not mentioned in TeXbook:

{\catcode`/=0 \catcode`\\=12 /message{/string\}}

Incidentally, why catcode changes cannot be put directly to \message, without the need for extra grouping (even with the original Knuth's active character example), i.e. why if we change the original

{\catcode`/=0 \catcode`\\=13 /message{/string\}}

into

\message{\catcode`/=0 \catcode`\\=13 /string\}

then it stops working?

  • 2
    Category code changes are assignments and, as such, can only be performed in TeX's "stomach"; \message{<text>} simply displays <text> on the terminal, expanding expandable tokens and displaying in symbolic form unexpandable ones. In your example, for instance, \\ would be expanded, while \catcode would be displayed symbolically, i.e., as if it had been preceded by \string. Also, after giving to \ the \catcode "other", \string\ and just \ are essentially equivalent. Your other questions are pretty subjective. – GuM Jun 10 '15 at 5:04
  • Sorry, I cannot get the \ character work as I would like to between backquotes. – GuM Jun 10 '15 at 5:08
  • @GustavoMezzetti -- go to this question in the meta queue: Formatting Sand-Box it has examples of things that are hard to format. – barbara beeton Jun 10 '15 at 13:11
10

The command \message is pretty similar to \write in its working: it accepts a token list as argument and shows its expansion on the terminal; unexpandable tokens are shown by their name, followed by a space if they are control words.

No command is executed, in particular assignments are not performed. So your try with

\message{\catcode`/=0 \catcode`\\=13 /string\}

is doomed to failure for a number of reasons.

  1. The argument for \message must be ended by an explicit right brace which isn't in the code; TeX will continue scanning the input for a <right brace> matching the { after \message, without probably finding one.

  2. Even if you type \message{\catcode`/=0 \catcode`\\=13 /string\ } you don't get what you want, because the category code of \ is not changed.

  3. What you get is due to a, mmmh, feature of plain.tex that leaves defined \\ as a macro with a delimited argument; but even if you say \let\\=\relax before \message what you get on the terminal is just

    \catcode `/=0 \catcode `\\=13 /string\ 
    

    and after the fact the category code of the backslash is still 0, even if the argument to \message doesn't technically form a group.

Note that no \expandafter can solve the issue, because it does expansion, not execution: these are different concepts in TeX and are performed at different stages.

Now why does Knuth compare \string~ with \string\~? Possibly because one might think that \string behaves with character tokens in a similar way to alphabetic constants, whereby

\char`~
\char`\~
\char126

are equivalent. This is not true for \string, however.

Why does Knuth say \ must be made active? I don't know; any character code other than 0, 5, 9, 10, 14, 15 would work the same.

So, how do you get a macro \backslashstring whose expansion is \12?

There are several ways:

\begingroup\catcode`/=0 \catcode`\\=12 /gdef/backslashstring{\}\endgroup

\begingroup\escapechar=-1 \xdef\backslashstring{\string\\}\endgroup

\begingroup\lccode`?=`\\ \lowercase{\endgroup\def\backslashstring{?}}

each using a different idea.

With LuaTeX (version 0.75 or later) one can also do

\edef\backslashstring{\Uchar`\\}

With XeTeX 0.99992 (available with TeX Live mid June 2015), a further possibility has been added

\edef\backslashstring{\Ucharcat`\\ 12}

and also the \Uchar method works.

  • Note that LuaTeX can also do the same as XeTeX here, with the latest LuaTeX providing a mechanism to emulate primitive syntax (see github.com/davidcarlisle/utex/blob/master/regression-test.cfg for an implementation). – Joseph Wright Jun 10 '15 at 7:18
  • @JosephWright This is very interesting, but requires other code for working. When the (pseudo)primitive \Ucharcat will be in luatex.fmt – egreg Jun 10 '15 at 7:22
  • BTW, another possible for the list of ways to create \backslashstring is \long\def\gobble#1{}\edef\backslashstring{\expandafter\gobble\string\\} [for completeness :-)]. (I'm assuming a printable non-space escape char: we have some code in expl3 that will do the same for without such an assumption but it's longer.) – Joseph Wright Jun 10 '15 at 7:24
  • @JosephWright I wanted to just use primitives, but of course your suggestion is good. – egreg Jun 10 '15 at 7:26
  • There's also \edef\backslashstring{\Uchar`\\} with LuaTeX? (I think, I'm not sure.) – Manuel Jun 10 '15 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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