2

In this question a solution is proposed to patch cleveref \crefformat in order to give access to the last used label.

Unfortunately, it seems that the patch is not sufficient to handle cases where multiple labels are given as argument to a single \cref{} command. In particular, range formats seem to be problematic.

How can I handle all cases?

Here is a MWE (well, minimal enough):

\documentclass{article}
\usepackage{cleveref}
\usepackage{etoolbox}

\makeatletter
\xdef\@curr@label{?}
\apptocmd{\cref@getref}
    {%
        \xdef\@curr@label{#1}%
    }%
    {}{error}

\newrobustcmd{\mytag}{%
    \textsuperscript{%
        \ensuremath{\to}%
        \cpageref{\@curr@label} 
        (\@curr@label)%
    }%
}

\creflabelformat{section}{#2#1#3\mytag{\@curr@label}}%
\makeatother

\begin{document}
\section{Section 1}\label{sec:1}\ldots\clearpage
\section{Section 2}\label{sec:2}\ldots\clearpage
\section{Section 3}\label{sec:3}\ldots\clearpage
\section{Section 4}\label{sec:4}\ldots\clearpage
\section{Section 5}\label{sec:5}\ldots\clearpage
\section{Section 6}\label{sec:6}\ldots\clearpage
\section{Section 7}\label{sec:7}\ldots\clearpage

\section{Test}\label{sec:test}
\begin{itemize}
    \item Single cref: \cref{sec:1}
    \item Already-sorted range cref: \cref{sec:1,sec:2,sec:3,sec:4}
    \item To-be-sorted range cref: \cref{sec:3,sec:2,sec:1,sec:4}
    \item To-be-sorted multi-range cref: \cref{sec:5,sec:1,sec:3,sec:2,sec:7,sec:6}
\end{itemize}
\end{document}

This produces (I'm showing only the page with section "Test"):

Excerpt from page 8

It can be seen that the highlighted labels, as captured by the patched \cref@getref, are wrong, as they correspond to the labels of the last section in each range.

My current goal is to show pointers to the page of each \cref. However, I believe that having access to the all labels as long as they are processed by \cref (that is after sorting and compression) would be extraordinarily useful for many purposes.

Thanks!

1
  • Welcome to TeX.SE!
    – Mico
    Commented Jan 6, 2020 at 22:52

1 Answer 1

1

I found a possible solution. I post it here as a candidate answer, hoping to help others.

Clearly, the ideal approach would be to have a native access to each label given to \cref commands. I hope this feature will be added soon.

Anyway, by looking into the source code of the cleveref package, it seems that only the last two used labels are needed to handle all cases.

Hence, we can simply patch \@cref@getref to enable storing of the last two seen labels (in two distinct macros).

\documentclass{article}
\usepackage{cleveref}
\usepackage{etoolbox}

\makeatletter
\xdef\@curr@label@prev@last{a?}
\xdef\@curr@label@last{b?}
\apptocmd{\cref@getref}
    {%
        \xdef\@curr@label@prev@last{\@curr@label@last}%
        \xdef\@curr@label@last{#1}%
    }%
    {}{error}


\newrobustcmd{\mytag}[1]{%
    \textsuperscript{%
        \ensuremath{\to}%
        \cpageref{#1} 
        (#1)%
    }%
}

\creflabelformat{section}{#2#1#3\mytag{\@curr@label@last}}%
\crefrangelabelformat{section}{%
    #3#1#4\mytag{\@curr@label@prev@last} 
    to~#5#2#6\mytag{\@curr@label@last}}%
\makeatother

\begin{document}
\section{Section 1}\label{sec:1}\ldots\clearpage
\section{Section 2}\label{sec:2}\ldots\clearpage
\section{Section 3}\label{sec:3}\ldots\clearpage
\section{Section 4}\label{sec:4}\ldots\clearpage
\section{Section 5}\label{sec:5}\ldots\clearpage
\section{Section 6}\label{sec:6}\ldots\clearpage
\section{Section 7}\label{sec:7}\ldots\clearpage

\section{Test}\label{sec:test}
\begin{itemize}
    \item Single cref: \cref{sec:1}
    \item Already-sorted range cref: \cref{sec:1,sec:2,sec:3,sec:4}
    \item To-be-sorted range cref: \cref{sec:3,sec:2,sec:1,sec:4}
    \item To-be-sorted multi-range cref: \cref{sec:5,sec:1,sec:3,sec:2,sec:7,sec:6}
\end{itemize}
\end{document}

which correctly produces:

Excerpt from page 8

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .