↑↑ Home ↑ TeX tricks

Listing pre-defined macros

So you want to know how to hack internal LaTeX macros? You've come to the right place :)=).

TeX offers a primitive control sequence (ie one not defined as a composition of others) for listing the definition of a macro. It is called \show. If you type "\show\show", the latex program will output at compile time:

> \show=\show.
l.15 \show\show
This indicates that \show is not a macro. To give you a non-trivial example, here is the listing of LaTeX's newline control sequence, \\:
> \\=macro:
->\x@protect \\\protect \\  .
l.16 \show\\
This seems to tell us that \\ is defined as twice itself plus some other obscure control sequences. (The fact that there is no simple non-trivial example because there doesn't seem to be a single LaTeX macro which is not composed of several obscure internal macros is a measure of the openness of LaTeX.) We can now try to list the other two sequences.
> \protect=\relax.
l.17 \show\protect
                  
> \x=undefined.
l.18 \show\x
            @protect
The sequence \protect is defined as \relax, the no-operation command of TeX. Listig the other command doesn't work: TeX interprets just the first x as the name of the control sequence and assumes the rest to be following text. Internal macros deliberately contain "@" characters to make it impossible for the user to redefine them and thereby derail LaTeX.

So how were they defined in the first place? The answer is complex: Characters have category codes assigned to them. The names of control sequences must consist of characters of category 11. To mess around with internal control sequences, one has to set the category code of "@" to 11 with the control sequence \catcode.

\catcode`\@=11
\show\x@protect
We get even more internal control sequences. :(
> \x@protect=macro:
#1->\ifx \protect \@typeset@protect \else \@x@protect #1\fi .
l.18 \show\x@protect
\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!

To list this macro one would have to redefine the category code of the space. This doesn't work for some reason. But there is a better way to list macros with all kinds of characters in their names. The commands \csname ... \endcsname create the the control sequence the name of which is given in between them. The control sequence "\string" converts a control sequence to ordinary characters, which makes it possible to give the name of control sequences with names starting with a backslash, like \\. With these two commands one can define a macro called \shown ("show macro with name...") which can list nearly all control sequences. The name of the control sequence to list has to be given in braces as its argument, without the leading backslash. Due to a peculiarity of \csname, undefined control sequences are reported as equal to \relax. If you want to list macros with several spaces in their names, you have to say \obeyspaces, or TeX will contract them to one space. What \shown still cannot list are control sequences whose name contains a backslash as a second or later character, but I've never encountered that. One can also define a command \showthen corresponding to \showthe which gives the value (rather than the definition) of variables. Finally, for calling internal macros, there is \don ("do macro with name..."). No comment on what the fourth macro is for. So the complete hacker's toolkit is:


\scrollmode

\obeyspaces

\def\shown#1{\expandafter\show\csname\string#1\endcsname}
\def\showthen#1{\expandafter\showthe\csname\string#1\endcsname}
\def\don#1{\csname\string#1\endcsname}
\def\defn#1{\expandafter\def\csname\string#1\endcsname}

By the way, the listing of "\\ " is worse than all the others on this page, but it has a few control sequences with names like "\@xnewline" in it so it is bound to be the one which really does the job.


TOS / Impressum