当定理环境位于类文件中时,如何使用 autoref 或 cleveref?

当定理环境位于类文件中时,如何使用 autoref 或 cleveref?

日记轻型飞机控制系统提供一种风格,lmcs.cls,包含定理环境的定义:

%%% Theorem environments

% the following environments switch to a slanted font:
\theoremstyle{plain}

\newtheorem{thm}{Theorem}[section]
\newtheorem{cor}[thm]{Corollary}
\newtheorem{lem}[thm]{Lemma}
\newtheorem{prop}[thm]{Proposition}
\newtheorem{asm}[thm]{Assumption}

% the following environments keep the roman font:
\theoremstyle{definition}

\newtheorem{rem}[thm]{Remark}
\newtheorem{rems}[thm]{Remarks}
\newtheorem{exa}[thm]{Example}
\newtheorem{exas}[thm]{Examples}
\newtheorem{defi}[thm]{Definition}
\newtheorem{conv}[thm]{Convention}
\newtheorem{conj}[thm]{Conjecture}
\newtheorem{prob}[thm]{Problem}
\newtheorem{oprob}[thm]{Open Problem}
\newtheorem{algo}[thm]{Algorithm}
\newtheorem{obs}[thm]{Observation}
\newtheorem{qu}[thm]{Question}
\newtheorem{fact}[thm]{Fact}
\newtheorem{pty}[thm]{Property}

他们非常坚持作者使用这种风格:参见第 85-87 页示例文件,说

作者应避免改变定理、定义等的编号样式,例如,重新定义已经提供的环境。

但即使我加载amsthm(如这里推荐),按照所谓正确的顺序加载包(即然后amsthm)并尝试,我所有的参考文献都标有“定理”。hyperrefcleverefautorefcref

MWE(需要lmcs.cls):

\documentclass{lmcs}
\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{cleveref}

\def\defiautorefname{Definition} % For autoref
\def\thmautorefname{Theorem} % autoref will use that definition!

\crefname{defi}{Definition}{Definitions} % For cref
\crefname{thm}{Theorem}{Theorems} % cref will use that definition!

\begin{document}
\begin{defi}\label{defi}
This is not that.
\end{defi}

The \autoref{defi}, as well as the \cref{defi}, are not definitions!
\end{document}

提供: 该定义被称为定理。

答案1

您可以重新定义类似定理的环境 hyperrefcleveref使用类中的相同方案进行加载。

\documentclass{lmcs}
\usepackage{hyperref}
\usepackage{cleveref}

\newcommand{\renewtheorem}[1]{%
  \expandafter\let\csname #1\endcsname\relax
  \expandafter\let\csname c@#1\endcsname\relax
  \expandafter\let\csname end#1\endcsname\relax
  \newtheorem{#1}%
}

\theoremstyle{plain}

\renewtheorem{thm}{Theorem}[section]
\renewtheorem{cor}[thm]{Corollary}
\renewtheorem{lem}[thm]{Lemma}
\renewtheorem{prop}[thm]{Proposition}
\renewtheorem{asm}[thm]{Assumption}

% the following environments keep the roman font:
\theoremstyle{definition}

\renewtheorem{rem}[thm]{Remark}
\renewtheorem{rems}[thm]{Remarks}
\renewtheorem{exa}[thm]{Example}
\renewtheorem{exas}[thm]{Examples}
\renewtheorem{defi}[thm]{Definition}
\renewtheorem{conv}[thm]{Convention}
\renewtheorem{conj}[thm]{Conjecture}
\renewtheorem{prob}[thm]{Problem}
\renewtheorem{oprob}[thm]{Open Problem}
\renewtheorem{algo}[thm]{Algorithm}
\renewtheorem{obs}[thm]{Observation}
\renewtheorem{qu}[thm]{Question}
\renewtheorem{fact}[thm]{Fact}
\renewtheorem{pty}[thm]{Property}

\begin{document}

\section{Test}

\begin{defi}\label{defi}
This is not that.
\end{defi}

As you see, \cref{defi} is a definition!

\end{document}

因为\autoref还需要做更多的工作,所以aliascnt可以将其纳入\renewtheorem,但cleveref无论如何都是更胜一筹。

在此处输入图片描述

我不知道文字编辑是否可以接受这一点。

答案2

\autoref这里和都失败的原因cleveref是共享计数器thm,即,所有定义的环境都使用相同的计数器,该计数器既用作hyperref构建锚点的信息(autoref稍后从中生成名称,又用作的误导信息cleveref

这个cleveref问题比较容易解决,比如,使用\label[defi]{somelabel}命令或名为的包装器\theolabel,它会尝试提取存储在中的当前环境的名称\@currenvir。这假设\crefname为相关环境名称定义了。

重新定义\hyper@refstepcounter知道环境和计数器名称,其策略类似:假装计数器名称不同。如果计数器名称是thm或任何其他计数器,则不会发生任何异常,否则将使用环境名称。

\documentclass{lmcs}
\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{cleveref}


\makeatletter

\let\orig@hyper@refstepcounter\hyper@refstepcounter%

\newcommand{\thmcountername}{thm}% This is the counter name for the theorems as defined in the lmcs class

\renewcommand{\hyper@refstepcounter}[1]{%
  \begingroup
  \def\temp@a{#1}% 
  \edef\temp@b{\thmcountername}% Which is the counter name
  \ifx\temp@a\temp@b% Is #1 = counter name?
  \ifx\@currenvir\temp@b% Is this the original environment -> do nothing special
  \orig@hyper@refstepcounter{#1}%
  \else% Now fake the theH.... and pretend it is a different counter
  \expandafter\let\csname c@\@currenvir\expandafter\endcsname\csname c@\thmcountername\endcsname% Ugly trick!
  \orig@hyper@refstepcounter{\@currenvir}%
  \fi
  \else% Any other counter%
  \orig@hyper@refstepcounter{#1}%
  \fi
  \endgroup
}


\newcommand{\theolabel}[1]{%
  \label[\@currenvir]{#1}%
}
\makeatother



\def\defiautorefname{Definition} % For autoref
\def\exaautorefname{Example} % For autoref
\def\thmautorefname{Theorem} % autoref will use that definition!

\Crefname{exa}{Example}{Examples} % For cref
\crefname{defi}{Definition}{Definitions} % For cref
\crefname{thm}{Theorem}{Theorems} % cref will use that definition!

\begin{document}

\section{Foo}

\begin{exa}
  Stuff \theolabel{exastuff}
\end{exa}
\begin{defi}\theolabel{defi}
This is not that.
  \begin{equation}
    E=mc^2 \label{fooequation}
    \end{equation}
\end{defi}

\begin{thm}\theolabel{thmstuff}
  This is not that.
\end{thm}

See \autoref{exastuff}  or \Cref{exastuff} or \cref{fooequation}

The \autoref{defi}, as well as the \cref{defi}, are definitions and not reported as Theorems any longer!
\end{document}

在此处输入图片描述

答案3

由于这个问题似乎仍出现在搜索引擎中,让我以 LMCS 团队的一员的身份来回答。如今(2023 年,但已经有几年了),lmcs.cls使用 hyperref 包效果很好:

\documentclass{lmcs}
\usepackage{hyperref}

\begin{document}
\section{Tests}
\begin{thm}\label{mythm}
The theorem.
\end{thm}
\begin{defi}\label{mydef}
The definition.
\end{defi}

\begin{tabular}{@{}lll@{}}
Environment & autoref \\ \hline
Theorem & \autoref{mythm} \\
Definition & \autoref{mydef} \\
\end{tabular}
\end{document}

在此处输入图片描述

所以不需要cleveref。如果你仍然坚持使用,cleveref你可以通过以下方式进行\crefname(无需加载amsthm包!):

\documentclass{lmcs}
\usepackage{hyperref}
\usepackage{cleveref}

\crefname{defi}{Definition}{Definitions} % For cref
\crefname{thm}{Theorem}{Theorems} % cref will use that definition!

\begin{document}
\section{Tests}
\begin{thm}\label{mythm}
The theorem.
\end{thm}
\begin{defi}\label{mydef}
The definition.
\end{defi}

\begin{tabular}{lll}
Environment & autoref & cref \\ \hline
Theorem & \autoref{mythm} & \cref{mythm} \\
Definition & \autoref{mydef} & \cref{mydef} \\
\end{tabular}
\end{document}

在此处输入图片描述

相关内容