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.

In my bibliography style, I have added a trigger to change the biblatex bibliography back reference mechanism to refer to the paragraph numbers in the margins ("runners") instead of pages.

\def\blx@addbackref@i#1{%
  \ifbacktracker
    \blx@leavevmode
    \if@filesw
      \protected@write\@mainaux{}{\string\abx@aux@backref
        {\the\c@instcount}{#1}{\the\c@refsection}%
        {\ifbool{bbx:runner}%
          {\therunner}%
          {\thepage}}%
      {\noexpand\the\c@page}}%
    \fi
  \fi%
 }

\therunner is added to a paragraph by using the macro from the jurabook class

\newcommand*{\rn}[2][]{%
  \if@dorunners%
    \stepcounter{runner}%
    #2\marginpar%
      [\hfill{\small\sffamily\therunner}\hspace*{\jb@runnersspace@length}]%
      {\hspace*{\jb@runnersspace@length}{\small\sffamily\therunner}\hfill}%
    \protected@edef\@currentlabel{\therunner}%
   \else%
    #2
  \fi% do NOT delete the percentage sign
  \ifthenelse{\equal{#1}{\@empty}}%
    {}% nix
    %else
    {\label{#1}}%
}

Since the runner mechanism is the only feature from the jurabook class I needed, I have copied that macro into my preamble rather than using the entire class.

If I now set the biblatex option runner to true, thus switching bbx:runner to true, the back reference numbers shown in the bibliography show the paragraph numbers shown in the document margins rather than the page numbers for each cited entry.

However, if I click the number, the link takes me to the page corresponding to the number rather than the paragraph corresponding to the number. This means that I have an entry that is cited in paragraph number 10 on page 6, the number shown in the bibliography will be 10. Clicking that number, however, takes me to page number 10.

Does anyone know how I need to adjust the back referencing mechanism to make the paragraph the hyperref target of the numbers shown in the biblatex bibliography?

share|improve this question
    
This is not the best place for asking this, but I see from your other questions that you are writing a BibLaTeX style for legal citations. Would it be possible to discuss this topic with you, privately perhaps? I have the same problem (in French, though) and would be very interested in knowing how you are dealing with it. — Sorry I can't help with your question, I have no knowledge of hyperref. –  ienissei Jan 28 '12 at 19:38
1  
Maybe it is possible and simpler to use \hyperlink and \hypertarget directly? I have used this combo in a similar situation - questions in the running text, and answers at the chapter end pointing to each other. –  Michael Palmer Jan 29 '12 at 18:56
    
@MichaelPalmer My thesis currently contains around 600 cases cited, and since many are cited multiple times, probably over a 1000 case citations. Furthermore, my ambition is to have a feature complete legal citation style at some point. Shouldn't I be able to somehow set a \hypertarget each time \blx@addbackref@i is called and then patch the back reference mechanism in biblatex to refer to this target? My problem basically is that I don't know how biblatex sets the link? Does it use \hyperlink? How does it determine the argument for it? I understand the biblatex.sty code too little. –  jjbornheim Jan 29 '12 at 22:18
    
@jjbornheim It does use \hyperlink, and probably prefixes the argument with page.. The link is set by the pageref bibmacro in standard styles. You can see this by taking a look at standard.bbx. The pageref bibmacro is defined in biblatex.def. –  Audrey Jan 31 '12 at 14:45
    
Thanks @Audrey. Here is what I learned so far. The pageref macro prints the pageref link. The hyperlinking is done by the list formatting for this list. If the pageref list contains more than one item, \DeclareListFormat{pageref} calls, amongst others, three macros: pageref:init, pageref:comp and pageref:dump. If the pageref list contains exactly one item, it is printed by \hyperlink{page.#1}{#1} (provided hyperrefs are used). So in the easiest example (only one back reference), I would need to modify \hyperlink{page.#1}{#1} to refer to the therunner rather than thepage. –  jjbornheim Jan 31 '12 at 15:48

2 Answers 2

up vote 9 down vote accepted

A whole lot goes on under the hood to collect and set the list of page numbers in back references. One easy way out of your problem is to make the page hyperlinks set by the pageref bibliography macro point to runners via \hypertarget.

The document below illustrates this approach. I've closely followed the code you provided, but you might prefer other ways to set paragraph numbers. \hypertarget links to the baseline of its second argument, which is too low for runners. I've adapted the solution in this post to raise the link.

\documentclass[twoside]{report}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{csquotes}
\usepackage[backref]{biblatex}
\usepackage[colorlinks]{hyperref}
\usepackage{lipsum}

\newtoggle{bbx:runner}
\toggletrue{bbx:runner}

\iftoggle{bbx:runner}
  {\DefineBibliographyStrings{german}{%
     backrefpage = {siehe Rn\adddot},
     backrefpages = {siehe Rn\adddot}}}
  {}

\newcounter{runner}
\renewcommand{\therunner}{%
  \iftoggle{bbx:runner}{\arabic{runner}}{\thepage}}

\newlength{\runnersep}
\setlength{\runnersep}{0.5em}

\makeatletter

\patchcmd{\blx@addbackref@i}{\thepage}{\therunner}{}{}
\patchcmd{\blx@addbackref@i}{\c@page}{\c@runner}{}{}

\newcommand{\backreftarget}[1]{%
  \Hy@raisedlink{\hypertarget{page.#1}{}}\small#1}

\newcommand*{\rn}[2][]{%
  \iftoggle{bbx:runner}
    {\stepcounter{runner}#2%
     \marginpar%
       [\hfill{\backreftarget{\therunner}}\hspace*{\runnersep}]%
       {\hspace*{\runnersep}{\backreftarget{\therunner}}\hfill}}
    {\setcounter{runner}{\value{page}}#2}%
  \protected@edef\@currentlabel{\therunner}%
  \ifblank{#1}{}{\phantomsection\label{#1}}}

\makeatother

\newcommand*{\rnref}[1]{%
  \iftoggle{bbx:runner}{Rn.~\ref{#1}}{S.~\ref{#1}}}

\addbibresource{biblatex-examples.bib}

\begin{document}
\rn{Filler} text \parencite{ctan,markey}. \lipsum[1] \vfill
\rn{Filler} text \parencite{companion}. See \rnref{run}. \lipsum[2]
\chapter{Titel}
\rn{Filler} text \parencite{companion,markey}. \lipsum[3]
\chapter{Titel}
\rn[run]{Filler} text \parencite{companion,markey}. \lipsum[4]
\printbibliography
\end{document}

Here's the bibliography from the resulting document.

enter image description here

Commenting out \toggletrue{bbx:runner} back-references page numbers.

enter image description here

share|improve this answer
    
Thanks a lot Audrey. I didn't notice I was logged out, so it took me a while to see your response. Your code does exactly what I want. –  jjbornheim Feb 22 '12 at 11:45

I wanted to add a small detail to Audrey's solution. It bugged me that after I implemented the code, I would get warnings from hyperref like

destination with the same identifier (name{page.19}) has been already used

I figured they were due to the fact that a destination by the same name is already set by the page numbering mechanism. So I changed

\newcommand{\backreftarget}[1]{%
  \Hy@raisedlink{\hypertarget{page.#1}{}}\small#1}

to

\newcommand{\backreftarget}[1]{%
  {\Hy@raisedlink{\hypertarget{runner.#1}{}}}\small#1}

and added another \iftoggle{bbx:runner} test to change every instance of \hyperlink{page. to \hyperlink{runner. in the pageref format, pageref:comp and pageref:dump bibliography macros defined in biblatex.def. These edits can easily be made using egreg's extension of etoolbox patch commands.

\makeatletter

\def\act@on@bibmacro#1#2{%
  \expandafter#1\csname abx@macro@\detokenize{#2}\endcsname}
\def\patchbibmacro{\act@on@bibmacro\patchcmd}

\def\act@on@listformat#1#2{%
  \expandafter#1\csname abx@lfd@*@\detokenize{#2}\endcsname}
\def\patchlistformat{\act@on@listformat\patchcmd}

\iftoggle{bbx:runner}
  {\patchlistformat{pageref}{page.}{runner.}{}{}%
   \patchbibmacro{pageref:comp}{page.}{runner.}{}{}%
   \patchbibmacro{pageref:comp}{page.}{runner.}{}{}%
   \blx@tempcnta\z@%
   \loop\ifnum\blx@tempcnta<10
     \patchbibmacro{pageref:dump}{page.}{runner.}{}{}%
     \advance\blx@tempcnta\@ne
   \repeat}
  {}

\makeatother
share|improve this answer
    
+1 In \rn, \backreftarget is issued only when bbx:runner is true. So you can just replace page with runner in the original definition. Those bibliography macro edits might be less of a pain using \xpatchbibmacro from egreg's xpatch package. –  Audrey Feb 22 '12 at 16:35
    
D'oh @Audrey, thanks for pointing that out. I modified my answer accordingly to make the definition of '\backreftarget` independent of bbx:runner's value. Also thanks for suggesting \xpatchbibmacro. I might do that later to make the code more elegant, but as it stands, it does what needs to be done. I simply patched the macros using find and replace in my text editor. –  jjbornheim Feb 22 '12 at 18:36
    
I added patches for the pageref format and related bibliography macros. Hope you don't mind. Please feel free to edit or omit the new content as you see fit. –  Audrey Jun 11 '12 at 2:11

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.