I'm trying to associate some text (dynamically generated with counters) to a label, so that I can refer to that label and print the text associated(without re-generating it, that would cause problems with counters).
Example of usage:
\textLabel{key}{\dynamicText}
Somewhere, after, in the document i want to have a new macro that links to key and displays the text generated by \dynamictext.
This macro does not quite work:
\makeatletter
\newcommand{\textLabel}[2]{%
\protected@edef\var{\expandafter\noexpand#2}%
\label{#1}\var%
\global\expandafter\def\csname#1\endcsname{\hyperref[#1]{\var}}%
}
\makeatother
The macro \var
seems to work just fine.
The problem is that the macro identified with \#1
is nor visible in the document, and produces an error (control sequence not found).
Where am I goingwrong?
Context:
I have a long list of items that need an unique ID in some strange format.
I'm automatically generating the ID for the items in the list, with a call to a macro that increases some counters and returns the IDs in function of the values of the counters.
Now, I want to write the IDs generated and refer to the items, without the need of recall the macro used to build them. (It would mean to call the \getID
in the same order and number of times, and I don't want it)
Here a minimal (not) working example:
\documentclass[11pt]{report}
\makeatletter
\newcommand{\textLabel}[2]{%
\protected@edef\var{\expandafter\noexpand#2}%
\label{#1}\var%
\global\expandafter\def\csname #1\endcsname{\hyperref[#1]{\var}}
}
\makeatother
\newcounter{req}
\newcommand{\getid}[1]{%
\stepcounter{req}%
#1.\arabic{req}%
}
\begin{document}
\begin{itemize}
\item \textLabel{itemkeyone}{\getid{ITEM}}
\item \textLabel{itemkeytwo}{\getid{ITEM}}
\end{itemize}
\itemkeyone %I want: ITEM.1, instead produces command not found
\end{document}
Here a minimal working example, but with the wrong behaviour:
\documentclass[11pt]{report}
\usepackage{hyperref}
\newcommand{\textLabel}[2]{%
\label{#1}#2%
\global\expandafter\def\csname#1\endcsname{\hyperref[#1]{#2}}
}
\newcounter{req}
\newcommand{\getid}[1]{%
\stepcounter{req}%
#1.\arabic{req}%
}
\begin{document}
\begin{itemize}
\item \textLabel{itemkeyone}{\getid{ITEM}}
\item \textLabel{itemkeytwo}{\getid{ITEM}}
\end{itemize}
\itemkeyone %I want: ITEM.1, instead produces ITEM.3
\end{document}
Thank you very much
Best Answer
Here is a completely different approach using pgfkeys. With all of the comments the code is longer than Manuel's so pehaps I can't claim simplicity, but I just like using pgfkeys for things like this.
To show that it works here's what my code produces:
...and here is the code:
Edit: Solution II
I realised that this is all overkill: you should just be using LaTeX's
\label
and\ref
commands. When you create a label what happens is that the current value of\@currentlabel
is written to the aux file and this is then accessible on the next compile using\ref
. So if you set\@currentlabel
to the output of\getID
then you are done. You can't, however, set\@currentlabel
equal to\getID{item}
because the\getID
command contains some unexpandable stuff. Instead you should make\getID
set a dummy variable or, better still, set\@currentlabel
.Here is a second solution based on your MWE:
As this is using
\label
and\ref
behind the scenes the labels will persist from one compile to the next but you will need to compile the document twice before it takes effect.Here's the output: