#+RESULTS:
| :volume | 99 | :indexed | (:timestamp 1399964115538.0 :date-parts [[2014 5 13]]) | :publisher | American Physical Society (APS) | :source | CrossRef | :URL | http://dx.doi.org/10.1103/PhysRevLett.99.016105 | :ISSN | [0031-9007 1079-7114] | :DOI | 10.1103/physrevlett.99.016105 | :type | journal-article | :title | Scaling Properties of Adsorption Energies for Hydrogen-Containing Molecules on Transition-Metal Surfaces | :issue | 1 | :deposited | (:timestamp 1313712000000.0 :date-parts [[2011 8 19]]) | :reference-count | 26 | :container-title | Phys. Rev. Lett. | :author | [(:given F. :family Abild-Pedersen) (:given J. :family Greeley) (:given F. :family Studt) (:given J. :family Rossmeisl) (:given T. :family Munter) (:given P. :family Moses) (:given E. :family Skúlason) (:given T. :family Bligaard) (:given J. :family Nørskov)] | :prefix | http://id.crossref.org/prefix/10.1103 | :score | 1.0 | :issued | (:date-parts [[2007 7]]) | :subject | [Physics and Astronomy(all)] | :subtitle | [] |
+or for a book:
+#+BEGIN_SRC emacs-lisp :tangle no
+(doi-utils-get-json-metadata "10.1007/978-1-4612-4968-9")
+#+END_SRC
+
+#+RESULTS:
+| :member | nil | :indexed | (:timestamp 1423773021494 :date-parts [[2015 2 12]]) | :publisher | Springer New York | :source | CrossRef | :URL | http://dx.doi.org/10.1007/978-1-4612-4968-9 | :ISBN | [http://id.crossref.org/isbn/978-0-387-96347-1 http://id.crossref.org/isbn/978-1-4612-4968-9] | :ISSN | [0172-6056] | :DOI | 10.1007/978-1-4612-4968-9 | :type | book | :title | Constructive Combinatorics | :deposited | (:timestamp 1378684800000 :date-parts [[2013 9 9]]) | :reference-count | 0 | :container-title | Undergraduate Texts in Mathematics | :author | [(:given Dennis :family Stanton) (:given Dennis :family White)] | :prefix | none | :score | 1.0 | :issued | (:date-parts [[1986]]) | :subtitle | [] |
+
We can use that data to construct a bibtex entry. We do that by defining a template, and filling it in. I wrote this template expansion code which makes it easy to substitute values like %{} in emacs lisp.
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
Now we define a function that fills in that template from the metadata.
+As different bibtex types share common keys, it is advantageous to separate data extraction from json, and the formatting of the bibtex entry.
+
+#+BEGIN_SRC emacs-lisp :notangle doi-utils.el
+(defmacro defpar (name &optional value)
+ `(progn (defvar ,name)
+ (setf ,name ,value)))
+
+(defpar doi-utils-json-metadata-extract
+ '((type (plist-get results :type))
+ (author (mapconcat (lambda (x) (concat (plist-get x :given) " " (plist-get x :family)))
+ (plist-get results :author) " and "))
+ (title (plist-get results :title))
+ (subtitle (plist-get results :subtitle))
+ (journal (plist-get results :container-title))
+ (series (plist-get results :container-title))
+ (publisher (plist-get results :publisher))
+ (volume (plist-get results :volume))
+ (issue (plist-get results :issue))
+ (number (plist-get results :issue))
+ (year (elt (elt (plist-get (plist-get results :issued) :date-parts) 0) 0))
+ (month (elt (elt (plist-get (plist-get results :issued) :date-parts) 0) 1))
+ (pages (plist-get results :page))
+ (doi (plist-get results :DOI))
+ (url (plist-get results :URL))
+ (booktitle (plist-get results :container-title))))
+#+END_SRC
+
+Next, we need to define the different bibtex types. Each type has a bibtex type (for output) and the type as provided in the doi record. Finally, we have to declare the fields we want to output.
+
+#+BEGIN_SRC emacs-lisp :notangle doi-utils.el
+(defvar doi-utils-bibtex-type-generators nil)
+
+(defun concat-prepare (lst &optional acc)
+ "Given a list `lst' of strings and other expressions, which are
+intented to passed to `concat', concat any subsequent strings,
+minimising the number of arguments being passed to `concat'
+without changing the results."
+ (cond ((null lst) (nreverse acc))
+ ((and (stringp (car lst))
+ (stringp (car acc)))
+ (concat-prepare (cdr lst) (cons (concat (car acc) (car lst))
+ (cdr acc))))
+ (t (concat-prepare (cdr lst) (cons (car lst) acc)))))
+
+
+(defmacro doi-utils-def-bibtex-type (name matching-types &rest fields)
+ "Define a BibTeX type identified by (symbol) `name' with
+`fields' (given as symbols), matching to retrieval expressions in
+`doi-utils-json-metadata-extract'. This type will only be used
+when the `:type' parameter in the JSON metadata is contained in
+`matching-types' - a list of strings."
+ `(push (lambda (type results)
+ (when (or ,@(mapcar (lambda (match-type) `(string= type ,match-type)) matching-types))
+ (let ,(mapcar (lambda (field) (or (assoc field doi-utils-json-metadata-extract)
+ (error "unknown bibtex field type %s" field)))
+ fields)
+ (concat
+ ,@(concat-prepare
+ (-flatten
+ (list (concat "@" (symbol-name name) "{,\n")
+ ;; there seems to be some bug with mapcan,
+ ;; so we fall back to flatten
+ (mapcar (lambda (field)
+ `(,(concat " " (symbol-name field) " = {")
+ ,field
+ "},\n"))
+ fields)
+ "}\n")))))))
+ doi-utils-bibtex-type-generators))
+
+(doi-utils-def-bibtex-type article ("journal-article" "article-journal")
+ author title journal year volume number pages doi url)
+
+(doi-utils-def-bibtex-type inproceedings ("proceedings-article")
+ author title booktitle year month pages doi url)
+
+(doi-utils-def-bibtex-type book ("book")
+ author title series publisher year pages doi url)
+#+END_SRC
+
+With the code generating the bibtex entry in place, we can glue it to the json retrieval code.
+#+BEGIN_SRC emacs-lisp :notangle doi-utils.el
+(defun doi-utils-doi-to-bibtex-string (doi)
+ "return a bibtex entry as a string for the doi. Only articles are currently supported"
+ (let* ((results (doi-utils-get-json-metadata doi))
+ (type (plist-get results :type)))
+ (format "%s" results) ; json-data
+ (some (lambda (g) (funcall g type results)) doi-utils-bibtex-type-generators)
+ (message-box "%s not supported yet." type)))
+#+END_SRC
+
+
#+BEGIN_SRC emacs-lisp :tangle doi-utils.el
(defun doi-utils-doi-to-bibtex-string (doi)
"return a bibtex entry as a string for the doi. Only articles are currently supported"