Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.9 KiB

4 years ago
  1. ;;; biblio-dissemin.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2016 Clément Pit-Claudel
  3. ;; Author: Clément Pit-Claudel <clement.pitclaudel@live.com>
  4. ;; URL: http://github.com/cpitclaudel/biblio.el
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;;
  10. ;; This program is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;;
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;;
  19. ;; Lookup publication records on Dissemin by DOI using `dissemin-lookup'.
  20. ;;
  21. ;; This package also plugs into `biblio-selection-mode' by adding an entry to
  22. ;; the extended actions menu (`x') to quickly locate the Dissemin record of
  23. ;; e.g. a CrossRef entry.
  24. ;;; Code:
  25. (require 'biblio-core)
  26. (defun biblio-dissemin--format-author (author)
  27. "Format a Dissemin AUTHOR entry."
  28. (let-alist author
  29. (format "%s %s" .name.first .name.last)))
  30. (defun biblio-dissemin--insert-button (url prefix)
  31. "Insert a button pointing to URL, prefixed by PREFIX."
  32. (unless (seq-empty-p url)
  33. (insert "\n" prefix)
  34. (insert (biblio-make-url-button url))))
  35. (defun biblio-dissemin--insert-record (record)
  36. "Insert a Dissemin RECORD entry into the current buffer."
  37. (let-alist record
  38. (insert "\n\n")
  39. (biblio-with-fontification 'font-lock-preprocessor-face
  40. (biblio-insert-with-prefix ">> " .identifier))
  41. (biblio-dissemin--insert-button .pdf_url " ")
  42. (unless (string= .pdf_url .splash_url)
  43. (biblio-dissemin--insert-button .splash_url " "))
  44. (unless (seq-empty-p .abstract)
  45. (insert "\n")
  46. ;; (biblio-with-fontification 'font-lock-doc-face
  47. (biblio-insert-with-prefix " " .abstract))))
  48. (defun biblio-dissemin--translate-classification (classification)
  49. "Translate Dissemin's CLASSIFICATION for display."
  50. (pcase classification
  51. (`"OA" "Available from the publisher")
  52. (`"OK" "Some versions may be shared by the author")
  53. (`"UNK" "Sharing policy is unclear")
  54. (`"CLOSED" "Subject to a restrictive sharing policy")
  55. (_ classification)))
  56. (defun biblio-dissemin--suggest-upload (doi)
  57. "Insert a link to Dissemin's upload page for DOI."
  58. (insert "\n\nDid you write this paper? ")
  59. (biblio-with-fontification '(:weight bold)
  60. (insert
  61. (biblio-make-url-button (format "http://dissem.in/%s" doi) "upload it")))
  62. (insert "!\n"))
  63. (defun biblio-dissemin--pretty-print (paper doi)
  64. "Pretty-print a Dissemin PAPER entry (with DOI) to current buffer."
  65. (let-alist paper
  66. (biblio-insert-result
  67. (list (cons 'title .title)
  68. (cons 'authors (seq-map #'biblio-dissemin--format-author .authors))
  69. (cons 'open-access-status
  70. (biblio-dissemin--translate-classification .classification)))
  71. t)
  72. (biblio-dissemin--insert-button .pdf_url " ")
  73. (if (seq-empty-p .records)
  74. (progn (insert "\n\n(no records)")
  75. (when (member .classification '("OA" "OK"))
  76. (biblio-dissemin--suggest-upload doi)))
  77. (seq-do #'biblio-dissemin--insert-record .records))
  78. (goto-char (point-min))))
  79. (defun biblio-dissemin--print-results (paper doi)
  80. "Create a buffer for Dissemin, and print PAPER (with DOI) into it."
  81. (with-current-buffer (biblio-dissemin--make-buffer)
  82. (let ((inhibit-read-only t))
  83. (erase-buffer)
  84. (help-mode)
  85. (visual-line-mode)
  86. (biblio-dissemin--pretty-print paper doi))
  87. (setq buffer-read-only t)
  88. (pop-to-buffer (current-buffer))))
  89. (defun biblio-dissemin--make-buffer ()
  90. "Create a buffer to display Dissemin results in."
  91. (get-buffer-create "*Dissemin search results*"))
  92. (defun biblio-dissemin--parse-buffer ()
  93. "Extract search results from DBLP response."
  94. (biblio-decode-url-buffer 'utf-8)
  95. (let-alist (json-read)
  96. (unless (string= .status "ok")
  97. (display-warning 'biblio-dissemin "Dissemin query failed"))
  98. .paper))
  99. (defun biblio-dissemin--url (doi)
  100. "Create a DBLP url to look up DOI."
  101. (format "http://dissem.in/api/%s" (url-encode-url doi)))
  102. (defun biblio-dissemin--callback (doi)
  103. "Generate a callback to parse Dissemin results for DOI."
  104. (lambda () ;; no allowed errors, so no arguments
  105. (biblio-dissemin--print-results (biblio-dissemin--parse-buffer) doi)))
  106. ;;;###autoload
  107. (defun biblio-dissemin-lookup (doi &optional cleanup)
  108. "Retrieve a record by DOI from Dissemin, and display it.
  109. Interactively, or if CLEANUP is non-nil, pass DOI through
  110. `biblio-cleanup-doi'."
  111. (interactive "MDOI: \nd")
  112. (when cleanup
  113. (setq doi (biblio-cleanup-doi doi)))
  114. (let ((buf (biblio-dissemin--make-buffer)))
  115. (biblio-url-retrieve (biblio-dissemin--url doi)
  116. (biblio-generic-url-callback (biblio-dissemin--callback doi)))
  117. buf))
  118. ;;;###autoload
  119. (defalias 'dissemin-lookup 'biblio-dissemin-lookup)
  120. (defun biblio-dissemin--lookup-record (record)
  121. "Retrieve a RECORD from Dissemin, and display it.
  122. RECORD is a formatted record as expected by `biblio-insert-result'."
  123. (let-alist record
  124. (if .doi (dissemin-lookup .doi)
  125. (user-error "Dissemin needs a DOI, but this record does not contain one"))))
  126. ;;;###autoload
  127. (defun biblio-dissemin--register-action ()
  128. "Add Dissemin to list of `biblio-selection-mode' actions."
  129. (add-to-list 'biblio-selection-mode-actions-alist
  130. '("Dissemin (find open access copies of this article)" . biblio-dissemin--lookup-record)))
  131. ;;;###autoload
  132. (add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
  133. (provide 'biblio-dissemin)
  134. ;;; biblio-dissemin.el ends here