X-Git-Url: https://git.donarmstrong.com/?p=org-ref.git;a=blobdiff_plain;f=org-ref.org;h=dbaf75be246913a0f9625ea94c7573a77ec7fb69;hp=1f66c11842d017843aa391a27cc66e13bc4debc8;hb=3044d6641e83953951a3a576abde2cc7e51dc553;hpb=f60345ce8373124a6718dfa963b598650dfbb656 diff --git a/org-ref.org b/org-ref.org index 1f66c11..dbaf75b 100644 --- a/org-ref.org +++ b/org-ref.org @@ -12,6 +12,19 @@ This document is an experiment at creating a literate program to provide similar 4. Exportable links to LaTeX 5. Utility functions for dealing with bibtex files and org-files +1. Get minibuffer messages for the cite/ref/label link under point + +With helm integration (default) you can: + +1. C-c ] to insert a citation link + in helm-bibtex + - Enter to insert or append citation(s) + - C-u Enter to insert an alternative cite link + - C-u C-u Enter to replace the citation at point +2. C-u C-c ] to insert a ref link with helm completion +3. C-u C-u C-c ] to insert a label with completion +4. M-x org-ref to get a helm completion buffer with link checks, utilities and export options + ** Header #+BEGIN_SRC emacs-lisp :tangle org-ref.el ;;; org-ref.el --- setup bibliography, cite, ref and label org-mode links. @@ -917,17 +930,17 @@ The label link provides a way to create labels in org-mode. We make it clickable #+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) + (+ (count-matches (format "label:%s\\b[^-:]" label) (point-min) (point-max)) ;; 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) + (count-matches (format "^#\\+tblname:\\s-*%s\\b[^-:]" label) (point-min) (point-max)) + (count-matches (format "\\label{%s}\\b" label) (point-min) (point-max)) ;; 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)) (let ((custom-id-count 0)) (org-map-entries (lambda () - (when (string= label (org-entry-get (point) "CUSTOM_ID")) + (when (string= label (org-entry-get (point) "CUSTOM_ID")) (setq custom-id-count (+ 1 custom-id-count))))) custom-id-count))) @@ -935,7 +948,14 @@ The label link provides a way to create labels in org-mode. We make it clickable "label" (lambda (label) "on clicking count the number of label tags used in the buffer. A number greater than one means multiple labels!" - (message (format "%s occurences" (org-ref-count-labels label)))) + (let ((count (org-ref-count-labels label))) + (message (format "%s occurence%s" + count + (if (or (= count 0) + (> count 1)) + "s" + "")) + (org-ref-count-labels label)))) (lambda (keyword desc format) (cond ((eq format 'html) (format "()" path)) @@ -1100,26 +1120,79 @@ 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." + "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, 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. @@ -1142,19 +1215,24 @@ 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." +If you are on link, replace with newly selected label. +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") + (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 @@ -1163,16 +1241,47 @@ 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) - (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 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 " ") + " " + "")))) + (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 + (concat + (helm :sources '((name . "Ref link types") + (candidates . ("ref" "eqref" "pageref" "nameref")) + (action . (lambda (x) x)))) + ":" label))) + )))))))) #+END_SRC #+RESULTS: @@ -2980,13 +3089,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 !!!")))) @@ -3025,6 +3127,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) @@ -3033,24 +3141,26 @@ 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 (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 @@ -3116,7 +3226,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) @@ -3141,7 +3257,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")))) @@ -3153,8 +3269,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 ",")))) @@ -3175,11 +3289,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)