Hyperref-Ziele ohne \refstepcounter

Hyperref-Ziele ohne \refstepcounter

Ich versuche mit dem Paket einen dokumentinternen Link zu erstellen hyperref. An der Stelle, auf die der Link zeigen soll, führe ich (im Rahmen der Einrichtung einer LaTeX-Umgebung) folgenden Befehl aus:

\edef\@currentlabel{LABEL}

Danach verwende ich \label{...}zum Erstellen einer Referenz und die \ref{...}. Das hyperrefPaket wandelt die \ref{...}wie erwartet in einen Hyperlink um, aber der Link zeigt an die falsche Stelle (weiter oben im Text). Wie erkenne ich, hyperrefwohin der Link zeigen soll?

Ich kann es nicht verwenden \refstepcounter, da meine Beschriftungen aus Text bestehen und keinem LaTeX-Zähler zugeordnet sind.

Hier ist ein „minimales“ (also „eher kleines“) funktionierendes Beispiel zur Veranschaulichung des Problems:

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

Antwort1

Sie müssen an der entsprechenden Stelle einen Anker setzen. Dies geschieht automatisch, wenn \refstepcounterausgegeben wird, aber Sie müssen es manuell tun, wenn \@currentlabelohne Hilfe eines Zählers gesetzt wird.

Ein Anker kann mit gesetzt werden \phantomsection(das ist allerdings ein schlechter Name).

\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

Antwort2

Sie können die Pakete \hyperlinkund \hypertargetMakros verwenden. Sie erfordern keine Zähler, \refstepcounterAktionen oder Neudefinitionen von \@currentlabel.

  • \hypertarget{<anchor name>}{<some text>}In den Standort einfügenzu welchemder Leser sollte springen.

  • \hyperlink{<anchor name>}{<other text>}An einer oder mehreren Stellen einfügenaus denenDer Leser soll an die Stelle springen, die an einer anderen Stelle im Dokument durch eine \hypertargetAnweisung angegeben ist.

Ein ganz einfaches Beispiel:

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

Das Wort „hier“ auf der zweiten Seite wird blau dargestellt und wenn Sie darauf klicken, gelangen Sie zur Zeile „Eine wunderbare Geschichte“ auf der vorhergehenden Seite.

Es können mehrere \hyperlinkAnweisungen auf denselben Ankernamen verweisen, \hypertargetfür einen bestimmten Ankernamen sollte es jedoch nur eine Anweisung geben.

Wenn Sie diese Ideen an Ihren Testcode anpassen, könnte er folgendermaßen aussehen:

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

verwandte Informationen