checkdoc.
[org-ref.git] / arxiv.el
1 ;;; arxiv.el --- arxiv utilities for org-mode        -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2015  John Kitchin
4
5 ;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
6 ;; Keywords:
7
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22 ;; this library creates a new org-link for Arxiv (http://arxiv.org/) entries,
23 ;; and provides functions to retrieve bibtex entries from an Arxiv number.
24 ;;
25 ;; An Arxiv number might look like: cond-mat/0410285 or 1503.01742
26
27 ;;; Code:
28 ;; * The org-mode link
29 ;; this just makes a clickable link that opens the entry.
30 (org-add-link-type
31  "arxiv"
32  ;; clicking
33  (lambda (link-string) (browse-url (format "http://arxiv.org/abs/%s" link-string)))
34  ;; formatting
35 (lambda (keyword desc format)
36    (cond
37     ((eq format 'html)
38      (format  "<a href=\"http://arxiv.org/abs/%s\">arxiv:%s</a>" keyword  keyword))
39     ((eq format 'latex)
40      ;; write out the latex command
41      (format "\\url{http://arxiv.org/abs/%s}" keyword)))))
42
43 ;; arxiv:cond-mat/0410285
44
45 ;; * Getting a bibtex entry for an arxiv article
46 ;; For an arxiv article, there is a link to a NASA ADS page like this:
47 ;; http://adsabs.harvard.edu/cgi-bin/bib_query?arXiv:1503.01742
48 ;; On that page, there is a link to a bibtex entry:
49 ;; http://adsabs.harvard.edu/cgi-bin/nph-bib_query?bibcode=2015arXiv150301742H&data_type=BIBTEX&db_key=PRE&nocookieset=1
50 ;;
51 ;; It looks like you need to get a Bibliographic code from the arxiv number to
52 ;; then get the bibtex entry.
53
54 (defun arxiv-get-bibliographic-code (arxiv-number)
55   "Get Bibliographic code for ARXIV-NUMBER."
56   (with-current-buffer
57       (url-retrieve-synchronously
58        (concat
59         "http://adsabs.harvard.edu/cgi-bin/bib_query?arXiv:"
60         arxiv-number))
61     (search-forward-regexp "name=\\\"bibcode\\\" value=\\\"\\(.*\\)\\\"")
62     (match-string 1)))
63
64 (defun arxiv-get-bibtex-entry (arxiv-bibliographic-code)
65   "Get bibtex entry for ARXIV-BIBLIOGRAPHIC-CODE"
66   (with-current-buffer
67       (url-retrieve-synchronously
68        (format
69         "http://adsabs.harvard.edu/cgi-bin/nph-bib_query?bibcode=%s&data_type=BIBTEX&db_key=PRE&nocookieset=1"
70         arxiv-bibliographic-code))
71     (goto-char  url-http-end-of-headers)
72     (if (search-forward  "Retrieved 1 abstracts" (point-max) t)
73         (progn
74           (forward-line)
75           (buffer-substring (point) (point-max)))
76       (error "Did not get one entry: %s" (buffer-substring (point) (point-max))))))
77
78
79 (defun arxiv-add-bibtex-entry (arxiv-number bibfile)
80   "Add bibtex entry for ARXIV-NUMBER to BIBFILE."
81  (interactive
82    (list (read-input "arxiv: ")
83          ;;  now get the bibfile to add it to
84          (ido-completing-read
85           "Bibfile: "
86           (append (f-entries "." (lambda (f) (f-ext? f "bib")))
87                   org-ref-default-bibliography))))
88  (save-window-excursion
89    (find-file bibfile)
90    (goto-char (point-max))
91    (when (not (looking-at "^")) (insert "\n"))
92    (insert (arxiv-get-bibtex-entry (arxiv-get-bibliographic-code arxiv-number)))
93    (save-buffer)))
94
95
96 (defun arxiv-get-pdf (arxiv-number pdf)
97   "Retrieve a pdf for ARXIV-NUMBER and save it to PDF."
98   (interactive "sarxiv: \nsPDF: ")
99   (let ((pdf-url (with-current-buffer
100                      (url-retrieve-synchronously
101                       (concat
102                        "http://arxiv.org/abs/" arxiv-number))
103                    ;; <meta name="citation_pdf_url" content="http://arxiv.org/pdf/0801.1144" />
104                    (search-forward-regexp
105                     "name=\\\"citation_pdf_url\\\" content=\\\"\\(.*\\)\\\"")
106                    (match-string 1))))
107     (url-copy-file pdf-url pdf)
108     ;; now check if we got a pdf
109     (with-temp-buffer
110       (insert-file-contents pdf-file)
111       ;; PDFS start with %PDF-1.x as the first few characters.
112       (if (not (string= (buffer-substring 1 6) "%PDF-"))
113           (progn
114             (message "%s" (buffer-string))
115             (delete-file pdf-file))
116         (message "%s saved" pdf-file)))
117
118     (org-open-file pdf)))
119
120 (provide 'arxiv)
121 ;;; arxiv.el ends here