What exactly do \csname
and \endcsname
do? What are their job?
I have glanced at the Texbook and some other books, but none of them was clear enough to me.
Can anyone please give a simple example to clarify this issue?
-
11See TeX by Topic, section 11.6– Martin SchröderCommented Dec 26, 2011 at 22:26
6 Answers
Normally, control sequence names are made only of letters or of one non-letter character.
A letter is, more precisely, a character having category code 11 at the moment the control sequence name is read. So, any character can become part of a control sequence name, provided we change its catcode before the definition and each usage.
With \csname...\endcsname
we are freed from this limitation and every character can go inside them to form a control sequence name (of course, %
is excluded because it disappears together with what remains on the line before TeX is doing its work on characters).
However, this is not the main purpose of \csname...\endcsname
. This construction is used to build commands from "variable parts". Think, for instance to LaTeX's \newcounter
: after \newcounter{foo}
, TeX knows \thefoo
that is built precisely in this way. Roughly, what LaTeX does is
\newcommand{\newcounter}[1]{%
\expandafter\newcount\csname c@#1\endcsname
\expandafter\def\csname the#1\endcsname{\arabic{#1}}%
}
so that \newcounter{foo}
does the right job. It's more complicated than this, of course, but the main things are here; \newcount
is the low-level command to allocate a counter. The \expandafter
is just to build the control sequence before \newcount
and \def
see the token.
Inside \csname...\endcsname
, category codes don't matter (with one main exception: active characters will be expanded if not preceded by \string
, see final note). LaTeX exploits this in order to build control sequence names that users won't be able to access (easily). For example, the control sequence to choose the default ten point font is \OT1/cmr/m/n/10
, which can be easily split internally (by the "reverse" operation that is \string
) and is not available to the casual user.
Another important use is in environments: when you say \newenvironment{foo}
, LaTeX really defines \foo
and \endfoo
. Upon finding \begin{foo}
, LaTeX does some bookkeeping and then executes \csname foo\endcsname
(that's why one can say also \newenvironment{foo*}
); similarly, at \end{foo}
LaTeX executes \csname endfoo\endcsname
and after this it does some bookkeeping again.
Other uses: \label{foo}
will define control sequences based on foo
via \csname...\endcsname
that can be used by \ref
.
When one says \csname foo\endcsname
, LaTeX will look whether \foo
is defined; if not, it will execute \relax
and from then on (respecting grouping), \foo
will be interpreted as \relax
. An interesting usage for this feature is that one can say
\chapter*{Introduction}
\csname phantomsection\endcsname
\addcontentsline{toc}{chapter}{Introduction}
and keep hyperref
happy if it's loaded, while doing nothing if the package is not loaded.
It's possible to give many other interesting uses of this trick. But one should always keep in mind that TeX does complete expansion of what it finds in that context and that only characters must remain. So
\csname abc\relax def\endcsname
is forbidden. But, after \def\xyz{abc}
,
\csname \xyz def\endcsname
will be legal and equivalent to saying \csname abcdef\endcsname
or \abcdef
.
Final note
It's better to add something about category codes. An active character in \csname...\endcsname
will be expanded, so to get a literal ~
one has to write \string~
. Comment (category 14), ignored (category 9) and invalid (category 15) characters will remain such. So
\csname %\endcsname
will give an error (Missing \endcsname
); in \csname ^^@\endcsname
there will be no character and \csname ^^?\endcsname
will raise an error.
Caveat
Spaces inside \csname...\endcsname
are honored. As usual, spaces after control words don't actually exist (better, they're ignored when forming tokens), but other spaces count!
Thus \csname foo\endcsname
and \csname foo \endcsname
are different. In the previous example
\csname \xyz def\endcsname
there is no space token, but in
\csname xyz def\endcname
there is one.
By the way, the clever trick used by \DeclareRobustCommand
exploits this feature. If one does \DeclareRobustCommand{\foo}{<tokens>}
, LaTeX will do something similar to
\expandafter\def\csname foo \endcsname{<tokens>}
\expandafter\def\expandafter\foo\expandafter{%
\expandafter\protect\csname foo \endcsname
}
so when writing \foo x
to a file, when \protect
means \noexpand
, the tokens will first become \noexpand\foo• x
and therefore
\foo x
will be written (I used •
to denote a space in the name). The trick consists in the fact that when reading back the file, \foo
followed by two spaces is the same as if it is followed by one space, at the moment of forming tokens.
-
2Braces don't need to be balanced.
\expandafter\show\csname{\endcsname
works fine with usual catcodes. Otherwise, very good response. Commented Dec 27, 2011 at 2:03 -
1@BrunoLeFloch Right; they have to be balanced only if used to surround arguments to macros, of course.– egregCommented Dec 27, 2011 at 10:37
-
1@Vladimir You can't use
\com?mand
unless you change the category code of?
; you also seem to have a space in front of\endcsname
and it should be removed.– egregCommented Oct 17, 2021 at 13:27 -
1@Smiley1000 It's not that it doesn't work: the space token after
foo
counts!– egregCommented Jul 2 at 21:29 -
1
For reference, from the TeX Book (with slight formatting changes), Chapter 7: How TeX Reads What You Type (p 40):
...you can go from a list of character tokens to a control sequence by saying
\csname<tokens>\endcsname
. The tokens that appear in this construction between\csname
and\endcsname
may include other control sequences, as long as those control sequences ultimately expand into characters instead of TeX primitives; the final characters can be of any category, not necessarily letters. For example,\csname TeX\endcsname
is essentially the same as\TeX
; but\csname\TeX\endcsname
is illegal, because\TeX
expands into tokens containing the\kern
primitive. Furthermore,\csname\string\TeX\endcsname
will produce the unusual control sequence\\TeX
, i.e., the token<\TeX>
, which you can't ordinarily write.
I have used this indirectly by using the \label
-\ref
system and defining labels based on counters:
\newcounter{mycount}
%...
\newcommand{\mycmd}{%
\stepcounter{mycount}%
\label{abc\themycount}%
%...
}
This creates a "successive label abc1
, abc2
, ... for every call to \mycmd
, in order to avoid creating multiply defined labels with the same name. Indirectly, \label{abc\themycount}
calls \@namedef{r@abc\themycount}
, which calls
\expandafter\def\csname r@abc\themycount\endcsname
thereby expanding r@abc\themycount
to r@abc1
and defining \r@abc1
for the first label, \r@abc2
for the second label, etc. Yes, labels in LaTeX are actually control sequences prepended with r@
and is constructed using \csname ... \endcsname
which then allows numerals.
\csname
/\endcsname
allows you to build commands whose names contains 1. non-letters (e.g. dots or colons or numbers) and - more importantly - 2. commands which are expanded when you define or use the command. Both is useful if you want to construct a command name from various pieces of informations.
As an example: The xskak-Package loops through the notation of a chess game and stores a lot of informations of every move in commands. Its code contains a lot of definition of this type:
\expandafter\xdef
\csname Xskak.\xskak@val@gameid.\the\c@move.\WhiteToMove{w}{b}.piece\endcsname{%
....
}
where \xskak@val@gameid
is the id of the current game, \the\c@move
gives the current move number, \WhiteToMove{w}{b}
gives w or b depending on which player currently moves. So in the 10th move of black in the game with id "mygame" this \xdef
defines a "command" \Xskak.mygame.10.b.piece
which contains the name of the piece which has been moved by black in the tenth move.
Suppose you want to define a command \foo2
. You cannot do this because 2 is not a letter. However, this construction works: \csname foo2\endcsname
. Sometimes this is useful, e.g. when you need a series of commands, \foo1
, \foo2
, etc (another way is to use roman numerals). Another example, suppose you want to define a series of commands like \endsection
, \endsubsection
, etc. Then you can use a loop with \expandafter\def\csname end#1\endcsname...
-
Thanks for your example, but can you tell me what generally their job are? When and where do I need to use them? Commented Dec 26, 2011 at 22:35
-
4Well, @egreg beat me to it. Basically a TeX command is either (1) a sequence of letters starting from
`, e.g.
\parskip, or (2) a special symbol optionally preceded by a backslash, e.g.
\@, and (3) any sequence of symbols between
\csname` and\endcsname
. So the job of these commands is to introduce a way to produce TeX commands. You do not need to use them unless you do TeX programming. In the latter case they are handy.– BorisCommented Dec 26, 2011 at 23:34 -
Short answer: \csname
and \endcsname
are a "macro environment" whose contents, if they evaluate (after expanding macros) to "ordinary text", are converted into the name of a macro (or control sequence, hence "csname").
Actually, it is a perhaps strange joke that by the rules of LaTeX macros, you can actually write \begin{csname}...\end{csname}
and it will act as you expect, to a certain extent. For example:
\def\macro{text}
\def\o{o}
\begin{csname}%
macr\o
\end{csname}
% Same as \csname macr\o \endcsname
(when run with latex
rather than tex
) will produce the word "text" in the output. The %
sign is there so that unnecessary spaces don't creep into the name of the macro we are constructing.
What exactly do
\csname
and\endcsname
do? What are their job?
Short/oversimplified story:
\csname ... \endcsname
can be used for obtaining the control-sequence-token whose name is denoted by the tokens nested between \csname
and \endcsname
.
Expansion is not suppressed but is triggered with the tokens nested between \csname
and \endcsname
.
\csname
itself is expandable.
So you can say:
Expanding the token \csname
causes TeX to remove the token \csname
and to initiate the process of gathering the name of a control-sequence-token by gathering explicit unexpandable character-tokens, hereby not suppressing but triggering expansion of expandable tokens.
A token \endcsname
that matches a preceding token \csname
is also removed and ends that process of gathering and triggers replacing the gathered explicit unexpandable
character-tokens by the corresponding control-sequence-token.
You can use macros for storing data by having macros expand to tokens, e.g., sequences of character-tokens, that represent data.
Assume you wish to systematize names of macro-tokens so that based on the names of the macro-tokens one can deduce what data are (to be) stored in them. Conversely, if you know the type of data, you wish to be able to deduce the names of the macro-tokens in which the data in question are (to be) stored.
In such situations you also need a mechanism for getting from the name of a macro-token to the macro-token itself. This is when \csname..\endcsname
is handy.
Complicated story:
Basically \csname
triggers TeX into expanding expandable tokens and keeping unexpandable explicit character-tokens until encountering
- either a matching
\endcsname
, - or a non-expandable control-sequence-token.
In the further case the resulting set of unexpandable tokens consists only of unexpandable explicit character-tokens. That set of unexpandable explicit character-tokens is taken for the name of a control-sequence-token by which that set of unexpandable explicit character-tokens is replaced.
In the latter case an error-message about inserting a missing \endcsname
is delivered and the missing \endcsname
-token is inserted before the non-expandable control-sequence-token in question. Thus the unexpandable explicit character-tokens gathered so far are taken for the name of a control-sequence-token and the corresponding control-sequence-token is delivered.
That control-sequence-token in turn is trailed by the non-expandable control-sequence-token that triggered the error-message about inserting a missing \endcsname
.
In case expansion during the process of gathering initiated by \csname
triggers an error-message, e.g., due to a control-sequence being undefined, or due to the use of a macro not matching its definition, TeX will ignore the tokens causing the error-message.
Some examples of \csname..\endcsname
-expressions:
\csname TeX\endcsname
yields the control-sequence-token \TeX
.
\csname Te\relax\endcsname
yields
- an error-message about inserting a missing
\endcsname
and - insertion of
\endcsname
before\relax
because\relax
is a non-expandable control-sequence-token.
Thus this—except for the error-message about inserting a missing \endcsname
—is like
\csname Te\endcsname\relax\endcsname
, i.e., you get the control-sequence token \Te
, trailed by \relax
, trailed by \endcsname
, whereby \endcsname
may trigger an error-message about extra-\endcsname
.
Inside \edef
/\xdef
and the like you don't get extra-\endcsname
-errors:
E.g., \edef\macro{a\endcsname}
doesn't trigger error-messages and yields that \macro
expands to the tokens a\endcsname
.
\def\macro{Te}
\csname\macro X\endcsname
yields the control-sequence-token \TeX
: \csname
is removed and triggers gathering explicit unexpandable character-tokens that represent the name of a control-sequence-token, whereby expansion of expandable tokens is not suppressed but triggered. Thus \macro
is expanded and yields Te
. Then X
is found. Then the matching \endcsname
is found. The matching \endcsname
is removed and triggers replacing the characters TeX
that were found so far by the control-sequence-token whose name is TeX
, i.e., by the control-sequence-token \TeX
. I.e., the character-tokens T
, e
, x
are removed and the control-sequence-token \TeX
is inserted.
\csname a\undefined b\endcsname
yields
- an error-message about
\undefined
being undefined and - the control-sequence-token
\ab
.
\def\delimited x{y}
\csname ab\delimited z\endcsname
yields
- an error-message about
\delimited
not matching its definition and - the control-sequence-token
\ab
.
\def\macroA{Te}
\def\macroB{X}
\csname\csname macroA\endcsname\csname macroB\endcsname\endcsname
yields the control-sequence-token \TeX
: \csname
both triggers expansion and itself is expandable and therefore \csname..\endcsname
-expressions can be nested (as long as sufficient memory is available/as long as TeX-capacities are not exceeded by having too many pending \csname..
-thingies).
\csname TeX\csname endcsname\endcsname
seems a little imbalanced at first glimpse but yields the control-sequence-token \TeX
.
If a control-sequence-token delivered by \csname..\endcsname
is undefined, it will be assigned the meaning of the \relax
-primitive (only!) within the scope where the \csname..\endcsname
-expression occurred. (This is the case even if the \globaldefs
-parameter has a positive value.)
Basic facts/tricks related to expansion:
First:
\csname
itself is expandable: The tokens forming the \csname..\endcsname
-expression are removed from the token-stream. The replacement is the control-sequence-token whose name is denoted by the \csname..\endcsname
-expression. In expansion-contexts where you wish to control the order in time in which single expansion-steps take place, triggering one expansion-step on \csname
is sufficient for obtaining that token.
Second:
Expansion is not suppressed with the tokens forming the "content" of a \csname..\endcsname
-expression.
Thus:
With subsequent \csname..\endcsname
-expressions you can have \csname..\endcsname
-expressions further ahead trigger carrying out \csname..\endcsname
-expressions further back—e.g., triggering expansion of the first \csname
in
\csname foo\expandafter\endcsname\csname bar\expandafter\endcsname\csname baz\endcsname
yields
\foo\bar\baz
.
The token \expandafter
right before the first \csname..\endcsname
-expression's \endcsname
triggers TeX into producing the expansion-result of the second \csname
before "looking" at the first \endcsname
.
The token \expandafter
right before the second \csname..\endcsname
-expression's \endcsname
triggers TeX into producing the expansion-result of the third \csname
before "looking" at the second \endcsname
.
In other words:
Due to \expandafter
occurring right before the first \csname..\endcsname
-expression's \endcsname
the second \csname..\endcsname
-expression is evaluated while evaluation of the first \csname..\endcsname
-expression is still in progress.
Due to \expandafter
occurring right before the second \csname..\endcsname
-expression's \endcsname
the third \csname..\endcsname
-expression in turn is evaluated while evaluation of the second \csname..\endcsname
-expression is still in progress.