-** Sort entries in citation links with shift-arrow keys
-Sometimes it may be helpful to manually change the order of citations. These functions define shift-arrow functions.
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-swap-keys (i j keys)
- "swap the keys in a list with index i and j"
- (let ((tempi (nth i keys)))
- (setf (nth i keys) (nth j keys))
- (setf (nth j keys) tempi))
- keys)
-
-(defun org-ref-swap-citation-link (direction)
- "move citation at point in direction +1 is to the right, -1 to the left"
- (interactive)
- (let* ((object (org-element-context))
- (type (org-element-property :type object))
- (begin (org-element-property :begin object))
- (end (org-element-property :end object))
- (link-string (org-element-property :path object))
- key keys i)
- ;; We only want this to work on citation links
- (when (-contains? org-ref-cite-types type)
- (setq key (org-ref-get-bibtex-key-under-cursor))
- (setq keys (org-ref-split-and-strip-string link-string))
- (setq i (index key keys)) ;; defined in org-ref
- (if (> direction 0) ;; shift right
- (org-ref-swap-keys i (+ i 1) keys)
- (org-ref-swap-keys i (- i 1) keys))
- (setq keys (mapconcat 'identity keys ","))
- ;; and replace the link with the sorted keys
- (cl--set-buffer-substring begin end (concat type ":" keys " "))
- ;; now go forward to key so we can move with the key
- (re-search-forward key)
- (goto-char (match-beginning 0)))))
-
-;; add hooks to make it work
-(add-hook 'org-shiftright-hook (lambda () (org-ref-swap-citation-link 1)))
-(add-hook 'org-shiftleft-hook (lambda () (org-ref-swap-citation-link -1)))
-#+END_SRC
-
-** Lightweight messages about links
-To get a lighter weight message about the label, ref and cite links, we define a function that gives us the minibuffer message, without the menu. We run this in an idle timer.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-label-context (label)
- "Return a string of context around a label."
- (save-excursion
- (catch 'result
- (goto-char (point-min))
- (when (re-search-forward
- (format "label:%s\\b" label) nil t)
- (throw 'result (buffer-substring
- (progn
- (previous-line)
- (beginning-of-line)
- (point))
- (progn
- (forward-line 4)
- (point)))))
-
- (goto-char (point-min))
- (when (re-search-forward
- (format "\\label{%s}" label) nil t)
- (throw 'result (buffer-substring
- (progn
- (previous-line)
- (beginning-of-line)
- (point))
- (progn
- (forward-line 4)
- (point)))))
-
- (goto-char (point-min))
- (when (re-search-forward
- (format "^#\\+label:\\s-*\\(%s\\)\\b" label) nil t)
- (throw 'result (buffer-substring
- (progn
- (previous-line)
- (beginning-of-line)
- (point))
- (progn
- (forward-line 4)
- (point)))))
-
- (goto-char (point-min))
- (when (re-search-forward
- (format "^#\\+tblname:\\s-*\\(%s\\)\\b" label) nil t)
- (throw 'result (buffer-substring
- (progn
- (previous-line)
- (beginning-of-line)
- (point))
- (progn
- (forward-line 4)
- (point)))))
-
- ;; maybe we have a CUSTOM-ID
- (org-map-entries
- (lambda () (when (string=
- label
- (org-entry-get (point) "CUSTOM_ID"))
- (throw 'result (org-get-heading)))))
- (beep)
- (throw 'result "!!! NO CONTEXT FOUND !!!"))))
-
-
-(defun org-ref-link-message ()
- "Print a minibuffer message about the link that point is on."
- (interactive)
- (when (eq major-mode 'org-mode)
- (let* ((object (org-element-context))
- (type (org-element-property :type object)))
- (save-excursion
- (cond
- ;; cite links
- ((-contains? org-ref-cite-types type)
- (message (org-ref-get-citation-string-at-point)))
-
- ;; message some context about the label we are referring to
- ((string= type "ref")
- (message (org-ref-get-label-context
- (org-element-property :path object))))
-
- ((string= type "eqref")
- (message (org-ref-get-label-context
- (org-element-property :path object))))
-
- ;; message the count
- ((string= type "label")
- (let ((count (org-ref-count-labels
- (org-element-property :path object))))
- ;; get plurality on occurrence correct
- (when (> count 1) (beep))
- (message (concat
- (number-to-string count)
- " occurence"
- (when (or (= count 0)
- (> count 1))
- "s")))))
-
- ;; check if the bibliography files exist.
- ((string= type "bibliography")
- (let* ((bibfile)
- ;; object is the link you clicked on
- (object (org-element-context))
- (link-string (org-element-property :path object))
- (link-string-beginning)
- (link-string-end))
-
- (save-excursion
- (goto-char (org-element-property :begin object))
- (search-forward link-string nil nil 1)
- (setq link-string-beginning (match-beginning 0))
- (setq link-string-end (match-end 0)))
-
- ;; now if we have comma separated bibliographies
- ;; we find the one clicked on. we want to
- ;; search forward to next comma from point
- (save-excursion
- (goto-char link-string-beginning)
- (if (search-forward "," link-string-end 1 1)
- (setq key-end (- (match-end 0) 1)) ; we found a match
- (setq key-end (point)))) ; no comma found so take the point
- ;; and backward to previous comma from point
- (save-excursion
- (goto-char link-string-beginning)
- (if (search-backward "," link-string-beginning 1 1)
- (setq key-beginning (+ (match-beginning 0) 1)) ; we found a match
- (setq key-beginning (point)))) ; no match found
- ;; save the key we clicked on.
- (setq bibfile
- (org-ref-strip-string
- (buffer-substring key-beginning key-end)))
- (if (file-exists-p bibfile)
- (message "%s exists." bibfile)
- (beep)
- (message "!!! %s NOT FOUND !!!" bibfile))))
- )))))
-#+END_SRC
-
-* Aliases
-I like convenience. Here are some aliases for faster typing.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defalias 'oro 'org-ref-open-citation-at-point)
-(defalias 'orc 'org-ref-citation-at-point)
-(defalias 'orp 'org-ref-open-pdf-at-point)
-(defalias 'oru 'org-ref-open-url-at-point)
-(defalias 'orn 'org-ref-open-notes-at-point)
-(defalias 'ornr 'org-ref-open-notes-from-reftex)
-
-(defalias 'orib 'org-ref-insert-bibliography-link)
-(defalias 'oric 'org-ref-insert-cite-link)
-(defalias 'orir 'org-ref-insert-ref-link)
-(defalias 'orsl 'org-ref-store-bibtex-entry-link)
-
-(defalias 'orcb 'org-ref-clean-bibtex-entry)
-#+END_SRC
-* Helm interface
-[[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]] is a very cool interface to bibtex files. Out of the box though, it is not super convenient for org-ref. Here, we modify it to make it fit our workflow and extend it where needed.
-
-1. Make the default action to insert selected keys.
-2. Make open entry second action
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(setq helm-source-bibtex
- '((name . "BibTeX entries")
- (init . helm-bibtex-init)
- (candidates . helm-bibtex-candidates)
- (filtered-candidate-transformer . helm-bibtex-candidates-formatter)
- (action . (("Insert citation" . helm-bibtex-insert-citation)
- ("Show entry" . helm-bibtex-show-entry)
- ("Open PDF file (if present)" . helm-bibtex-open-pdf)
- ("Open URL or DOI in browser" . helm-bibtex-open-url-or-doi)
- ("Insert reference" . helm-bibtex-insert-reference)
- ("Insert BibTeX key" . helm-bibtex-insert-key)
- ("Insert BibTeX entry" . helm-bibtex-insert-bibtex)
- ("Attach PDF to email" . helm-bibtex-add-PDF-attachment)
- ("Edit notes" . helm-bibtex-edit-notes)
- ))))
-#+END_SRC