Managing BibTeX Files with Emacs

Here are a couple of tips on exploiting Emacs when working with BibTeX databases. I do not use a BibTeX database manager (though I have tried Jabref). I prefer to edit my bib files entirely within Emacs, and have had no trouble doing so even with my largest database of around 6800 entries.

1. Cleaning Downloaded Bib Entries

Back in the 1980s and 1990s BibTeX users had little choice but to create bib entries from scratch. Nowadays most journal websites have an “export citation” option that allows you to download a bib entry for a paper you are looking at. Unfortunately, these bib entries are of widely variable quality and are almost never entirely correct. What’s more, they will not match your own house style as regards ordering of fields and use of abbreviations. A great help in reformatting bib entries is the bibtex-clean-entry command in the BibTeX-mode of Emacs. I use it to

  • remove unwanted blank lines and spaces,
  • put the fields in the order I prefer,
  • change field delimiters from curly brackets to quotes,
  • delete delimiters around numerical fields,
  • change double dashes to single dashes in page ranges (BibTeX will convert single dashes to double as necessary),
  • change the entry type and field names to lower case,
  • set the indentation of field to two spaces.

These and other aspects of the formatting are customizable. Here is an example of a bib entry downloaded from JSTOR.

@article{10.2307/2323313,
 ISSN = {00029890, 19300972},
 URL = {http://www.jstor.org/stable/2323313},
 author = {Dan Scott, Donald R. Peeples},
 journal = {The American Mathematical Monthly},
 number = {7},
 pages = {651-653},
 publisher = {Mathematical Association of America},
 title = {A Constructive Proof of the Partial Fraction Decomposition},
 volume = {95},
 year = {1988}
}

After I hit C-c C-c in Emacs the entry is transformed to

@article{10.2307/2323313,
  author = "Dan Scott, Donald R. Peeples",
  title = "A Constructive Proof of the Partial Fraction Decomposition",
  journal = "The American Mathematical Monthly",
  volume = 95,
  number = 7,
  pages = "651-653",
  year = 1988,
  issn = "00029890, 19300972",
  url = "http://www.jstor.org/stable/2323313",
  publisher = "Mathematical Association of America"
        }

Further work is needed (such as replacing the comma by “and” in the author field), but the entry is now much closer to the format I require.

BibTeX-mode is not perfect. While bibtex-clean-entry can even generate a new key for the entry, I have not been able to get it to match my key-generating algorithm. And I have not found a way to make bibtex-clean-entry delete fields (such as issn, or publisher for the article type) that I do not use.

If you would like to see how I customized BibTeX-mode, take a look at the .emacs and .emacs-custom_windows files in my dot-emacs setup.

2. Bib Search and PDF Display with Helm-BibTeX

The Emacs RefTeX package provides some useful features for handling citations within a \LaTeX document, providing an intelligent link between the \LaTeX document and the relevant BibTeX databases. One thing it does not do is enable easy access to PDF files corresponding to bib entries. The Helm-BibTeX package can do this and much more.

To explain how I use Helm-BibTeX, suppose I have the following lines in my dot emacs.

(setq helm-bibtex-bibliography '("~/texmf/bibtex/bib/la.bib"
                                 "~/texmf/bibtex/bib/njhigham.bib"
                                 ))

(setq helm-bibtex-library-path '("~/pdf_papers" "~/pdf_books"))

These tell Helm-BibTeX to look in the first path for bib files and in the second path for PDF files whose names match a specified bib key.

If I type M-x helm-bibtex and type dongarra in the minibuffer then all bib entries in la.bib and njhigham.bib containing dongarra in the author or title fields are displayed, one per line. I can narrow the list down by typing a space and then another search term. Hitting tab displays several options, which include options to insert a \cite command for the item under the cursor, to insert a formatted reference for the item under the cursor, and to go to that entry in the bib file. The fourth column shows a looped square symbol (⌘) that indicates the presence of a matching PDF file. Hitting enter (or f1, or Ctrl-j) opens the PDF file in the default PDF application.

Here is Helm-BibTeX in action. helm-bibtex.jpg

Helm-BibTeX relies on the Helm package, which provides a powerful framework for incremental completion and selection narrowing.

9 thoughts on “Managing BibTeX Files with Emacs

  1. I too was not satisfied with the autogenerated keys. Fortunately, it’s quite straightforward to override what bibtex-generate-autokey does, with perhaps something like:

    (require ‘bibtex)

    (defun bibtex-generate-autokey ()
    (let* ((bibtex-autokey-names nil)
    (bibtex-autokey-year-length 2)
    (bibtex-autokey-name-separator “\0”)
    (names (split-string (bibtex-autokey-get-names) “\0”))
    (year (bibtex-autokey-get-year))
    (name-char (cond ((= (length names) 1)
    4)
    ((= (length names) 2)
    2)
    (t 1)))
    (existing-keys (bibtex-parse-keys))
    key)
    (setq names (mapconcat (lambda (x)
    (substring x 0 name-char))
    names
    “”))
    (setq key (format “%s%s” names year))
    (let ((ret key))
    (loop for c from ?a to ?z
    while (assoc ret existing-keys)
    do (setq ret (format “%s%c” key c)))
    ret)))

    This generates keys according to:

    1 author: four letters of surname + YY
    2 authors: 2 lettters of surnames + YY
    > 2 authors: 1 letter of surnames + YY

    If that key matches an existing one in the buffer, it tries appending in order a-z to make a unique key. This obviously fails if there are already 26 papers with the same author-year substring in the bibtex file.

  2. The looped square symbol is wider than other characters in your font. That’s the reason for the ugly line breaks. You can configure another symbol using the customization variable helm-bibtex-pdf-symbol. Alternatively, you might want to consider another font. I’m very happy with DejaVu Sans Mono.

  3. I’ve found the bibtex-clean-entry-hook to be helpful for deleting unwanted fields, often followed by a C-c C-q to realign the entry:

    (defvar bp/bibtex-fields-ignore-list ‘(“keywords” “abstract” “file” “issn”))
    (defun bp/bibtex-clean-entry-hook ()
    (save-excursion
    (let (bounds)
    (when (looking-at bibtex-entry-maybe-empty-head)
    (goto-char (match-end 0))
    (while (setq bounds (bibtex-parse-field))
    (goto-char (bibtex-start-of-field bounds))
    (if (member (bibtex-name-in-field bounds)
    bp/bibtex-fields-ignore-list)
    (kill-region (caar bounds) (nth 3 bounds))
    (goto-char (bibtex-end-of-field bounds))))))))
    (add-hook ‘bibtex-clean-entry-hook ‘bp/bibtex-clean-entry-hook)

      1. Hi Nick, Bernhard,

        I maintain the bibtex-utils package on melpa, and I’ve added your bp/clean-entry-hook as a new feature. I renamed it to bu-clean-entry-hook, for consistency with the ‘namespace’ for the package. I’ve cited this blog and Bernhard in the manual and the source code for the function.

        I’m not sure of the copyright status of short code snippets offered up on the web, I hope this is acceptable to you both. If not, let me know and I’ll figure something out.

        Thanks!

        Tyler

  4. Great post. Im a newbie here and trying to get my paper right. How do you export all the bibtex references to a file (say, for someone that is working with Latex)? Thanks!

Leave a comment