为一种标签创建多种引用方式

为一种标签创建多种引用方式

我想创建一个statement枚举环境以及一个引用机制,以便代码

\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{Test2},

\labelreference{Test3},

\labelreferenceWithTheorem{Test4}

\referenceWithTheorem{Test5}

生成带有适当超链接的以下输出:

在此处输入图片描述

以下内容对我很重要:

  1. statement我可以在theorem和中使用相同的环境lemma
  2. 如果我使用\referenceWithTheorem\labelreferenceWithTheorem,那么就精确地<section>.<theorem> <statement>变成指向该语句的超链接。
  3. 该机制决定语句是放在theorem还是 内lemma

如果有人能提供帮助,我将非常感激。

附录:以下是我用来制作屏幕截图的代码:

\documentclass{article}

\usepackage{amsthm}
\usepackage{enumitem}
\usepackage{hyperref}

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

\begin{document}
    \section{A section}
    \begin{theorem}
        \begin{enumerate}[label=(\roman*)]
            \item Test \label{Test1}
            \item Test \label{Test2}
        \end{enumerate}
    \end{theorem}
    \begin{lemma}
        \begin{enumerate}[label=(\roman*)]
            \item Test \label{Test3}
            \item Test \label{Test4}
            \item Test \label{Test5}
        \end{enumerate}
    \end{lemma}

    Statement~\hyperref[Test1]{(i)},

    Theorem~\hyperref[Test2]{1.1 (ii)},

    \hyperref[Test3]{(i)},

    \hyperref[Test4]{1.2 (ii)},

    Lemma~\hyperref[Test5]{1.2 (iii)}



\end{document}

答案1

这是另一种可能的解决方案。

我使用的cleveref包定义了自动格式化引用的宏。使用此包,\Cref{<some section>}将生成“Section ⟨number⟩”,如果您使用 amsthm,\Cref{<some theorem>}将生成“⟨theorem type⟩ ⟨number⟩”。

我做了一些修改,允许您以两种方式引用statement环境中的项目(及其名称)。

  • 我正在使用该包enumitem(您似乎也在使用它)来定义statement环境,并且我已经对其进行了设置,以便写入辅助文件的标签实际上是这种形式\@twolabels{(i)}{1.1~(i)}
  • 我已将其定义\@twolabels\@firstoftwo,因此\@twolabels{(i)}{1.1~(i)}扩展为(i)。因此,当您扩展时,\ref{Test<n>}输出将为(i)
  • 当你调用 时\refWithTheorem{Test<n>}\@twolabels会暂时将其重新定义为\@secondoftwo,之后会\ref{Test<n>}调用 。因此,你将看到标签的第二部分,其中包含周围定理的编号。
  • 在环境启动的时候statement,我告诉 cleveref 该计数器对应的类型statementi\@twolabels{statementi}{<the type of the surrounding environment>}
  • 该宏\CrefWithTheorem定义为\refWithTheorem:它重新定义\@twolabels\@secondoftwo,然后调用\Cref

以下是代码:

\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}

输出如下:

在此处输入图片描述

编辑:修复了一个愚蠢的错误,不要使用旧版本。

编辑:显然\setlist有一个before密钥,这使得使用\AtBeginEnvironment(和加载)变得etoolbox没有必要。还添加了对带星号(未链接)版本的支持\ref\cref\Cref

编辑:删除尾随\makeatletter(哎呀)

答案2

更复杂的参考问题需要更复杂的工具来生成交叉引用信息。

zref是一款功能强大的工具。它具有property存储附加信息的功能。

我定义了3个属性:

  • envname,存储外部环境名称,例如 Theorem 或 Lemma
  • theorem→ 将定理数存储为输出\thetheorem
  • lemma→ 类似于theorem,商店\thelemma

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

全部提取所写的相关信息\zlabel并按需要显示信息。

\zlabel是通过使用 自动完成的\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}

在此处输入图片描述

相关内容