1

While trying to learn macros in LaTeX, I came across this definition:

\x@protect is a macro with one argument, represented by the "#1". \@typeset@protect also is defined as \relax and therefore the first branch of the \ifx is executed, which does nothing. (\ifx compares the meaning of two macros.) So the only result of \x@protect is that its argument, the first "\\" in the definition of \\, is thrown away. This leaves the command \protect, which is a no-operation, and \\ itself. This seems to be a circular definition. In fact, it isn't. It is a nasty trick on the part of LaTeX's authors trying to cover their tracks. Have a second, exceedingly suspicious look at the listing of \\. There are two spaces between the last "\\" and the period, while after the last control sequence in other listings, there is only one! In fact there is only one trailing space in all listings. The last but one space in the listing of \\ is part of the name of its last control sequence, which is "\\ ", including the space!`

Why the circular reference?

Why doesn't it break down on encountering a circular reference?

6
  • This is a remnant of the pre-eTeX protection mechanism, where you would prefix things with \protect and use \protected@edef instead of plain \edef. The \protected@edef changes \protect into \noexpand temporarily. Otherwise \protect is just \relax. Nowadays you'd just use \DeclareRobustCommand but the LaTeX kernel strives for maximum compatibility, so old definitions won't be adjusted. Commented Dec 6, 2019 at 1:49
  • 2
    The short answer to your question is that the reference isn't circular, as stated in the paragraph ("... This seems to be a circular definition. In fact, it isn't..."). Commented Dec 6, 2019 at 3:04
  • @HenriMenke \DeclareRobustCommand doesn't use etex \protect either. (in fact until this year nothing did by default) Commented Dec 6, 2019 at 8:10
  • @DavidCarlisle I see. What is the LaTeX way for \protected\def then? Commented Dec 6, 2019 at 8:27
  • 1
    @HenriMenke \protected\def or something with _ and : in its name. or \DeclareDocumentCommand from xparse Commented Dec 6, 2019 at 8:27

1 Answer 1

3

Let's start an interactive session with pdflatex test, where test.tex is

\documentclass{article} \DeclareRobustCommand{\?}{js bibra} \makeatletter \show\? 

The \show command will stop the run, so we're able to issue more commands

This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex) restricted \write18 enabled. entering extended mode (./test.tex LaTeX2e <2019-10-01> patch level 3 (/usr/local/texlive/2019/texmf-dist/tex/latex/base/article.cls Document Class: article 2019/10/25 v1.4k Standard LaTeX document class (/usr/local/texlive/2019/texmf-dist/tex/latex/base/size10.clo)) > \?=macro: ->\x@protect \?\protect \? . l.7 \show\? ? i\show\x@protect > \x@protect=macro: #1->\ifx \protect \@typeset@protect \else \@x@protect #1\fi . <insert> \show\x@protect l.7 \show\? ? i\show\@x@protect > \@x@protect=macro: #1\fi #2#3->\fi \protect #1. <insert> \show\@x@protect l.7 \show\? 

What happens when \? is processed? There are two cases: if \protect hasn't the same meaning as \@typeset@protect (which is \relax), then the false branch is followed. Thus the input stream will have

\@x@protect\?\fi\protect\? 

and the expansion of \@x@protect will remove the last two tokens, leaving \protect\?\fi (and \fi will eventually disappear).

This happens, for instance, in \protected@edef or \protected@write, when \protect is assigned a different meaning than \@typeset@protect.

If it has, the conditional is true, so the input stream will have, after skipping the false branch,

\protect\? 

Now \protect disappears and we seem to be in the same place as before. But we aren't, because the token following \protect is different from \? that was input in the test document.

Look closely at the output of the first \show command. We get

->\x@protect \?\protect \? . 

Between -> and the trailing period, TeX represents the replacement text of the macro. The rules for this representation are that control words are followed by a space, whereas control symbols aren't. This explains the space after \x@protect and \protect as well as no space after \?. But the trailing period is preceded by two spaces! Where do they come from?

When you do \DeclareRobustCommand{\?}{js bibra}, LaTeX does several things, the main one being something like

\expandafter\def\csname ? \endcsname{js bibra} 

and then using this macro with a very nonstandard name for defining the “user level version” of \?. Note the space before \endcsname, which ends up in the macro name.

There are some more details, but the idea is to ease writing of auxiliary files. In the older versions of LaTeX, we saw something like

\def\LaTeX{\protect\pLaTeX} \def\pLaTeX{<the real definition>} 

When LaTeX2e was released, the previous code became

\DeclareRobustCommand{\LaTeX}{<the real definition>} 

exploiting a new abstraction level. In the older versions, \LaTeX{} in a section title would have written

\protect\pLaTeX {} 

in the auxiliary files. Now it writes out

\LaTeX {} 

because of the trailing space in the name and the rule. The double space will be ignored when the auxiliary file is read in.

It's slightly different for control symbols such as \\ or \?, but the general idea is the same.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.