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?
[Tex/LaTex] What exactly do \csname and \endcsname do
macrostex-core
Related Solutions
Let's look at the simplest case
\hbox to \hsize{<horizontal material>}
Among the <horizontal material>
there will be also glue, implicit (that is, space tokens) or explicit (\hskip
commands).
TeX maintains two four dimensional vectors in order to compute the glue ratio, say v for the stretching and w for the shrinking. A glue such as
\hskip 4pt plus 2pt minus 1pt
contributes 2pt to the first component of v and 1pt to the first component of w. A glue such as
\hskip 6pt plus 1fil minus 0.5fill
contributes 1 to the second component of v and 0.5 to the third component of w. At the end we'll have
v=(finite, first order infinite, second order infinite, third order infinite)
and similarly for w, where the components are the sum of all contributions. TeX also maintains the sum of the natural widths of characters, boxes and glues in the <horizontal material>
.
When TeX has finished gathering the material for the \hbox
, it compares the natural width to the desired box width (in our example to \hsize
) and decides what to do. If the natural width is equal to the desired width, it typesets the box. Otherwise it decides that it has to stretch or shrink the glue. In the former case it looks at v and in the latter to w.
Let's look at the stretching case (the other is similar). If v is zero, there' little to do: there's no glue or the glues all cancel with each other: the box will be underfull.
Otherwise one entry in v will be different from zero; TeX will choose the rightmost non-zero component. This is the order of infinity that wins (it may be the "finite" component). The excess space to fill is then distributed proportionally among the glues that contributed that order of infinity.
Let's look at some examples
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fil minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
The box must stretch by 3cm (it's a convenient syntax for doing experiments of this kind), so we have to compute v=(2pt,3,0,0). The first-order infinity wins, so the excess space will be divided adding 1cm between B and C, and 2cm between C and D; between A and B there will be a 4pt wide space (no stretching). The result is ( denotes the resulting space)
A<4pt>B<4pt+1cm>C<4pt+2cm>D
Let's see with
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fill minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
Here v=(2pt,2,1,0), so the second-order infinity wins and the 3cm wide space will go between B and C:
A<4pt>B<4pt+3cm>C<4pt>D
Third order infinities are rarely used, but they are there for emergency cases when one has to cancel second order infinities.
The coefficient before fil(ll)
should be a decimal number less than 16384 in absolute value (there must be one). The minimum non-zero value is 2^(-16)=0.000015
, so saying 0.000014filll
is equivalent to say 0filll
(and useless, of course).
TeX has some primitives equivalent to glue specifications:
\hfil = \hskip 0pt plus 1fil minus 0pt
\hfilneg = \hskip 0pt plus -1fil minus 0pt
\hss = \hskip 0pt plus 1fil minus 1fil
\hfill = \hskip 0pt plus 1fill minus 0pt
The same algorithm is used for shrinking, but no glue will be stretched to become less than its natural width, while all glues may be used for stretching (possibly resulting in an underfull box). The same holds for vertical boxes.
\newlength
is the LaTeX2e version of \newskip
. It has extra check to avoid redefinition or illegal name. In LaTeX2e, it is defined
\def\newlength#1{\@ifdefinable#1{\newskip#1}}
For example,
\newlength\foo % OK
\newlength\foo % redefinition ERROR!
\newlength\endbar % ERROR: \endbar is illegal command name in LaTeX2e.
% It is reserved by LaTeX kernel to define bar environment together with \bar
\newskip
only allocates a new skip (glue, or rubber space) register. If you use low-level TeX command \newskip
instead, no error message will be shown.
You should always use \newlength
rather than \newskip
in LaTeX.
\newdimen
is another low-level TeX macro that allocates a new dimension register, it is different with \newskip
. They have different meaning. For example,
\newdimen\rigidlength
\rigidlength=2pt % or \setlength{\rigidlength}{2pt}
\newlength\rubberlength % you cannot use \newdimen here
\setlength{\rubberlength}{2pt plus 2pt minus 1pt}
Best Answer
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 isso 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 onfoo
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 sayand 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
is forbidden. But, after
\def\xyz{abc}
,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. Sowill give an error (Missing
\endcsname
); in\csname ^^@\endcsname
there will be no character and\csname ^^?\endcsname
will raise an error.