23

Is it possible with Cleverref to reference not only the number of an environment but the "name" (the thing that is passed to it in square brackets?

In the following example I want to replace the line enter code here

Now since \Cref{boringLemma} we have that \Cref{awesomeTheorem} directly follows.

with something such that I do not get

Now since Lemma 1.1 we have that Theorem 1.2 directly follows.

but something like

Now since Boring Lemma (1.1) we have that Awesome Theorem (1.2) directly follows.
\documentclass{article}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage[amsmath]{ntheorem}
\usepackage{cleveref}

\newtheorem{thm}{Theorem}[section]
\newtheorem{lemma}[thm]{Lemma}

\crefname{lemma}{lemma}{lemmas}
\Crefname{lemma}{Lemma}{Lemmas}
\crefname{thm}{theorem}{theorems}
\Crefname{thm}{Theorem}{Theorems}

\begin{document}
\section{Boring and Awesome stuff}

\begin{lemma}[Boring Lemma]\label{boringLemma}
This is some boring statement.
\end{lemma}

\begin{thm}[Awesome Theorem]\label{awesomeTheorem}
This is a really awesome statement.
\end{thm}

Now since \Cref{boringLemma} we have that \Cref{awesomeTheorem} directly follows.

\end{document}
lockstep
  • 250,273
born
  • 332
  • 4
    Not related to the question, but don't use \Crefname in the middle of a sentence. \Crefname should only be used at the beginning of sentences. \Crefname is not the "capitalised variant" of \crefname. It is the start-of-sentence variant. It doesn't just capitalise the name, it also e.g. suppresses abbreviations. If you want capitalised reference names, use the capitalise (or capitalize) package option and/or use capitalised names in your \crefname definitions. – Toby Cubitt Nov 24 '13 at 14:34

3 Answers3

17

Loading thmtools and nameref will give you this feature. You will have to use \nameref instead of \cref, but I think most of the time it is you who is the best to decide whether it is the theorem's name or number you want to reference.

EDIT Code added with commands \myref and \Myref for single references to automatically add the name in brackets when defined.

Sample output

\documentclass{article}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage[amsmath]{ntheorem}
\usepackage{thmtools}
\usepackage{nameref,cleveref}

\newtheorem{thm}{Theorem}[section]
\newtheorem{lemma}[thm]{Lemma}

\crefname{lemma}{lemma}{lemmas}
\Crefname{lemma}{Lemma}{Lemmas}
\crefname{thm}{theorem}{theorems}
\Crefname{thm}{Theorem}{Theorems}

\makeatletter
\newcommand{\myref}[1]{\cref{#1}\mynameref{#1}{\csname r@#1\endcsname}}
\newcommand{\Myref}[1]{\Cref{#1}\mynameref{#1}{\csname r@#1\endcsname}}

\def\mynameref#1#2{%
  \begingroup
    \edef\@mytxt{#2}%
    \edef\@mytst{\expandafter\@thirdoffive\@mytxt}%
    \ifx\@mytst\empty\else
    \space(\nameref{#1})\fi
  \endgroup
}
\makeatother

\begin{document}
\section{Boring and Awesome stuff}

\begin{lemma}\label{noname}
  Extremely important lemma that has no name.
\end{lemma}

\begin{lemma}[Boring Lemma]\label{boringLemma}
  This is some boring statement.
\end{lemma}

\begin{thm}[Awesome Theorem]\label{awesomeTheorem}
  This is a really awesome statement.
\end{thm}

Now since \Cref{boringLemma} we have that \Cref{awesomeTheorem}
directly follows.  Alternatively, we see that \nameref{boringLemma}
leads directly to \nameref{awesomeTheorem}.

Finally we see that \Myref{boringLemma} and \Myref{awesomeTheorem}
have names whereas \Myref{noname} is unnamed despite its indisputable
importance.

\end{document}
Andrew Swann
  • 95,762
  • Is it possible to redefine Cref to have this behaviour? This would mean that Cref is the only referencing command needed throughout the document. – oliversm Jun 14 '18 at 11:20
  • @oliversm You could load the package letltxmacro, set \LetLtxMacro{\oldcref}{\cref} and \LetLtxMacro{\oldCref}{\Cref} and then renew \cref and \Cref via \renewcommand{\cref}[1]{\oldcref{#1}\mynameref{#1}{\csname r@#1\endcsname}} etc., but then you may loose some other functionality of \cref. – Andrew Swann Jun 14 '18 at 15:08
  • Note that the intended feature is virtually impossible to achieve in other languages. In German, a reference to „Lemma (langweiliges Lemma)“ might need to come out as „Mit dem langweiligen Lemma folgt, dass das langweilige Lemma eine Konsequenz des langweiligen Lemmas ist.“ At most the variant with name in parentheses might work internationally. – Hagen von Eitzen Apr 30 '22 at 09:18
6

Andrew Swann's answer is a nice solution. If you always include the "Lemma" in your lemma names etc (as in "Boring Lemma" and "Awesome Theorem"), then the following modification of Andrew's code will produce exactly the formatting you asked for:

\makeatletter
\newcommand{\myref}[1]{%
  \begingroup%
    \edef\@mytxt{\csname r@#1\endcsname}%
    \edef\@mytst{\expandafter\@thirdoffive\@mytxt}%
    \ifx\@mytst\empty\relax%
      \cref{#1}%
    \else%
      \nameref{#1}~\labelcref{#1}%
    \fi%
  \endgroup}
\newcommand{\Myref}[1]{%
  \begingroup%
    \edef\@mytxt{\csname r@#1\endcsname}%
    \edef\@mytst{\expandafter\@thirdoffive\@mytxt}%
    \ifx\@mytst\empty\relax%
      \Cref{#1}%
    \else%
      \nameref{#1}~\labelcref{#1}%
    \fi%
  \endgroup}
\makeatother

If you omitted the "Lemma" from the lemma names etc, which is also common (just calling it "Boring" instead of "Boring Lemma" and "Awesome" instead of "Awesome Theorem"), then you'd need something like this instead:

\makeatletter
\newcommand{\myref}[1]{%
  \begingroup%
    \edef\@mytxt{\csname r@#1\endcsname}%
    \edef\@mytst{\expandafter\@thirdoffive\@mytxt}%
    \ifx\@mytst\empty\relax%
      \cref{#1}%
    \else%
      \nameref{#1} \cref{#1}%
    \fi%
  \endgroup}
\newcommand{\Myref}[1]{%
  \begingroup%
    \edef\@mytxt{\csname r@#1\endcsname}%
    \edef\@mytst{\expandafter\@thirdoffive\@mytxt}%
    \ifx\@mytst\empty\relax%
      \Cref{#1}%
    \else%
      \nameref{#1} \cref{#1}%
    \fi%
  \endgroup}
\makeatother
Toby Cubitt
  • 2,072
2

The package ntheorem and the corresponding label doens't write the name of the environment to the aux file. So you can't use the label name of the environment. A small fix by using hyperref is:

\makeatletter
\def\@ythm#1#2#3[#4]{\def\@currentlabelname{#4}%
  \expandafter\global\expandafter\def\csname#1name\endcsname{#4}%
  \@opargbegintheorem{#3}{\csname the#2\endcsname}{#4}%
  \ifx\thm@starredenv\@undefined
    \thm@thmcaption{#1}{{#3}{\csname the#2\endcsname}{#4}}\fi
  \ignorespaces}
\DeclareRobustCommand{\Gref}[1]{\nameref{#1}\ \ref{#1}}
\makeatother

So you can use the command \Gref as usual. I am sure that Heiko has a better definition of \Gref.

\documentclass{article}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage[amsmath]{ntheorem}
\usepackage{hyperref}
\usepackage{cleveref}
\makeatletter
\def\@ythm#1#2#3[#4]{\def\@currentlabelname{#4}%
  \expandafter\global\expandafter\def\csname#1name\endcsname{#4}%
  \@opargbegintheorem{#3}{\csname the#2\endcsname}{#4}%
  \ifx\thm@starredenv\@undefined
    \thm@thmcaption{#1}{{#3}{\csname the#2\endcsname}{#4}}\fi
  \ignorespaces}
\DeclareRobustCommand{\Gref}[1]{\nameref{#1}\ \ref{#1}}
\makeatother

\newtheorem{thm}{Theorem}[section]
\newtheorem{lemma}[thm]{Lemma}

\crefname{lemma}{lemma}{lemmas}
\Crefname{lemma}{Lemma}{Lemmas}
\crefname{thm}{theorem}{theorems}
\Crefname{thm}{Theorem}{Theorems}

\begin{document}
\section{Boring and Awesome stuff}\label{sec}

\begin{lemma}[Boring Lemma]\label{boringLemma}
This is some boring statement.
\end{lemma}

\begin{thm}[Awesome Theorem]\label{awesomeTheorem}
This is a really awesome statement.
\end{thm}

Now since \Cref{boringLemma} we have that \Cref{awesomeTheorem} directly follows.

Now since \nameref{boringLemma} we have that \nameref{awesomeTheorem} directly follows.

Now since \Gref{boringLemma} we have that \Gref{awesomeTheorem} directly follows.

\end{document}
Marco Daniel
  • 95,681