Another parsing of links for citations with pre and post text.

| categories: org-mode, emacs, org-ref | tags:

Some LaTeX citations look like \cite[pretext][post text]{key}. Here I explore parsing a link like (pre text)(post text)key. Note you cannot use [] inside the link, as it breaks the link syntax. Also, these links must be wrapped in [[]] because of the parentheses and spaces in the parentheses. This is a very different approach than used here which used the description of the link to define the pre and post text. The disadvantage of that approach is that the key is hidden, whereas in this approach it is not; you can see the key and pre/post text.

The basic strategy will be to use a regexp to parse the link path. The regexp below is pretty hairy, but basically it looks for optional text in () and uses numbered groups to store what is found. Then, we use what we found to construct the LaTeX syntax. We redefine the function in org-ref that gets the key for clicking, and we redefine the cite format function. The result is that we retain the click functionality that shows us what the key refers to.

(defun org-ref-parse-key (s)
  "return pretext, posttext and bibtex key from a string like \"(pre text)(post text)bibtexkey\""
  (string-match "\\(?1:(\\(?2:[^)]*\\))\\)?\\(?3:(\\(?4:[^]]*\\))\\)?\\(?5:.*\\)" s)
  ;; return pretext postext key
  (list (match-string 2 s) (match-string 4 s) (match-string 5 s)))

(defun org-ref-get-bibtex-key-and-file (&optional key)
  "returns the bibtex key and file that it is in. If no key is provided, get one under point"
 (interactive)
 (let ((org-ref-bibliography-files (org-ref-find-bibliography))
       (file))
   (unless key
     ;; get the key
     (setq key (nth 2 (org-ref-parse-key (org-ref-get-bibtex-key-under-cursor)))))
   (setq file     (catch 'result
		    (loop for file in org-ref-bibliography-files do
			  (if (org-ref-key-in-file-p key (file-truename file)) 
			      (throw 'result file)))))
   (cons key file)))

(defun org-ref-format-cite (keyword desc format)
   (cond
    ((eq format 'latex)
     (let* ((results (org-ref-parse-key keyword))
	    (pretext (nth 0 results))
	    (posttext (nth 1 results))
	    (key (nth 2 results)))
       (concat "\\cite" 
	       (when pretext (format "[%s]" pretext))
	       (when posttext (format "[%s]" posttext))
	       (format "{%s}" key))))))
org-ref-format-cite
(org-ref-format-cite "(pre text)(post text)key" nil 'latex)
\cite[pre text][post text]{key}
(org-ref-format-cite "(pre text)key" nil 'latex)
\cite[pre text]{key}
(org-ref-format-cite "key" nil 'latex)
\cite{key}

It looks like they all work! Let us test the links: mehta-2014-ident-poten, (pre text)mehta-2014-ident-poten and (pre text)(post text)biskup-2014-insul-ferrom-films. a multiple citation mehta-2014-ident-poten,thompson-2014-co2-react,calle-vallejo-2013-number.

This seems to work from an export point of view. You can not mix multiple citations with this syntax, and I did not define the html export above. Otherwise, it looks like this might be a reasonable addition to org-ref.

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