11

I use biblatex and would like my bibliography to only include a DOI field, whenever there is DOI information available. This involves two things:

  1. Biblatex has to suppress the URL field whenever a DOI field is present. This can be done with the following code in the preamble. (This is a simplified version of Joseph Wright's answer here).

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

    So everytime a DOI field is present in the bibtex file, the URL field is cleared.

  2. My bibtex file is exported from Zotero. Unfortunately Zotero does not provide DOI fields for all entry types (yet), so I often enter the DOI information into the URL field like http://dx.doi.org/10.1145/1364782.1364794. So my question is: Is it possible to have biblatex take the DOI information from the URL field, store it into the DOI field and write only that into the bibliography?

    I guess one would have to modify the \usebibmacro{url+urldate} conditional: First, check whether the URL field contains "dx.doi.org/" (ideally one should allow for http and https). If it does, take everything after "dx.doi.org/", copy it into the DOI field (with \restorefield?) and \printfield{doi}. If it does not, i.e. if it is not a DOI-URL, \usebibmacro{url+urldate}.

Is that possible?

5
  • 1
    Out of curiosity, why do you enter DOI as a URL in Zotero ? It would obviously be easier to generate a URL from doi than the other way round -- I suppose it's too late for that now ?
    – ach
    Jun 14, 2013 at 10:39
  • 1
    There is a related ticket in the Zotero tracker: zotero.org/trac/ticket/1716 but it is three years old already...
    – matth
    Jun 14, 2013 at 10:59
  • @ach: Well, for one, the URL field is the only predefined field available that is suitable. Reports, books, and other entry types do not have a DOI field. Also, I use the URL within Zotero not only when exported to bibtex (e.g. click on URL to open it, which does not work if it only contains the DOI). Also, some Zotero translaters store the DOI in the URL field (as a URL), so it is not only done by me manually.
    – dpprdan
    Jun 14, 2013 at 11:03
  • @matth: Yes, there also a long thread about adding new fields etc. on the Zotero forum somewhere, but my question is not about Zotero. I just mentioned it to stress that the bibtex file is generated (and updated!) automatically. So I'd prefer a solution that takes the bibtex file as given. Edit It's here: forums.zotero.org/discussion/15636/…
    – dpprdan
    Jun 14, 2013 at 11:06
  • I do not have time now (maybe this evening) but this seems like something you can solve using the xstring package in combination with test like ifthenelse (biblatex manual section 4.6.3).
    – ach
    Jun 14, 2013 at 11:21

1 Answer 1

11

If biber is used as backend, then one can use the \DeclareSourcemap facilities to change fields.

For the case at hand a solution is to remap url entries with dx.doi.org as initial part using the following code:

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[ % copies url to doi field if it starts with http://dx.doi.org/
        fieldsource=url,
        match=\regexp{http://dx.doi.org/(.+)},
        fieldtarget=doi,
      ]
    \step[ % removes http://dx.doi.org/ string from doi field
      fieldsource=doi,
      match=\regexp{http://dx.doi.org/(.+)},
      replace=\regexp{$1}
    ]
    }
  \map{ % removes url + urldate field from all entries that have a doi field
   \step[fieldsource=doi, final]
   \step[fieldset=url, null]
   \step[fieldset=urldate, null]
   }
 }
}

The actual value inside \regexp can be adjusted.

In the first step we create a doi field for each entry where the url field matches the regexp, and the novel field has the value of the url field. In the second step we remove the doi "namespace".

In the second \map sequence the url and urldate fields are cleared if a doi field is present, to mimic the behavior in the first part of the original question.

3
  • 1
    A nice solution!
    – ach
    Jun 14, 2013 at 15:17
  • Indeed nice. A few comments though: 1. Does this overwrite the DOI field if a 'DOI-URL' is present or not? My tests suggest that it does not (which is desired) but I do not understand why not. 2. What is the equivalent to \iffieldundef{} and \clearfield{}? One could just clear the URL and URLDATE fields if a DOI is defined, to mimic the behavior of the \renewbibmacro.
    – dpprdan
    Jun 17, 2013 at 12:52
  • I guess a quick look at the biblatex manual (§ 4.5.2) helps to answer my questions: 1. It does not overwrite the DOI field, because the \maps default is overwrite=false. 2. My \renewbibmacro can be mimicked by \map{ \step[fieldsource=doi, final] \step[fieldset=url, null] \step[fieldset=urldate, null]} @Guido, I hope you don't mind me editing your answer to include this?
    – dpprdan
    Jun 18, 2013 at 9:46

You must log in to answer this question.

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