带有共享计数器的 amsthm 弄乱了 autoref 引用

带有共享计数器的 amsthm 弄乱了 autoref 引用

当我使用共享计数器定义amsthm定理环境时,autoref 会弄乱引用的名称。例如,在下面的输出中,我们应该使用“定义 2”而不是“定理 2”。

\documentclass{article}

\usepackage{amsthm}
\usepackage{hyperref}

\theoremstyle{theorem}
\newtheorem{theorem}{Theorem}
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}

\begin{document}

\begin{theorem}
\label{wonderful-theorem}
This is a wonderful theorem.
\end{theorem}

\begin{definition}
\label{awesome-definition}
This is an awesome definition.
\end{definition}

Look at the wonderful \autoref{wonderful-theorem}
and the awesome \autoref{awesome-definition}.

\end{document}

在此处输入图片描述

答案1

我会改用cleveref,它确实理解amsthm。以下内容接近您上面得到的输出:

示例输出

\documentclass{article}

\usepackage{amsthm}
\usepackage[colorlinks]{hyperref}
\usepackage[capitalize,nameinlink]{cleveref}

\theoremstyle{theorem}
\newtheorem{theorem}{Theorem}
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}

\begin{document}

\begin{theorem}
\label{wonderful-theorem}
This is a wonderful theorem.
\end{theorem}

\begin{definition}
\label{awesome-definition}
This is an awesome definition.
\end{definition}

Look at the wonderful \cref{wonderful-theorem}
and the awesome \cref{awesome-definition}.

\end{document}

我个人不会使用此nameinlink选项,并cleveref认为其风格不好。如果没有此选项,超链接就只是数字,点击区域不包含名称。

注意包加载的顺序,参见哪些包应该在 hyperref 之后加载而不是之前加载?

答案2

这个问题不太容易解决。问题在于:

  • hyperref仅当您将\newtheorem{theorem}{<theorem name>}for 与 一起使用时才定义一个名称\autoref。此名称Theorem为英文(如果我们使用 ,显然会更改babel),它存储在宏中\theoremautorefname,可以使用 进行更改\renewcommand{\theoremautorefname}{<new name>}

  • 如果您创建不同的结构(例如\newtheorem{lemma}{Lemma}\autoref则不输入任何名称。

  • \autoreftheorem通过引用所基于的计数器名称(在本例中)进行工作。

  • \autoref如果计数器用于不同的事情,有时会选择错误的名称。例如,\newtheorem如果引理(或用户创建的其他结构)与定理

为此,该包aliascnt提供了一种生成模拟秒计数器的方法,可以区分定理和引理或其他结构。


为了解决这个问题我建议这样做:

  • 使用 加载aliascnt\usepackage{aliascnt}

  • 创建主要结构(如果您计划共享柜台)

    \newtheorem{<main str>}{<Main str name>}
    

    (这修复了计数器)。

  • 如果您的结构不是,请theorem创建一个新名称以供\autoref使用\providecommand*{\<main str>autorefname}{<Main str name>}。例如,如果您想要lemma使用

    \newtheorem{lemma}{Lemma}
    \providecommand*{\lemmaautorefname}{Lemma}
    
  • 如果你不打算共享计数器,只需使用

    \newtheorem{<name>}{<Name>}
    \providecommand*{\<name>autorefname}{<Name>}
    

    对于每个<name>定理

  • 如果你打算与<main str>每个<newTh>(新定理)共享计数器,则写入

    \newaliascnt{<newTh>}{<main str>}% alias counter "<newTh>"
    \newtheorem{<newTh>}[<newTh>]{<newTh name>}
    \aliascntresetthe{<newTh>}
    \providecommand*{\<newTh>autorefname}{<newTh name>} % name for \autoref
    

以下是代码

\documentclass{article}

\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{aliascnt}

\theoremstyle{theorem}
    \newtheorem{theorem}{Theorem}

\theoremstyle{definition}
    \newaliascnt{definition}{theorem}
    \newtheorem{definition}[definition]{Definition}
    \aliascntresetthe{definition}
    \providecommand*{\definitionautorefname}{Definition}

\begin{document}

\begin{theorem}
\label{wonderful-theorem}
This is a wonderful theorem.
\end{theorem}

\begin{definition}
\label{awesome-definition}
This is an awesome definition.
\end{definition}

Look at the wonderful \autoref{wonderful-theorem}
and the awesome \autoref{awesome-definition}.

\end{document}

结果

在此处输入图片描述

答案3

此软件包thmtools修复了这个问题。摘自文档:

A.1.7 修复 autoref 及其相关内容

hyperref\autoref命令对于共享计数器的定理不太适用:即使它是一个共享引理计数器的注释,它也会始终认为它是一个引理。加载此包以修复它。无需进一步干预。

事实上,只需加载包就可以解决问题:

\documentclass{article}

\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{hyperref}

\theoremstyle{theorem}
\newtheorem{theorem}{Theorem}
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}

\begin{document}

\begin{theorem}
\label{wonderful-theorem}
This is a wonderful theorem.
\end{theorem}

\begin{definition}
\label{awesome-definition}
This is an awesome definition.
\end{definition}

Look at the wonderful \autoref{wonderful-theorem}
and the awesome \autoref{awesome-definition}.

\end{document}

或者,如果你要使用thmtools,你也可以利用其更简洁的定理声明:替换

\theoremstyle{theorem}
\newtheorem{theorem}{Theorem}
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}

经过

\declaretheorem[style=plain]{theorem}
\declaretheorem[style=definition,sibling=theorem]{definition}

(当然,这些只是 的众多功能中的两个thmtools。)

相关内容