-**** Finding the bibliography file a key is in
-Now, we can see if an entry is in a file.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-key-in-file-p (key filename)
- "determine if the key is in the file"
- (interactive "skey: \nsFile: ")
- (save-current-buffer
- (let ((bibtex-files (list filename)))
- (bibtex-search-entry key t))))
-#+END_SRC
-
-Finally, we want to know which file the key is in.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-bibtex-key-and-file (&optional key)
- "returns the bibtex key and file that it is in. If no key is provided, get one under point"
- (interactive)
- (let ((org-ref-bibliography-files (org-ref-find-bibliography))
- (file))
- (unless key
- (setq key (org-ref-get-bibtex-key-under-cursor)))
- (setq file (catch 'result
- (loop for file in org-ref-bibliography-files do
- (if (org-ref-key-in-file-p key (file-truename file))
- (throw 'result file)))))
- (cons key file)))
-#+END_SRC
-
-**** convenience functions to act on citation at point
- :PROPERTIES:
- :ID: af0b2a82-a7c9-4c08-9dac-09f93abc4a92
- :END:
-We need some convenience functions to open act on the citation at point. These will get the pdf, open the url, or open the notes.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-open-pdf-at-point ()
- "open the pdf for bibtex key under point if it exists"
- (interactive)
- (let* ((results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (pdf-file (format (concat org-ref-pdf-directory "%s.pdf") key)))
- (if (file-exists-p pdf-file)
- (org-open-file pdf-file)
-(message "no pdf found for %s" key))))
-
-
-(defun org-ref-open-url-at-point ()
- "open the url for bibtex key under point."
- (interactive)
- (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-search-entry key)
- ;; I like this better than bibtex-url which does not always find
- ;; the urls
- (catch 'done
- (let ((url (bibtex-autokey-get-field "url")))
- (when url
- (browse-url url)
- (throw 'done nil)))
-
- (let ((doi (bibtex-autokey-get-field "doi")))
- (when doi
- (if (string-match "^http" doi)
- (browse-url doi)
- (browse-url (format "http://dx.doi.org/%s" doi)))
- (throw 'done nil))))))))
-
-
-(defun org-ref-open-notes-at-point ()
- "open the notes for bibtex key under point."
- (interactive)
- (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-search-entry key)
- (org-ref-open-bibtex-notes)))))
-
-
-(defun org-ref-citation-at-point ()
- "give message of current citation at point"
- (interactive)
- (let* ((cb (current-buffer))
- (results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (bibfile (cdr results)))
- (message "%s" (progn
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-search-entry key)
- (org-ref-bib-citation))))))
-
-
-(defun org-ref-open-citation-at-point ()
- "open bibtex file to key at point"
- (interactive)
- (let* ((cb (current-buffer))
- (results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (bibfile (cdr results)))
- (find-file bibfile)
- (bibtex-search-entry key)))
-#+END_SRC
-
-**** the actual minibuffer menu
-Now, we create the menu. This is a rewrite of the cite action. This makes the function extendable by users.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defvar org-ref-cite-menu-funcs '()
- "Functions to run on cite click menu. Each entry is a list of (key menu-name function).
-The function must take no arguments and work on the key at point. Do not modify this variable, it is set to empty in the menu click function, and functions are conditionally added to it.")
-
-
-(defvar org-ref-user-cite-menu-funcs
- '(("C" "rossref" org-ref-crossref-at-point)
- ("y" "Copy entry to file" org-ref-copy-entry-at-point-to-file)
- ("s" "Copy summary" org-ref-copy-entry-as-summary))
- "user-defined functions to run on bibtex key at point.")
-
-
-(defun org-ref-copy-entry-as-summary ()
- "Copy the bibtex entry for the citation at point as a summary."
- (interactive)
- (save-window-excursion
- (org-ref-open-citation-at-point)
- (kill-new (org-ref-bib-citation))))
-
-
-(defun org-ref-copy-entry-at-point-to-file ()
- "Copy the bibtex entry for the citation at point to NEW-FILE.
-Prompt for NEW-FILE includes bib files in org-ref-default-bibliography, and bib files in current working directory. You can also specify a new file."
- (interactive)
- (let ((new-file (ido-completing-read
- "Copy to bibfile: "
- (append org-ref-default-bibliography
- (f-entries "." (lambda (f) (f-ext? f "bib"))))))
- (key (org-ref-get-bibtex-key-under-cursor)))
- (save-window-excursion
- (org-ref-open-citation-at-point)
- (bibtex-copy-entry-as-kill))
-
- (let ((bibtex-files (list (file-truename new-file))))
- (if (assoc key (bibtex-global-key-alist))
- (message "That key already exists in %s" new-file)
- ;; add to file
- (save-window-excursion
- (find-file new-file)
- (goto-char (point-max))
- ;; make sure we are at the beginning of a line.
- (unless (looking-at "^") (insert "\n\n"))
- (bibtex-yank)
- (save-buffer))))))
-
-
-(defun org-ref-get-doi-at-point ()
- "Get doi for key at point."
- (interactive)
- (let* ((results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (bibfile (cdr results))
- doi)
- (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-search-entry key)
- (setq doi (bibtex-autokey-get-field "doi"))
- ;; in case doi is a url, remove the url part.
- (replace-regexp-in-string "^http://dx.doi.org/" "" doi)))))
-
-
-;; functions that operate on key at point for click menu
-(defun org-ref-wos-at-point ()
- "open the doi in wos for bibtex key under point."
- (interactive)
- (doi-utils-wos (org-ref-get-doi-at-point)))
-
-
-(defun org-ref-wos-citing-at-point ()
- "open the doi in wos citing articles for bibtex key under point."
- (interactive)
- (doi-utils-wos-citing (org-ref-get-doi-at-point)))
-
-
-(defun org-ref-wos-related-at-point ()
- "open the doi in wos related articles for bibtex key under point."
- (interactive)
- (doi-utils-wos-related (org-ref-get-doi-at-point)))
-
-
-(defun org-ref-google-scholar-at-point ()
- "open the doi in google scholar for bibtex key under point."
- (interactive)
- (doi-utils-google-scholar (org-ref-get-doi-at-point)))
-
-
-(defun org-ref-pubmed-at-point ()
- "open the doi in pubmed for bibtex key under point."
- (interactive)
- (doi-utils-pubmed (org-ref-get-doi-at-point)))
-
-
-(defun org-ref-crossref-at-point ()
- "open the doi in crossref for bibtex key under point."
- (interactive)
- (doi-utils-crossref (org-ref-get-doi-at-point)))
-
-
-(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."
- (interactive)
- (let* ((results (org-ref-get-bibtex-key-and-file))
- (key (car results))
- (pdf-file (format (concat org-ref-pdf-directory "%s.pdf") key))
- (bibfile (cdr results))
- (url (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-search-entry key)
- (bibtex-autokey-get-field "url"))))
- (doi (save-excursion
- (with-temp-buffer
- (insert-file-contents bibfile)
- (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-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))))))