I used the answer here to help me create a document where numbering for theorems and the like appears on the left. But I would like to be able to reference and hyperlink back to these theorems/definitions/etc in my document. When I added hyperref and clicked on the links, they both sent me back to the front page. (I created a newpage in the code below to make the issue clearer, and I changed the documentclass from article to book since that is what I am using. The issue persists in either case.)

Any ideas to get the hyperlinks working correctly?

\documentclass{book}
\usepackage{showframe} % just for the example
\usepackage{amsthm}
\usepackage{enumitem}
\usepackage{xparse}
\usepackage{hyperref}

\usepackage{lipsum}

\newtheoremstyle{fctaylor}% name
  {\topsep}%      Space above
  {\topsep}%      Space below
  {\normalfont}%         Body font
  {}%         Indent amount (empty = no indent, \parindent = para indent)
  {\bfseries}% Thm head font
  {}%        Punctuation after thm head
  {0pt}%     Space after thm head: " " = normal interword space;
  {\makethmhead{#1}{#2}{#3}}

\newlength\fctaylortheoremindent
\AtBeginDocument{\setlength\fctaylortheoremindent{3em}} % <- customize here
\newlength\fctaylorlabelsep
\AtBeginDocument{\setlength\fctaylorlabelsep{1em}} % <- customize here

\makeatletter
\newcommand{\makethmhead}[3]{%
  \gdef\thisthmhead{%
    \makebox[\fctaylortheoremindent][l]{\bfseries#2}%
    {\bfseries#1}%
    \@ifnotempty{#3}{ (#3)}%
    \hspace{\fctaylorlabelsep}%
  }%
}
\makeatother

\newenvironment{fctayloritemize}
 {\list{}{%
    \leftmargin=\fctaylortheoremindent
    \labelwidth=\dimexpr\fctaylortheoremindent-\labelsep\relax
    \itemindent=0pt
  }}
 {\endlist}

\NewDocumentCommand{\newfctaylortheorem}{smomo}{%
  \IfBooleanTF{#1}
   {\newtheorem*{fctaylor@#2}{#4}}
   {\IfNoValueTF{#3}
     {\IfNoValueTF{#5}
       {\newtheorem{fctaylor@#2}{#4}}
       {\newtheorem{fctaylor@#2}{#4}[#5]}}
     {\newtheorem{fctaylor@#2}[fctaylor@#3]{#4}}}%
  \NewDocumentEnvironment{#2}{o}
   {\IfNoValueTF{##1}{\begin{fctaylor@#2}}{\begin{fctaylor@#2}[##1]}%
    \begin{fctayloritemize}\item[\thisthmhead\hfill]}
   {\end{fctayloritemize}\end{fctaylor@#2}}%
}

\theoremstyle{fctaylor}
\newfctaylortheorem{thm}{Theorem}[section]
\newfctaylortheorem*{defn}{Definition}

\begin{document}
\section{One}

\begin{defn}
\lipsum*[2]
\end{defn}

\newpage

\begin{thm}\label{A}
\lipsum*[2]
\end{thm}

\begin{thm}[Somebody]\label{B}
Something that should show how the text is split across line boundaries
and is correctly indented. And some equivalent conditions:
\begin{enumerate}[label=\upshape(\alph*),ref=(\alph*)]
\item a condition
\item another
\item and another
\end{enumerate}
which show the point made.
\end{thm}

\newpage

Here are the references: \ref{A} and \ref{B}.

\end{document}
  • 1
    If you try hyperref with the answer I gave to your other similar question, you'll see it works out of the box. – egreg Jul 23 at 20:33
up vote 2 down vote accepted

I observe exactly the same problem you observe.

Besides the fact that clicking hyperlinks yields navigating to the front page instead of the location where the referenced theorem-thingie can be found, I observed that the .log-file contains warnings:

pdfTeX warning (dest): name{fctaylor@thm.0.1.1} has been referenced but does no
t exist, replaced by a fixed one

pdfTeX warning (dest): name{fctaylor@thm.0.1.2} has been referenced but does no
t exist, replaced by a fixed one

I think playing around with \phantomsection is not the best approach at solving that problem as \phantomsection would, e.g., break the \autoref-feature for your thm-environments.

The problem is:

Theorem-like environments usually put their label-phrases into a box-register whose name is \@labels and rely on \everypar for placing that box/the content of that box-register into the output-file. The hyperref-package causes that at the time of putting the label-phrase into the box-register, also the name of a new anchor for hyperlinks gets created. The hyperref-package also causes placing the anchor when—due to \everypar—that box gets placed.

In your unusual case both that box and the anchor do never get placed because the thm-environment does have another nesting-level where the label is typeset within the optional argument of an \item of the fctayloritemize-environment, while the LaTeX 2ε-kernel-macro \@item which does underlie \item does override both the \@labels-box and the\everypar-hook with things/instructions which do not refer to placing an anchor with the name in question into the output-file. Thus you have an anchor-name for \label-commands but no suitable anchor when carrying out a command like \ref which also does attempt to create a link to the corresponding anchor.

When the TeX-engine (pdflatex or whatever) finds itself attempting to produce a link to a non existing anchor/destination, it will issue a warning-message which will also occur in the .log-file and will link to a "dummy-destination/dummy-anchor" on the first page of the document.

While the name for the anchor is already created by the surrounding-theorem-environment, you need to pass directives for placing the anchor into the optional argument of that \list-item as well:

\documentclass{book}
\usepackage{showframe} % just for the example
\usepackage{amsthm}
\usepackage{enumitem}
\usepackage{xparse}
\usepackage{hyperref}

\usepackage{lipsum}

\newtheoremstyle{fctaylor}% name
  {\topsep}%      Space above
  {\topsep}%      Space below
  {\normalfont}%         Body font
  {}%         Indent amount (empty = no indent, \parindent = para indent)
  {\bfseries}% Thm head font
  {}%        Punctuation after thm head
  {0pt}%     Space after thm head: " " = normal interword space;
  {\makethmhead{#1}{#2}{#3}}

\newlength\fctaylortheoremindent
\AtBeginDocument{\setlength\fctaylortheoremindent{3em}} % <- customize here
\newlength\fctaylorlabelsep
\AtBeginDocument{\setlength\fctaylorlabelsep{1em}} % <- customize here

\makeatletter
\newcommand{\makethmhead}[3]{%
  \gdef\thisthmhead{%
    \makebox[\fctaylortheoremindent][l]{\bfseries#2}%
    {\bfseries#1}%
    \@ifnotempty{#3}{ (#3)}%
    \hspace{\fctaylorlabelsep}%
  }%
}
\makeatother

\newenvironment{fctayloritemize}
 {\list{}{%
    \leftmargin=\fctaylortheoremindent
    \labelwidth=\dimexpr\fctaylortheoremindent-\labelsep\relax
    \itemindent=0pt
  }}
 {\endlist}

\makeatletter
\NewDocumentCommand{\newfctaylortheorem}{smomo}{%
  \IfBooleanTF{#1}
   {\newtheorem*{fctaylor@#2}{#4}}
   {\IfNoValueTF{#3}
     {\IfNoValueTF{#5}
       {\newtheorem{fctaylor@#2}{#4}}
       {\newtheorem{fctaylor@#2}{#4}[#5]}}
     {\newtheorem{fctaylor@#2}[fctaylor@#3]{#4}}}%
  %
  % Create the macro holding the textual phrase for `\autoref`:
  % Be aware that this only works when the theorem in question dose not
  % share its counter with an other theorem-like environment defined
  % previously.
  \IfBooleanTF{#1}{}{%%
    \expandafter\newcommand\csname fctaylor@#2autorefname\endcsname{#4}%
  }%
  %
  \NewDocumentEnvironment{#2}{o}
   {\IfNoValueTF{##1}{\begin{fctaylor@#2}}{\begin{fctaylor@#2}[##1]}%
    \begin{fctayloritemize}\item[{%
      % Also pass instructions for placing an anchor.
      % The name of the anchor was already created by the
      % fctaylor@#2-environment and saved either in the nacro
      % \@currentHref or in the macro \Hy@dth@currentHref:
      % In case there is a counter, its name is saved in 
      % \dth@counter, otherwise \dth@counter expands to emptiness.
      \ifx\@empty\dth@counter\else
        \Hy@raisedlink{%
          \hyper@anchorstart{%
            \ltx@ifundefined{Hy@dth@currentHref}%
            \@currentHref\Hy@dth@currentHref
          }\hyper@anchorend
        }%
      \fi
      \thisthmhead\hfill}]}
   {\end{fctayloritemize}\end{fctaylor@#2}}%
}
\makeatother

\theoremstyle{fctaylor}
\newfctaylortheorem{thm}{Theorem}[section]
\newfctaylortheorem*{defn}{Definition}

\begin{document}
\section{One}

\begin{defn}
\lipsum*[2]
\end{defn}

\newpage

\begin{thm}\label{A}
\lipsum*[2]
\end{thm}

\begin{thm}[Somebody]\label{B}
Something that should show how the text is split across line boundaries
and is correctly indented. And some equivalent conditions:
\begin{enumerate}[label=\upshape(\alph*),ref=(\alph*)]
\item a condition
\item another
\item and another
\end{enumerate}
which show the point made.
\end{thm}

\newpage

Here are the references: \ref{A} and \ref{B}

and \autoref{A} and \autoref{B}

\end{document}

Seems with these modifications you don't get warnings into the .log file and hyperlinks link to correct destinations/anchors.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.