Using org-ref for citations and references

| categories: org-mode, emacs | tags:

org-ref is an emacs-lisp module to handle bibliographic citations, and references to figures, tables and sections in org-mode. It was written first for use in org-mode, and for reasonable export to LaTeX. It does not work well for any other export (eg HTML) for now. The goal of org-ref is to make it easy to add citations, and that the citations be useful, clickable links. Below, I illustrate some of those features.

1 Installation

You can get the source here: https://github.com/jkitchin/jmax/blob/master/org-ref.org . This is an org-mode file, and you can load it with

(org-babel-load-file "org-ref.org")

That should be all you need for basic usage.

2 Basic usage for citations

org-ref was written with bibtex in mind. We will discuss customization to use biblatex later.

The first thing you should do is add a bibliography link to your document. This link is usually put at the end of the document, where you want the bibliography to be printed in a LaTeX export. Use the filename of the bibliography with its extension in the link, and you can use multiple files if they are separated by commas. The bibliography link is clickable, and it will open the bibliography that you clicked on. Depending on the LaTeX class you are exporting to, you may also need to set a bibliographystyle.

Out of the box, org-ref binds the key "C-c ]" to insert a citation. That key runs the command org-ref-insert-cite-link, which will prompt you for a regular expression to search your bibliographies for. The search is done using reftex, so you can mark several entries at once, and they will be added as a citation link. The actual kind of link used is dependent on the value of org-ref-default-citation-link, which defaults to cite.

If your cursor is on a citation link, or at the end of the link, you can run the command again to append new citations to the link. The new entries are separated by commas. The links are clickable, and when you click on them you will see a message in the minibuffer with the citation, and options to open the entry, open a pdf (if you have it), open the url (if the entry has one), or to open notes about the entry. You get this menu for the entry that you clicked on.

If you want a different type of citation, type C-u C-c ]. You will be prompted for a format, and you can choose a different type of link format. Most bibtex formats are supported, and some biblatex formats are supported.

3 Basic usage for references

The other use of org-ref is for references to labels in your document. You can put labels in figure and table captions, and then reference them in your document. The label link is clickable, and when you click on it there will be a message in the minibuffer telling you how many labels of that name were found (it should be one).

Table 1: An uninteresting table. ()
0 3
4 7

You can then refer to Table (tab-boring). The ref links are also clickable, and they take you to the spot where the label is defined. You can enter ref links with completion. Press C-c C-l, type ref, press enter, and then press tab. You will get a list of the labels defined in the buffer you can choose from. There are many things you can make a ref to including a tblname, a label link, an explicit \label{}, and an org-mode #+label: line. (tab-boring)

There is an eqref link that is used for equations. You must use LaTeX labels in the equation for this.

\[e^x = 4 \label{eq-exp} \]

You can see in (eq-exp) the problem to solve.

4 Miscellaneous links

There are two link types for generating a LateX list of tables and list of figures. These links are clickable, and they open a temporary buffer with a list of the tables or figures that you can click on. They export to \listoftables and \listoffigures

You can run these as commands, org-ref-list-of-tables and org-ref-list-of-figures if you do not want a list of those things in your exported document.

5 Customization

5.1 Default bibliography, pdf directory,

This is an optional configuration, but it is handy to define a default bibliography so that you can add citations to an org-file without defining a bibliography link. I store all pdfs of bibtex entries in the directory defined by org-ref-pdf-directory, and by the name of the bibtex entry label. This enables org-ref to open the pdf if it can find it. The notes file is optional, I create org-entries for each bibtex entry, which I have experimented with various ways of organizing them with tags, and in topical headings.

(setq org-ref-bibliography-notes "~/Dropbox/bibliography/notes.org"
      org-ref-default-bibliography '("~/Dropbox/bibliography/references.bib")
      org-ref-pdf-directory "~/Dropbox/bibliography/bibtex-pdfs/")

5.2 New key binding

The default key binding to insert a citation is C-c ]. I chose that because I do not like pressing shift to get ). However, this key binding usurps an org-mode agenda file command. To change this, set this variable

(setq org-ref-insert-cite-key "C-c )")
  • You may have to restart emacs to get C-c ] back.

5.3 Default link type

If you use another citation type alot, you may change the default link type. For example, you may prefer autocite links by default. Just set it like this:

(setq org-ref-default-citation-link "autocite")

5.4 New citation types

There are so many citation types between bibtex and biblatex. I did not try to add them all. You can add new citation links yourself in your init file. Here, we add a new cite link called citez, and assign a reftex menu key of z to it. This function automatically adds the new link to org-mode, with the citation menu functionality, creates the completion function, and adds the citation to the list of known types.

(org-ref-define-citation-link "citez" ?z)

(org-ref-define-citation-link "citeauthorfull" ?F) citeauthorfull:hautier-2012-accur

hautier-2012-accur

It is assumed that this will be exported as \citez[optional stuff]{label}. If you need more flexibility than that, you will have to define everything manually.

For example, the original cite link was defined like this.

(defun org-ref-cite-link-format (keyword desc format)
   (cond
    ((eq format 'html) (format "(<cite>%s</cite>)" path))
    ((eq format 'latex)
     (concat "\\cite" (when desc (format "[%s]" desc)) "{"
             (mapconcat (lambda (key) key) (org-ref-split-and-strip-string keyword) ",")
             "}"))))

(org-add-link-type
 "cite"
 'org-ref-cite-onclick-minibuffer-menu ;; clicking function
 'org-ref-cite-link-format) ;; formatting function

You should also add your new citation type to the list of org-ref-cite-types.

6 Summary

This covers most of the basic org-ref functionality. There are also several utility functions for interacting with org-buffers and bibtex files that will be described later.

See http://screencast.com/t/bxfafVydE for a screencast of using org-ref.

http://screencast.com/t/bxfafVydE

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter

Finding missing citation entries in an org-file

| categories: bibtex, org-mode | tags:

Today we consider how to find citations in a document that have no corresponding entries in a bibtex file. There are a couple of pieces to this which we work out in stages below. First, we specify the bibtex file using a bibliography link defined in jorg-bib.el.

jorg-bib provides a function that gives us the relevant bibliography files found in this file.

(cite-find-bibliography)
bib1.bib bib2.bib

We can get a list of keys in these files

(let ((bibtex-files (cite-find-bibliography)))
(bibtex-global-key-alist))
(adams-1993-orien-imagin . t) (aarik-1997-effec-tio2 . t) (aruga-1985-struc-iron . t)

Now, here are some citations that we want to include in this document.

cite:aruga-1985-struc-iron,aarik-1997-effec-tio2

Here is a citation that is not in the bibtex file

cite:kitchin-2016-nobel-lecture

To find out if any of these are missing, we need a list of the citation keys in this document. We first get all the content from the cite links. We parse the buffer, and for each cite link, we get the path of the link, which contains our keys.

(let ((parsetree (org-element-parse-buffer)))
  (org-element-map parsetree 'link
    (lambda (link)       
      (let ((type (nth 0 link))
            (plist (nth 1 link))
            (content (nth 2 link)))
	(when (equal (plist-get plist ':type) "cite")
	  (plist-get plist ':path))))))
aruga-1985-struc-iron,aarik-1997-effec-tio2 kitchin-2016-nobel-lecture

That is almost what we need, but we need to separate the keys that are joined by commas. That function already exists in jorg-bib as cite-split-keys. We need to make a slight variation to get a list of all the entries, since the cite-split-keys returns a list of entries for each link. Here is on approach to that.

(let ((parsetree (org-element-parse-buffer))
      (results '()))
  (org-element-map parsetree 'link
    (lambda (link)       
      (let ((plist (nth 1 link)))
	(when (equal (plist-get plist ':type) "cite")
	  (setq results (append results (cite-split-keys (plist-get plist ':path))))))))
results)
aruga-1985-struc-iron aarik-1997-effec-tio2 kitchin-2016-nobel-lecture

Ok, now we just need to check each entry of that list against the list of entries in the bibtex files, and highlight any that are not good. We use an index function below to tell us if an element is in a list. This index function works for strings. We use the strange remove-if-not function, which requires something like triple negative logic to get the list of keys that are not in the bibtex files.

(require 'cl)

(defun index (substring list)
  "return the index of string in a list of strings"
  (let ((i 0)
	(found nil))
    (dolist (arg list i)
      (if (string-match substring arg)
	  (progn 
	    (setq found t)
	    (return i)))
      (setq i (+ i 1)))
    ;; return counter if found, otherwise return nil
    (if found i nil)))

;; generate the list of bibtex-keys and cited keys
(let* ((bibtex-files (cite-find-bibliography))
       (bibtex-keys (mapcar (lambda (x) (car x)) (bibtex-global-key-alist)))
       (parsetree (org-element-parse-buffer))
       (cited-keys))
  (org-element-map parsetree 'link
    (lambda (link)       
      (let ((plist (nth 1 link)))			     
	(when (equal (plist-get plist ':type) "cite")
	  (setq cited-keys (append cited-keys (cite-split-keys (plist-get plist ':path))))))))

(princ (remove-if-not (lambda (arg) (not (index arg bibtex-keys))) cited-keys))
)
(kitchin-2016-nobel-lecture)

The only improvement from here would be if this generated a temporary buffer with clickable links to find that bad entry! Let us take a different approach here, and print this to a temporary buffer of clickable links.

(require 'cl)

(defun index (substring list)
  "return the index of string in a list of strings"
  (let ((i 0)
	(found nil))
    (dolist (arg list i)
      (if (string-match substring arg)
	  (progn 
	    (setq found t)
	    (return i)))
      (setq i (+ i 1)))
    ;; return counter if found, otherwise return nil
    (if found i nil)))

;; generate the list of bibtex-keys and cited keys
(let* ((bibtex-files (cite-find-bibliography))
       (bibtex-keys (mapcar (lambda (x) (car x)) (bibtex-global-key-alist)))
       (bad-citations '()))

  (org-element-map (org-element-parse-buffer) 'link
    (lambda (link)       
      (let ((plist (nth 1 link)))			     
	(when (equal (plist-get plist ':type) "cite")
	  (dolist (key (cite-split-keys (plist-get plist ':path)) )
	    (when (not (index key bibtex-keys))
	      (setq bad-citations (append bad-citations
			    `(,(format "%s [[elisp:(progn (find-file \"%s\")(goto-char %s))][not found here]]\n"
		      key (buffer-file-name)(plist-get plist ':begin)))))
			    ))))))

(mapconcat 'identity bad-citations ""))

kitchin-2016-nobel-lecture

elisp:(progn (find-file "/home-research/jkitchin/Dropbox/blogofile-jkitchin.github.com/_blog/blog.org")(goto-char 1052))

That is likely to come in handy. I have put a variation of this code in jorb-bib, in the function called jorg-bib-find-bad-citations.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.6

Discuss on Twitter

A popup menu for citation links in org-mode

| categories: bibtex, org-mode | tags:

I have been exploring ways to get more information out of links in org-mode. I have considered popups , and right-clicking . Here I show how to get a popup menu on a citation link. The idea is that clicking or opening the ditation link should give you a menu. The menu should give you some context, e.g. if the bibtex key even exists. If it does, you should be able to get a quick view of the citation in the minibuffer. You should be able to open the entry in the bibtex file from the menu. If you have a pdf of the reference, you should have an option to open it. You should be able to open the url associated with the entry from the menu too.

Here is the function. We use https://github.com/auto-complete/popup-el , and some code from https://github.com/jkitchin/jmax/blob/master/jorg-bib.el .

(org-add-link-type
 "cite"
 ;; this function is run when you click on the link
 (lambda (link-string) 
   (let* ((menu-choice)
         ;; this is in jorg-bib.el
         (results (get-bibtex-key-and-file))
	 (key (car results))
	 (cb (current-buffer))
         (pdf-file (format (concat jorg-bib-pdf-directory "%s.pdf") key))
         (bibfile (cdr results)))
     (setq menu-choice
	   (popup-menu* 
	    (list (popup-make-item (if 
				       (progn
					 (let ((cb (current-buffer)) result)					
					   (find-file bibfile)
					   (setq result (bibtex-search-entry key))
					   (switch-to-buffer cb)
					   result))
				       "Simple citation"
				     "No key found")  :value "cite")
		  (popup-make-item (if
				       (progn
					 (let ((cb (current-buffer)) result)					  
					   (find-file bibfile)
					   (setq result (bibtex-search-entry key))
					   (switch-to-buffer cb)
					   result))
				       (format "Open %s in %s" key bibfile)
				     "No key found") :value "bib")
		  (popup-make-item 
		   ;; check if pdf exists.jorg-bib-pdf-directory is a user defined directory.
                   ;; pdfs are stored by bibtex key in that directory
		   (if (file-exists-p pdf-file)
		       (format "Open PDF for %s" key)
		     "No pdf found") :value "pdf")
		  (popup-make-item "Open URL" :value "web")
		  (popup-make-item "Open Notes" :value "notes")
		  )))

     (cond
      ;; goto entry in bibfile
      ((string= menu-choice "bib")       
       (find-file bibfile)
       (bibtex-search-entry key))

      ;; goto entry and try opening the url
      ((string= menu-choice "web")   
       (let ((cb (current-buffer)))
	 (save-excursion
	   (find-file bibfile)
	   (bibtex-search-entry key)
	   (bibtex-url))
	 (switch-to-buffer cb)))
       
      ;; goto entry and open notes, create notes entry if there is none
      ((string= menu-choice "notes")   
       (find-file bibfile)
       (bibtex-search-entry key)       
       (jorg-bib-open-bibtex-notes))

     ;; open the pdf file if it exists
     ((string= menu-choice "pdf")
      (when (file-exists-p pdf-file)
	  (org-open-file pdf-file)))

     ;; print citation to minibuffer
     ((string= menu-choice "cite")
      (let ((cb (current-buffer)))	
	(message "%s" (save-excursion (find-file bibfile)
				      (bibtex-search-entry key)  
				      (jorg-bib-citation)))
	(switch-to-buffer cb))))))
 ;; formatting
(lambda (keyword desc format)
   (cond
    ((eq format 'html) (format "(<cite>%s</cite>)" path))
    ((eq format 'latex)
     (concat "\\cite{"
	     (mapconcat (lambda (key) key) (cite-split-keys keyword) ",")
	     "}")))))

cite:daza-2014-carbon-dioxid,mehta-2014-ident-poten,test,ahuja-2001-high-ruo2

Here you can see an example of a menu where I have the PDF:

Here is an example menu of a key with no entry:

And, and entry with no PDF:

Here is the simple citation:

And a reference from the other bibliography:

Not bad! I will probably replace the cite link in jorg-bib with something like this.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.6

Discuss on Twitter

A better insert citation function for org-mode

| categories: bibtex, org-mode | tags:

I have setup a reftex citation format that inserts a cite link using reftex like this.

(eval-after-load 'reftex-vars
  '(progn
      (add-to-list 'reftex-cite-format-builtin
                   '(org "Org-mode citation"
                         ((?\C-m . "cite:%l"))))))

I mostly like this, but it does not let me add citations to an existing citation; doing that leads to the insertion of an additional cite within the citation, which is an error. One way to make this simple is to add another cite format which simple returns the selected keys. You would use this with the cursor at the end of the link, and it will just append the results.

(add-to-list 'reftex-cite-format-builtin
                   '(org "Org-mode citation"
                         ((?\C-m . "cite:%l")
			  (?a . ",%l"))))

That actually works nicely. I would like a better approach though, that involves less keywork. Ideally, a single function that does what I want, which is when on a link, append to it, and otherwise insert a new citation link. Today I will develop a function that fixes that problem.

(defun insert-cite-link ()
  (interactive)
  (let* ((object (org-element-context))
	 (link-string-beginning (org-element-property :begin object))
	 (link-string-end (org-element-property :end object))
	 (path (org-element-property :path object)))    
    (if (and (equal (org-element-type object) 'link) 
               (equal (org-element-property :type object) "cite"))
	(progn
	  (goto-char link-string-end)
	  (insert (concat "," (mapconcat 'identity (reftex-citation t ?a) ","))))
      (insert (concat "cite:" (mapconcat 'identity (reftex-citation t) ",")))
      )))

That function is it! Org-mode just got a lot better. That function only puts a cite link in, but since that is all I use 99.99+% of the time, it works fine for me!

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.6

Discuss on Twitter

Putting link references to lines of code in a source block

| categories: org-mode | tags:

I keep forgetting about this interesting gem of a feature in org-mode code blocks. You can put references to specific lines of code outside the block! http://orgmode.org/manual/Literal-examples.html#Literal-examples

The following code block has some references in it that we can refer to later:

#+BEGIN_SRC emacs-lisp -n -r
(save-excursion (sc)
  (goto-char (point-min))) (jump)
#+END_SRC
1: (save-excursion
2:   (goto-char (point-min)))

In line

(sc)
we remember the current position.
(jump)
jumps to point-min.

To make this work with python we have to make a slight change to the reference format in the header.

#+BEGIN_SRC python -n -r -l "#(ref:%s)"
for i in range(5):                # (for)
    print i                       # (body)
#+END_SRC
1: for i in range(5):
2:     print i
0
1
2
3
4

In line

(for)
we initialize the loop, and in line
(body)
we run it.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.5h

Discuss on Twitter
« Previous Page -- Next Page »