
Я пытаюсь создать внутреннюю ссылку документа с помощью hyperref
пакета. В позиции, куда должна указывать ссылка, я выполняю следующую команду (как часть настройки среды LaTeX):
\edef\@currentlabel{LABEL}
После этого я использую \label{...}
для создания ссылки и \ref{...}
. hyperref
Пакет превращает \ref{...}
в гиперссылку, как и ожидалось, но ссылка указывает на неправильное место (выше по тексту). Как узнать, hyperref
куда должна указывать ссылка?
Я не могу использовать, \refstepcounter
потому что мои метки текстовые и не связаны со счетчиком LaTeX.
Вот «минимальный» (ну, «небольшой») рабочий пример, иллюстрирующий проблему:
\documentclass{article}
\usepackage{lipsum}
\usepackage{amsthm}
\usepackage{hyperref}
\newtheorem{theorem}{Theorem}[section]
\makeatletter
\newenvironment{algorithm}[2]%
{\medbreak
\edef\@currentlabel{#1}%
% more stuff here (put entry in table of algorithms, etc.)
\noindent
\textbf{Algorithm~\@currentlabel\ (#2)}\hfill\break
\ignorespaces}%
{\medbreak}
\makeatother
\begin{document}
\section{Test}
\begin{theorem}
\lipsum[1]
\end{theorem}
\begin{algorithm}{TEST}{Test Algorithm}\label{alg:TEST}%
\lipsum[2]
\end{algorithm}
The following link points to the theorem instead of the algorithm: \ref{alg:TEST}.
\end{document}
решение1
Вам необходимо установить якорь в соответствующем месте. Это делается автоматически при \refstepcounter
выдаче, но вам придется сделать это вручную при \@currentlabel
установке без помощи счетчика.
Якорь можно установить с помощью \phantomsection
(хотя это плохое название).
\makeatletter
\newenvironment{algorithm}[2]%
{\medbreak
\edef\@currentlabel{#1}%
% more stuff here (put entry in table of algorithms, etc.)
\noindent\phantomsection % <------------------------ add the anchor
\textbf{Algorithm~\@currentlabel\ (#2)}\hfill\break
\ignorespaces}%
{\medbreak}
\makeatother
решение2
Вы можете использовать пакеты \hyperlink
и \hypertarget
макросы. Они не требуют никаких счетчиков, \refstepcounter
действий или переопределений \@currentlabel
.
Вставьте
\hypertarget{<anchor name>}{<some text>}
в местоположениекоторомучитатель должен подпрыгнуть.Вставьте
\hyperlink{<anchor name>}{<other text>}
в одно или несколько местиз которогочитатель должен перейти к месту, указанному в другом месте документа с помощью\hypertarget
инструкции.
Очень простой пример:
\documentclass{article}
\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\begin{document}
\hypertarget{jump_destination}{\textbf{A wonderful tale}}
Once upon a time, \dots
\clearpage
If you want to read a wonderful tale, click \hyperlink{jump_destination}{here}.
\end{document}
Слово «здесь» на второй странице будет выделено синим цветом, и, нажав на него, вы перейдете на строку «Замечательная сказка» на предыдущей странице.
Возможно наличие нескольких инструкций, указывающих на одно и то же имя якоря, но для данного имени якоря \hyperlink
должна быть только одна инструкция.\hypertarget
Если адаптировать эти идеи к вашему тестовому коду, то он может выглядеть так:
\documentclass{article}
\usepackage{lipsum,amsthm,hyperref}
\newtheorem{theorem}{Theorem}[section]
\newenvironment{algorithm}[2]%
{\par\medbreak\noindent
% more stuff here (put entry in table of algorithms, etc.)
\hypertarget{#1}{\textbf{Algorithm~#1 (#2)}}%
\par\noindent\ignorespaces}%
{\medbreak}
\begin{document}
\section{Test}
\begin{theorem}
\lipsum[1]
\end{theorem}
\begin{algorithm}{TEST}{Test Algorithm}
\lipsum[2]
\end{algorithm}
\clearpage
The following link now points to the algorithm: \hyperlink{TEST}{here}.
\end{document}