Creating several ways of referencing for just one type of label

Here is another possible solution.

I'm using the cleveref package, which defines macros that automatically format references. With this package, \Cref{<some section>} will produce "Section ⟨number⟩" and, if you are using amsthm, \Cref{<some theorem>} will produce "⟨theorem type⟩ ⟨number⟩".

I've made some modifications that allow you to reference items in the statement environment (and their names) in two ways.

  • I'm using the package enumitem (which you also appear to use) to define the statement environment and I've set it up so that the label that is written to the aux file is actually of the form \@twolabels{(i)}{1.1~(i)}.
  • I've defined \@twolabels as \@firstoftwo, so that \@twolabels{(i)}{1.1~(i)} expands to (i). Thus, when you expand \ref{Test<n>} the output will be (i).
  • When you call \refWithTheorem{Test<n>}, \@twolabels is temporarily redefined to \@secondoftwo, after which \ref{Test<n>} is called. You will thus see the second part of the label, which contains the number of the surrounding theorem.
  • At the start of the statement environment, I tell cleveref that the type corresponding to the statementi counter is \@twolabels{statementi}{<the type of the surrounding environment>}.
  • The macro \CrefWithTheorem is defined as \refWithTheorem: it redefines \@twolabels to \@secondoftwo and then calls \Cref.

Here is the code:

\documentclass{article}

\usepackage{amsthm}
\usepackage{enumitem} %% For \newlist
\usepackage{hyperref}
\usepackage{cleveref} %% For \Cref,\cref. You may or may not want to add [capitalize]

%% Defining the statement environment
\newlist{statement}{enumerate}{1}
%% Set ref to a pair consisting of the statement label and the combined label, with \@twolabels in front
\setlist[statement]{label=(\roman*),ref=\doublelabel{(\roman*)},before=\setcrefdoublealias}
%% Teaching cleveref about the name of this environment
\crefname{statementi}{statement}{statements} %% arguments are: name of counter, singular name, plural name

\makeatletter
%% \doublelabel defines a label of the form \@twolabels{<current>}{<previous>~<current>}
\newcommand*\doublelabel[1]{\protect\@twolabels{#1}{\@currentlabel~#1}}
%% \@twolabels causes the first label to be shown by default
%% It can be redefined to \@secondoftwo to retrieve the other label
\let\@twolabels\@firstoftwo

%% Telling cleveref that statementi is an alias for either itself or for the surrounding environment
%% (Which it is depends on how \@twolabels is defined)
\def\setcrefdoublealias{%
  \begingroup\edef\x{\endgroup%
    \noexpand\crefalias{statementi}{%
      \noexpand\protect\noexpand\@twolabels%
        {statementi}{\expandafter\@extractcounterfromcreflabel\cref@currentlabel\end@extractcounterfromcreflabel}%
    }%
  }\x%
}
%% Extracts the environment name from \cref@currentlabel (which is of the form "[<counter name>]<other stuff>")
\def\@extractcounterfromcreflabel[#1]#2\end@extractcounterfromcreflabel{#1}

%% For defining WithTheorem versions of ref, cref, etc.
\newcommand*\versionWithTheorem[1]{\@ifstar{\versionWithTheorem@aux{#1*}}{\versionWithTheorem@aux{#1}}}
\newcommand*\versionWithTheorem@aux[2]{\begingroup\let\@twolabels\@secondoftwo#1{#2}\endgroup}
\makeatother

% % Versions of \ref and \Cref that include the surrounding environment name/label
\DeclareRobustCommand*\refWithTheorem{\versionWithTheorem\ref}
\DeclareRobustCommand*\CrefWithTheorem{\versionWithTheorem\Cref}
\DeclareRobustCommand*\crefWithTheorem{\versionWithTheorem\cref}
\DeclareRobustCommand*\nameCrefWithTheorem{\versionWithTheorem\nameCref}
\DeclareRobustCommand*\namecrefWithTheorem{\versionWithTheorem\namecref}

%% Theorem definitions
\newtheorem{theorem}{Theorem}[section]
\newtheorem{lemma}[theorem]{Lemma}

\begin{document}

\section{A section}
\begin{theorem}
        \begin{statement}
        \item Test \label{Test1} 
        \item Test \label{Test2}
    \end{statement}
\end{theorem}
\begin{lemma}
    \begin{statement}
        \item Test \label{Test3}
        \item Test \label{Test4}
        \item Test \label{Test5}
    \end{statement}
\end{lemma}

\Cref{Test1}

\CrefWithTheorem{Test2}

\ref{Test3},

\refWithTheorem{Test4}

\CrefWithTheorem{Test5}

%% Support for referencing multiple labels at once
%% To also capitalise "lemma", use "\usepackage[capitalize]{cref}" above
Bonus (plural): \CrefWithTheorem{Test1,Test5,Test2}

%% Support for starred versions
Bonus (unlinked): \CrefWithTheorem*{Test4}

\end{document}

And here is the output:

enter image description here

Edit: Fixed a silly bug, don't use the old version.

Edit: Apparently \setlist has a before key, which makes using \AtBeginEnvironment (and loading etoolbox) unnecessary. Also added support for the starred (unlinked) versions of \ref, \cref and \Cref

Edit: Removed trailing \makeatletter (oops)


More sophisticated reference problems require more sophisticated tools for generation of cross-referencing information.

zref is such a powerful tool. It has the property features which allows for storing additional information.

I have defined 3 properties:

  • envname, which stores the outer environment name, e.g. Theorem or Lemma
  • theorem → stores the theorem number as output by \thetheorem
  • lemma → similar to theorem, stores \thelemma.

The macros

  • \reference
  • \referencewithTheorem
  • \labelreference
  • \labelreferencewithTheorem

all extract the relevant information written by \zlabel and show the information as desired.

\zlabel is done automatically by using the \crtprelabelhook.


\documentclass{article}

\usepackage{amsthm}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage[user,counter,hyperref]{zref}
\usepackage{hyperref}

\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{lemma}[theorem]{Lemma}


\usepackage{crossreftools}

\newlist{statement}{enumerate}{1}
\setlist[statement,1]{label={(\roman*)}}


\makeatletter
\providecommand{\@lastouterenv}{}

\zref@newprop{envname}[-1]{\@lastouterenv}

\zref@newprop{Lemma}[-1]{\thelemma}
\zref@newprop{Theorem}[-1]{\thetheorem}


\zref@addprops{main}{envname,Lemma,Theorem}


\renewcommand{\crtprelabelhook}[1]{%
  \zlabel{#1}%
}

\AtBeginEnvironment{theorem}{\renewcommand{\@lastouterenv}{Theorem}}
\AtBeginEnvironment{lemma}{\renewcommand{\@lastouterenv}{Lemma}}



\newcommand{\reference}[1]{%
  \zref@ifrefundefined{#1}{}{%
    Statement \hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{default}}%
  }%
}

\newcommand{\labelreference}[1]{%
  \zref@ifrefundefined{#1}{}{%
    \hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{default}}%
  }%
}


\newcommand{\referencewithTheorem}[1]{%
  \zref@ifrefundefined{#1}{%
  }{%
    \zref@extract{#1}{envname}~\hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{\zref@extract{#1}{envname}} \zref@extract{#1}{default}}%
  }%
}

\newcommand{\labelreferencewithTheorem}[1]{%
  \zref@ifrefundefined{#1}{%
  }{%
    \hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{\zref@extract{#1}{envname}} \zref@extract{#1}{default}}%
  }%
}


\makeatother


\begin{document}
    \section{A section}
    \begin{theorem}
        \begin{statement}
            \item Test \label{Test1}
            \item Test \label{Test2}
        \end{statement}
    \end{theorem}
    \begin{lemma}
        \begin{statement}
            \item Test \label{Test3}
            \item Test \label{Test4}
            \item Test \label{Test5}
        \end{statement}
    \end{lemma}

    \reference{Test1}%

    \referencewithTheorem{Test1}

    \labelreference{Test3},

    \labelreferencewithTheorem{Test4}

    \referencewithTheorem{Test5}




\end{document}

enter image description here