When TeX reads your source, why does \ start a command and { open a group? The answer is the category code (catcode): a number assigned to every input character that tells the tokenizer what role that character plays. The same mechanism explains the mysterious @ you see inside LaTeX’s internal commands — and why you must wrap calls to them in \makeatletter … \makeatother when you use them in your preamble. This page covers both, and when to reach for them.
What category codes are
TeX’s processing begins with tokenization — turning a stream of characters into a stream of tokens. As it reads each character, TeX consults that character’s category code (catcode), a number from 0 to 15 that determines the typesetting role it plays. For example \ has catcode 0 (escape — the start of a command), { has catcode 1 (begin-group), and $ has catcode 3 (math shift). The key idea is that the role is decided by the catcode, not by the character itself. $ switches into math not “because it is a dollar sign” but “because it has catcode 3.”
The table below shows the default category codes in full. In daily use you mostly notice 0 (starts a command), 1/2 (grouping), 3 (math), 4 (column separator in tables), 5 (the line ending that builds paragraphs), 6 (a macro’s argument marker), 7/8 (super- and subscripts), the trio 10/11/12 that makes up running text, and 14 (comments).
| catcode | Role | Default character(s) |
|---|---|---|
0 | Escape (starts a command) | Backslash \ |
1 | Begin group | Left brace { |
2 | End group | Right brace } |
3 | Math shift | Dollar sign $ |
4 | Alignment tab | Ampersand & |
5 | End of line | Return / newline |
6 | Parameter (macro argument) | Hash # |
7 | Superscript | Caret ^ |
8 | Subscript | Underscore _ |
9 | Ignored character | Null character |
10 | Space | Space and tab |
11 | Letter (forms command names) | a–z, A–Z |
12 | Other | Digits, punctuation — everything else |
13 | Active character (acts as a command) | Tilde ~ |
14 | Comment | Percent % |
15 | Invalid character | Delete character |
Catcode 11 (letter) and command names
Among the categories, 11 (letter) is special because it is wired directly into how commands work. A TeX control word — a named command like \section — is recognized as **a catcode-0 character (usually \) followed by a run of catcode-11 characters**. In other words, only catcode-11 characters can normally form a command’s name. \section ends its name at section precisely because the next character (a space or {) is not catcode 11. The user-level consequences — that the space after a control word vanishes, that \LaTeXlogo reads as one undefined command — were covered on the “Syntax rules” page; here we are looking at the catcode machinery underneath them.
It also matters here that digits and punctuation are catcode 12 (other). Since only letters can be part of a command name, \a2 reads as the command \a followed by the character 2. Turn that around: if you change a character’s catcode to 11, that character becomes usable inside command names — and that single move is the key to the story of @ that follows.
Changing categories with `\catcode`
The mapping from characters to categories is not fixed — the primitive **\catcode** can rewrite it. The syntax is ` \catcode⟨char⟩=⟨number⟩ `: a backtick ` followed by the target character, then = and the new catcode. For instance \catcode@=11 ` says “from here on, treat @` as a letter (catcode 11).”
% catcode を直接いじる(上級・壊れやすい)/ Touching catcodes directly (advanced, fragile)
\catcode`@=11 % @ を英字に / make @ a letter
\catcode`@=12 % @ を「その他」に戻す / put @ back to “other”This is powerful but fragile, and using it raw is for advanced hands. Rewriting a category changes how everything after it is read, so forgetting to restore it breaks things in surprising places. Yet the same mechanism underlies familiar features: \verb and the verbatim environment can print source verbatim because internally they **temporarily lower the catcodes of the special characters (\, {, $, and friends) to 12 (other)**, so those characters are no longer read as commands or grouping. The \makeatletter of the next section is best understood as **a safe, named wrapper around exactly this \catcode move**.
`\makeatletter` and `\makeatother`
Many of LaTeX’s kernel and package internal commands carry @ in their names: \@startsection, which assembles section headings; \@ifnextchar, which peeks at the next token to branch; \p@, the length 0pt; and so on. These can be defined and used inside .sty/.cls files without trouble because there @ has catcode 11 (letter) and so counts as part of a command name. In fact, while \usepackage and \documentclass read a package or class, they switch @ to catcode 11 for you.
In an ordinary document body, however, @ has catcode 12 (other). So if you write \p@ directly in your text or preamble, TeX reads it as the command \p followed by the character @, and never reaches the internal command you meant. The declaration **\makeatletter** turns @ back into a letter for just the stretch where you use or redefine internal commands, and its partner **\makeatother** restores @’s catcode to its default of 12. As the names say — “make @ a letter” / “make @ other” — and under the hood they are exactly ` \catcode@=11 ` and \catcode@=12 ``.
Why have such a convention at all? To fence internal commands off from ordinary users. With @ at catcode 12 by default, someone merely writing a document cannot accidentally overwrite a name like \@startsection with one of their own. A name containing @ is a sign that says “internal use,” and to touch it you must explicitly “unlock the door” with \makeatletter.
A worked example, and the gotchas
The typical use is to lightly adjust an internal command defined by your class or package, right in the preamble. In the example below, the internal macro \@maketitle (how the title block is laid out) is redefined inside \makeatletter … \makeatother. Only within the wrapper is @ a letter, so the name \@maketitle is correctly recognized as a single command.
\documentclass{article}
\makeatletter
% 内部命令 \@maketitle を再定義する / redefine the internal \@maketitle
\renewcommand{\@maketitle}{%
\begin{center}
{\LARGE\bfseries \@title}\par
\vspace{1ex}{\large \@author}\par
\end{center}%
}
\makeatother
\title{カテゴリコード入門}
\author{名前}
\begin{document}
\maketitle
\end{document}The biggest gotcha is **forgetting \makeatother.** Leave it off and @ stays a letter into whatever follows, breaking any later text that contains @ (an email address, say) or the behavior of packages that treat @ specially. Whenever you open with \makeatletter, always close with its partner \makeatother — treat the two as an inseparable pair.
A second misconception is **writing \makeatletter inside a .sty/.cls file.** As noted, @ is already catcode 11 while a package or class is being read, so it is unnecessary there — and a stray \makeatother could even disturb later processing. Use \makeatletter … \makeatother only **inside a .tex document (typically the preamble) when you touch internal commands.** And if you can avoid touching internals at all — by overriding a public command with \renewcommand, or by using a proper package that provides what you need — that is safer. Writing macros and packages in earnest is covered on its own page.