Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The backref option and its variants in the hyperref package allow to include back-references in the bibliography to the page(s) or section(s) in which a given reference was cited.

The target of the back-reference is the beginning of the page (or of the section, depending on the option) in which the citation occurs (see backref manual).

How can I get the back-reference links to point precisely at the line in which the citation key occurs in the text?

Apparently, someone had a related issue with "runners" on the side of the page, but the solution hinges on the definition of the runners themselves.

I am looking to obtain, in the back-reference, the same behavior of the link from in-text citation to reference (i.e., point to the line of the reference in question), just backwards.

Any suggestion will be appreciated.

Edit Below is a minimal working example: the in-text citations are evenly spaced in the page and the back-reference commands in the bibliography should point to them, instead to the top of page.

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}   

\usepackage[pagebackref]{hyperref}   

\begin{document}
Top of page
\vfill
\cite{Cleveland2007}
\vfill
\cite{Spence1999}

\newpage

\begin{thebibliography}{2}
\providecommand{\natexlab}[1]{#1}
\providecommand{\url}[1]{\texttt{#1}}
\expandafter\ifx\csname urlstyle\endcsname\relax
  \providecommand{\doi}[1]{doi: #1}\else
  \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi

\bibitem[Cleveland(1984)]{Cleveland2007}
WS~Cleveland.
\newblock {Graphical perception: Theory, experimentation, and application to
  the development of graphical methods}.
\newblock \emph{Journal of the American Statistical Association}, 79\penalty0
  (387):\penalty0 531--554, 1984.

\bibitem[Spence et~al.(1999)Spence, Kutlesa, and Rose]{Spence1999}
I.~Spence, N.~Kutlesa, and D.L. Rose.
\newblock {Using color to code quantity in spatial analysis}.
\newblock \emph{Journal of Experimental Psychology: Applied}, 5:\penalty0 393,
  1999.

\end{thebibliography}
\end{document}

I compile with Pdflatex, twice.

share|improve this question

1 Answer 1

up vote 9 down vote accepted

There are essentially three parts to the patch.

  1. Adding a \phantomsection before every \cite does most of the work. These phantom sections are what the hyperrefs point back to.
  2. Convince backref to point the hyperlinks back to the phantom sections even if using page numbers as the labels.
  3. Don't let backref over-rule our hyper-target (and use the start of the document instead) if it thinks there's no section to point back to.

The patch has now been updated to hopefully work as expected in all situations, either when using natbib or not. See the post history if not interested in natbib support. Note that biblatex provides its own backref mode, but does not provide direct links, and this patch does not work there (and should not be used!)

Patch code (use in document preamble after loading the hyperref package with a backref option; note this will fail ungracefully without hyperref!):

%%%% these patches ensure that the backrefs point to the actual occurrences of the citations in the text, not just the page or section in which they appeared
%%%% http://tex.stackexchange.com/questions/54541/precise-back-reference-target-with-hyperref-and-backref
%%%% BEGIN BACKREF DIRECT PATCH, apply these AFTER loading hyperref package with appropriate backref option
% The following options are provided for the patch, currently with a poor interface!
% * If there are multiple cites on the same (page|section) (depending on backref mode),
%   should we show only the first one or should we show them all?
\newif\ifbackrefshowonlyfirst
\backrefshowonlyfirstfalse
%\backrefshowonlyfirsttrue
%%%% end of options
%
% hyperref is essential for this patch to make any sense, so it is not unreasonable to request it be loaded before applying the patch
\makeatletter
% 1. insert a phantomsection before every cite, so hyperref has something to target
%    * in case natbib is loaded. hyperref provides an appropriate hook so this should be safe, and we don't even need to check if natbib is loaded!
\let\BR@direct@old@hyper@natlinkstart\hyper@natlinkstart
\renewcommand*{\hyper@natlinkstart}{\phantomsection\BR@direct@old@hyper@natlinkstart}% note that the anchor will appear after any brackets at the start of the citation, but that's not really a big issue?
%    * if natbib isn't used, backref lets \@citex to \BR@citex during \AtBeginDocument
%      so just patch \BR@citex
\let\BR@direct@oldBR@citex\BR@citex
\renewcommand*{\BR@citex}{\phantomsection\BR@direct@oldBR@citex}%

% 2. if using page numbers, show the page number but still hyperlink to the phantomsection instead of just the page!
\long\def\hyper@page@BR@direct@ref#1#2#3{\hyperlink{#3}{#1}}

% check which package option the user loaded (pages (hyperpageref) or sections (hyperref)?)
\ifx\backrefxxx\hyper@page@backref
    % they wanted pages! make sure they get our re-definition
    \let\backrefxxx\hyper@page@BR@direct@ref
    \ifbackrefshowonlyfirst
        %\let\backrefxxxdupe\hyper@page@backref% test only the page number
        \newcommand*{\backrefxxxdupe}[3]{#1}% test only the page number
    \fi
\else
    \ifbackrefshowonlyfirst
        \newcommand*{\backrefxxxdupe}[3]{#2}% test only the section name
    \fi
\fi

% 3. now make sure that even if there is no numbered section, the hyperref's still work instead of going to the start of the document!
\RequirePackage{etoolbox}
\patchcmd{\Hy@backout}{Doc-Start}{\@currentHref}{}{\errmessage{I can't seem to patch backref}}
\makeatother
%%%% END BACKREF PATCHES

And all together in the context of an MWE (based on the provided one, but extended), and now using the biblio.bib example file which should hopefully get found automatically (otherwise use the link to get it from CTAN):

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{natbib}
\bibliographystyle{plainnat}
\usepackage[backref=page]{hyperref}

%%%% these patches ensure that the backrefs point to the actual occurrences of the citations in the text, not just the page or section in which they appeared
%%%% http://tex.stackexchange.com/questions/54541/precise-back-reference-target-with-hyperref-and-backref
%%%% BEGIN BACKREF DIRECT PATCH, apply these AFTER loading hyperref package with appropriate backref option
% The following options are provided for the patch, currently with a poor interface!
% * If there are multiple cites on the same (page|section) (depending on backref mode),
%   should we show only the first one or should we show them all?
\newif\ifbackrefshowonlyfirst
\backrefshowonlyfirstfalse
%\backrefshowonlyfirsttrue
%%%% end of options
%
% hyperref is essential for this patch to make any sense, so it is not unreasonable to request it be loaded before applying the patch
\makeatletter
% 1. insert a phantomsection before every cite, so hyperref has something to target
%    * in case natbib is loaded. hyperref provides an appropriate hook so this should be safe, and we don't even need to check if natbib is loaded!
\let\BR@direct@old@hyper@natlinkstart\hyper@natlinkstart
\renewcommand*{\hyper@natlinkstart}{\phantomsection\BR@direct@old@hyper@natlinkstart}% note that the anchor will appear after any brackets at the start of the citation, but that's not really a big issue?
%    * if natbib isn't used, backref lets \@citex to \BR@citex during \AtBeginDocument
%      so just patch \BR@citex
\let\BR@direct@oldBR@citex\BR@citex
\renewcommand*{\BR@citex}{\phantomsection\BR@direct@oldBR@citex}%

% 2. if using page numbers, show the page number but still hyperlink to the phantomsection instead of just the page!
\long\def\hyper@page@BR@direct@ref#1#2#3{\hyperlink{#3}{#1}}

% check which package option the user loaded (pages (hyperpageref) or sections (hyperref)?)
\ifx\backrefxxx\hyper@page@backref
    % they wanted pages! make sure they get our re-definition
    \let\backrefxxx\hyper@page@BR@direct@ref
    \ifbackrefshowonlyfirst
        %\let\backrefxxxdupe\hyper@page@backref% test only the page number
        \newcommand*{\backrefxxxdupe}[3]{#1}% test only the page number
    \fi
\else
    \ifbackrefshowonlyfirst
        \newcommand*{\backrefxxxdupe}[3]{#2}% test only the section name
    \fi
\fi

% 3. now make sure that even if there is no numbered section, the hyperref's still work instead of going to the start of the document!
\RequirePackage{etoolbox}
\patchcmd{\Hy@backout}{Doc-Start}{\@currentHref}{}{\errmessage{I can't seem to patch backref}}
\makeatother
%%%% END BACKREF PATCHES

\begin{document}
Top of page. No sections at all here yet.
\vfill
\cite{GSM97}
\vfill
\cite{Lam94}
\section*{Unnumbered}
Check that things work in unnumbered sections.

\cite{Lam94}

\newpage
\section{Numbered}
And in numbered sections!

This is just a test \citep{GSM97} on another page and not at the start of the line to see how well things work.

And other citation to something already cited \cite{GSM97} on the same page in the same section.

\section{Another numbered one}
And another dupe test \citet{GSM97}.

\newpage
\bibliography{biblio}
\end{document}

Note that this example uses \citet and \citep from natbib just to check that they work as expected.

share|improve this answer
    
Hey! Thank you for digging up the question. I like your idea of using \phantomsection, it seems to be a panacea for many hyperref-related problems. Unfortunately, I didn't manage to get either of your solution to produce the required results. I tried a MWE (in the question, edited), either with the patch (before or after hyperref is loaded) or by adding \phantomsection near the \cite command. Am I missing something? Thank you for your suggestion. –  MatteoS Aug 19 '12 at 22:30
    
I wondered if you were using page numbers or section numbers in your back references. My suggestion only works if you use section numbers at the moment, i.e. \usepackage[backref=section]{hyperref}. It also only apparently works if there is at least one numbered section in the document! I will take a look to see if I am able to relax either of these restrictions when I get a chance, but I'm also hoping that I've now provided enough information for someone else to be able to take a look. I know David Carlisle is partly responsible for the backref package and he comes on here sometimes... –  cyberSingularity Aug 19 '12 at 22:43
    
I see. Now it works, but now the back reference in the bibliography is to the section, not the page. Still, we're getting closer. I added the MWE to your answer, I hope you don't mind. –  MatteoS Aug 19 '12 at 22:52
    
Note update. I think it is now working in all cases. (It was actually easier than I thought!) Once people have verified and reviewed it, and determined if it is likely to break any other packages or not, I will ask if it can be incorporated into the main backref.sty. (Thanks for asking the question and prompting this! It was perhaps the main reason I wasn't using backref myself...) –  cyberSingularity Aug 20 '12 at 23:58
1  
@MatteoS: Having conducted further testing with the natbib package, note that it previously would fail for \citep and \citet. The update I have just made should allow it to work in those situations also. –  cyberSingularity Dec 29 '12 at 12:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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