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.

222 lines
9.0 KiB

5 years ago
  1. ;;; org-ref-scopus.el --- Emacs-lisp interface to the Scopus API -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2015 John Kitchin
  3. ;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
  4. ;; Keywords:
  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. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; See http://dev.elsevier.com/index.html for more information about the Scopus API
  17. ;;
  18. ;; New org-links:
  19. ;; eid:2-s2.0-72649092395 with a hydra menu
  20. ;; [[scopus-search:alloy Au segregation]]
  21. ;; [[scopus-advanced-search:au-id(24176978500)]]
  22. ;;; Code:
  23. (require 'org)
  24. (require 'hydra)
  25. (require 'xml)
  26. (require 'org-ref-utils)
  27. (defvar url-request-method)
  28. (defvar url-mime-accept-string)
  29. (defvar url-http-end-of-headers)
  30. (defvar url-request-extra-headers)
  31. (defvar *scopus-api-key* nil
  32. "Your Scopus API key.
  33. You need to set this in your init files. Get a key here:
  34. http://dev.elsevier.com/myapikey.html.")
  35. ;; (defun scopus-doi-to-xml (doi)
  36. ;; "Return a parsed xml from the Scopus article retrieval api for DOI.
  37. ;; This does not always seem to work for the most recent DOIs."
  38. ;; (let* ((url-request-method "GET")
  39. ;; (url-request-extra-headers (list (cons "X-ELS-APIKey" *scopus-api-key*)))
  40. ;; (url (format "http://api.elsevier.com/content/article/doi/%s" doi))
  41. ;; (xml))
  42. ;; (setq xml
  43. ;; (with-current-buffer (url-retrieve-synchronously url)
  44. ;; (xml-parse-region url-http-end-of-headers (point-max))))
  45. ;; (if (eq 'service-error (caar xml))
  46. ;; (progn (message-box "%s\n%s\n%s" doi url xml)
  47. ;; nil)
  48. ;; xml)))
  49. (defun scopus-doi-to-eid (doi)
  50. "Get a Scopus eid from a DOI.
  51. Requires `*scopus-api-key*' to be defined."
  52. (unless *scopus-api-key* (error "You must define `*scopus-api-key*'"))
  53. (let* ((url-request-method "GET")
  54. (url-mime-accept-string "application/xml")
  55. (url-request-extra-headers (list (cons "X-ELS-APIKey" *scopus-api-key*)
  56. '("field" . "eid")))
  57. (url (format "http://api.elsevier.com/content/search/scopus?query=doi(%s)" doi))
  58. (xml (with-current-buffer (url-retrieve-synchronously url)
  59. (xml-parse-region url-http-end-of-headers (point-max))))
  60. (results (car xml))
  61. (entry (car (xml-get-children results 'entry))))
  62. (car (xml-node-children (car (xml-get-children entry 'eid))))))
  63. ;;;###autoload
  64. (defun scopus-related-by-keyword-url (doi)
  65. "Return a Scopus url to articles related by keyword for DOI."
  66. (interactive)
  67. (unless *scopus-api-key* (error "You must define `*scopus-api-key*'"))
  68. (let ((eid (scopus-doi-to-eid doi)))
  69. (when eid (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=key&zone=relatedDocuments" eid))))
  70. ;;;###autoload
  71. (defun scopus-related-by-author-url (doi)
  72. "Return a Scopus url to articles related by author for DOI."
  73. (interactive)
  74. (unless *scopus-api-key* (error "You must define `*scopus-api-key*'"))
  75. (let ((eid (scopus-doi-to-eid doi)))
  76. (when eid (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=aut&zone=relatedDocuments" eid))))
  77. ;;;###autoload
  78. (defun scopus-related-by-references-url (doi)
  79. "Return a Scopus url to articles related by references for DOI."
  80. (interactive)
  81. (unless *scopus-api-key* (error "You must define `*scopus-api-key*'"))
  82. (let ((eid (scopus-doi-to-eid doi)))
  83. (when eid (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=ref&zone=relatedDocuments" eid))))
  84. (defun scopus-citing-url (doi)
  85. "Return a Scopus url to articles citing DOI."
  86. (format "http://www.scopus.com/results/citedbyresults.url?sort=plf-f&cite=%s&src=s&imp=t&sot=cite&sdt=a&sl=0&origin=recordpage" (scopus-doi-to-eid doi)))
  87. ;;;###autoload
  88. (defun scopus-open-eid (eid)
  89. "Open article with EID in browser."
  90. (interactive "sEID: ")
  91. (browse-url (format "http://www.scopus.com/record/display.url?eid=%s&origin=resultslist" eid)))
  92. (defun scopus ()
  93. "Open http://scopus.com is a browser."
  94. (browse-url "http://www.scopus.com"))
  95. ;;;###autoload
  96. (defun scopus-basic-search (query)
  97. "Open QUERY as a basic title-abstract-keyword search at scopus.com."
  98. (interactive "sQuery: ")
  99. (browse-url
  100. (format
  101. "http://www.scopus.com/results/results.url?sort=plf-f&src=s&sot=b&sdt=b&sl=%s&s=TITLE-ABS-KEY%%28%s%%29&origin=searchbasic"
  102. (length (url-unhex-string (concat "TITLE-ABS-KEY%28" (url-hexify-string query) "%29")))
  103. (url-hexify-string query))))
  104. ;;;###autoload
  105. (defun scopus-advanced-search (query)
  106. "Open QUERY as an advanced search at scopus.com."
  107. (interactive "sQuery: ")
  108. (browse-url
  109. (format
  110. "http://www.scopus.com/results/results.url?sort=plf-f&src=s&sot=a&sdt=a&sl=%s&s=%s&origin=searchadvanced"
  111. (length query)
  112. (url-hexify-string query))))
  113. ;;; Org-mode EID link and an action menu
  114. ;; These functions use a global var *hydra-eid*
  115. (defvar *hydra-eid* nil
  116. "Global variable to pass an EID from an ‘org-mode’ link to a hydra function.")
  117. (defhydra scopus-hydra (:color blue)
  118. ("o" (scopus-open-eid *hydra-eid*) "Open in Scopus")
  119. ("a" (browse-url (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=aut&zone=relatedDocuments" *hydra-eid*))
  120. "Related by author")
  121. ("k" (browse-url (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=key&zone=relatedDocuments" *hydra-eid*))
  122. "Related by keyword")
  123. ("r" (browse-url (format "http://www.scopus.com/search/submit/mlt.url?eid=%s&src=s&all=true&origin=recordpage&method=ref&zone=relatedDocuments" *hydra-eid*))
  124. "Related by references")
  125. ("c" (browse-url (format "http://www.scopus.com/results/citedbyresults.url?sort=plf-f&cite=%s&src=s&imp=t&sot=cite&sdt=a&sl=0&origin=recordpage" *hydra-eid*))
  126. "Citing articles"))
  127. (org-ref-link-set-parameters "eid"
  128. :follow (lambda (eid)
  129. "Opens the hydra menu."
  130. (setq *hydra-eid* eid)
  131. (scopus-hydra/body))
  132. :export (lambda (keyword desc format)
  133. (cond
  134. ((eq format 'html)
  135. (format "<a href=\" http://www.scopus.com/record/display.url?eid=%s&origin=resultslist\">%s</a>" keyword (or desc keyword)))
  136. ((eq format 'latex)
  137. (format "\\href{http://www.scopus.com/record/display.url?eid=%s&origin=resultslist}{%s}"
  138. keyword (or desc keyword))))))
  139. (org-ref-link-set-parameters "scopus-search"
  140. :follow (lambda (query)
  141. (scopus-basic-search query))
  142. :export (lambda (query desc format)
  143. (let ((url (format
  144. "http://www.scopus.com/results/results.url?sort=plf-f&src=s&sot=b&sdt=b&sl=%s&s=TITLE-ABS-KEY%%28%s%%29&origin=searchbasic"
  145. (length (url-unhex-string (concat "TITLE-ABS-KEY%28" (url-hexify-string query) "%29")))
  146. (url-hexify-string query))))
  147. (cond
  148. ((eq format 'html)
  149. (format "<a href=\"%s\">%s</a>" url (or desc query)))
  150. ((eq format 'latex)
  151. (format "\\href{%s}{%s}" url (or desc query)))))))
  152. (org-ref-link-set-parameters "scopus-advanced-search"
  153. :follow (lambda (query)
  154. (scopus-advanced-search query))
  155. :export (lambda (query desc format)
  156. (let ((url (format
  157. "http://www.scopus.com/results/results.url?sort=plf-f&src=s&sot=a&sdt=a&sl=%s&s=%s&origin=searchadvanced"
  158. (length (url-hexify-string query))
  159. (url-hexify-string query))))
  160. (cond
  161. ((eq format 'html)
  162. (format "<a href=\"%s\">%s</a>" url (or desc query)))
  163. ((eq format 'latex)
  164. (format "\\href{%s}{%s}" url (or desc query)))))))
  165. (org-ref-link-set-parameters "scopusid"
  166. :follow (lambda
  167. (link-string)
  168. (browse-url
  169. (format
  170. "http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=%s"
  171. link-string)))
  172. :export (lambda (keyword desc format)
  173. (cond
  174. ((eq format 'latex)
  175. (format "\\href{http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=%s}{%s}"
  176. keyword (or desc (concat "scopusid:" keyword))))
  177. ((eq format 'html)
  178. (format "<a href=\"http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=%s\">%s</a>"
  179. keyword (or desc (concat "scopusid:" keyword)))))))
  180. (provide 'org-ref-scopus)
  181. ;;; org-ref-scopus.el ends here