;;; doi-utils.el --- get bibtex entries and pdfs from a DOI ;; Copyright(C) 2014 John Kitchin ;; Author: John Kitchin ;; This file is not currently part of GNU Emacs. ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 2, or (at ;; your option) any later version. ;; This program is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program ; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; ;; Lisp code to generate and update bibtex entries from a DOI, and to ;; download pdfs from publisher websites from a DOI. ;; ;; Package-Requires: ((org-ref)) (require 'json) (defvar *doi-utils-waiting* t "stores waiting state for url retrieval.") (defvar *doi-utils-redirect* nil "stores redirect url from a callback function") (defun doi-utils-redirect-callback (&optional status) "callback for url-retrieve to set the redirect" (when (plist-get status :error) (signal (car (plist-get status :error)) (cdr(plist-get status :error)))) (when (plist-get status :redirect) ; is nil if there none (message "redirects = %s" (plist-get status :redirect)) (message "*doi-utils-redirect* set to %s" (setq *doi-utils-redirect* (plist-get status :redirect)))) ;; we have done our job, so we are not waiting any more. (setq *doi-utils-waiting* nil)) (defun doi-utils-get-redirect (doi) "get redirect url from dx.doi.org/doi" ;; we are going to wait until the url-retrieve is done (setq *doi-utils-waiting* t) ;; start with no redirect. it will be set in the callback. (setq *doi-utils-redirect* nil) (url-retrieve (format "http://dx.doi.org/%s" doi) 'doi-utils-redirect-callback) ; I suspect we need to wait here for the asynchronous process to ; finish. we loop and sleep until the callback says it is done via ; `*doi-utils-waiting*'. this works as far as i can tell. Before I ; had to run this a few times to get it to work, which i suspect ; just gave the first one enough time to finish. (while *doi-utils-waiting* (sleep-for 0.1))) (defvar doi-utils-pdf-url-functions nil "list of functions that return a url to a pdf from a redirect url. Each function takes one argument, the redirect url. The function must return a pdf-url, or nil.") (defun aps-pdf-url (*doi-utils-redirect*) (when (string-match "^http://journals.aps.org" *doi-utils-redirect*) (replace-regexp-in-string "/abstract/" "/pdf/" *doi-utils-redirect*))) (defun science-pdf-url (*doi-utils-redirect*) (when (string-match "^http://www.sciencemag.org" *doi-utils-redirect*) (concat *doi-utils-redirect* ".full.pdf"))) (defun nature-pdf-url (*doi-utils-redirect*) (when (string-match "^http://www.nature.com" *doi-utils-redirect*) (let ((result *doi-utils-redirect*)) (setq result (replace-regexp-in-string "/full/" "/pdf/" result)) (replace-regexp-in-string "\.html$" "\.pdf" result)))) (defun doi-utils-get-wiley-pdf-url (redirect-url) "wileyscience direct hides the pdf url in html. we get it out here" (setq *doi-utils-waiting* t) (url-retrieve redirect-url (lambda (status) (beginning-of-buffer) (re-search-forward "