My understanding is that \@currentlabel
holds a register value. This also applies when hyperref
is used.
I was having a look at kpsewhich ltxref.dtx
when I read that \@currentlabel
handles situations when \label
is put outside of an environment (this happens when you tack them onto headings e.g. \section{blah}\label{blah}
).
Its definition is
\def\@currentlabel{}
This looks to me like effectively initializing a macro. I proceeded to review the document, source2e
, but I still do not understand \@currentlabel
.
To get a proper
\@currentlabel
we have to redefine it for the whole display. Note that we can't use\refstepcounter
as this results in\@currentlabel
getting
restored at the wrong and thus always writing the first label to the.aux
file.
What is meant by whole display?
If I create my own sectioning/heading command, is it then a requirement to include \refstepcounter{CNT}
if I want to be able to tack on \label{}
to it?
Does titlesec
automatically add \refstepcounter{CNT}
to new sectioning commands?
In the sectioning/heading definitions, there is \refstepcounter{CNT}
. This is the only connection I found to \@currentlabel
.
A referencable counter CNT is incremented by the command
\refstepcounter{CNT}
, which sets\@currentlabel == {CNT}{eval(\p@cnt\theCNT)}
. The command\label{FOO}
then writes the following on file\@auxout : \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}}
\def\refstepcounter#1{\stepcounter{#1}%
\protected@edef\@currentlabel
{\csname p@#1\endcsname\csname the#1\endcsname}%
}
It seems like magic how \subsection{subsec1}\label{subsec1}
results in \@currentlabel
equal to 1.1
:
\newlabel{subsec1}{{1.1}{1}{subsec1}{subsection.1.1}{}}
Example
\documentclass{article}
\usepackage{hyperref}
\begin{document}
\section{sec1}
\label{sec1}
\subsection{subsec1}
\label{subsec1}
\subsubsection{subsubsec1}
\label{subsubsec1}
\paragraph{par1}
\label{par1}
\section{sec2}
\end{document}
Relevant .aux
lines
\newlabel{sec1}{{1}{1}{}{section.1}{}}
\newlabel{subsec1}{{1.1}{1}{subsec1}{subsection.1.1}{}}
\newlabel{subsubsec1}{{1.1.1}{1}{subsubsec1}{subsubsection.1.1.1}{}}
\newlabel{par1}{{1.1.1.1}{1}{par1}{paragraph.1.1.1.1}{}}
Best Answer
The macro is initialized to expand to nothing, but every
\refstepcounter
command redefines it. If you have\newcounter{foo}
, then part of the job of\refstepcounter{foo}
is, after having stepped the counter, to doThe job of
\label{baz}
is to issue a command that eventually writesbut the two macros
\@currentlabel
and\thepage
will be expanded. The former is expanded immediately, the latter only at shipout time, when the\write
command to the.aux
file actually happens.Note that
\refstepcounter
only does\edef
and not\xdef
, so if\refstepcounter
happens inside a group (an environment, for instance), the value of\@currentlabel
will not survive the end of the group.Your quotation about a display refers to some workarounds that need to be made in
eqnarray
; this is not really important, becauseeqnarray
should never be used. Theamsmath
package uses different tricks for\label
inside its alignment environments.By the way, what's
\p@foo
? For standard counters it is empty, but it can be redefined for a particular counter in order to provide a prefix. This is the case forenumii
,enumiii
andenumiv
, for instance, used inenumerate
.Just to make an example. Let's see a summary of what happens with
The command
\subsection
does, before processing the sectional title,\refstepcounter{subsection}
. As said before, this redefines\@currentlabel
usingSince the definition is expanded, the current value of
\p@subsection
and\thesubsection
are stored; the former is empty, the latter, in your code, expands to\thesection.\arabic{subsection}
and, eventually to1.1
.Later
\label{subsec1}
essentially doeswhich will (approximately) translate to
as expansion of
\thepage
is neutralized during\protected@write
. The\write
operation is recorded in the main vertical list and will be executed at shipout time; only at this moment\thepage
will be expanded.It's immaterial whether you use the alternate method
because
\label
will only be processed when the title is typeset. The macro\label
just gobbles its argument during a\protected@write
, so this won't show when the argument is moved around. But this is another topic.