gusbrs / zref-clever

Clever LaTeX cross-references based on zref
LaTeX Project Public License v1.3c
11 stars 4 forks source link

`\zcref` should display the name of unnumbered objects #17

Closed dbitouze closed 1 year ago

dbitouze commented 1 year ago

The following MCE points out that \zcref doesn't display the name of unnumbered objects.

\documentclass{article}
\usepackage{amsthm}
\usepackage{zref-clever}

\newtheorem{theorem}{Theorem}
\newtheorem*{lemma}{Lemma}

\begin{document}
\begin{theorem}\zlabel{theorem}
A theorem.
\end{theorem}
Cf. \zcref{theorem} \zcpageref{theorem}.\par
Cf. \zcref[noref]{theorem} \zcpageref{theorem}.
\newpage
\begin{lemma}\zlabel{lemma}
A lemma.
\end{lemma}
Cf. \zcref[noref]{lemma} \zcpageref{lemma}
\end{document}

Indeed, though \zcpageref{lemma} gives the right page number, \zcref[noref]{lemma} doesn't display anything, and we are warned about this by the following message:

Package zref-clever Warning: Reference format option 'name-sg' undefined for (zref-clever)

which looks odd since there's no (obvious) reason for name-sg to not be defined in such a case.

It would be nice for \zcref to display the name of unnumbered objects (and BTW, to not require the user to resort the noref option for them and to automatically display only the name for such unnumbered objects).

gusbrs commented 1 year ago

Hi @dbitouze , well, this is expected behavior. The reference type is inferred from the current counter, if there's no counter, there's no (automatic) way to tell. It's the same thing with the standard referencing system. Page references always get the page where \label is called, but the reference itself is taken from the last numbered object, usually the one to have last called \refstepcounter, which sets both \@currentlabel and \@currentcounter.

If you put a section in your document, that lemma reference won't think its name is missing, but will believe it is a section, rather than a lemma. So, the reason name-sg is undefined in your document is that there's no previous (global) call to \refstepcounter. The theorem does call it once (I think), but sets \@currentcounter locally within the environment.

zref-clever lets you force the type for it:

\AddToHook{env/lemma/begin}{\zcsetup{reftype=lemma}}

But if you try a regular reference to the same label, you'll still get the wrong number. Same thing for hyperlinks, that's why \phantomsection exists. For example:

\documentclass{article}
\usepackage{amsthm}
\usepackage{zref-clever}
\usepackage{hyperref}

\newtheorem{theorem}{Theorem}
\newtheorem*{lemma}{Lemma}

\AddToHook{env/lemma/begin}{\zcsetup{reftype=lemma}}

\begin{document}
\setcounter{section}{5}
\section{Section 1}
\begin{theorem}\zlabel{theorem}
A theorem.
\end{theorem}
Cf. \zcref{theorem} \zcpageref{theorem}.\par
Cf. \zcref[noref]{theorem} \zcpageref{theorem}.
\newpage
\begin{lemma}\zlabel{lemma}
A lemma.
\end{lemma}
Cf. \zcref[noref]{lemma} \zcpageref{lemma}
\zcref{lemma} % that's the number of Section 1, and it links to Theorem 1,
              % since hyperref sets the anchors globally.
\end{document}

Regarding:

It would be nice for \zcref to display the name of unnumbered objects (and BTW, to not require the user to resort the noref option for them and to automatically display only the name for such unnumbered objects).

Again, it's the same thing as with the standard referencing system, everything is tailored to work for numbered objects. And there's a reason for it, it is really hard to know what to do in their absence.

dbitouze commented 1 year ago

Indeed, thanks!