24

Is there a way to insert a doi of an entry only in case it is missing a URL field? It happens a lot that the doi and URL are essentially the same, and inserting them both yields a redundancy. I am using biblatex with biber.

PS: If you think this goal doesn't make sense please share your thoughts!

2

2 Answers 2

22

You can redefine the bibmacro doi+eprint+url so that the doi field is printed only if the url field is not defined, that is, add the following lines in the preamble:

\renewbibmacro*{doi+eprint+url}{%
  \iftoggle{bbx:doi}
    {\iffieldundef{url}{\printfield{doi}}{}}
    {}%
  \newunit\newblock
  \iftoggle{bbx:eprint}
    {\usebibmacro{eprint}}
    {}%
  \newunit\newblock
  \iftoggle{bbx:url}
    {\usebibmacro{url+urldate}}
    {}}

MWE

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[backend=biber]{biblatex}

\addbibresource{\jobname.bib}

\renewbibmacro*{doi+eprint+url}{%
  \iftoggle{bbx:doi}
    {\iffieldundef{url}{\printfield{doi}}{}}
    {}%
  \newunit\newblock
  \iftoggle{bbx:eprint}
    {\usebibmacro{eprint}}
    {}%
  \newunit\newblock
  \iftoggle{bbx:url}
    {\usebibmacro{url+urldate}}
    {}}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@article{kastenholz1,
  hyphenation = {american},
  author = {Kastenholz, M. A. and H{\"u}nenberger, Philippe H.},
  indextitle = {Computation of ionic solvation free energies},
  title = {Computation of methodology\hyphen independent ionic solvation free
    energies from molecular simulations},
  subtitle = {I. The electrostatic potential in molecular liquids},
  journaltitle = jchph,
  volume = {124},
  eid = {124106},
  date = {2006},
  url = {http://dx.doi.org/10.1063/1.2172593},
  urldate = {2006-10-01},
  doi = {10.1063/1.2172593},
}
@article{kastenholz2,
  hyphenation = {american},
  author = {Kastenholz, M. A. and H{\"u}nenberger, Philippe H.},
  indextitle = {Computation of ionic solvation free energies},
  title = {Computation of methodology\hyphen independent ionic solvation free
    energies from molecular simulations},
  subtitle = {I. The electrostatic potential in molecular liquids},
  journaltitle = jchph,
  volume = {124},
  eid = {124106},
  date = {2006},
  doi = {10.1063/1.2172593},
}
\end{filecontents}


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

Output:

enter image description here

As you can see the two entries are identical except for the url field, and if this field is defined, the doi field is not printed.

3
  • 1
    How can I adapt this to do the opposite, i.e. use DOI if possible, use URL only if there is no DOI?
    – user21155
    Jul 8, 2015 at 20:39
  • 6
    @user21155. Define \renewbibmacro*{doi+eprint+url}{% \iftoggle{bbx:url} {\iffieldundef{doi}{\usebibmacro{url+urldate}}{}} {}% \newunit\newblock \iftoggle{bbx:eprint} {\usebibmacro{eprint}} {}% \newunit\newblock \iftoggle{bbx:doi} {\printfield{doi}} {}} Jul 20, 2015 at 6:56
  • @user21155 You're welcome. Jul 21, 2015 at 14:10
19

You can do this via mapping of datasources. The \DeclareSourcemap command

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldsource=url,final]
      \step[fieldset=doi,null]
    }  
  }
}

processes any bibtex input data and for each item in the bibliograhpy file it executes a number of commands given by \step:

  • the first step fieldsource checks the url field

    • the instruction final means processing of the current entry is terminated if this field is empty or does not exist
  • otherwise the next step fieldset=doi,null is executed; this clears the doi field, in fact it makes it look as if there was never a doi field in the input.

The result of this is that all biber/biblatex sees is an entry with either a url field or a doi field, but not both.

This has the advantage that you don't need to know how the particular biblatex style chooses to process these fields.

Sample output

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[backend=biber]{biblatex}

\addbibresource{\jobname.bib}

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldsource=url,final]
      \step[fieldset=doi,null]
    }  
  }
}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@Article{Akbulut-S:deformations-G2,
  author =   {Akbulut, Selman and Salur, Sema},
  title =    {Deformations in {$G_2$} manifolds},
  journal =  {Adv. Math.},
  volume =   217,
  year =     2008,
  number =   5,
  pages =    {2130--2140},
  issn =     {0001-8708},
  doi =      {10.1016/j.aim.2007.09.009},
  url =      {http://dx.doi.org/10.1016/j.aim.2007.09.009}
}
@Article{Akbulut-S:deformations-G22,
  author =   {Akbulut, Selman and Salur, Sema},
  title =    {Deformations in {$G_2$} manifolds},
  journal =  {Adv. Math.},
  volume =   217,
  year =     2008,
  number =   5,
  pages =    {2130--2140},
  issn =     {0001-8708},
  url =      {http://dx.doi.org/10.1016/j.aim.2007.09.009}
}
@Article{Akbulut-S:deformations-G23,
  author =   {Akbulut, Selman and Salur, Sema},
  title =    {Deformations in {$G_2$} manifolds},
  journal =  {Adv. Math.},
  volume =   217,
  year =     2008,
  number =   5,
  pages =    {2130--2140},
  issn =     {0001-8708},
  doi =      {10.1016/j.aim.2007.09.009},
}

\end{filecontents}

\begin{document}
  \nocite{*}
  \printbibliography
\end{document}
6
  • 1
    @Dror Thanks for asking. Is it clearer now? Jan 19, 2014 at 16:48
  • 1
    Almost ;) If in the first \step url does not exist, then the entry is skipped, the next \step is not executed and the \map ends. Next, the \map is started again for the next entry (if one exists). Is this correct? How do you understand this from the manual?
    – Dror
    Jan 19, 2014 at 16:53
  • @Dror Your interpretation is correct. Most of my understand is from the discussion of the \step command in the manual. It is not the most lucid, but there are a number of examples given afterwards that can help - however there are almost too many examples. A little experimenting with small examples is also effective. Jan 19, 2014 at 16:57
  • Thank you Andrew, this is such an excellent and elegant solution. I've been looking for hours for this and didn't dare to try the 100-lines scripts provided elsewhere. This one is a beauty!
    – Janos
    Aug 15, 2014 at 19:30
  • 1
    @Eike I haven't tried other backends, but would guess that this should be independent. Feb 20, 2022 at 13:05

You must log in to answer this question.

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