amsthm with shared counters messes up autoref references

This problem isn't so easy to solve. the problem consist in this:

  • hyperref only defines a name if you use \newtheorem{theorem}{<theorem name>} for using with \autoref. This name is Theorem in English (obviously changes if we use babel), it is stored in the macro \theoremautorefname and can be changed using \renewcommand{\theoremautorefname}{<new name>}.

  • If you create a different structure (for example \newtheorem{lemma}{Lemma}) \autoref doesn't put any name.

  • \autoref works via the counter name (in this case theorem) where the reference is based on.

  • Sometimes \autorefchooses the wrong name, if the counter is used for different things. For example, it happens with \newtheorem if a lemma (or other structure created by the user) shares a counter with theorems.

For this the package aliascnt provides a method to generate a simulated second counter that allows the differentiation between theorems and lemmas or other structures.


To solve this problem i recommend to do this:

  • Load the aliascnt package with \usepackage{aliascnt}.

  • Create the main structure (if you plan to share the counters) with

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

    (This fixes the counter).

  • If your structure is not a theorem create a new name for \autoref using \providecommand*{\<main str>autorefname}{<Main str name>}. For example if you want a lemma use

    \newtheorem{lemma}{Lemma}
    \providecommand*{\lemmaautorefname}{Lemma}
    
  • If you don't plan to share counters simply use

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

    for each <name> theorem.

  • If you plan to share counters with <main str> then for each <newTh> (new theorem) write

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

Here is the code

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

and the result

enter image description here


I would use cleveref instead, which does understand amsthm. The following is close to the output you were getting above:

Sample output

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

Personally I would not use the nameinlink option, and cleveref describes it as bad style. Without this option the hyperlink is just the number and the click area does not include the name.

Note the order of the package loading, cf. Which packages should be loaded after hyperref instead of before?


The package thmtools fixes this. From the documentation:

A.1.7 Fixing autoref and friends

hyperref’s \autoref command does not work well with theorems that share a counter: it’ll always think it’s a Lemma even if it’s a Remark that shares the Lemma counter. Load this package to fix it. No further intervention needed.

Indeed, merely loading the package fixes the problem:

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

Alternatively, if you're going to use thmtools, you might as well take advantage of its more concise theorem declarations: replace

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

by

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

(Of course, these are but two of the many features of thmtools.)