From 2f9fe18ffe8259b04340de034032eceda6516ec7 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Sun, 25 Jan 2015 14:02:28 -0500 Subject: [PATCH 01/16] fix bug in adding to end of cite link --- org-ref.org | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/org-ref.org b/org-ref.org index 1e03bdf..e4fc35b 100644 --- a/org-ref.org +++ b/org-ref.org @@ -2821,6 +2821,7 @@ Technically, this function should return a string that is inserted by helm. This (-contains? org-ref-cite-types (org-element-property :type object))) + (message-box "in a link") (goto-char (org-element-property :end object)) ;; sometimes there are spaces at the end of the link ;; this code moves point pack until no spaces are there @@ -2828,18 +2829,21 @@ Technically, this function should return a string that is inserted by helm. This (insert (concat "," (mapconcat 'identity keys ",")))) ;; We are next to a link, and we want to append + ;; next to a link means one character back is on a link. ((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))))) - (goto-char (org-element-property :end object)) + (message-box "at end of a link") + ;; (goto-char (org-element-property :end object)) (while (looking-back " ") (backward-char)) (insert (concat "," (mapconcat 'identity keys ",")))) ;; insert fresh link (t + (message-box "fresh link") (insert (concat (if helm-current-prefix-arg (helm :sources `((name . "link types") -- 2.39.2 From 87443725857486d1576d9baf3e53e004f331ae85 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Sun, 25 Jan 2015 14:14:52 -0500 Subject: [PATCH 02/16] make message function only run in org-mode --- org-ref.org | 57 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/org-ref.org b/org-ref.org index e4fc35b..92b3252 100644 --- a/org-ref.org +++ b/org-ref.org @@ -2679,8 +2679,6 @@ Sometimes it may be helpful to manually change the order of citations. These fun ** 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 add it to a hook that updates after every command, including cursor movements. -ref:test citep:test label:rett - #+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-get-label-context (label) "Return a string of context around a label." @@ -2738,34 +2736,35 @@ ref:test citep:test label:rett (defun org-ref-link-message () "Print a minibuffer message about the link that point is on." (interactive) - (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 + (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)))) - ;; get plurality on occurrence correct - (message (concat - (number-to-string count) - " occurence" - (when (or (= count 0) - (> count 1)) - "s"))))))))) + + ;; message the count + ((string= type "label") + (let ((count (org-ref-count-labels + (org-element-property :path object)))) + ;; get plurality on occurrence correct + (message (concat + (number-to-string count) + " occurence" + (when (or (= count 0) + (> count 1)) + "s")))))))))) #+END_SRC * Aliases -- 2.39.2 From 4420a5ef0e7ca6eba8922b4b3b3758e63736b591 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Sun, 25 Jan 2015 14:21:57 -0500 Subject: [PATCH 03/16] remove messageboxes --- org-ref.org | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/org-ref.org b/org-ref.org index 92b3252..1425868 100644 --- a/org-ref.org +++ b/org-ref.org @@ -2047,7 +2047,6 @@ And at the end of the document put \makeglossaries. #+END_SRC - * Utilities ** create simple text citation from bibtex entry @@ -2677,7 +2676,7 @@ Sometimes it may be helpful to manually change the order of citations. These fun #+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 add it to a hook that updates after every command, including cursor movements. +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) @@ -2820,7 +2819,7 @@ Technically, this function should return a string that is inserted by helm. This (-contains? org-ref-cite-types (org-element-property :type object))) - (message-box "in a link") + ;;(message-box "in a link") (goto-char (org-element-property :end object)) ;; sometimes there are spaces at the end of the link ;; this code moves point pack until no spaces are there @@ -2835,14 +2834,14 @@ Technically, this function should return a string that is inserted by helm. This (-contains? org-ref-cite-types (org-element-property :type (org-element-context))))) - (message-box "at end of a link") + ;;(message-box "at end of a link") ;; (goto-char (org-element-property :end object)) (while (looking-back " ") (backward-char)) (insert (concat "," (mapconcat 'identity keys ",")))) ;; insert fresh link (t - (message-box "fresh link") + ;;(message-box "fresh link") (insert (concat (if helm-current-prefix-arg (helm :sources `((name . "link types") -- 2.39.2 From 1640b223fedc30e829bea58d949881d27894b572 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Sun, 25 Jan 2015 18:03:31 -0500 Subject: [PATCH 04/16] add scopus --- org-ref.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/org-ref.org b/org-ref.org index 1425868..c59d8d1 100644 --- a/org-ref.org +++ b/org-ref.org @@ -2863,6 +2863,11 @@ Technically, this function should return a string that is inserted by helm. This (helm-bibtex))) (require 'helm-bibtex) + +(mapc (lambda (x) (add-to-list 'helm-bibtex-fallback-options x t)) + '(("Crossref" . "http://search.crossref.org/?q=%s") + ("Scopus" . "http://www.scopus.com/scopus/search/submit/xadvanced.url?searchfield=TITLE-ABS-KEY(%s)") + ("Open Web of Science" . (lambda () (browse-url "http://apps.webofknowledge.com"))))) #+END_SRC ** A helm click menu -- 2.39.2 From 56658921640ee1eddc7077dd0d2fc9c40e696fd0 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 15:10:58 -0500 Subject: [PATCH 05/16] many helm integration changes --- org-ref.org | 386 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 360 insertions(+), 26 deletions(-) diff --git a/org-ref.org b/org-ref.org index c59d8d1..0c2e1d9 100644 --- a/org-ref.org +++ b/org-ref.org @@ -599,7 +599,6 @@ We use a link for the bibliography so that we can click on it to open the biblio (let* ((bibfile) ;; object is the link you clicked on (object (org-element-context)) - (link-string-beginning) (link-string-end)) @@ -913,20 +912,24 @@ In long documents, a list of figures is not uncommon. Here we create a clickable #+END_SRC ** label -The label link provides a way to create labels in org-mode. We make it clickable because we want to make sure labels are unique. This code will tell you how many instances of a label are found. We search for label links, LaTeX labels, and the org-mode format for labels. We probably should search for tblnames too. -*************** TODO search tblnames, custom_ids and check for case sensitivity -*************** END +The label link provides a way to create labels in org-mode. We make it clickable because we want to make sure labels are unique. This code will tell you how many instances of a label are found. We search for label links, LaTeX labels, and org-mode format for labels, tblnames too. #+BEGIN_SRC emacs-lisp :tangle org-ref.el - (defun org-ref-count-labels (label) + "Counts number of matches for label in the document" (+ (count-matches (format "label:%s\\b[^-:]" label) (point-min) (point-max) t) ;; for tblname, it is not enough to get word boundary ;; tab-little and tab-little-2 match then. (count-matches (format "^#\\+tblname:\\s-*%s\\b[^-:]" label) (point-min) (point-max) t) (count-matches (format "\\label{%s}\\b" label) (point-min) (point-max) t) ;; this is the org-format #+label: - (count-matches (format "^#\\+label:\\s-*%s\\b[^-:]" label) (point-min) (point-max) t))) + (count-matches (format "^#\\+label:\\s-*%s\\b[^-:]" label) (point-min) (point-max) t) + (let ((custom-id-count 0)) + (org-map-entries + (lambda () + (when (string= label (org-entry-get (point) "CUSTOM_ID")) + (setq custom-id-count (+ 1 custom-id-count))))) + custom-id-count))) (org-add-link-type "label" @@ -1096,6 +1099,29 @@ Now, we can put all the labels together which will give us a list of candidates. (append matches (org-ref-get-org-labels) (org-ref-get-latex-labels) (org-ref-get-tblnames) (org-ref-get-custom-ids)))))) #+END_SRC +Let us make a helm function to insert a label link. This will help you enter unique labels. +#+BEGIN_SRC emacs-lisp +(defun org-ref-helm-insert-label-link () + "Insert a label link. helm just shows you what labels already exist." + (interactive) + (let* ((labels (org-ref-get-labels)) + (cb (current-buffer))) + (helm :sources `(((name . "Existing labels") + (candidates . ,labels) + (action . (lambda (label) + ;; unfortunately I do not have markers here + (org-open-link-from-string (format "ref:%s" label))))) + ((name . "Create new label") + (dummy) + (action . (lambda (label) + (switch-to-buffer ,cb) + (insert + (concat + "label:" + (or label + helm-pattern)))))))))) +#+END_SRC + Now we create the completion function. This works from the org-machinery, e.g. if you type C-c C-l to insert a link, and use completion by pressing tab. #+BEGIN_SRC emacs-lisp :tangle org-ref.el @@ -1114,6 +1140,44 @@ Alternatively, you may want to just call a function that inserts a link with com (insert (org-ref-complete-link))) #+END_SRC +Another alternative ref insertion is to use helm. + +#+BEGIN_SRC emacs-lisp +(defun org-ref-helm-insert-ref-link () + "Helm menu to insert ref links to labels in the document. +Use C-u to insert a different kind of ref link." + (interactive) + (let* ((labels (org-ref-get-labels)) + (contexts (mapcar 'org-ref-get-label-context labels)) + (cb (current-buffer))) + + (helm :sources `(((name . "Available labels to ref") + (candidates . ,(loop for label in labels + for context in contexts +;; we do some kludgy adding spaces and bars to make it "easier" to see in helm. + collect (cons (concat + label "\n" + (mapconcat + (lambda (x) + (concat " |" x)) + (split-string context "\n") + "\n" + ) "\n\n") label))) + (action . (lambda (label) + (switch-to-buffer ,cb) + (insert + (concat + (if helm-current-prefix-arg + (helm :sources '((name . "Ref link types") + (candidates . ("ref" "eqref" "pageref" "nameref")) + (action . (lambda (x) x)))) + "ref") + ":" label))))))))) +#+END_SRC + +#+RESULTS: +: org-ref-helm-insert-ref-link + ** pageref This refers to the page of a label in LaTeX. @@ -2046,7 +2110,6 @@ And at the end of the document put \makeglossaries. (format "\\Glspl{%s}" path))))) #+END_SRC - * Utilities ** create simple text citation from bibtex entry @@ -2387,6 +2450,9 @@ If no bibliography is in the buffer the `reftex-default-bibliography' is used." #+END_SRC ** Find bad cite links + :PROPERTIES: + :ID: 8515E800-EDA0-4B2A-85FD-55B6FF849203 + :END: Depending on how you enter citations, you may have citations with no corresponding bibtex entry. This function finds them and gives you a clickable table to navigate to them. #+BEGIN_SRC emacs-lisp :tangle org-ref.el @@ -2444,6 +2510,190 @@ Makes a new buffer with clickable links." (message "No bad cite links found")))) #+END_SRC +** helm interface to org-ref +In [[id:8515E800-EDA0-4B2A-85FD-55B6FF849203][Find bad cite links]] we wrote a function that finds bad links and creates a buffer of links to them. + +Here we develop a similar idea, but instead of an org-buffer with links, we create helm sources for bad cite links, bad ref links, and multiple labels. + +#+BEGIN_SRC emacs-lisp :tangle org-ref.el +(defun org-ref-bad-cite-candidates () + "Returns a list of conses (key . marker) where key does not exist in the known bibliography files, and marker points to the key." + (let* ((cp (point)) ; save to return to later + (bibtex-files (org-ref-find-bibliography)) + (bibtex-file-path (mapconcat + (lambda (x) + (file-name-directory (file-truename x))) + bibtex-files ":")) + (bibtex-keys (mapcar (lambda (x) (car x)) + (bibtex-global-key-alist))) + (bad-citations '())) + + (org-element-map (org-element-parse-buffer) 'link + (lambda (link) + (let ((plist (nth 1 link))) + (when (-contains? org-ref-cite-types (plist-get plist ':type)) + (dolist (key (org-ref-split-and-strip-string (plist-get plist ':path)) ) + (when (not (index key bibtex-keys)) + (goto-char (plist-get plist ':begin)) + (re-search-forward key) + (push (cons key (point-marker)) bad-citations))) + )))) + (goto-char cp) + bad-citations)) + +;; It seems I forgot I already defined this earlier! +;; (defun org-ref-get-labels () +;; "Returns a list of known labels in the org document. These include label links, latex labels, label tags, and table names. The list contains all labels, not just unique ones. +;; " +;; (let ((cp (point)) +;; (labels '())) +;; (goto-char (point-min)) +;; (while (re-search-forward "[^#+]label:\\(.*\\)\\s-" nil t) +;; (push (match-string 1) labels)) + +;; (goto-char (point-min)) +;; (while (re-search-forward "\\label{\\(.*\\)}\\s-?" nil t) +;; (push (match-string 1) labels)) + +;; (goto-char (point-min)) +;; (while (re-search-forward "^#\\+label:\\s-*\\(.*\\)" nil t) +;; (push (match-string 1) labels)) + +;; (goto-char (point-min)) +;; (while (re-search-forward "^#\\+tblname:\\s-*\\(.*\\)" nil t) +;; (push (match-string 1) labels)) +;; ;; check for CUSTOM_ID +;; (org-map-entries +;; (lambda () +;; (when (org-entry-get (point) "CUSTOM_ID") +;; (push (org-entry-get (point) "CUSTOM_ID") labels)))) +;; ;; return to original place +;; (goto-char cp) +;; labels)) + + +(defun org-ref-bad-ref-candidates () + "Returns a list of conses (ref . marker) where ref is a ref link that does not point to anything (i.e. a label)." + ;; first get a list of legitimate labels + (let ((cp (point)) + (labels (org-ref-get-labels)) + (bad-refs '())) + ;; now loop over ref links + (goto-char (point-min)) + (org-element-map (org-element-parse-buffer) 'link + (lambda (link) + (let ((plist (nth 1 link))) + (when (or (equal (plist-get plist ':type) "ref") + (equal (plist-get plist ':type) "eqref") + (equal (plist-get plist ':type) "pageref") + (equal (plist-get plist ':type) "nameref")) + (unless (-contains? labels (plist-get plist :path)) + (goto-char (plist-get plist :begin)) + (add-to-list + 'bad-refs + (cons (plist-get plist :path) + (point-marker)))))))) + (goto-char cp) + bad-refs)) + + +(defun org-ref-bad-label-candidates () + "Return a list of labels where label is multiply defined." + (let ((labels (org-ref-get-labels)) + (multiple-labels '())) + (when (not (= (length labels) + (length (-uniq labels)))) + (dolist (label labels) + (when (> (-count (lambda (a) + (equal a label)) + labels) 1) + ;; this is a multiply defined label. + (let ((cp (point))) + (goto-char (point-min)) + (while (re-search-forward + (format "[^#+]label:%s\\s-" label) nil t) + (push (cons label (point-marker)) multiple-labels)) + + (goto-char (point-min)) + (while (re-search-forward + (format "\\label{%s}\\s-?" label) nil t) + (push (cons label (point-marker)) multiple-labels)) + + (goto-char (point-min)) + (while (re-search-forward + (format "^#\\+label:\\s-*%s" label) nil t) + (push (cons label (point-marker)) multiple-labels)) + + (goto-char (point-min)) + (while (re-search-forward + (format "^#\\+tblname:\\s-*%s" label) nil t) + (push (cons label (point-marker)) multiple-labels)) + (goto-char cp))))) + multiple-labels)) +#+END_SRC + +#+RESULTS: +: org-ref-bad-label-candidates + +Now, we have a functions for candidates, we can make helm sources for each one, and then run a helm command to view them. + +#+BEGIN_SRC emacs-lisp :tangle org-ref.el +(defun org-ref () + "Opens a helm interface to actions for org-ref. +Shows bad citations, ref links and labels" + (interactive) + (let ((cb (current-buffer)) + (bad-citations (org-ref-bad-cite-candidates)) + (bad-refs (org-ref-bad-ref-candidates)) + (bad-labels (org-ref-bad-label-candidates))) + + (helm :sources `(((name . "Bad citations") + (candidates . ,bad-citations) + (action . (lambda (marker) + (switch-to-buffer (marker-buffer marker)) + (goto-char marker)))) + ;; + ((name . "Bad Labels") + (candidates . ,bad-labels) + (action . (lambda (marker) + (switch-to-buffer (marker-buffer marker)) + (goto-char marker)))) + ;; + ((name . "Bad ref links") + (candidates . ,bad-refs) + (action . (lambda (marker) + (switch-to-buffer (marker-buffer marker)) + (goto-char marker)))) + ;; + ((name . "Utilities") + (candidates . (("Check buffer again" . org-ref) + ("Insert citation" . helm-bibtex) + ("Insert label link" . org-ref-helm-insert-label-link) + ("Insert ref link" . org-ref-helm-insert-ref-link) + ("List of figures" . org-ref-list-of-figures) + ("List of tables" . org-ref-list-of-tables) + ("Table of contents" . nil) + )) + (action . (lambda (x) + (switch-to-buffer ,cb) + (funcall x)))) + ;; + ((name . "Export functions") + (candidates . (("Extract cited entries" . org-ref-extract-bibtex-entries) + ("Export to html and open" . (lambda () (org-open-file (org-html-export-to-html)))) + ("Export to pdf and open" . (lambda () + (org-open-file (org-latex-export-to-pdf)))) + ("Export to manuscript pdf and open" . ox-manuscript-export-and-build-and-open) + ("Export submission manuscript pdf and open" . ox-manuscript-build-submission-manuscript-and-open) + + )) + (action . (lambda (x) + (switch-to-buffer ,cb) + (funcall x)))) + )))) +#+END_SRC + + ** Finding non-ascii characters I like my bibtex files to be 100% ascii. This function finds the non-ascii characters so you can replace them. @@ -2729,7 +2979,16 @@ To get a lighter weight message about the label, ref and cite links, we define a (point)) (progn (forward-line 4) - (point)))))))) + (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 () @@ -2758,12 +3017,52 @@ To get a lighter weight message about the label, ref and cite links, we define a (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")))))))))) + "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 @@ -2811,7 +3110,12 @@ Now, let us define a function that inserts the cite links: #+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun helm-bibtex-format-org-ref (keys) "Insert selected KEYS as cite link. Append KEYS if you are on a link. -Technically, this function should return a string that is inserted by helm. This function does the insertion and gives helm an empty string to insert. This lets us handle appending to a link properly." +Technically, this function should return a string that is inserted by helm. This function does the insertion and gives helm an empty string to insert. This lets us handle appending to a link properly. + +In the helm-bibtex buffer, C-u will give you a helm menu to select a new link type for the selected entries. + +C-u C-u will change the key at point to the selected keys. +" (let* ((object (org-element-context))) (cond ;; case where we are in a link @@ -2819,12 +3123,30 @@ Technically, this function should return a string that is inserted by helm. This (-contains? org-ref-cite-types (org-element-property :type object))) - ;;(message-box "in a link") - (goto-char (org-element-property :end object)) - ;; sometimes there are spaces at the end of the link - ;; this code moves point pack until no spaces are there - (while (looking-back " ") (backward-char)) - (insert (concat "," (mapconcat 'identity keys ",")))) + (cond + ;; no prefix. append keys + ((equal helm-current-prefix-arg nil) + (goto-char (org-element-property :end object)) + (while (looking-back " ") (backward-char)) + (insert (concat "," (mapconcat 'identity keys ",")))) + ;; double prefix, replace key at point + ((equal helm-current-prefix-arg '(16)) + (message-box "Replacing %s with %s" + (car (org-ref-get-bibtex-key-and-file)) + (mapconcat 'identity keys ",")) + (setf (buffer-substring + (org-element-property :begin object) + (org-element-property :end object)) + (concat + (replace-regexp-in-string + (car (org-ref-get-bibtex-key-and-file)) ; key + (mapconcat 'identity keys ",") ; new keys + (org-element-property :raw-link object) + ) + ;; replace space at end to avoid collapsing into next word. + " "))) + (t + (message-box "Not found")))) ;; We are next to a link, and we want to append ;; next to a link means one character back is on a link. @@ -2843,7 +3165,7 @@ Technically, this function should return a string that is inserted by helm. This (t ;;(message-box "fresh link") (insert - (concat (if helm-current-prefix-arg + (concat (if (equal helm-current-prefix-arg '(4)) (helm :sources `((name . "link types") (candidates . ,org-ref-cite-types) (action . (lambda (x) x)))) @@ -2864,10 +3186,19 @@ Technically, this function should return a string that is inserted by helm. This (require 'helm-bibtex) -(mapc (lambda (x) (add-to-list 'helm-bibtex-fallback-options x t)) - '(("Crossref" . "http://search.crossref.org/?q=%s") - ("Scopus" . "http://www.scopus.com/scopus/search/submit/xadvanced.url?searchfield=TITLE-ABS-KEY(%s)") - ("Open Web of Science" . (lambda () (browse-url "http://apps.webofknowledge.com"))))) +;; add our own fallback entries where we want them. These appear in reverse order of adding in the menu +(setq helm-bibtex-fallback-options + (-insert-at 1 '("Crossref" . "http://search.crossref.org/?q=%s") helm-bibtex-fallback-options)) + +(setq helm-bibtex-fallback-options + (-insert-at + 1 + '("Scopus" . "http://www.scopus.com/scopus/search/submit/xadvanced.url?searchfield=TITLE-ABS-KEY(%s)") + helm-bibtex-fallback-options)) + +(setq helm-bibtex-fallback-options + (-insert-at 1 '("Open Web of Science" . (lambda () (browse-url "http://apps.webofknowledge.com"))) + helm-bibtex-fallback-options)) #+END_SRC ** A helm click menu @@ -2879,11 +3210,14 @@ This code provides a helm interface to things you can do when you click on a cit (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))))) + (if bibfile + (save-excursion + (with-temp-buffer + (insert-file-contents bibfile) + (bibtex-search-entry key) + (org-ref-bib-citation))) + (beep) + "!!! No entry found !!!" ))) (defun org-ref-cite-candidates () "Generate the list of possible candidates for click actions on a cite link. -- 2.39.2 From 56ba56b8a81178a301fb174d8d8c6623f9ed3e3b Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 15:13:53 -0500 Subject: [PATCH 06/16] rm message box --- org-ref.org | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/org-ref.org b/org-ref.org index 0c2e1d9..cde0cef 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3131,7 +3131,6 @@ C-u C-u will change the key at point to the selected keys. (insert (concat "," (mapconcat 'identity keys ",")))) ;; double prefix, replace key at point ((equal helm-current-prefix-arg '(16)) - (message-box "Replacing %s with %s" (car (org-ref-get-bibtex-key-and-file)) (mapconcat 'identity keys ",")) (setf (buffer-substring @@ -3146,7 +3145,7 @@ C-u C-u will change the key at point to the selected keys. ;; replace space at end to avoid collapsing into next word. " "))) (t - (message-box "Not found")))) + (message "Not found")))) ;; We are next to a link, and we want to append ;; next to a link means one character back is on a link. -- 2.39.2 From f60345ce8373124a6718dfa963b598650dfbb656 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 15:22:29 -0500 Subject: [PATCH 07/16] fix type --- org-ref.org | 2 -- 1 file changed, 2 deletions(-) diff --git a/org-ref.org b/org-ref.org index cde0cef..1f66c11 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3131,8 +3131,6 @@ C-u C-u will change the key at point to the selected keys. (insert (concat "," (mapconcat 'identity keys ",")))) ;; double prefix, replace key at point ((equal helm-current-prefix-arg '(16)) - (car (org-ref-get-bibtex-key-and-file)) - (mapconcat 'identity keys ",")) (setf (buffer-substring (org-element-property :begin object) (org-element-property :end object)) -- 2.39.2 From 46a88d1f19dd80cb33673bbd61a2eef3b099dc91 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 15:31:26 -0500 Subject: [PATCH 08/16] add tangle to two blocks --- org-ref.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org-ref.org b/org-ref.org index 1f66c11..7d66a79 100644 --- a/org-ref.org +++ b/org-ref.org @@ -1100,7 +1100,7 @@ Now, we can put all the labels together which will give us a list of candidates. #+END_SRC Let us make a helm function to insert a label link. This will help you enter unique labels. -#+BEGIN_SRC emacs-lisp +#+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-helm-insert-label-link () "Insert a label link. helm just shows you what labels already exist." (interactive) @@ -1142,7 +1142,7 @@ Alternatively, you may want to just call a function that inserts a link with com Another alternative ref insertion is to use helm. -#+BEGIN_SRC emacs-lisp +#+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-helm-insert-ref-link () "Helm menu to insert ref links to labels in the document. Use C-u to insert a different kind of ref link." -- 2.39.2 From c52f96fe6fae23ff9d73651395ce8699a82284d1 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 15:49:49 -0500 Subject: [PATCH 09/16] make double prefix replace ref link --- org-ref.org | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/org-ref.org b/org-ref.org index 7d66a79..22cf65e 100644 --- a/org-ref.org +++ b/org-ref.org @@ -1145,7 +1145,8 @@ Another alternative ref insertion is to use helm. #+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-helm-insert-ref-link () "Helm menu to insert ref links to labels in the document. -Use C-u to insert a different kind of ref link." +Use C-u to insert a different kind of ref link. +C-u C-u to replace the current ref with selection" (interactive) (let* ((labels (org-ref-get-labels)) (contexts (mapcar 'org-ref-get-label-context labels)) @@ -1165,14 +1166,44 @@ Use C-u to insert a different kind of ref link." ) "\n\n") label))) (action . (lambda (label) (switch-to-buffer ,cb) - (insert - (concat - (if helm-current-prefix-arg - (helm :sources '((name . "Ref link types") - (candidates . ("ref" "eqref" "pageref" "nameref")) - (action . (lambda (x) x)))) - "ref") - ":" label))))))))) + + (cond + ;; no prefix + ((equal helm-current-prefix-arg nil) + (insert + (concat + "ref:" label))) + ;; one prefix, alternate ref link + ((equal helm-current-prefix-arg '(4)) + (insert + (concat + (helm :sources '((name . "Ref link types") + (candidates . ("ref" "eqref" "pageref" "nameref")) + (action . (lambda (x) x)))) + ":" label))) + ;; two prefixes, replace current label + ((equal helm-current-prefix-arg '(16)) + ;; get link + (let* ((object (org-element-context)) + (last-char (save-excursion + (goto-char (org-element-property :end object)) + (backward-char) + (if (looking-at " ") + " " + "")))) + (setf + (buffer-substring + (org-element-property :begin object) + (org-element-property :end object)) + (concat + (replace-regexp-in-string + (org-element-property :path object) + label + (org-element-property :raw-link object)) + last-char)))))))))))) + + + #+END_SRC #+RESULTS: @@ -3153,8 +3184,6 @@ C-u C-u will change the key at point to the selected keys. (-contains? org-ref-cite-types (org-element-property :type (org-element-context))))) - ;;(message-box "at end of a link") - ;; (goto-char (org-element-property :end object)) (while (looking-back " ") (backward-char)) (insert (concat "," (mapconcat 'identity keys ",")))) -- 2.39.2 From 2d2531c06b7ea5ae425b159c2c0b2f73b4a2f71b Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 16:04:57 -0500 Subject: [PATCH 10/16] update insert ref so we can replace current link. --- org-ref.org | 61 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/org-ref.org b/org-ref.org index 22cf65e..b04c1a1 100644 --- a/org-ref.org +++ b/org-ref.org @@ -1145,17 +1145,21 @@ Another alternative ref insertion is to use helm. #+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-helm-insert-ref-link () "Helm menu to insert ref links to labels in the document. +If you are on link, replace with newly selected label. Use C-u to insert a different kind of ref link. -C-u C-u to replace the current ref with selection" +" (interactive) (let* ((labels (org-ref-get-labels)) (contexts (mapcar 'org-ref-get-label-context labels)) (cb (current-buffer))) - (helm :sources `(((name . "Available labels to ref") + (helm :input (thing-at-point 'word) + :sources `(((name . "Available labels to ref") (candidates . ,(loop for label in labels for context in contexts -;; we do some kludgy adding spaces and bars to make it "easier" to see in helm. + ;; we do some kludgy adding spaces + ;; and bars to make it "easier" to + ;; see in helm. collect (cons (concat label "\n" (mapconcat @@ -1168,11 +1172,33 @@ C-u C-u to replace the current ref with selection" (switch-to-buffer ,cb) (cond - ;; no prefix + ;; no prefix or on a link ((equal helm-current-prefix-arg nil) - (insert - (concat - "ref:" label))) + (let* ((object (org-element-context)) + (last-char (save-excursion + (goto-char (org-element-property :end object)) + (backward-char) + (if (looking-at " ") + " " + "")))) + (if (-contains? '("ref" "eqref" "pageref" "nameref") + (org-element-property :type object)) + ;; we are on a link, so replace it. + (setf + (buffer-substring + (org-element-property :begin object) + (org-element-property :end object)) + (concat + (replace-regexp-in-string + (org-element-property :path object) + label + (org-element-property :raw-link object)) + last-char)) + ;; insert a new link + (insert + (concat + "ref:" label)) + ))) ;; one prefix, alternate ref link ((equal helm-current-prefix-arg '(4)) (insert @@ -1181,26 +1207,7 @@ C-u C-u to replace the current ref with selection" (candidates . ("ref" "eqref" "pageref" "nameref")) (action . (lambda (x) x)))) ":" label))) - ;; two prefixes, replace current label - ((equal helm-current-prefix-arg '(16)) - ;; get link - (let* ((object (org-element-context)) - (last-char (save-excursion - (goto-char (org-element-property :end object)) - (backward-char) - (if (looking-at " ") - " " - "")))) - (setf - (buffer-substring - (org-element-property :begin object) - (org-element-property :end object)) - (concat - (replace-regexp-in-string - (org-element-property :path object) - label - (org-element-property :raw-link object)) - last-char)))))))))))) + )))))))) -- 2.39.2 From 236918d8c5dc176729b4720dd7e7a74e24a756af Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 16:25:51 -0500 Subject: [PATCH 11/16] fixed some issues. added prefix keys for helm commands. --- org-ref.org | 68 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/org-ref.org b/org-ref.org index b04c1a1..73562e9 100644 --- a/org-ref.org +++ b/org-ref.org @@ -1102,17 +1102,49 @@ Now, we can put all the labels together which will give us a list of candidates. Let us make a helm function to insert a label link. This will help you enter unique labels. #+BEGIN_SRC emacs-lisp :tangle org-ref.el (defun org-ref-helm-insert-label-link () - "Insert a label link. helm just shows you what labels already exist." + "Insert a label link. helm just shows you what labels already exist. +If you are on a label link, replace it." (interactive) (let* ((labels (org-ref-get-labels)) (cb (current-buffer))) (helm :sources `(((name . "Existing labels") (candidates . ,labels) + ;; default action is to open to the label (action . (lambda (label) ;; unfortunately I do not have markers here - (org-open-link-from-string (format "ref:%s" label))))) + (org-open-link-from-string (format "ref:%s" label)))) + ;; if you select a label, replace current one + (action . (lambda (label) + (switch-to-buffer ,cb) + (cond + ;; no prefix or on a link + ((equal helm-current-prefix-arg nil) + (let* ((object (org-element-context)) + (last-char (save-excursion + (goto-char (org-element-property :end object)) + (backward-char) + (if (looking-at " ") + " " + "")))) + (when (-contains? '("label") + (org-element-property :type object)) + ;; we are on a link, so replace it. + (setf + (buffer-substring + (org-element-property :begin object) + (org-element-property :end object)) + (concat + (replace-regexp-in-string + (org-element-property :path object) + label + (org-element-property :raw-link object)) + last-char))))) + ;; no prefix options defined + )))) + ;; no matching selection creates a new label ((name . "Create new label") (dummy) + ;; default action creates a new label (action . (lambda (label) (switch-to-buffer ,cb) (insert @@ -1168,6 +1200,7 @@ Use C-u to insert a different kind of ref link. (split-string context "\n") "\n" ) "\n\n") label))) + ;; default action to replace or insert ref link. (action . (lambda (label) (switch-to-buffer ,cb) @@ -1208,9 +1241,6 @@ Use C-u to insert a different kind of ref link. (action . (lambda (x) x)))) ":" label))) )))))))) - - - #+END_SRC #+RESULTS: @@ -3154,7 +3184,13 @@ In the helm-bibtex buffer, C-u will give you a helm menu to select a new link ty C-u C-u will change the key at point to the selected keys. " - (let* ((object (org-element-context))) + (let* ((object (org-element-context)) + (last-char (save-excursion + (goto-char (org-element-property :end object)) + (backward-char) + (if (looking-at " ") + " " + "")))) (cond ;; case where we are in a link ((and (equal (org-element-type object) 'link) @@ -3179,7 +3215,7 @@ C-u C-u will change the key at point to the selected keys. (org-element-property :raw-link object) ) ;; replace space at end to avoid collapsing into next word. - " "))) + last-char))) (t (message "Not found")))) @@ -3211,11 +3247,19 @@ C-u C-u will change the key at point to the selected keys. (setq helm-bibtex-format-citation-functions '((org-mode . helm-bibtex-format-org-ref))) -(defun org-ref-helm-insert-cite-link () - "org-ref function to use helm on the bibliography defined in the org-file." - (interactive) - (let ((helm-bibtex-bibliography (org-ref-find-bibliography))) - (helm-bibtex))) +(defun org-ref-helm-insert-cite-link (arg) + "org-ref function to use helm-bibtex to insert a citation link. +With one prefix arg, insert a ref link. +With two prefix args, insert a label link." + (interactive "P") + (cond + ((equal arg nil) + (let ((helm-bibtex-bibliography (org-ref-find-bibliography))) + (helm-bibtex))) + ((equal arg '(4)) + (org-ref-helm-insert-ref-link)) + ((equal arg '(16)) + (org-ref-helm-insert-label-link)))) (require 'helm-bibtex) -- 2.39.2 From 50440af50787febd2d7797ff722a9d107416a98a Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 16:39:27 -0500 Subject: [PATCH 12/16] fix insert label to replace if needed --- org-ref.org | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/org-ref.org b/org-ref.org index 73562e9..40a2940 100644 --- a/org-ref.org +++ b/org-ref.org @@ -1144,14 +1144,35 @@ If you are on a label link, replace it." ;; no matching selection creates a new label ((name . "Create new label") (dummy) - ;; default action creates a new label + ;; default action creates a new label, or replaces old one (action . (lambda (label) (switch-to-buffer ,cb) - (insert - (concat - "label:" - (or label - helm-pattern)))))))))) + (let* ((object (org-element-context)) + (last-char (save-excursion + (goto-char (org-element-property :end object)) + (backward-char) + (if (looking-at " ") + " " + "")))) + (if (-contains? '("label") + (org-element-property :type object)) + ;; we are on a link, so replace it. + (setf + (buffer-substring + (org-element-property :begin object) + (org-element-property :end object)) + (concat + (replace-regexp-in-string + (org-element-property :path object) + helm-pattern + (org-element-property :raw-link object)) + last-char)) + ;; new link + (insert + (concat + "label:" + (or label + helm-pattern)))))))))))) #+END_SRC Now we create the completion function. This works from the org-machinery, e.g. if you type C-c C-l to insert a link, and use completion by pressing tab. -- 2.39.2 From 828c6fdc6640c263e054136431ce74680970da11 Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 16:53:29 -0500 Subject: [PATCH 13/16] fix bug in bibliography message --- org-ref.org | 2 -- 1 file changed, 2 deletions(-) diff --git a/org-ref.org b/org-ref.org index 40a2940..04746fe 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3133,13 +3133,11 @@ To get a lighter weight message about the label, ref and cite links, we define a ;; 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 -- 2.39.2 From 7c808fb33c8a5412691a787e685e745f73d8c5fe Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 17:08:09 -0500 Subject: [PATCH 14/16] fix issue in bibliography link message --- org-ref.org | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/org-ref.org b/org-ref.org index 04746fe..2e9647f 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3122,13 +3122,16 @@ To get a lighter weight message about the label, ref and cite links, we define a (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))) + ;; make sure we are in link and not before the : + (when (> link-string-beginning (point)) + (goto-char link-string-beginning)) + ;; now if we have comma separated bibliographies ;; we find the one clicked on. we want to ;; search forward to next comma from point @@ -3136,6 +3139,7 @@ To get a lighter weight message about the label, ref and cite links, we define a (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 (if (search-backward "," link-string-beginning 1 1) -- 2.39.2 From a6303d3c099b45c9baf63a60c2b9e9140daa0e3c Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 17:08:54 -0500 Subject: [PATCH 15/16] remove custom_id. we cannot ref these. --- org-ref.org | 7 ------- 1 file changed, 7 deletions(-) diff --git a/org-ref.org b/org-ref.org index 2e9647f..db0e205 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3069,13 +3069,6 @@ To get a lighter weight message about the label, ref and cite links, we define a (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 !!!")))) -- 2.39.2 From 6ca766186d0bfe13398a3c97219e1f66a078865f Mon Sep 17 00:00:00 2001 From: John Kitchin Date: Mon, 26 Jan 2015 17:14:53 -0500 Subject: [PATCH 16/16] make custom-id links have a message. --- org-ref.org | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/org-ref.org b/org-ref.org index db0e205..0582874 100644 --- a/org-ref.org +++ b/org-ref.org @@ -3107,6 +3107,12 @@ To get a lighter weight message about the label, ref and cite links, we define a (> count 1)) "s"))))) + ((string= type "custom-id") + (save-excursion + (org-open-link-from-string + (format "[[#%s]]" (org-element-property :path object))) + (message "%s" (org-get-heading)))) + ;; check if the bibliography files exist. ((string= type "bibliography") (let* ((bibfile) -- 2.39.2