forked from cpitclaudel/biblio.el
-
Notifications
You must be signed in to change notification settings - Fork 0
/
biblio-dissemin.el
157 lines (134 loc) · 5.88 KB
/
biblio-dissemin.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
;;; biblio-dissemin.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
;; Copyright (C) 2016 Clément Pit-Claudel
;; Author: Clément Pit-Claudel <[email protected]>
;; URL: https://github.com/cpitclaudel/biblio.el
;; 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 3 of the License, 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. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Lookup publication records on Dissemin by DOI using `dissemin-lookup'.
;;
;; This package also plugs into `biblio-selection-mode' by adding an entry to
;; the extended actions menu (`x') to quickly locate the Dissemin record of
;; e.g. a CrossRef entry.
;;; Code:
(require 'biblio-core)
(defun biblio-dissemin--format-author (author)
"Format a Dissemin AUTHOR entry."
(let-alist author
(format "%s %s" .name.first .name.last)))
(defun biblio-dissemin--insert-button (url prefix)
"Insert a button pointing to URL, prefixed by PREFIX."
(unless (seq-empty-p url)
(insert "\n" prefix)
(insert (biblio-make-url-button url))))
(defun biblio-dissemin--insert-record (record)
"Insert a Dissemin RECORD entry into the current buffer."
(let-alist record
(insert "\n\n")
(biblio-with-fontification 'font-lock-preprocessor-face
(biblio-insert-with-prefix ">> " .identifier))
(biblio-dissemin--insert-button .pdf_url " ")
(unless (string= .pdf_url .splash_url)
(biblio-dissemin--insert-button .splash_url " "))
(unless (seq-empty-p .abstract)
(insert "\n")
;; (biblio-with-fontification 'font-lock-doc-face
(biblio-insert-with-prefix " " .abstract))))
(defun biblio-dissemin--translate-classification (classification)
"Translate Dissemin's CLASSIFICATION for display."
(pcase classification
(`"OA" "Available from the publisher")
(`"OK" "Some versions may be shared by the author")
(`"UNK" "Sharing policy is unclear")
(`"CLOSED" "Subject to a restrictive sharing policy")
(_ classification)))
(defun biblio-dissemin--suggest-upload (doi)
"Insert a link to Dissemin's upload page for DOI."
(insert "\n\nDid you write this paper? ")
(biblio-with-fontification '(:weight bold)
(insert
(biblio-make-url-button (format "https://dissem.in/%s" doi) "upload it")))
(insert "!\n"))
(defun biblio-dissemin--pretty-print (paper doi)
"Pretty-print a Dissemin PAPER entry (with DOI) to current buffer."
(let-alist paper
(biblio-insert-result
(list (cons 'title .title)
(cons 'authors (seq-map #'biblio-dissemin--format-author .authors))
(cons 'open-access-status
(biblio-dissemin--translate-classification .classification)))
t)
(biblio-dissemin--insert-button .pdf_url " ")
(if (seq-empty-p .records)
(progn (insert "\n\n(no records)")
(when (member .classification '("OA" "OK"))
(biblio-dissemin--suggest-upload doi)))
(seq-do #'biblio-dissemin--insert-record .records))
(goto-char (point-min))))
(defun biblio-dissemin--print-results (paper doi)
"Create a buffer for Dissemin, and print PAPER (with DOI) into it."
(with-current-buffer (biblio-dissemin--make-buffer)
(let ((inhibit-read-only t))
(erase-buffer)
(help-mode)
(visual-line-mode)
(biblio-dissemin--pretty-print paper doi))
(setq buffer-read-only t)
(pop-to-buffer (current-buffer))))
(defun biblio-dissemin--make-buffer ()
"Create a buffer to display Dissemin results in."
(get-buffer-create "*Dissemin search results*"))
(defun biblio-dissemin--parse-buffer ()
"Extract search results from DBLP response."
(biblio-decode-url-buffer 'utf-8)
(let-alist (json-read)
(unless (string= .status "ok")
(display-warning 'biblio-dissemin "Dissemin query failed"))
.paper))
(defun biblio-dissemin--url (doi)
"Create a DBLP url to look up DOI."
(format "https://dissem.in/api/%s" (url-encode-url doi)))
(defun biblio-dissemin--callback (doi)
"Generate a callback to parse Dissemin results for DOI."
(lambda () ;; no allowed errors, so no arguments
(biblio-dissemin--print-results (biblio-dissemin--parse-buffer) doi)))
;;;###autoload
(defun biblio-dissemin-lookup (doi &optional cleanup)
"Retrieve a record by DOI from Dissemin, and display it.
Interactively, or if CLEANUP is non-nil, pass DOI through
`biblio-cleanup-doi'."
(interactive "MDOI: \nd")
(when cleanup
(setq doi (biblio-cleanup-doi doi)))
(let ((buf (biblio-dissemin--make-buffer)))
(biblio-url-retrieve (biblio-dissemin--url doi)
(biblio-generic-url-callback (biblio-dissemin--callback doi)))
buf))
;;;###autoload
(defalias 'dissemin-lookup 'biblio-dissemin-lookup)
(defun biblio-dissemin--lookup-record (record)
"Retrieve a RECORD from Dissemin, and display it.
RECORD is a formatted record as expected by `biblio-insert-result'."
(let-alist record
(if .doi (dissemin-lookup .doi)
(user-error "Dissemin needs a DOI, but this record does not contain one"))))
;;;###autoload
(defun biblio-dissemin--register-action ()
"Add Dissemin to list of `biblio-selection-mode' actions."
(add-to-list 'biblio-selection-mode-actions-alist
'("Dissemin (find open access copies of this article)" . biblio-dissemin--lookup-record)))
;;;###autoload
(add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
(provide 'biblio-dissemin)
;;; biblio-dissemin.el ends here