2

Can I access the original label in cleveref's \crefformat? In this MWE, I am trying to get the same output as in the first line, but with the second line:

\documentclass{article}
\usepackage{hyperref}
\usepackage{cleveref}
\crefformat{section}{#2the \nameref*{#1} section#3}
\begin{document}

Please read the \nameref{sec:Introduction} section!

Please read \cref{sec:Introduction}!

\section{Introduction}
\label{sec:Introduction}

\end{document}

However, this is what I get:

line 9: Reference `1' on page 1 undefined
: There were undefined references.

This is of course not unexpected, since in \crefformat, #1 is replaced by the section number 1, as explained in the documentation. However, #2 and #3 are used for hyperlinking, and #4 does not exist, so I wonder whether, and how, I can access the original label (in this case, sec:Introduction) within \crefformat.

I guess one workaround would be a macro that returns the the nth section label, given n, but that would become messy, I suppose.

Another idea that I had is to patch cleveref, maybe to the extent such that my MWE makes sense with \section* instead of \section - because as it is, \cref{sec:Introduction} does not output anything useful (not even the or section) when the section does not have a number.

bers
  • 5,404

2 Answers2

4

As far as I know, there is no way to access the current label name directly, but it can be stored in \cref@getref (thereby changing the command slightly, say to define \@lastusedlabel.

\documentclass{article}
\usepackage{hyperref}
\usepackage{cleveref}
\makeatletter
\def\cref@getref#1#2{%
  \xdef\@lastusedlabel{#1}%
  \expandafter\let\expandafter#2\csname r@#1@cref\endcsname%
  \expandafter\expandafter\expandafter\def%
    \expandafter\expandafter\expandafter#2%
    \expandafter\expandafter\expandafter{%
      \expandafter\@firstoftwo#2}}%
\creflabelformat{section}{#2the \nameref*{\@lastusedlabel} section#3}
\makeatother
\begin{document}

Please read the \nameref{sec:Introduction} section!

Please read \cref{sec:Introduction}!

\section{Introduction}
\label{sec:Introduction}

\end{document}

enter image description here

  • 2
    I compressed your solution into \usepackage{etoolbox} \makeatletter \apptocmd{\cref@getref}{\xdef\@lastusedlabel{#1}}{}{error} \crefformat{section}{#2the \nameref*{\@lastusedlabel} section#3} \makeatother to make it future-proof, but that does not change the main idea. Thanks! – bers Jul 14 '16 at 16:13
  • @bers: future-proof is relative. A patch may also become disfunctional if the underlying command changes etc. –  Jul 14 '16 at 16:22
  • 1
    Certainly true, it is not optimal either. But if future-proof is relative, then I find that my solution is "more" future-proof :) – bers Jul 14 '16 at 16:32
  • 1
    @bers: And mine does not need an extra package ;-) –  Jul 14 '16 at 16:33
1

I found myself with a similar problem, and realised that the proposed patch is not sufficient for range-formats.

Here I made another question (I had no reputation points to comment here) seeking for a more complete approach.

Actually, it seems that I found a fully-working solution by myself.

Guido
  • 31