«Двусторонний» макрос гиперссылки: как сделать его максимально автоматическим?

«Двусторонний» макрос гиперссылки: как сделать его максимально автоматическим?

В общем случае ссылка на конкретный объект может встречаться в документе несколько раз. Поэтому невозможно сделать вывод о том, какая именно ссылка привела нас к указанному объекту.

Но что, если ссылка гарантированно появится только один раз? В таком случае можно представить себе двустороннюю гиперссылку: нажатие на ссылку перенесет вас на другой конец, а нажатие на другой конец вернет вас в исходное положение.

Вот ручная реализация двусторонней гиперссылки:

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

Было бы неплохо обернуть ручную реализацию в максимально автоматизированный макрос. Простая реализация макроса:

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

Но у него есть несколько недостатков:

  • При повторном использовании меток не возникнет никаких соответствующих ошибок.

  • пользователь должен запомнить 1/2, чтобы указать «направление» гиперссылки

  • Необходимо 4 аргумента!

Есть идеи, как можно упростить такой макрос?

решение1

В этом варианте используется одна метка для обоих концов, а также используется \@ifundefinedдля определения, является ли это первым или вторым появлением.

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

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