Macro de hiperreferencia de "doble extremo": ¿cómo hacerla lo más automática posible?

Macro de hiperreferencia de "doble extremo": ¿cómo hacerla lo más automática posible?

En general, una referencia a un objeto concreto puede aparecer varias veces en un documento. Por tanto, no se puede inferir qué referencia nos llevó al objeto referido.

Pero ¿qué pasa si se garantiza que una referencia aparecerá sólo una vez? En tal caso, uno puede imaginar un hipervínculo de doble extremo: al hacer clic en el enlace se llegará al otro extremo, y al hacer clic en el otro extremo se regresará a la posición original.

Aquí hay una implementación manual de un hipervínculo de doble extremo:

\documentclass{article}

\usepackage{hyperref}

\begin{document}

\hypertarget{alpha}{\hyperlink{beta}{soft}} 

kitty, 

warm 

kitty, 

little 

ball 

of 

fur! 

Happy 

kitty, 

sleepy 

kitty, 

purr 

purr 

\hypertarget{beta}{\hyperlink{alpha}{purr!}}  

\end{document}

Sería bueno incluir la implementación manual en una macro lo más automática posible. Una implementación de macro simple es:

\documentclass{article}

\usepackage{hyperref}
\usepackage{xstring}

\newcommand*{\dehref}[4]{%
    \IfEqCase{#3}{%
        {1}{\hypertarget{#1}{\hyperlink{#2}{#4}}}%
        {2}{\hypertarget{#2}{\hyperlink{#1}{#4}}}%
    }%
}%

\begin{document}

\dehref{alpha}{beta}{1}{soft}

kitty, 

warm 

kitty, 

little 

ball 

of 

fur! 

Happy 

kitty, 

sleepy 

kitty, 

purr 

purr 

\dehref{alpha}{beta}{2}{purr!}

\end{document}

Pero tiene varios inconvenientes:

  • No se generarán errores relevantes si reutilizamos etiquetas.

  • El usuario debe recordar 1/2 para indicar la "dirección" del hipervínculo.

  • ¡Se necesitan 4 argumentos!

¿Alguna idea sobre cómo se puede simplificar una macro de este tipo?

Respuesta1

Esta variante utiliza una etiqueta para ambos extremos y se utiliza \@ifundefinedpara determinar si se trata de la primera o segunda aparición.

\documentclass{article}
\usepackage{hyperref}

\makeatletter
\newcommand{\backlink}[2]% #1 = label, #2 = text
{\@ifundefined{back@#1}%
  {\expandafter\xdef\csname back@#1\endcsname{1}%
    \hypertarget{back@#1}{\hyperlink{#1}{#2}}}%
  {\ifnum\csname back@#1\endcsname>1
    \errmessage{backlink #1 already used twice.}%
  \else
    \expandafter\xdef\csname back@#1\endcsname{2}%
    \hypertarget{#1}{\hyperlink{back@#1}{#2}}%
  \fi}%
}
\makeatother

\begin{document}

\backlink{alpha}{soft}

kitty, 

warm 

kitty, 

little 

ball 

of 

fur! 

Happy 

kitty, 

sleepy 

kitty, 

purr 

purr 

\backlink{alpha}{purr!}

\end{document}

información relacionada