# Cross reference to any counter

I guess \ref{Label} returns the last counter found where the \label{Label} appeared?

Is it possible to get any value of another counter at that point? \pageref returns the page number, how to get one counter I have made?

• not really, \label records the current reference number and the page number at that point it doesn't really "know" which counter is being saved, so if you set your counter with \refstepcounter{mycount} then a following \label will use that value. – David Carlisle Aug 5 '18 at 17:09

Not really the last counter: \label{foo} will refer to the last counter that is stepped using \refstepcounter in the same scope as \label.

An error that I've seen a few times is

\begin{figure}
\begin{center}
\includegraphics{whatever}
\caption{The caption text}
\end{center}
\label{foo}
\end{figure}


This is wrong for several reason, but in this case it serves to illustrate the point above: the center environment is the scope where the figure counter is stepped (as a side-effect of \caption), but \label is outside this scope, so it won't refer to the figure number.

The mechanism works this way: \refstepcounter{figure} does two things

1. \stepcounter{figure} (a global operation) that steps the figure counter
2. \edef\@currentlabel{\thefigure}

Note that the second part is a local redefinition; \@currentlabel is the internal macro where the last “refstepped” counter is saved.

If you want \label to refer to fredcounter, you have to issue \refstepcounter{fredcounter} somewhere and ensure that \label{foo} appears before any other counter is “refstepped” (by commands such as \section, \caption or \item) and in the same scope.

• When using the hyperref-package, you have fun: It does redefine \@currentHref (last anchor name) globally. When placing a label right behind the \endgroup or closing brace or whatever of a local scope, the textual phrase will denote the value of the last counter 'refstepped' before that local scope was opened up while the hyperlink will lead to the last element of sectioning that occurred inside that local scope. (I get many pdf-papers to read where people didn't realize that hyperlinks go to other sections than denoted by the textual phrase. Maybe they did realize but didn't care. ;-) ) – Ulrich Diez Aug 6 '18 at 17:26

I have absolutely no clue why you would ever need to have access to the values all counters had when placing a label.

I suppose learning about how the \label..\ref-mechanism works in LaTeX might help you reconsidering your wish.

Just a few weeks ago there was a question here on TeX - LaTeX StackExchange "How to prevent reference to enumeration inside new environment?" where I saw the opportunity of elaborating on the ways in which things related to the \label..\ref-mechanism interact in LaTeX 2ε. My answer from back then can be found here: https://tex.stackexchange.com/a/442118/118714

In case you already know about the details of the \label..\ref-mechanism and have good reason to stick to your wish, I've provided an example below, outlining the way in which one might probably approach the matter.

The gist of the idea is:

The LaTeX2e-kernel-macro \cl@@ckpt, which is used for the \include..\includeonly-feature, does hold an \@elt{⟨countername⟩}-list with the names of all counters created via \newcounter.

When using Heiko Oberdiek's zref-package, you can easily use that list for defining a referenceable property for each counter.

You need to distinguish between counters whose values are set immediately and counters whose values are set/adjusted when the output-routine ships out the page in question.

Thus with the example below I did not implement that as I didn't see a reason for guessing what kind of workflow would be needed with that.

\documentclass{article}
\usepackage{zref}
\makeatletter
%%-------------------------------------------------------------------------
%% Paraphernalia:
%%.........................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@temp{}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%%
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-------------------------------------------------------------------------
%% Check whether argument contains no \relax-token on top-brace-level:
%%.........................................................................
%% \UD@CheckWhetherNoRelax{<Argument which is to be checked>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does not contain \relax>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does contain \relax>}%
\newcommand*\UD@RemoveToRelax{}\long\def\UD@RemoveToRelax#1\relax{}%
\newcommand\UD@CheckWhetherNoRelax[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@RemoveToRelax#1\relax}%
}%
%%-------------------------------------------------------------------------
%% Fork depending on strings being "page", "abspage", i.e., the names
%% of counters whose values are not set immediately but at
%% page-shipout-time:
%%.........................................................................
\newcommand*\UD@@ForkDelayedCounter{}%
% Manually add the names of more counters whose values are not set immediately
% but at page-shipout-time.
\long\def\UD@@ForkDelayedCounter%
#1\relax page\relax abspage\relax#2#3\relax\relax\relax{#2}%
\newcommand\UD@ForkDelayedCounter[1]{%
\UD@CheckWhetherNoRelax{#1}{%
\UD@@ForkDelayedCounter
\relax#1\relax abspage\relax{\UD@firstoftwo}%<-page-counter
\relax page\relax#1\relax{\UD@firstoftwo}%<-abspage-counter
\relax page\relax abspage\relax{\UD@secondoftwo}%<-counter other than both page and abspage
\relax\relax\relax
}{\UD@secondoftwo}%<-\relax-token in counter name. This should not happen.
}%
%%-------------------------------------------------------------------------
%% At the beginning of the document-environment, when all counter-defining
%% should be done, create a new property list holding all counter values:
%%  (The LaTeX2e-kernel-macro \cl@@ckpt which is used for the
%%   \include/\includeonly-feature does hold an \@elt{<countername>}-list
%%   with the names of all counters created via \newcounter.)
%%.........................................................................
\zref@newlist{UD@AllCounterValues}%
\newcommand\UD@CounterValueAsProperty[1]{%
\UD@ForkDelayedCounter{#1}{%
\zref@newprop*{Ref#1}{\csname the#1\endcsname}%
}{%
\zref@newprop{Ref#1}{\csname p@#1\endcsname\csname the#1\endcsname}%
}%
}%
\newcommand*\UD@AllCounterValuesAsProperties{%
\let\UD@temp=\@elt
\let\@elt=\UD@CounterValueAsProperty
\cl@@ckpt
\let\@elt=\UD@temp
}%
\AtBeginDocument{\UD@AllCounterValuesAsProperties}%
%%-------------------------------------------------------------------------
%% Create referencing and label commands:
%%.........................................................................
\newcommand*\AllCounterValuesLabel[1]{%
\@bsphack
\zref@labelbylist{#1}{UD@AllCounterValues}%
\@esphack
}%
\newcommand*\CounterValueRef[2]{%
\zifrefundefined{#1}{%
\zref@refused{#1}\nfss@text{\reset@font\bfseries??}%
}{%
\zref@extractdefault{#1}{Ref#2}{%
\@latex@warning{%
Reference #1' on page \thepage\space does not hold a value of counter #2%
}%
\nfss@text{\reset@font\bfseries??}%
}%
}%
}%
\makeatother

\newcounter{mycounter}

\newcommand\DoSomethingWithMycounter{%
\stepcounter{mycounter}%
\texttt{mycounter} has the value \number\value{mycounter}.
}%

\begin{document}
\section{A section}
Some text
\subsection{A subsection}
Some text
\subsection{Another subsection}
\subsubsection{A subsubsection}
\subsubsection{Another subsubsection}
\subsubsection{Yet another subsubsection}
\begin{enumerate}
\item Item 1
\item Item 2
\item Item 3
\item Item 4\par
\DoSomethingWithMycounter\par
\DoSomethingWithMycounter\par
\AllCounterValuesLabel{MyNiceLabel}%
\end{enumerate}

\newpage

\section*{Referencing:}

\hskip\parindent
At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@section\thesection! expanded to:
\CounterValueRef{MyNiceLabel}{section}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@subsection\thesubsection! expanded to:
\CounterValueRef{MyNiceLabel}{subsection}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@subsubsection\thesubsubsection! expanded to:
\CounterValueRef{MyNiceLabel}{subsubsection}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@enumi\theenumi! expanded to:
\CounterValueRef{MyNiceLabel}{enumi}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@mycounter\themycounter! expanded to:
\CounterValueRef{MyNiceLabel}{mycounter}
\bigskip

\end{document}
`