-#+RESULTS:
-: org-ref-clean-bibtex-entry
-
-** Sort the entries in a citation link by year
-I prefer citations in chronological order within a grouping. These functions sort the link under the cursor by year.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-citation-year (key)
- "get the year of an entry with key. Returns year as a string."
- (interactive)
- (let* ((results (org-ref-get-bibtex-key-and-file key))
- (bibfile (cdr results)))
- (with-temp-buffer
- (insert-file-contents bibfile)
- (bibtex-search-entry key nil 0)
- (prog1 (reftex-get-bib-field "year" (bibtex-parse-entry t))
- ))))
-
-(defun org-ref-sort-citation-link ()
- "replace link at point with sorted link by year"
- (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))
- keys years data)
- (setq keys (org-ref-split-and-strip-string link-string))
- (setq years (mapcar 'org-ref-get-citation-year keys))
- (setq data (mapcar* (lambda (a b) `(,a . ,b)) years keys))
- (setq data (cl-sort data (lambda (x y) (< (string-to-int (car x)) (string-to-int (car y))))))
- ;; now get the keys separated by commas
- (setq keys (mapconcat (lambda (x) (cdr x)) data ","))
- ;; and replace the link with the sorted keys
- (cl--set-buffer-substring begin end (concat type ":" keys))))
-#+END_SRC
-
-** 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)