3

I'm trying to generate bookmarks for all Tables and Figures in a document using the code below. However, with this code, the Table 1 bookmark points to Figure 1 and the Figure 2 bookmark points to Table 2 and I cannot find why the Figure and Table numbers get mixed up.

Also, with this code, the entire caption is included in the bookmark. I would prefer to only have the short caption in the bookmark, but fail to figure out how to get the short caption. Any help with this problem would be much appreciated.

Thanks!

% needs two runs
 \documentclass{article}
 \usepackage{caption}
 \usepackage{hyperref}

 \DeclareCaptionTextFormat{Tablebookmark}{\belowpdfbookmark{Table \thetable: #1}{\thetable}#1}
  \captionsetup[table]{textformat=Tablebookmark}
 \DeclareCaptionTextFormat{Figurebookmark}{\belowpdfbookmark{Figure \thefigure: #1}{\thefigure}#1}
  \captionsetup[figure]{textformat=Figurebookmark}

\begin{document}
\null\newpage

\begin{figure}[ht]
 \centering
 \rule{6cm}{3cm}
 \caption{Figure caption text}
\end{figure}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption[Table caption text]{This is a table with a very long caption text and it would be nice to use the short caption in the bookmark}
\end{table}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption{Another caption text 2}
\end{table}

\newpage

\begin{figure}[ht]
  \centering
  \rule{6cm}{3cm}
  \caption{Caption text}
\end{figure}

\newpage %added two blank pages to make it easier to see bookmark targets
blank 
\newpage
blank

\end{document}
2

The bookmark should use the destination name (set by \caption more or less). Package hyperref uses \@currentHref to store the current destination name. In your case you have the same destination name for both the figure and table by using their numbers without further specification. Also \belowpdfbookmark sets a new anchor, not the optimal position, the anchor \@currentHref set by hyperref/caption is better here.

Package bookmark provides an easier interface to access the destination:

\bookmark[
  rellevel=1,
  keeplevel,
  dest=\@currentHref,
]{Table \thetable: #1}%

Next issue: \caption often sets its argument twice, because it wants to check, whether the caption fits in one line. This can be turned off with singlelinecheck=false. But this affects the formatting of single line captions.

\documentclass{article}
\usepackage{caption}
\usepackage{hyperref}
\usepackage{bookmark}

\captionsetup{singlelinecheck=off}
\makeatletter
\DeclareCaptionTextFormat{Tablebookmark}{%
  \bookmark[
    rellevel=1,
    keeplevel,
    dest=\@currentHref,
  ]{Table \thetable: #1}%
  #1%
}
\captionsetup[table]{textformat=Tablebookmark}
\DeclareCaptionTextFormat{Figurebookmark}{%
  \bookmark[
    rellevel=1,
    keeplevel,
    dest=\@currentHref,
  ]{Figure \thefigure: #1}%
  #1%
}
\captionsetup[figure]{textformat=Figurebookmark}
\makeatother

\begin{document}
\null\newpage

\begin{figure}[ht]
 \centering
 \rule{6cm}{3cm}
 \caption{Figure caption text}
\end{figure}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption[Table caption text]{This is a table with a very long caption text
 and it would be nice to use the short caption in the bookmark}
\end{table}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption{Another caption text 2}
\end{table}

\newpage

\begin{figure}[ht]
  \centering
  \rule{6cm}{3cm}
  \caption{Caption text}
\end{figure}

\newpage %added two blank pages to make it easier to see bookmark targets
blank 
\newpage
blank

\end{document}

\end{figure} and \end{table} could be used as another place for setting the bookmark, if these float environments alwasy contain one \caption. Since package nameref stores the caption text in macro \@currentlabelname, it can be used in the bookmark:

\documentclass{article}
\usepackage{caption}
\usepackage{hyperref}
\usepackage{bookmark}
\usepackage{etoolbox}

\makeatletter
\pretocmd\endtable{%
  \bookmark[
    rellevel=1,
    keeplevel,
    dest=\@currentHref,
  ]{Table \thetable: \@currentlabelname}%
}{}{\errmessage{Patching \noexpand\endtable failed}}
\pretocmd\endfigure{%
  \bookmark[
    rellevel=1,
    keeplevel,
    dest=\@currentHref,
  ]{Figure \thefigure: \@currentlabelname}%
}{}{\errmessage{Patching \noexpand\endfigure failed}}
\makeatother

\begin{document}
\null\newpage

\begin{figure}[ht]
 \centering
 \rule{6cm}{3cm}
 \caption{Figure caption text}
\end{figure}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption[Table caption text]{This is a table with a very long caption text
 and it would be nice to use the short caption in the bookmark}
\end{table}

\newpage

\begin{table}[ht]
 \begin{tabular}{cc}
 Header & Header \\
 1&2\\
 \end{tabular}
 \caption{Another caption text 2}
\end{table}

\newpage

\begin{figure}[ht]
  \centering
  \rule{6cm}{3cm}
  \caption{Caption text}
\end{figure}

\newpage %added two blank pages to make it easier to see bookmark targets
blank 
\newpage
blank

\end{document}
  • This is perfect! – user1570707 May 19 '14 at 7:24
  • As per tex.stackexchange.com/questions/27096/… you can make the link point to the image instead of the caption by loading \usepackage[all]{hypcap} after hyperref – Jon Nov 30 '15 at 19:24
  • @Jon This is already done by package caption. – Heiko Oberdiek Nov 30 '15 at 19:29
  • @HeikoOberdiek Sorry, I'm in a situation where I cannot load caption so I didn't notice that was in your answer. – Jon Nov 30 '15 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.