1

This is a follow-up question to nameref With Arbitrary Text and also Refer to arbitrary text (without numbering and not by section)

To summarize, the question was about how to reference to an arbitrary point in text, with an arbitrary string; and the prevalent solution was to use

previousText 
\phantomsection 
\label{L} 
textToBeReferenced 
[...] 
\hyperref[L]{textPointingToReference}

In these questions, the authors were content with defining the textPointingToReference at the point where the reference is inserted, but in my use case, I really need to define the string textPointingToReference (or the output of \nameref, if you will) at label creation.

This is because I want to access the name of the referenced object from multiple points in the document, and if I used \hyperref[ObjectLabel]{ObjectNameExplicitlyGiven} I would need to edit all instances of \hyperref if the object name changes.

I read in the nameref documentation that \@currentlabelname was stored in the aux file when calling \label. The use of \phantomsection has no bearing on the value of \@currentlabelname, so I naively tried setting \@currentlabelname manually, as follows:

\documentclass{article}

\usepackage{hyperref}

%% outputs an object (in fact, a music score, that is a paragraph for TeX purposes) with label
\newcommand{\insertobject}[2]{
  %% #1 : reference of the object
  %% #2 : name of the object
  \makeatletter\edef\@currentlabelname{#2}\makeatother
  \phantomsection
  \label{#1}
  %% the objects I work with are music scores but this is irrelevant
  %% the commented line below would fetch and insert a music file named #1
  %\insert_music_score{#1}
  Object with reference #1 is here
}

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

\insertobject{XYZ}{Object XYZ Name}

\objectreference{XYZ}

\end{document}

And of course this does nothing, \@currentlabelname as written by \label into the aux file is still "Section Title" and not "Object XYZ Name":

enter image description here

But then, I tried substituting the code of \insertobject into the document, and lo and behold, it works:

\documentclass{article}

\usepackage{hyperref}

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

  \makeatletter\edef\@currentlabelname{Object XYZ Name}\makeatother
  \phantomsection
  \label{XYZ}
  Object with reference XYZ is here

\objectreference{XYZ}

\end{document}

enter image description here

Then I read \@currentlabelname and custom counter and, not knowing a thing about protection, I tried substituting the line in the definition of \insertobject with \makeatletter\protected@edef\@currentlabelname{#2}\makeatother and then protecting the call to \insertobject, but it just gives me the classic "You can't use a prefix with the character @" error.

Any idea on how to get this going?

New contributor
xmarteo is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • 1
    the \makeatletter/\makeatother must be outside/around the \newcommand. Jun 23 at 12:57

1 Answer 1

1

Solved by @Ulrike Fischer in the comments: "the \makeatletter/\makeatother must be outside/around the \newcommand."

The following MWE produces the intended output (second image in the question):

\documentclass{article}

\usepackage{hyperref}

%% outputs an object (in fact, a music score, that is a paragraph for TeX purposes) with label
\makeatletter
\newcommand{\insertobject}[2]{
  %% #1 : reference of the object
  %% #2 : name of the object
  \protected@edef\@currentlabelname{#2}
  \phantomsection
  \label{#1}
  %% the objects I work with are music scores but this is irrelevant
  %% the commented line below would fetch and insert a music file named #1
  %\insert_music_score{#1}
  Object with reference #1 is here
}
\makeatother

%% Macro to print a cross-reference to an object
\newcommand{\objectreference}[1]{
    See object \nameref{#1}, page \pageref{#1}%
}

\begin{document}

\section{Section Title}

Lorem Ipsum

\insertobject{XYZ}{Object XYZ Name}

\objectreference{XYZ}

\end{document}
New contributor
xmarteo is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

xmarteo is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.