* Adding a bibtex entry from a crossref query
+The idea here is to perform a query on Crossref, get a helm buffer of candidates, and select the entry(ies) you want to add to your bibtex file. You can select a region, e.g. a free form citation, or set of words, or you can type the query in by hand.
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
(defun doi-utils-add-entry-from-crossref-query (query bibtex-file)
(cond
;; If region is active assume we want it
((region-active-p)
- (buffer-substring (region-beginning) (region-end)))
+ (replace-regexp-in-string
+ "\n" " "
+ (buffer-substring (region-beginning) (region-end))))
;; type or paste it in
(t
nil)))
(setq json-string (buffer-substring url-http-end-of-headers (point-max)))
(setq json-data (json-read-from-string json-string)))
- (let* ((name (format "Crossref hits for %s" query))
+ (let* ((name (format "Crossref hits for %s"
+ ;; remove carriage returns. they cause problems in helm.
+ (replace-regexp-in-string "\n" " " query)))
(helm-candidates (mapcar (lambda (x)
(cons
(concat
;; just return the candidate
(action . (("Insert bibtex entry" . (lambda (doi)
(doi-utils-add-bibtex-entry-from-doi
- (replace-regexp-in-string "^http://dx.doi.org/" "" doi))))
+ (replace-regexp-in-string "^http://dx.doi.org/" "" doi) ,bibtex-file)))
("Open url" . (lambda (doi)
(browse-url doi))))))))
(helm :sources '(source)))))
#+END_EXAMPLE
-#+BEGIN_SRC emacs-lisp :var data=json :results value raw
+#+BEGIN_SRC emacs-lisp :var data=json :results value raw :tangle no
(let ((json-object-type 'plist)
(json (json-read-from-string data)))
(aref json 0))
Here is a list of helm candidates
-#+BEGIN_SRC emacs-lisp :var data=json :results code
+#+BEGIN_SRC emacs-lisp :var data=json :results code :tangle no
(let (;(json-object-type 'plist)
(json (json-read-from-string data)))
(mapcar (lambda (x) (cons (assoc 'fullCitation x) x)) json))
#+END_SRC
#+RESULTS:
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp :tangle no
+
(((fullCitation . "Ann M. Deml, Vladan Stevanovi\304\207, Christopher L. Muhich, Charles B. Musgrave, Ryan O'Hayre, 2014, 'Oxide enthalpy of formation and band gap energy as accurate descriptors of oxygen vacancy formation energetics', <i>Energy & Environmental Science</i>, vol. 7, no. 6, p. 1996")
(year . "2014")
(coins . "ctx_ver=Z39.88-2004&rft_id=info%3Adoi%2Fhttp%3A%2F%2Fdx.doi.org%2F10.1039%2Fc3ee43874k&rfr_id=info%3Asid%2Fcrossref.org%3Asearch&rft.atitle=Oxide+enthalpy+of+formation+and+band+gap+energy+as+accurate+descriptors+of+oxygen+vacancy+formation+energetics&rft.jtitle=Energy+%26+Environmental+Science&rft.date=2014&rft.volume=7&rft.issue=6&rft.spage=1996&rft.aufirst=Ann+M.&rft.aulast=Deml&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&rft.genre=article&rft.au=Ann+M.+Deml&rft.au=+Vladan+Stevanovi%C4%87&rft.au=+Christopher+L.+Muhich&rft.au=+Charles+B.+Musgrave&rft.au=+Ryan+O%27Hayre")
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
(defun isbn-to-bibtex-lead (isbn)
"Search lead.to for ISBN bibtex entry. You have to copy the entry if it is on the page to your bibtex file."
- (interactive "ISBN: ")
+ (interactive "sISBN: ")
(browse-url
(format "http://lead.to/amazon/en/?key=%s+&si=all&op=bt&bn=&so=sa&ht=us" isbn)))
#+END_SRC
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
(defun isbn-to-bibtex (isbn bibfile)
"Get bibtex entry for ISBN and insert it into BIBFILE unless an
-entry with the generated key already exists in the file. "
+entry with the generated key already exists in the file."
(interactive
(list
(read-input
"ISBN: "
;; now set initial input
(cond
- ;; If region is active assume we want it
- ((region-active-p)
+ ;; If region is active and it starts with a number, we use it
+ ((and (region-active-p)
+ (s-match "^[0-9]" (buffer-substring (region-beginning) (region-end))))
(buffer-substring (region-beginning) (region-end)))
;; if first entry in kill ring starts with a number assume it is an isbn
;; and use it as the guess
(new-entry)
(new-key))
+ ;; check if we got something
(unless (string= "ok" status)
(error "Status is %s" status))
+ ;; construct an alphabetically sorted bibtex entry. I assume ISBN numbers go
+ ;; with book entries.
(setq new-entry
(concat "\n@book{,\n"
(mapconcat
"\n")
"\n}\n"))
- ;; build entry in temp buffer to get the key
+ ;; build entry in temp buffer to get the key so we can check for duplicates
(setq new-entry (with-temp-buffer
(insert new-entry)
(org-ref-clean-bibtex-entry)
new-key)))
(goto-char (point-max))
(insert new-entry)
- ;; set key
+ ;; set key. It is simplest to just replace it, even if it is the same.
(bibtex-beginning-of-entry)
(re-search-forward bibtex-entry-maybe-empty-head)
(if (match-beginning bibtex-key-in-head)
(delete-region (match-beginning bibtex-key-in-head)
(match-end bibtex-key-in-head)))
(insert new-key)
- (bibtex-fill-entry)))
+ (bibtex-fill-entry)
+ (save-buffer)))
#+END_SRC
+
+
* end of file
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
(provide 'doi-utils)
#+RESULTS:
: Loaded doi-utils.el
-
-
-
-
-
-#+BEGIN_SRC emacs-lisp
-(setq data '(("John" . "john@email.com")
- ("Jim" . "jim@email.com")
- ("Jane" . "jane@email.com")
- ("Jill" . "jill@email.com")))
-
-(setq some-helm-source
- `((name . "HELM at the Emacs")
- (candidates . ,(mapcar 'car data))
- (action . (lambda (candidate)
- (message-box "%s" (cdr (assoc candidate data)))))))
-
-(message-box "you chose %s" (helm :sources '(some-helm-source)))
-#+END_SRC
-
-#+RESULTS:
-: you chose jim@email.com