home

TeX: makeatletter and makeatother

Ever wondered why some TeX macros have to be put between the makeatletter and makeatother commands? Like this one:

\usepackage{remreset}
\makeatletter
\@removefromreset{footnote}{chapter}
\makeatother

which allows to keep the footnote counter from being reseted with each chapter, which would be the default behaviour in the book and report document classes.

Radhakrishnan gives an excellent, detailed explanation from which I’d like to quote:

\makeatletter changes the category code of ‘@’ character to 11 (…)
\makeatother reverts this to its original catcode of 12.

Knuth [the creator of TeX] assigns a category code for each and every character like 0 for escape ‘\’, (…) 11 for letters, (…) and 12 for characters other than the above. (…)

You might have noted that an escape character combined with the characters of catcode 11 becomes a control sequence. As such, all the user defined control sequences or macros will be of this nature.

This raises the problems of risks of an user defined macro having the same name as that of a macro in a package or even LaTeX kernel even. (…)

In order to circumvent this foreseeable problem, package writers always use the character ‘@’ in their control sequences by changing the cat code of `@’ character to 11 which is the catcode of alpha characters. This is accomplished by the command \makeatletter.

At the end of the package, the author will revert the catcode of `@’ to 12 with the command \makeatother. So you will find lots of macros
with `@’ like \@title, etc., which you cant define in a document without changing the catcode. So novice users will not create macros that might clash with kernal macros.

2 Responses to “TeX: makeatletter and makeatother”

  1. Torsten
    August 7th, 2007 17:03
    1

    Aaah, das also sind die Folgen exzessiven Drogenmissbrauchs. Erschreckend.

  2. Torsten
    August 8th, 2007 10:25
    2

    Wenn ich bei TeX irgendwann die Funktion \makeout entdecke, wechsel ich zu Winzigweich Wort.

    Error thrown

    Call to undefined function mysql_query()