我想创建一个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}
生成带有适当超链接的以下输出:
以下内容对我很重要:
statement
我可以在theorem
和中使用相同的环境lemma
。- 如果我使用
\referenceWithTheorem
或\labelreferenceWithTheorem
,那么就精确地<section>.<theorem> <statement>
变成指向该语句的超链接。 - 该机制决定语句是放在
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 或 Lemmatheorem
→ 将定理数存储为输出\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}