Bibliography: add a small "open access" logo in the margin

Update Version 0.6 of biblatex-ext comes with the support package biblatex-ext-oa that can be used to display open access symbols. biblatex-ext-oa can be used with styles other than those from biblatex-ext as well, it should certainly work for the standard styles and possibly for many contributed styles as well.

Version 0.7 slightly changes the interface for selecting the open access symbol and introduces new package options to draw them (symbolpackage with values pict2e, l3draw and tikz)

biblatex-ext-oa

The package biblatex-ext-oa supports two main methods for finding the best known open access URL that is linked from the symbol: (i) A semi-automatic heuristic based on the data given in the .bib file and governed by configuration commands and (ii) a fully automatic Lua module (can only be used with LuaLaTeX) that queries Unpaywall.org using the DOI.

The following gives a short rundown of the most important bits and bobs of biblatex-ext-oa, for a more detailed description, please consult §7 Open Access Symbols of the biblatex-ext documentation.

auto: semi-automatic heuristic

The heuristic relies on data in the .bib file and additional configuration to identify open access links. This heuristic (which can be also be set with \ExecuteBibliographyOptions{openaccess=auto} after biblatex-ext-oa has been loaded) is the default when biblatex-ext-oa is loaded.

The main idea is that certain fields and eprinttypes are so-called 'open access fields', which means that they can deliver open access URLs. Such URLs can be of two types: Either they are always open access (type 'always': like eprinttype = {arxiv}) or they are only open access under certain conditions (type 'conditional': like the doi field or eprinttype = {jstor}). Fields of type 'conditional' only return open access URLs if they are marked with the openaccess field annotation in the .bib file (see the MWE below).

If there are several possible open access URLs, a simple priority order decides which one gets to be the 'best open access URL'. If an entry has a 'best open access URL' a little open access symbol is shown in the margin and the URL is linked from there.

By default biblatex-ext-oa has sensible defaults for url, doi and the eprinttypes arxiv, jstor, hdl and pubmed. If you add a new eprinttype, you will have to declare its open access links and state to be able to use that type for open access detection. See the definitions for hal in the example below. The same holds if you want to define an entirely new field for open access URLs.

This is a comprehensive example that shows how openaccess=auto works

\documentclass[british]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber, style=numeric]{biblatex}
\usepackage[symbolpackage=pict2e, symbol=plos]{biblatex-ext-oa}

\usepackage{kantlipsum}
\usepackage[colorlinks]{hyperref}

\newcommand*{\halurl}[1]{http://hal.archives-ouvertes.fr/#1}
\DeclareFieldFormat{eprint:hal}{%
  \ifhyperref
    {\href{\halurl{#1}}{hal:~\nolinkurl{#1}}}
    {hal:~\nolinkurl{#1}}}
\DeclareFieldAlias{eprint:HAL}{eprint:hal}

% HAL is always open access (I think)
\DeclareOpenAccessEprintUrl[always]{hal}{%
  http://hal.archives-ouvertes.fr/\thefield{eprint}}
\DeclareOpenAccessEprintAlias{HAL}{hal}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
% open access DOIs need to be marked up explicitly
@article{cipriani,
  author  = {Cipriani, Alessandra and Hazra, Rajat Subhra
             and Ruszel, Wioletta M.},
  title   = {Scaling limit of the odometer in divisible sandpiles},
  journal = {Probability Theory and Related Fields},
  date    = {2018},
  volume  = {172},
  number  = {3},
  pages   = {829--868},
  doi     = {10.1007/s00440-017-0821-x},
  doi+an  = {=openaccess},
}
% arXiv is always open access
@online{meckes,
  author      = {Elizabeth Meckes and Kathryn Stewart},
  title       = {On the eigenvalues of truncations
                 of random unitary matrices},
  eprinttype  = {arxiv},
  eprint      = {1811.08340},
  eprintclass = {math.PR},
  date        = {2018-11-20}
}
% DOI is not open access, the arXiv has an open access version
@article{dolan,
  author      = {Matthew J. Dolan and Christoph Englert and Michael Spannowsky},
  title       = {Higgs self-coupling measurements at the {LHC}},
  journal     = {Journal of High Energy Physics},
  volume      = {2012},
  number      = {10},
  doi         = {10.1007/jhep10(2012)112},
  eid         = {112},
  date        = {2012},
  eprint      = {1206.5001},
  eprinttype  = {arxiv},
  eprintclass = {hep-ph},
}
% new eprinttype hal: is always open access, see
% \DeclareOpenAccessEprintUrl[always]{hal}{...}
@online{labbe,
  title      = {New models for the location of \emph{controversial}
                facilities},
  subtitle   = {A bilevel programming approach},
  author     = {Labbé, Martine and Leal, Marina and Puerto, Justo},
  date       = {2018-11},
  eprinttype = {hal},
  eprint     = {hal-01933601},
}
% no open access that I know of
@article{sigfridsson,
  author       = {Sigfridsson, Emma and Ryde, Ulf},
  title        = {Comparison of methods for deriving atomic charges from the
                  electrostatic potential and moments},
  journaltitle = {Journal of Computational Chemistry},
  date         = 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},
}
% non-open JSTOR
@article{russell:denoting,
  author     = {Bertrand Russell},
  title      = {On Denoting},
  journal    = {Mind},
  series     = {newseries},
  volume     = {14},
  number     = {56},
  date       = {1905-10},
  pages      = {479-493},
  eprinttype = {jstor},
  eprint     = {2248381},
}
% open access JSTOR
@article{russell:atomism,
  author     = {Bertrand Russell},
  title      = {The Philosophy of Logical Atomism},
  subtitle   = {{V}. {General} Propositions and Existence},
  journal    = {The Monist},
  volume     = {29},
  number     = {2},
  date       = {1919-04},
  pages      = {190-222},
  eprinttype = {jstor},
  eprint     = {27900737},
  eprint+an  = {=openaccess},
}
\end{filecontents*}


\addbibresource{\jobname.bib}
\begin{document}
\kant[1]
\nocite{*}
\printbibliography
\end{document}

Screenshot of the bibliography section of the MWE. All entries but <code>sigfridsson</code> have a small open access logo.

doiapi: fully automatic open access detection with Unpaywall.org

Inspired by Eric Marsden's answer the package also features a Lua module that queries open access information from Unpaywall.org based on the DOI.

The module can only be used with LuaLaTeX and needs to be loaded by passing the option doiapi=true to biblatex-ext-oa. The option can then be enabled with \ExecuteBibliographyOptions{openaccess=doiapi}. If doiapi is enabled, biblatex-ext-oa will query the best open access URL from the Unpaywall API. To reduce load to the API the results are cached in a temporary .oai file.

Please note that the Unpaywall API can only be used if you supply an email address. You can do this with \SetDOIAPIMail. You will be warned if you load the doiapi module and forget to give an email. It is a fatal error to query the database if no mail address was given.

Uncomment \SetDOIAPIMail and give a valid email address before you run the following MWE with LuaLaTeX. Note the different symbol compared to the previous MWE, the symbol option allows you to switch between plos (the default, above) and oanet (here) if symbolpackage is set to one of the values pict2e, l3draw or tikz.

\documentclass[british]{article}
\usepackage{etoolbox}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber, style=numeric]{biblatex}
\usepackage[doiapi=true, symbolpackage=tikz, symbol=oanet]{biblatex-ext-oa}
% symbolpackage=tikz chooses open access symbols drawn in TikZ
% symbol=oanet gives an the open access symbol from
% open-access.net (https://open-access.net/),
% logo by
% Medien + Design
% Center for Digital Systems
% Competence Center for E-Learning and Multimedia
% Freie Universität Berlin
% CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
\ExecuteBibliographyOptions{openaccess=doiapi}

%\SetDOIAPIMail{<your email here>}% <- this MUST be set for doiapi
%\SetDOIAPICacheExpiration{15}% if you like, you can set the expiration period
                              % for the cache here, default is seven days

\usepackage{kantlipsum}
\usepackage[colorlinks]{hyperref}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
% this article is open access at the source
@article{valfort,
  author   = {Valfort, Aurore-Cécile and Launay, Caroline and Sémon, Marie
              and Delattre, Marie},
  title    = {Evolution of mitotic spindle behavior during the first
              asymmetric embryonic division of nematodes},
  journal  = {PLOS Biology},
  date     = {2018-01},
  volume   = {16},
  number   = {1},
  pages    = {1-23},
  doi      = {10.1371/journal.pbio.2005099},
}
% has open access version on Harvard DASH
@article{kucsko,
  author   = {G. Kucsko and P. C. Maurer and N. Y. Yao and M. Kubo
              and H. J. Noh and P. K. Lo and H. Park and M. D. Lukin},
  title    = {Nanometre-scale thermometry in a living cell},
  journal  = {Nature},
  volume   = {500},
  number   = {7460},
  pages    = {54--58},
  doi      = {10.1038/nature12373},
  date     = {2013},
}
% has open access version on the arXiv
@article{randall,
  author   = {Lisa Randall and Raman Sundrum},
  title    = {Large Mass Hierarchy from a Small Extra Dimension},
  journal  = {Physical Review Letters},
  year     = {1999},
  volume   = {83},
  number   = {17},
  pages    = {3370--3373},
  doi      = {10.1103/physrevlett.83.3370},
}
% second open access at HAL
@article{abiakle,
  author     = {Abi Akle, Audrey and Stéphanie Minel and Bernard Yannou},
  title      = {Information visualization for selection in Design by Shopping},
  journal    = {Research in Engineering Design},
  volume     = {28},
  number     = {1},
  year       = {2017},
  pages      = {99--117},
  doi        = {10.1007/s00163-016-0235-2},
}
% no open access that I know of
@article{sigfridsson,
  author       = {Sigfridsson, Emma and Ryde, Ulf},
  title        = {Comparison of methods for deriving atomic charges from the
                  electrostatic potential and moments},
  journaltitle = {Journal of Computational Chemistry},
  date         = 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*}


\addbibresource{\jobname.bib}
\begin{document}
\kant[1]
\nocite{*}
\printbibliography
\end{document}

Screenshot of the references section: All entries except for <code>sigfridsson</code> have a little open access symbol.


This is the old version of the answer.

Old answer

Here is one attempt that should address both requirements.

Instead of a OA keyword I went with an option openaccess, since I felt that an option would be more natural here. But it is straightforward to change the code to work with a keyowrd. (You only need to replace \iftoggle{bbxpluton:openaccess} with \ifkeyword{OA}).

The non-trivial bit was to obtain the URL to which the open access symbol should be linked. For certain eprint types the actual URL to link is only put together when the field is processed for printing, the full URL is never 'known' to biblatex. This was solved by defining the macro \pluton@getoaurl. The macro needs a branch for each eprinttype you intend to use.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
\usepackage[backend=biber, style=numeric]{biblatex}
\usepackage[hidelinks]{hyperref}

\usepackage{kantlipsum}

\makeatletter
\newtoggle{bbxpluton:openaccess}
\DeclareEntryOption[boolean]{openaccess}[true]{%
  \settoggle{bbxpluton:openaccess}{#1}}


\newcommand*{\pluton@getoaurl}{%
  \undef\bbx@pluton@oaurl
  \iftoggle{bbxpluton:openaccess}
    {% URL and DOI are only open access if indicated
     \iffieldundef{url}
       {}
       {\def\bbx@pluton@oaurl{\thefield{url}}}%
     \iffieldundef{doi}
       {}
       {\def\bbx@pluton@oaurl{%
          https://doi.org/\thefield{doi}}}%
     % the eprinttypes listed here are open access only if indicated
     \iffieldundef{eprint}
       {}
       {\ifboolexpr{   test {\iffieldequalstr{eprinttype}{jstor}}
                    or test {\iffieldequalstr{eprinttype}{JSTOR}}}
          {}
          {\def\bbx@pluton@oaurl{%
             http://www.jstor.org/stable/\thefield{eprint}}}%
        \ifboolexpr{   test {\iffieldequalstr{eprinttype}{hdl}}
                    or test {\iffieldequalstr{eprinttype}{HDL}}}
          {}
          {\def\bbx@pluton@oaurl{%
             http://hdl.handle.net/\thefield{eprint}}}%
        \ifboolexpr{   test {\iffieldequalstr{eprinttype}{pubmed}}
                    or test {\iffieldequalstr{eprinttype}{PubMed}}}
          {}
          {\def\bbx@pluton@oaurl{%
             http://www.ncbi.nlm.nih.gov/pubmed/\thefield{eprint}}}%
       }%
    }
    {}%
  % eprinttype listed here are always open access
  \iffieldundef{eprint}
    {}
    {\ifboolexpr{   test {\iffieldequalstr{eprinttype}{arxiv}}
                 or test {\iffieldequalstr{eprinttype}{arXiv}}}
       {\def\bbx@pluton@oaurl{%
          https://arxiv.org/\abx@arxivpath/\thefield{eprint}}}
       {}%
     \iffieldequalstr{eprinttype}{hal}
       {\def\bbx@pluton@oaurl{%
          http://hal.archives-ouvertes.fr/\thefield{eprint}}}
       {}%
    }%
}

\AtEveryBibitem{\pluton@getoaurl}

\renewbibmacro*{begentry}{%
  \ifundef\bbx@pluton@oaurl
    {}
    {\oamark@link}}

% based on egreg's answer to https://tex.stackexchange.com/a/123451/35864
% originally CC BY-SA 3.0, but dual-licensed under LPPL
% see https://tex.meta.stackexchange.com/a/3333/35864
\newcommand{\oamark@link}{\strut\vadjust{\dooamark@link}}
\newcommand{\dooamark@link}{%
  \vbox to 0pt{
    \kern-3\dp\strutbox
    \strut\hfill\rlap{\kern1em
      \ifhyperref
        {\href{\bbx@pluton@oaurl}{\oasymbol}}
        {\oasymbol}}
    \vss
  }%
}


% PLoS Open Access symbol based on
% https://commons.wikimedia.org/wiki/File:Open_Access_logo_PLoS_white.svg
% public domain/CC0 by PLoS & Wikipedia users Nina, Beao and JakobVoss
\definecolor{oaploscol}{HTML}{f68212}
\newcommand*{\oaplossymbol}{%
  \begin{tikzpicture}[x=.1pt,y=.1pt]
    \fill[oaploscol] (06,73)   arc (180:0:26);
    \fill[white]     (17,72.9) arc (180:-45:15);
    \fill[oaploscol] (47,32) rectangle ++ (11,41.1);
    \fill[oaploscol] (32,32) circle[radius=32];
    \fill[white]     (32,32) circle[radius=21];
    \fill[oaploscol] (32,32) circle[radius= 9];
  \end{tikzpicture}
}

% Open-Acess.net Open Acess symbol
% redrawn with TikZ from
% http://open-access.net/fileadmin/logos/oa.svg
% public domain according to
% https://commons.wikimedia.org/wiki/File:Open_access.svg
% might be covered by open-access.net's overall CC-BY 4.0
% https://creativecommons.org/licenses/by/4.0/
% https://open-access.net/impressum/
% the site states no specific conditions for use of the logo
% other than
%   "Das Logo der Informationsplattform darf nachgenutzt werden,
%    gerne mit einem Link zu open-access.net"
% on https://open-access.net/ueber-uns/
% see also https://open-access.net/community/materialien/
% logo by
% Medien + Design
% Center for Digital Systems
% Competence Center for E-Learning and Multimedia
% Freie Universität Berlin
\definecolor{oanetgreen}{HTML}{356031}
\definecolor{oanetyellow}{HTML}{f9c63a}
\definecolor{oanetintersect}{HTML}{89923a}

\newcommand*{\oanetsymbol}{%
  \begin{tikzpicture}[x=1.1pt,y=1.1pt]
    \fill[oanetgreen] (4,4) circle[radius=4.3];
    \fill[oanetyellow] (11,4) ++ (0:4.3) arc (0:300:4.3)
      -- (11,4) ++ (300:4.3) -- cycle;
    \begin{scope}
      \clip (4,4) circle[radius=4.3];
      \fill[oanetintersect] (11,4) circle[radius=4.3];
    \end{scope}
    \fill[white] (4,4) circle[radius=2.7];
    \fill[white] (11,4) circle[radius=2.7];
    \fill[oanetyellow] (11,4) ++ (2.7,.1) rectangle ++(1.6,-4.1);
  \end{tikzpicture}
}

% reusable box for the symbol, so the image is not
% processed on every use
\newsavebox{\oasymbolbox}
% choose \oaplossymbol or \oanetsymbol here
\sbox{\oasymbolbox}{\oaplossymbol}
\newcommand*{\oasymbol}{\usebox{\oasymbolbox}}

\newcommand*{\halurl}[1]{http://hal.archives-ouvertes.fr/#1}
\DeclareFieldFormat{eprint:hal}{%
  \ifhyperref
    {\href{\halurl{#1}}{hal:~\nolinkurl{#1}}}
    {hal:~\nolinkurl{#1}}}
\makeatother


\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@article{bib:A,
  author  = {Anne Uthor},
  title   = {Generic Title},
  journal = {Journal},
  year    = {2018},
}
@article{bib:B,
  author     = {Anne Uthor},
  title      = {Open Access Title (HAL)},
  journal    = {Open Journal},
  year       = {2018},
  eprinttype = {hal},
  eprint     = {hal-01917888},
}
@article{bib:C,
  author     = {Anne Uthor},
  title      = {Open Access Title (arXiv)},
  journal    = {Closed Journal},
  year       = {2018},
  eprinttype = {arxiv},
  eprint     = {1811.03094},
}
@article{bib:D,
  author     = {Anne Uthor},
  title      = {Open Access Title (DOI)},
  journal    = {Open Journal},
  year       = {2018},
  doi        = {12345/67898.0},
  options    = {openaccess},
}
@article{bib:E,
  author     = {Anne Uthor},
  title      = {Open Access (URL)},
  journal    = {Open Journal},
  year       = {2018},
  url        = {https://example.com/~author/my_paper.pdf#page20},
  options    = {openaccess},
}
@article{bib:F,
  author     = {Anne Uthor},
  title      = {\emph{Not} Open Access (DOI)},
  journal    = {Closed Journal},
  year       = {2018},
  doi        = {12345/67898.0},
}
\end{filecontents*}

\addbibresource{\jobname.bib}
\begin{document}
\kant[1]
\nocite{*}
\printbibliography
\end{document}

The bibliography of the MWE: The open access articles are marked with a little linked open access logo in the right margin.

edit: Extended and simplified the open access URL detection (\hyperref can accept the URLs in a macro even with different levels of expansion). Place the TikZ-drawn logos in a reusable box to improve performance.


This is a partial answer, namely to the requirement of automatically placing the logo for arxiv and oai eprinttypes, without requiring adding the keyword manually in the bib file. But I've kept the possibility of manually adding the keyword, for any arbitrary entry.

Essentially, we can perform a test to check whether eprinttype is equal to arxiv or oai:

\renewbibmacro*{begentry}{%
  \iffieldequalstr{eprinttype}{arxiv}
  {\impmark}
  {\iffieldequalstr{eprinttype}{oai}
    {\impmark}
    {\ifkeyword{OA}{\impmark}{}}}}

In full:

\documentclass{article}
\usepackage{graphicx}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@article{bib:A,
    author={Authors},
    title={Title},
    journal={Journal name},
    year={2018},
}
@article{bib:B,
    author={Authors},
    title={Title},
    journal={Journal name},
    year={2018},
    eprinttype={oai},
    eprint={hal-01917888},
}
@article{bib:C,
    author={Authors},
    title={Title},
    journal={Journal name},
    year={2018},
    eprinttype={arxiv},
    eprint={arXiv:1811.03094},
}
\end{filecontents*}

\usepackage[backend=bibtex,style=numeric,eprint=true]{biblatex}
\addbibresource{\jobname.bib}

% new eprinttype
\def\oaitourl#1{http://hal.archives-ouvertes.fr/#1}
\DeclareFieldFormat{eprint:oai}{%
    \ifhyperref
        {\href{\oaitourl#1}{hal:~\nolinkurl{#1}}}
        {hal:~\nolinkurl{#1}}}

% OA logo in the margin
\newcommand{\impmark}{\strut\vadjust{\domark}}
\newcommand{\domark}{%
  \vbox to 0pt{
    \kern-3\dp\strutbox
    \strut\hfill\rlap{\kern1em\includegraphics[height=10pt]{OA}}
    \vss
  }%
}
\renewbibmacro*{begentry}{%
  \iffieldequalstr{eprinttype}{arxiv}
  {\impmark}
  {\iffieldequalstr{eprinttype}{oai}
    {\impmark}
    {\ifkeyword{OA}{\impmark}{}}}}

\usepackage[hidelinks]{hyperref}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

enter image description here

As for the second requirement, the relevant information would be either in eprint or url or doi fields. In general, you would have to wrap the \includegraphics inside \domark in a \href. But the first and third of these cases would have to be dealt with conditionals, and the links built with a "linkbase+field" somehow.


Articles with a DOI can be open access too, and unpaywall.org has an API that can tell us whether a DOI is known to have an open access version. Just for fun, here's a version that does just that, using oldschool bibtex and modern luatex.

In your .bst file, add the function

FUNCTION {openaccess.check}
{
  doi empty$
    'skip$
    { "\MyMaybeOpenAccess{" doi * "}" * write$ }
  if$
}

and call it in the code that handles an article (just after output.bibitem for example.

In your document preamble, define a macro

\newcommand{\MyMaybeOpenAccess}[1]{%
  \directlua{
  local http = require('socket.http')
  local url = 'https://api.unpaywall.org/v2/' .. \luastring{#1} .. '?email=your@email'
  body, code, headers, status = http.request(url)
  if code == 200 and body then
     local found = string.match(body, '"is_oa": ([a-z]+)')
     if found == "true" then
        tex.print("\noexpand\\marginpar{\noexpand\\includegraphics[width=0.3cm]{open-access-logo}}")
     end
  end
}}

(For serious use, would also need to handle isbn and eprint fields, cache accesses to the API, include the OA URL under the logo, and so on.)

Tags:

Biblatex