цели hyperref без \refstepcounter

цели hyperref без \refstepcounter

Я пытаюсь создать внутреннюю ссылку документа с помощью 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}

Связанный контент