198

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?

1

6 Answers 6

187

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.

16
  • 2
    Braces 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.
    – egreg
    Commented 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.
    – egreg
    Commented Oct 17, 2021 at 13:27
  • 1
    @Smiley1000 It's not that it doesn't work: the space token after foo counts!
    – egreg
    Commented Jul 2 at 21:29
  • 1
    @Smiley1000 I added a final Caveat section.
    – egreg
    Commented Jul 2 at 23:46
40

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.

28

\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.

28

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...

3
  • 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
  • 4
    Well, @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.
    – Boris
    Commented Dec 26, 2011 at 23:34
  • sounds like double quotes in bash or perl Commented Mar 3, 2021 at 16:17
23

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.

2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .