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.

274 lines
8.8 KiB

5 years ago
  1. ;;; org-ref-reftex.el --- org-ref completion setup with reftex -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2016 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: This is a bare-bones completion engine using only org-mode and
  16. ;;; vanilla Emacs functions. It is not being further developed.
  17. ;;
  18. ;;; Code:
  19. (require 'reftex)
  20. (require 'reftex-cite)
  21. (require 'org-ref-utils)
  22. (declare-function 'org-ref-find-bibliography "org-ref-core.el")
  23. (declare-function 'org-ref-get-bibtex-key-and-file "org-ref-core.el")
  24. (declare-function 'org-ref-bib-citation "org-ref-core.el")
  25. (defvar org-ref-cite-types)
  26. (defvar org-ref-open-notes-function)
  27. (defvar org-ref-get-pdf-filename-function)
  28. (defvar org-ref-open-pdf-function)
  29. ;;;###autoload
  30. (defun org-ref-reftex-completion ()
  31. "Use reftex and org-mode for completion."
  32. (interactive)
  33. ;; Define core functions for org-ref
  34. (setq org-ref-insert-link-function 'org-ref-insert-cite-link
  35. org-ref-insert-cite-function 'org-ref-insert-cite-link
  36. org-ref-insert-label-function 'org-insert-link
  37. org-ref-insert-ref-function 'org-insert-link
  38. org-ref-cite-onclick-function 'org-ref-cite-onclick-minibuffer-menu)
  39. (message "reftex completion in org-ref loaded."))
  40. (org-ref-reftex-completion)
  41. (define-key org-mode-map
  42. (kbd org-ref-insert-cite-key)
  43. org-ref-insert-link-function)
  44. ;; Messages in the minbuffer conflict with the minibuffer menu. So we turn them
  45. ;; off.
  46. (setq org-ref-show-citation-on-enter nil)
  47. ;;* org-mode / reftex setup
  48. (defun org-mode-reftex-setup ()
  49. "Setup `org-mode' and reftex for `org-ref'."
  50. (and (buffer-file-name)
  51. (file-exists-p (buffer-file-name))
  52. (global-auto-revert-mode t))
  53. (make-local-variable 'reftex-cite-format)
  54. (setq reftex-cite-format 'org))
  55. (add-hook 'org-mode-hook 'org-mode-reftex-setup)
  56. (eval-after-load 'reftex-vars
  57. '(progn
  58. (add-to-list 'reftex-cite-format-builtin
  59. '(org "Org-mode citation"
  60. ((?\C-m . "cite:%l") ; default
  61. (?d . ",%l") ; for appending
  62. (?a . "autocite:%l")
  63. (?t . "citet:%l")
  64. (?T . "citet*:%l")
  65. (?p . "citep:%l")
  66. (?P . "citep*:%l")
  67. (?h . "citeauthor:%l")
  68. (?H . "citeauthor*:%l")
  69. (?y . "citeyear:%l")
  70. (?x . "citetext:%l")
  71. (?n . "nocite:%l"))))))
  72. (defun org-ref-insert-cite-link (alternative-cite)
  73. "Insert a default citation link using reftex.
  74. If you are on a link, it appends to the end of the link,
  75. otherwise, a new link is inserted. Use a prefix
  76. arg (ALTERNATIVE-CITE) to get a menu of citation types."
  77. (interactive "P")
  78. (org-ref-find-bibliography)
  79. (let* ((object (org-element-context))
  80. (link-string-end (org-element-property :end object)))
  81. (if (not alternative-cite)
  82. (cond
  83. ;; case where we are in a link
  84. ((and (equal (org-element-type object) 'link)
  85. (-contains? org-ref-cite-types
  86. (org-element-property :type object)))
  87. (goto-char link-string-end)
  88. ;; sometimes there are spaces at the end of the link
  89. ;; this code moves point pack until no spaces are there
  90. (skip-chars-backward " ")
  91. (insert (concat "," (mapconcat
  92. 'identity
  93. (reftex-citation t ?a) ","))))
  94. ;; We are next to a link, and we want to append
  95. ((save-excursion
  96. (backward-char)
  97. (and (equal (org-element-type (org-element-context)) 'link)
  98. (-contains? org-ref-cite-types
  99. (org-element-property
  100. :type (org-element-context)))))
  101. (skip-chars-backward " ")
  102. (insert (concat "," (mapconcat
  103. 'identity
  104. (reftex-citation t ?a) ","))))
  105. ;; insert fresh link
  106. (t
  107. (insert
  108. (concat org-ref-default-citation-link
  109. ":"
  110. (mapconcat 'identity (reftex-citation t) ",")))))
  111. ;; you pressed a C-u so we run this code
  112. (reftex-citation))))
  113. ;;;###autoload
  114. (defun org-ref-open-notes-from-reftex ()
  115. "Call reftex, and open notes for selected entry."
  116. (interactive)
  117. ;; now look for entry in the notes file
  118. (if org-ref-bibliography-notes
  119. (find-file-other-window org-ref-bibliography-notes)
  120. (error "org-ref-bibliography-notes is not set to anything"))
  121. (org-open-link-from-string
  122. (format "[[#%s]]" (car (reftex-citation t))))
  123. (funcall org-ref-open-notes-function))
  124. (defalias 'ornr 'org-ref-open-notes-from-reftex)
  125. ;;*** Minibuffer menu
  126. ;;;###autoload
  127. (defun org-ref-cite-onclick-minibuffer-menu (&optional _link-string)
  128. "Action when a cite link is clicked on.
  129. Provides a menu of context sensitive actions. If the bibtex entry
  130. has a pdf, you get an option to open it. If there is a doi, you
  131. get a lot of options. LINK-STRING is used by the link function."
  132. (interactive)
  133. (let* ((results (org-ref-get-bibtex-key-and-file))
  134. (key (car results))
  135. (pdf-file (funcall org-ref-get-pdf-filename-function key))
  136. (bibfile (cdr results))
  137. (url (save-excursion
  138. (with-temp-buffer
  139. (insert-file-contents bibfile)
  140. (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
  141. (bibtex-search-entry key)
  142. (bibtex-autokey-get-field "url"))))
  143. (doi (save-excursion
  144. (with-temp-buffer
  145. (insert-file-contents bibfile)
  146. (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
  147. (bibtex-search-entry key)
  148. ;; I like this better than bibtex-url which does not always find
  149. ;; the urls
  150. (bibtex-autokey-get-field "doi")))))
  151. (when (string= "" doi) (setq doi nil))
  152. (when (string= "" url) (setq url nil))
  153. (setq org-ref-cite-menu-funcs '())
  154. ;; open action
  155. (when
  156. bibfile
  157. (add-to-list
  158. 'org-ref-cite-menu-funcs
  159. '("o" "pen" org-ref-open-citation-at-point)))
  160. ;; pdf
  161. (when (file-exists-p pdf-file)
  162. (add-to-list
  163. 'org-ref-cite-menu-funcs
  164. `("p" "df" ,org-ref-open-pdf-function) t))
  165. ;; notes
  166. (add-to-list
  167. 'org-ref-cite-menu-funcs
  168. '("n" "otes" org-ref-open-notes-at-point) t)
  169. ;; url
  170. (when (or url doi)
  171. (add-to-list
  172. 'org-ref-cite-menu-funcs
  173. '("u" "rl" org-ref-open-url-at-point) t))
  174. ;; doi funcs
  175. (when doi
  176. (add-to-list
  177. 'org-ref-cite-menu-funcs
  178. '("w" "os" org-ref-wos-at-point) t)
  179. (add-to-list
  180. 'org-ref-cite-menu-funcs
  181. '("c" "iting" org-ref-wos-citing-at-point) t)
  182. (add-to-list
  183. 'org-ref-cite-menu-funcs
  184. '("r" "elated" org-ref-wos-related-at-point) t)
  185. (add-to-list
  186. 'org-ref-cite-menu-funcs
  187. '("g" "oogle scholar" org-ref-google-scholar-at-point) t)
  188. (add-to-list
  189. 'org-ref-cite-menu-funcs
  190. '("P" "ubmed" org-ref-pubmed-at-point) t))
  191. ;; add user functions
  192. (dolist (tup org-ref-user-cite-menu-funcs)
  193. (add-to-list
  194. 'org-ref-cite-menu-funcs
  195. tup t))
  196. ;; finally quit
  197. (add-to-list
  198. 'org-ref-cite-menu-funcs
  199. '("q" "uit" (lambda ())) t)
  200. ;; now we make a menu
  201. ;; construct menu string as a message
  202. (message
  203. (concat
  204. (let* ((results (org-ref-get-bibtex-key-and-file))
  205. (key (car results))
  206. (bibfile (cdr results)))
  207. (save-excursion
  208. (with-temp-buffer
  209. (insert-file-contents bibfile)
  210. (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
  211. (bibtex-search-entry key)
  212. (org-ref-bib-citation))))
  213. "\n"
  214. (mapconcat
  215. (lambda (tup)
  216. (concat "[" (elt tup 0) "]"
  217. (elt tup 1) " "))
  218. org-ref-cite-menu-funcs "")))
  219. ;; get the input
  220. (let* ((input (read-char-exclusive))
  221. (choice (assoc
  222. (char-to-string input) org-ref-cite-menu-funcs)))
  223. ;; now run the function (2nd element in choice)
  224. (when choice
  225. (funcall
  226. (elt
  227. choice
  228. 2))))))
  229. (provide 'org-ref-reftex)
  230. ;;; org-ref-reftex.el ends here