1

I want to change the reference text of a label before the next page. This is can be done with multiply defining the label, but I want to get rid of the warnings.
Because labels are written to the .aux file at the end of each page, this is possible by taking a command as reference text and changing the command before the end of the page. (I use custom reference text, with a preamble given by egreg in Retrieve link caption of hidden label) :

\documentclass{article}
\usepackage{etoolbox}
\usepackage{refcount}
\usepackage{hyperref}
\makeatletter
\newcommand{\customlabel}[2]{% custom reference text
  \csname phantomsection\endcsname
  \def\@currentlabel{%
    \bartodo{\unexpanded{#2}}%
  }%
  \label{#1}%
}
\protected\def\bartodo#1{#1}
\newcommand{\checklabel}[2]{% macro not used in this example, no need to read it
  \begingroup
  \let\bartodo\detokenize
  \begingroup\edef\x{\endgroup
    \noexpand\ifstrequal{\getrefnumber{#1}}{\detokenize{#2}}}%
  \x{\aftergroup\@firstoftwo}{\aftergroup\@secondoftwo}%
  \endgroup
}
\makeatother

\begin{document}

\def\mycommand{A}%
\customlabel{mylabel}{\mycommand}%
\getrefnumber{mylabel}
\def\mycommand{B}%
\getrefnumber{mylabel}

\end{document}

which, after 2 LaTeX runs, returns B B, as desired. (I use \def instead of \(re)newcommand because eventually I will put this somewhere inside, with \global.)

Now say I want to do this two times (in reality, a 1000 times), and the label name and command name depend on some other macro, say a counter, so that the two reference texts can be edited separately:

%preamble as before
\begin{document}
\newcounter{mycounter}

\expandafter\def\csname mycommand\themycounter\endcsname{A}%
\customlabel{mylabel\themycounter}{\csname mycommand\themycounter\endcsname}%
\getrefnumber{mylabel\themycounter}
\expandafter\def\csname mycommand\themycounter\endcsname{B}%
\getrefnumber{mylabel\themycounter}
%
\stepcounter{mycounter}%
% the same:
\expandafter\def\csname mycommand\themycounter\endcsname{C}%
\customlabel{mylabel\themycounter}{\csname mycommand\themycounter\endcsname}%
\getrefnumber{mylabel\themycounter}
\expandafter\def\csname mycommand\themycounter\endcsname{D}%
\getrefnumber{mylabel\themycounter}
\end{document}

This gives D D D D while I'd expect B B D D.

What happens is that when the labels are written to the .aux file, the updated value of \themycounter is used, and not the value at the point where the label was defined.

So I'd like to expand the second \themycounter in \customlabel{mylabel\themycounter}{\csname mycommand\themycounter\endcsname} without expanding \mycommand0 (because the latter has yet to be changeable).

Bart Michels
  • 1,298
  • 2
  • 13
  • 24

1 Answers1

1

So we fix the number of \themycounter at the moment of the label definition in a macro \ctr and then use that (expanded).

\begin{document}

\newcounter{mycounter}
\newcommand{\ccclabel}[1]{\customlabel{mylabel#1}{\csname mycommand#1\endcsname}}%

\expandafter\def\csname mycommand\themycounter\endcsname{A}%
\edef\ctr{\themycounter}\expandafter\ccclabel\expandafter{\ctr}
\getrefnumber{mylabel\themycounter}
\expandafter\def\csname mycommand\themycounter\endcsname{B}%
\getrefnumber{mylabel\themycounter}
%
\stepcounter{mycounter}%
% the same:
\expandafter\def\csname mycommand\themycounter\endcsname{C}%
\edef\ctr{\themycounter}\expandafter\ccclabel\expandafter{\ctr}
\getrefnumber{mylabel\themycounter}
\expandafter\def\csname mycommand\themycounter\endcsname{D}%
\getrefnumber{mylabel\themycounter}
\end{document}