Bibliography management with Org mode

2021-06-14

Tags: emacs org

After recently declaring my fourth (fifth?) Emacs bankruptcy, I started building my Emacs configuration from scratch, this time following the principle of understanding a piece of code before adding it to my configuration, instead of my usual copy-paste approach. I have had some experience in Scheme, 1 and I have been using Emacs for some time, so understanding Emacs Lisp was not impossible. It was not going to be as simple as cloning Doom, but I figured if I just added the features as I needed them, instead of building the entire configuration in one go, I would not be wasting a lot of time in just setting up my editor, and would always have a functional editor. And it will not be a black box. I just had three requirements:

  1. Use straight.el as the package manager - useful for reproducibility,
  2. Use the use-package macro as much as possible - at present this is a fine balance between understanding Emacs and using a “just works” black box,
  3. Use built-in features as much as possible - an effect of following Prot, and also has the benefit of being “bloat-less”.

I am also a big fan of Org mode. Usually unless I am writing a full-fledged journal article I prefer to write my “notes” with Org. I can easily export those notes to a semi-professional report in LaTeX or to an html presentation using reveal.js. I can even add code snippets à la Jupyter. And the ease of adding tables and images makes it a delight to use. It is very versatile writing/organizing solution. So when it came time to write a short report on my progress in one of machine learning projects, I booted Emacs with my spanking new configuration, and started typing away in an Org buffer. However one thing that I missed from my AUCTeX + RefTeX setup was the ability to easily look up and enter references. There’s the excellent org-ref package by John Kitchin, but for the life of me I could never make it work the way I wanted. It also has some hard dependencies on packages like Helm, which have no place in my present configuration. Fortunately I found this excellent post, and this screencast by Eric Shulte, and learned that I can effectively manage an annotated bibliography and easily enter references into an Org file using just the org and org-contrib packages. A word of caution, many of the packages in org-contrib are not maintained, so there is always a risk that it might not work with a newer version of org-mode2 With further ado here is the code to turn Emacs + Org in to a bibliography manager.

;; Install org-contrib
(use-package org-contrib)

;; Install org
(use-package org
  :config
  (setq org-latex-pdf-process '("latexmk -pdf -outdir=%o %f"))
  (setq org-export-with-smart-quotes t)

  ;; export citations
  (require 'ox-bibtex)

  ;; manage citations
  (require 'org-bibtex-extras)

  ;; ignore headline but include content when exporting
  (require 'ox-extra)
  (ox-extras-activate '(ignore-headlines))

  :custom (org-startup-indented t)
  :bind (:map org-mode-map
              ("<f12>" . org-bibtex-yank)))

There are a few things to unpack here:

All of the above still does not replicate the easy search feature of RefTeX. Thankfully Org includes org-reftex-citation that allows us to use RefTeX to enter references in an Org file. The problem is RefTeX enters \cite{<bibtex-key>} instead of cite: links. There is probably an easy way to add this behavior, but I figured that I can easily convert \cite{<bibtex-key>} to [[cite:<bibtex-key>]] by using a keyboard macro: 3

;; keyboard macro to convert reftex citations to `cite:' links
(defun insert-org-cite ()
  (interactive)
  (org-reftex-citation)
  (setq last-command-event 127)
  (org-delete-backward-char 1)
  (setq last-command-event 93)
  (org-self-insert-command 1)
  (setq last-command-event 93)
  (org-self-insert-command 1)
  (setq last-command-event 134217826)
  (backward-word 1)
  (setq last-command-event 127)
  (org-delete-backward-char 1)
  (setq last-command-event 58)
  (org-self-insert-command 1)
  (setq last-command-event 134217826)
  (backward-word 1)
  (setq last-command-event 127)
  (org-delete-backward-char 1)
  (setq last-command-event 91)
  (org-self-insert-command 1)
  (setq last-command-event 91)
  (org-self-insert-command 1)
  (setq last-command-event 'f4))

(with-eval-after-load 'org
  (bind-key "C-c C-x ]" #'insert-org-cite org-mode-map))

And with that I can simply use C-c C-x ] to insert a cite: link in my Org file. I chose C-c C-x ] as the key-binding for insert-org-cite because it completes the process of entering a citation in an Org file as a complement to C-c C-x [ which uses org-citation-reftex to insert a LaTeX-style citation in an Org file.

To round up the entire process, I have (setq org-latex-pdf-process '("latexmk -pdf -outdir=%o %f")) in my configuration because it automates running bibtex to add the relevant references to the final PDF output. You need to have the latexmk script installed for this.

That completes setting up Emacs and Org for maintaining an annotated bibliography and adding citations in Org files. It does not have all the bells and whistles of org-ref but is very easy to maintain and simply works (so far). And it is more than enough for my purposes.


  1. SICP is an amazing introduction to programming, give it a try if you have not. ↩︎

  2. If anyone would like to maintain one of the packages in org-contrib please check the org-contrib repo. ↩︎

  3. To save keyboard-macros as Emacs Lisp code use elmacro. ↩︎