1

I want to make my PDF more web-accessible.

Currently, \cite links to the entry in the bibliography section. This is fine. But I want to extend it, by a small hyperlink symbol, so that [Author 2000] becomes maybe [Author 2000 <link-symbol>] in the text.

The <link-symbol> could use some symbol from fontawesome like \faChain or \faExternalLink. And it should link to some URL (which I could define in the bibtex file, maybe a separate new entry like external_href -- this should be independent from any URL shown in the bibliography section).

How would I do sth like this?


Some details about my environment, although I hope that the answer could be generic that this does not matter. (I don't really know if any of this matters...)

I use \documentclass{scrbook}.

I don't really import any cite/bibtex related packages as far as I know, except maybe \usepackage{breakcites} (but no natbib nor biblatex).

In the end of my tex file, I have this:

\bibliographystyle{i6bibliostyle}
\bibliography{thesis}

So this is some custom bib style. But I think this is only about the style in the bibliography section (not sure).

3
  • this things can be done rather easily with biblatex, but not with a traditional bibliography style (there bibliography style also provides the info which can be used in cite commands and if it doesn't provide your url there is not much you can do) Jan 20, 2021 at 12:22
  • @UlrikeFischer Shouldn't this be easy with Bibtex as well? I'm looking at the custom i6bibliostyle.bst file. I don't really understand that code. What programming language is that? Where do I find documentation about it? But it looks like I might be able to modify the function calc.label in there to add a \href in some way...
    – Albert
    Jan 20, 2021 at 12:37
  • Ah, I think this is the reference bst code documentation, right?
    – Albert
    Jan 20, 2021 at 12:40

1 Answer 1

2

A scheme like this needs support on two sides: You need to extract the relevant data from the .bib file and you need to use that data in the citation.

With the normal BibTeX approach the entry data is not available when citations are generated, so the standard method to make something usable in citations is to write it to the .aux file. (In theory there are other methods like usebib that parse the .bib file in LaTeX directly, but that has its limits.)

So firstly, you need to tell your BibTeX style about the new field you intend to use to pass the URL on to LaTeX.

This is fairly straightforward if you have gotten the hang of the BibTeX programming language. The exact steps you have to do will vary from style to style. For this answer I use plain.bst as an example.

  1. Copy plain.bst to a place where LaTeX can find it (the directory of your current document will do) and rename it to plain-hrefcite.bst.

  2. Add a short note about the nature of the file in the comments at the beginning.

  3. Make the new field, say href, (and if necessary url) known to BibTeX by adding it to the first list in ENTRY at the beginning of your .bst file.

  4. Add code to write the href info to the .bbl file. This can be done by adding something like

    href empty$
      { url }
      { href }
    if$
    duplicate$ empty$
      'pop$
      {
        "\bbldefcitehref{" cite$ * "}{" * swap$ * "}" * write$
        newline$
      }
    if$
    

    to the function that prints the \bibitem (in the example FUNCTION {output.bibitem}).

  5. Just to be sure give a fallback definition for \bbldefcitehref in the function that writes \begin{thebibliography} (in our example FUNCTION {begin.bib})

    "\providecommand*{\bbldefcitehref}[2]{}" write$ newline$
    

The exact details of the modification will differ from style to style, but the general idea should be applicable to a broad range of styles.

You can get the modified version of plain.bst called plain-hrefcite.bst from https://gist.github.com/moewew/783770c4abbb3ce7cbfb84069c3c5a32. The changes to the original file are nicely highlighted in the revision tab and come down to

--- plain.bst   2010-12-09 04:18:56.000000000 +0100
+++ plain-hrefcite.bst  2021-01-21 08:04:09.349426800 +0100
@@ -1,3 +1,13 @@
+%%%% plain-hrefcite.bst
+%%%% 2021-01-21 MW
+%%%%
+%%%% add a linked item to citation label
+%%%%
+%%%% https://tex.stackexchange.com/q/579660/35864
+%%%%
+%%%% added a href field and write its contents to the bbl in \bbldefcitehref
+%%%%
+%%%%
 % BibTeX standard bibliography style `plain'
    % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later.
    % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik.
@@ -31,6 +41,8 @@
     type
     volume
     year
+    url
+    href
   }
   {}
   { label }
@@ -88,6 +100,17 @@
   cite$ write$
   "}" write$
   newline$
+  href empty$
+    { url }
+    { href }
+  if$
+  duplicate$ empty$
+    'pop$
+    {
+      "\bbldefcitehref{" cite$ * "}{" * swap$ * "}" * write$
+      newline$
+    }
+  if$
   ""
   before.all 'output.state :=
 }
@@ -1080,6 +1103,7 @@
     'skip$
     { preamble$ write$ newline$ }
   if$
+  "\providecommand*{\bbldefcitehref}[2]{}" write$ newline$
   "\begin{thebibliography}{"  longest.label  * "}" * write$ newline$
 }
 
 
 

Then it is just a matter of transferring the information from the .bbl file to the .aux file so it is available in citations from the start. With that sorted we can print the information in citations by modifying the macro that implements \cite (if you don't load any citation or bibliography-related packages, the relevant macro will be \@citex from the LaTeX kernel).

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{fontawesome}
\usepackage[colorlinks]{hyperref}

\makeatletter
\newcommand*{\bbldefcitehref}[2]{%
  \immediate\write\@mainaux{\noexpand\auxdefcitehref{\unexpanded{#1}}{\unexpanded{#2}}}}

\newcommand*{\auxdefcitehref}[2]{%
  \expandafter\global\expandafter\def\csname citehref@#1\endcsname{#2}}

\newcommand*{\mkcitehref}[1]{%#
  \ifx#1\empty
    \ \href{https://example.edu}{\faExternalLink}%
  \fi
  \ifcsname citehref@#1\endcsname
    \ \href{\csname citehref@#1\endcsname}{\faExternalLink}%
  \fi}

\def\@citex[#1]#2{\leavevmode
  \let\@citea\@empty
  \@cite{\@for\@citeb:=#2\do
    {\@citea\def\@citea{,\penalty\@m\ }%
     \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
     \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
     \@ifundefined{b@\@citeb}{\hbox{\reset@font\bfseries ?}%
       \G@refundefinedtrue
       \@latex@warning
         {Citation `\@citeb' on page \thepage \space undefined}}%
       {\@cite@ofmt{\csname b@\@citeb\endcsname
          \mkcitehref{\@citeb}}}}}{#1}}

\def\@lbibitem[#1]#2{\def\hrefcite@currentkey{#2}\item[\@biblabel{#1}\hfill]\if@filesw
      {\let\protect\noexpand
       \immediate
       \write\@auxout{\string\bibcite{#2}{#1}}}\fi\ignorespaces}
\def\@bibitem#1{\def\hrefcite@currentkey{#1}\item\if@filesw \immediate\write\@auxout
       {\string\bibcite{#1}{\the\value{\@listctr}}}\fi\ignorespaces}

\newcommand*{\hrefcite@currentkey}{}

\def\@biblabel#1{[#1\mkcitehref{\hrefcite@currentkey}]}
\makeatother


\begin{filecontents}{\jobname.bib}
@book{elk,
  author    = {Anne Elk},
  title     = {A Theory on Brontosauruses},
  year      = {1972},
  publisher = {Monthy \& Co.},
  location  = {London},
  href      = {https://example.edu/~elk/bronto.pdf},
}
@book{belk,
  author    = {Anne Belk},
  title     = {A Theory on Brontosauruses},
  year      = {1972},
  publisher = {Monthy \& Co.},
  location  = {London},
  url       = {https://example.edu/~elk/bronto.pdf},
}
@article{sigfridsson,
  author  = {Sigfridsson, Emma and Ryde, Ulf},
  title   = {Comparison of methods for deriving atomic charges from the
             electrostatic potential and moments},
  journal = {Journal of Computational Chemistry},
  year    = 1998,
  volume  = 19,
  number  = 4,
  pages   = {377-395},
  doi     = {10.1002/(SICI)1096-987X(199803)19:4<377::AID-JCC1>3.0.CO;2-P},
}
\end{filecontents}


\begin{document}
Lorem \cite{sigfridsson,elk,belk}

\bibliographystyle{plain-hrefcite}
\bibliography{\jobname}
\end{document}

Citation and bibliography labels are linked.

8
  • Wow. That is perfect. Thank you so much for the effort. I mostly understand the bst (Bibtex) language now after reading the documentation. But my Latex knowledge is really lacking. In principle I understand the concept of the aux file and the bbl file, and what you do there. But I don't really understand the details, such as \immediate, \string, \unexpanded, \expandafter\global, \leavevmode etc.
    – Albert
    Jan 20, 2021 at 20:58
  • Some small possible extensions: Now I wonder whether it would maybe be nice if the same link, in the same style, also in the references section, i.e. [1 <link>] in your example. And again I would not quite know how to achieve that... Or also, instead of using href, maybe it could also check url as a fallback if href is not defined?
    – Albert
    Jan 20, 2021 at 21:13
  • 1
    @Albert There is quite a bit going on in the LaTeX code. Have a look at tex.stackexchange.com/q/115932/35864, tex.stackexchange.com/q/10919/35864 and tex.stackexchange.com/q/24639/35864 for \immediate\write and general explanations about writing to the .aux file (the \string and \unexpanded are to stop LaTeX from trying to expand the macros before they are written to the file). The \expandafter thingy is the usual idiom to define a macro with a name that depends on other input (tex.stackexchange.com/q/451, tex.stackexchange.com/q/64020) ...
    – moewe
    Jan 21, 2021 at 6:39
  • ... The definition of \@citex with all its \leavevmodes comes from latex.ltx I only added the \mkcitehref{\@citeb} (near the end) to typeset the link label.
    – moewe
    Jan 21, 2021 at 6:43
  • 1
    For the link in the bibliography see the edit.
    – moewe
    Jan 21, 2021 at 7:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .