[Tex/LaTex] \hyperref within included pdfs

epstopdfhyperrefpdftex

In the paper I am currently writing I would really like to be able to \hyperref another part of the paper from within a graphic. The graphic output format is eps which I then convert to pdf with eps2pdf and then include the pdf in my document. Now I "somehow" want to be able to specify a reference in my eps which gets preserved from the eps2pdf step and then I can have a clickable link within my graphic that refers to a different part of the document. I have no clue how to achieve this.

A completely different approach using a different starting format and end format is fine with me also but I prefer it to still be vector graphics.

I use pdflatex to render my document.

Below is a reproducable example.

In my case I have a eps file that contains links to both a url and a \hyperref. To showcase this I made a quick dot file to illustrate what my kind of eps I am dealing with, I converted the dot file to eps with: dot -Teps test.dot -o test.eps. Please be aware though that my files aren't dot files actually and I use it here because it makes for an easier example.

digraph Test {
    g[href="https://www.google.com", fontcolor=blue, label="google"];
    test[href="\hyperref[sec:Introduction]{Links to intro}", fontcolor=blue, label="Introduction"];
}

Then I convert the resulting eps to pdf using epstopdf: epstopdf test.eps which then creates my pdf which has a \URL with the hyperref intact. Then I include the graphic in latex with \includegraphic:

\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{hyperref}
\usepackage{hypcap}
\usepackage{graphicx}

\begin{document}

\section{Introduction}
\label{sec:Introduction}

\hyperref[sec:Introduction]{Links to intro}

\begin{figure}[htbp]
\centering
\capstart

\includegraphics{test.pdf}
\caption{test}
\end{figure}

\end{document}

So now they are 2 problems. The real URL to google doesn't work since it isn't clickable at all and also the hyperref embedded doesn't work. The real url works if I open the test.pdf file.

So I don't mind writing some code to fix this with some transformations but I have no idea how.

Any help is appreciated.

Best Answer

Any interactive elements, such as links, embedded multimedia, PDF Layers, are stripped off while embedding a PDF by means of the usual commands from the graphicx and pdfpages packages.

There is an experimental package on CTAN, pax, which attempts to re-create such elements using an external Java programme. But the project seems to be discontinued.

Currently, re-inserting interactive elements require a tedious, manual procedure, which can be simplified a bit by package onimage, introduced ↗here. It can be downloaded as onimage.dtx↗here. Run pdflatex twice on it to get onimage.sty and the documentation onimage.pdf.

onimage was designed to facilitate annotating embedded image files. Optionally it can show a grid of helper lines that greatly simplifies finding the link rectangle coordinates.

For convenience, we define \linkRect(<lowerleft>)(<upper right>){...} which can be used inside a tikzonimage or tikzpicture environment to create a link rectangle between (<lowerleft>) and (<upper right>), e. g. as

\linkRect(llx,lly)(urx,ury) {\href{URL}{~}};

Use ~ as a placeholder for the link text.

The Perl-Script extractURIs.pl listed below extracts all URI (i. e. external) links from a given uncompressed PDF and writes readily formatted

\linkRect(llx,lly)(urx,ury) {\href{URL}{~}};

commands to the terminal. For uncompressing, use pdftk commandline tool:

pdftk input.pdf output - uncompress | extractURIs.pl

enter image description here

\documentclass{article}

\usepackage{graphicx}
\usepackage{tikz}
\usepackage{hyperref}
\usepackage{onimage}

% use `~' as placeholder for the link text
% \linkRect(llx,lly)(urx,ury) {\href{URL}{~}};
\def\linkRect(#1)(#2){
  \coordinate (ll) at (#1); \coordinate (ur) at (#2);\def~{\tikz \useasboundingbox (ll) rectangle (ur);}
  \node [anchor=south west, inner sep=0] at (ll)
}

\begin{document}

  \begin{tikzonimage}[width=5cm]{example-image-a}[tsx/show help lines]
    \linkRect(0.35,0.25)(0.65,0.75) {\href{https://www.google.de/search?q=onimage.dtx&ie=utf-8&oe=utf-8&client=firefox-b&gfe_rd=cr&dcr=0&ei=6lW6Wq_yEt6CgAfZq5mgDA}{~}};
  \end{tikzonimage}

\end{document}

Perl scipt extractURIs.pl:

#!/usr/bin/perl -w

@linkRect=();
@linkUri=();
$isLink=0;
$isUri=0;

while(<>){
  if (/\/MediaBox\s+\[([\d\.\s]+\d)\]/) {
    @mediaBox=split /\s+/, $1;
  }
  elsif(/\/Subtype\s*\/Link/) {$isLink=1;}
  elsif(/\/Rect\s+\[([\d\.\s]+\d)\]/) {
    $rect=$1;
  }
  elsif(/\/URI\s+\((.*)\)\s*$/) {
    $uri=$1;
    $isUri=1;
  }
  elsif(/endobj/) {
    if($isUri && $isLink) {
      push @linkUri, $uri;
      push @linkRect, $rect;
    }
    $isUri=0;
    $isLink=0;
  }
}

$width=$mediaBox[2]-$mediaBox[0];
$height=$mediaBox[3]-$mediaBox[1];

for($i=0; $i<@linkUri; $i++) {
  ($llx,$lly,$urx,$ury) = split /\s+/, $linkRect[$i];
  $llx=($llx-$mediaBox[0])/$width;
  $urx=($urx-$mediaBox[0])/$width;
  $lly=($lly-$mediaBox[1])/$height;
  $ury=($ury-$mediaBox[1])/$height;

  print "\\linkRect($llx,$lly)($urx,$ury) {\\href{$linkUri[$i]}{~}};\n";
}
Related Question