|
|
- ;;; org-ref-reftex.el --- org-ref completion setup with reftex -*- lexical-binding: t; -*-
-
- ;; Copyright (C) 2016 John Kitchin
-
- ;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
- ;; Keywords:
-
- ;; 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 <http://www.gnu.org/licenses/>.
-
- ;;; Commentary: This is a bare-bones completion engine using only org-mode and
- ;;; vanilla Emacs functions. It is not being further developed.
-
- ;;
-
- ;;; Code:
- (require 'reftex)
- (require 'reftex-cite)
- (require 'org-ref-utils)
-
- (declare-function 'org-ref-find-bibliography "org-ref-core.el")
- (declare-function 'org-ref-get-bibtex-key-and-file "org-ref-core.el")
- (declare-function 'org-ref-bib-citation "org-ref-core.el")
-
- (defvar org-ref-cite-types)
- (defvar org-ref-open-notes-function)
- (defvar org-ref-get-pdf-filename-function)
- (defvar org-ref-open-pdf-function)
-
- ;;;###autoload
- (defun org-ref-reftex-completion ()
- "Use reftex and org-mode for completion."
- (interactive)
- ;; Define core functions for org-ref
- (setq org-ref-insert-link-function 'org-ref-insert-cite-link
- org-ref-insert-cite-function 'org-ref-insert-cite-link
- org-ref-insert-label-function 'org-insert-link
- org-ref-insert-ref-function 'org-insert-link
- org-ref-cite-onclick-function 'org-ref-cite-onclick-minibuffer-menu)
- (message "reftex completion in org-ref loaded."))
-
- (org-ref-reftex-completion)
- (define-key org-mode-map
- (kbd org-ref-insert-cite-key)
- org-ref-insert-link-function)
-
- ;; Messages in the minbuffer conflict with the minibuffer menu. So we turn them
- ;; off.
- (setq org-ref-show-citation-on-enter nil)
-
- ;;* org-mode / reftex setup
- (defun org-mode-reftex-setup ()
- "Setup `org-mode' and reftex for `org-ref'."
- (and (buffer-file-name)
- (file-exists-p (buffer-file-name))
- (global-auto-revert-mode t))
- (make-local-variable 'reftex-cite-format)
- (setq reftex-cite-format 'org))
-
- (add-hook 'org-mode-hook 'org-mode-reftex-setup)
-
-
- (eval-after-load 'reftex-vars
- '(progn
- (add-to-list 'reftex-cite-format-builtin
- '(org "Org-mode citation"
- ((?\C-m . "cite:%l") ; default
- (?d . ",%l") ; for appending
- (?a . "autocite:%l")
- (?t . "citet:%l")
- (?T . "citet*:%l")
- (?p . "citep:%l")
- (?P . "citep*:%l")
- (?h . "citeauthor:%l")
- (?H . "citeauthor*:%l")
- (?y . "citeyear:%l")
- (?x . "citetext:%l")
- (?n . "nocite:%l"))))))
-
-
- (defun org-ref-insert-cite-link (alternative-cite)
- "Insert a default citation link using reftex.
- If you are on a link, it appends to the end of the link,
- otherwise, a new link is inserted. Use a prefix
- arg (ALTERNATIVE-CITE) to get a menu of citation types."
- (interactive "P")
- (org-ref-find-bibliography)
- (let* ((object (org-element-context))
- (link-string-end (org-element-property :end object)))
-
- (if (not alternative-cite)
-
- (cond
- ;; case where we are in a link
- ((and (equal (org-element-type object) 'link)
- (-contains? org-ref-cite-types
- (org-element-property :type object)))
- (goto-char link-string-end)
- ;; sometimes there are spaces at the end of the link
- ;; this code moves point pack until no spaces are there
- (skip-chars-backward " ")
- (insert (concat "," (mapconcat
- 'identity
- (reftex-citation t ?a) ","))))
-
- ;; We are next to a link, and we want to append
- ((save-excursion
- (backward-char)
- (and (equal (org-element-type (org-element-context)) 'link)
- (-contains? org-ref-cite-types
- (org-element-property
- :type (org-element-context)))))
- (skip-chars-backward " ")
- (insert (concat "," (mapconcat
- 'identity
- (reftex-citation t ?a) ","))))
-
- ;; insert fresh link
- (t
- (insert
- (concat org-ref-default-citation-link
- ":"
- (mapconcat 'identity (reftex-citation t) ",")))))
-
- ;; you pressed a C-u so we run this code
- (reftex-citation))))
-
-
- ;;;###autoload
- (defun org-ref-open-notes-from-reftex ()
- "Call reftex, and open notes for selected entry."
- (interactive)
- ;; now look for entry in the notes file
- (if org-ref-bibliography-notes
- (find-file-other-window org-ref-bibliography-notes)
- (error "org-ref-bibliography-notes is not set to anything"))
-
- (org-open-link-from-string
- (format "[[#%s]]" (car (reftex-citation t))))
- (funcall org-ref-open-notes-function))
-
- (defalias 'ornr 'org-ref-open-notes-from-reftex)
-
- ;;*** Minibuffer menu
- ;;;###autoload
- (defun org-ref-cite-onclick-minibuffer-menu (&optional _link-string)
- "Action when a cite link is clicked on.
- Provides a menu of context sensitive actions. If the bibtex entry
- has a pdf, you get an option to open it. If there is a doi, you
- get a lot of options. LINK-STRING is used by the link function."
- (interactive)
- (let* ((results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (pdf-file (funcall org-ref-get-pdf-filename-function key))
- (bibfile (cdr results))
- (url (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
- (bibtex-search-entry key)
- (bibtex-autokey-get-field "url"))))
- (doi (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
- (bibtex-search-entry key)
- ;; I like this better than bibtex-url which does not always find
- ;; the urls
- (bibtex-autokey-get-field "doi")))))
-
- (when (string= "" doi) (setq doi nil))
- (when (string= "" url) (setq url nil))
- (setq org-ref-cite-menu-funcs '())
-
- ;; open action
- (when
- bibfile
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("o" "pen" org-ref-open-citation-at-point)))
-
- ;; pdf
- (when (file-exists-p pdf-file)
- (add-to-list
- 'org-ref-cite-menu-funcs
- `("p" "df" ,org-ref-open-pdf-function) t))
-
- ;; notes
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("n" "otes" org-ref-open-notes-at-point) t)
-
- ;; url
- (when (or url doi)
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("u" "rl" org-ref-open-url-at-point) t))
-
- ;; doi funcs
- (when doi
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("w" "os" org-ref-wos-at-point) t)
-
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("c" "iting" org-ref-wos-citing-at-point) t)
-
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("r" "elated" org-ref-wos-related-at-point) t)
-
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("g" "oogle scholar" org-ref-google-scholar-at-point) t)
-
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("P" "ubmed" org-ref-pubmed-at-point) t))
-
- ;; add user functions
- (dolist (tup org-ref-user-cite-menu-funcs)
- (add-to-list
- 'org-ref-cite-menu-funcs
- tup t))
-
- ;; finally quit
- (add-to-list
- 'org-ref-cite-menu-funcs
- '("q" "uit" (lambda ())) t)
-
- ;; now we make a menu
- ;; construct menu string as a message
- (message
- (concat
- (let* ((results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (bibfile (cdr results)))
- (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-set-dialect (parsebib-find-bibtex-dialect) t)
- (bibtex-search-entry key)
- (org-ref-bib-citation))))
- "\n"
- (mapconcat
- (lambda (tup)
- (concat "[" (elt tup 0) "]"
- (elt tup 1) " "))
- org-ref-cite-menu-funcs "")))
- ;; get the input
- (let* ((input (read-char-exclusive))
- (choice (assoc
- (char-to-string input) org-ref-cite-menu-funcs)))
- ;; now run the function (2nd element in choice)
- (when choice
- (funcall
- (elt
- choice
- 2))))))
-
-
- (provide 'org-ref-reftex)
- ;;; org-ref-reftex.el ends here
|