[texhax] constructing labels from counters

Uwe Lück uwe.lueck at web.de
Fri Jul 28 21:12:26 CEST 2006


At 10:02 27.07.06, Moshe Kamensky wrote:

>I would like to construct a label for \label and \ref from a counter, so
>that I can do something like
>
>\newcommand{\foo}{\stepcounter{foo}\label{bar:\value{foo}}...}
>
>But the above example using \value doesn't work, nor when I replace it
>by, say, \alph{foo}. Is there a way to achieve this?

/Short answer:/ Try

     \newcommand{\foo}{%
       \stepcounter{foo}%
       \edef\thelabel{\noexpand\label{bar:\thefoo}}%
       \thelabel}

Here, \thefoo is the ordinary LaTeX way; however,
(i) \edef is not LaTeX, (ii) \thefoo may break with certain
complex (re-)definitions of \thefoo; in the latter case
replacing \edef by \protected at edef -- inside \makeatletter ...
\makeatother -- (and \noexpand by \protect) may help.

/Expanded answer:/

I feel I am the expert who has been asked since my ednotes bundle
does this at at least two points. The problem may be difficult to
understand from a mere LaTeX point of view, this understanding
may require knowing something about the underlying program TeX.
(The ednotes package originated when Christian Tapp, then knowing
about LaTeX only, asked me similar questions. To learn what TeX
does beyound LaTeX, I can't refer to something better than
D. Knuth's The TeXbook, while there are alternatives.)

You want that your \label command uses the value of the
`foo' counter that your \stepcounter brought about.

One problem of your approach is that, probably counter to your
expectation, \value{foo} does (in general) /not/ produce the
value of the `foo' counter. I consider this a didactical shortcoming
of LaTeX. I suppose that LaTeX's \value can't be understood
without knowing how it communicates with the TeX program.
(You probably get the `\endcsname inserted' error with mere \value.)

Rather, \thefoo produces the value. However, \thefoo may
-- due to some strange (re-)definitions, produce things that
don't concern the /value/, rather the design of how to print it.
(This may as well result in the `\endcsname inserted' error.)
To get the value only indeed, \the\value{foo} is more robust.
(\the is not LaTeX, but primitive TeX.)

Moreover, you need that your \label writes something
into the .aux file that uses the value of the `foo' counter
that your \stepcounter brought about. However, the \label
command first only stores a part of its input and writes
something to the .aux file only when -- in general --
your `foo' counter has got a larger value than the one
originating from your original \foo command.
\edef or \protected at edef ensures that the /current/ value
of the `foo' counter will be used in writing indeed.

Sometimes the TeX primitive \expandafter is more
reliable than \edef or \protected at edef -- instead of
expanding entirely, it just expands some token /for
one step/ before a preceding token is processed.

Hope this helps,

Uwe.



More information about the texhax mailing list