pkg update and first config fix
org-brain not working, add org-roam
This commit is contained in:
73
lisp/org-ref/contrib.el
Normal file
73
lisp/org-ref/contrib.el
Normal file
@@ -0,0 +1,73 @@
|
||||
;;; contrib.el --- Code contributed by users
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; * Add messages in minibuffer
|
||||
;; Contributed in https://github.com/jkitchin/org-ref/issues/938 by @DiogoFerrari
|
||||
|
||||
|
||||
(defun org-ref-get-bibtex-key-under-cursor--display ()
|
||||
"Return key under the cursor in `org-mode'.
|
||||
If not on a key, but on a cite, prompt for key."
|
||||
(if-let ((key (get-text-property (point) 'cite-key)))
|
||||
;; Point is on a key, so we get it directly
|
||||
key
|
||||
;; point is not on a key, but may still be on a cite link
|
||||
(let ((el (org-element-context))
|
||||
data
|
||||
keys)
|
||||
(cond
|
||||
;; on a cite-link type
|
||||
((and
|
||||
(eq (org-element-type el) 'link)
|
||||
(assoc (org-element-property :type el) org-ref-cite-types))
|
||||
|
||||
(goto-char (org-element-property :begin el))
|
||||
(setq data (org-ref-parse-cite-path (org-element-property :path el))
|
||||
keys (cl-loop for ref in (plist-get data :references)
|
||||
collect (plist-get ref :key)))
|
||||
(setq text nil)
|
||||
(dolist (key keys)
|
||||
(search-forward key)
|
||||
(goto-char (match-beginning 0))
|
||||
(get-text-property (point) 'cite-key)
|
||||
;; (message (bibtex-completion-apa-format-reference key))
|
||||
(setq text (concat text "\n" (bibtex-completion-apa-format-reference key))))))))
|
||||
(message (string-trim-left text)))
|
||||
|
||||
|
||||
(defvar org-ref-message-timer nil
|
||||
"Stores the idle timer for cite minibuffer messages.")
|
||||
|
||||
|
||||
(defcustom org-ref-message-interval 0.5
|
||||
"Time in seconds to wait for the idle timer that displays the cite message."
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defun org-ref-link-message ()
|
||||
"Display a message in the minibuffer when point is on a cite link."
|
||||
(when (and (eq major-mode 'org-mode) (eq (get-text-property (point) 'help-echo) 'org-ref-cite-tooltip))
|
||||
(save-excursion (org-ref-get-bibtex-key-under-cursor--display))))
|
||||
|
||||
|
||||
(defun org-ref-messages-on ()
|
||||
"Turn cite messages to minibuffer on."
|
||||
(interactive)
|
||||
(setq org-ref-message-timer (run-with-idle-timer org-ref-message-interval 0 'org-ref-link-message)))
|
||||
|
||||
|
||||
(defun org-ref-messages-off ()
|
||||
"Turn cite messages to minibuffer off."
|
||||
(interactive)
|
||||
(when org-ref-message-timer
|
||||
(cancel-timer org-ref-message-timer)
|
||||
(setq org-ref-message-timer nil)))
|
||||
|
||||
|
||||
(provide 'contrib)
|
||||
|
||||
;;; contrib.el ends here
|
||||
@@ -569,7 +569,7 @@ It would be better to parse this, but here I just use a regexp.
|
||||
(lambda (status)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "citation_pdf_url\" content=\"\\(.*\\)\"" nil t)
|
||||
(message-box (match-string 1))
|
||||
;; (message-box (match-string 1))
|
||||
(setq *doi-utils-pdf-url* (match-string 1)
|
||||
*doi-utils-waiting* nil)))
|
||||
(while (and *doi-utils-waiting* (< *doi-utils-waiting* 5))
|
||||
@@ -967,7 +967,7 @@ MATCHING-TYPES."
|
||||
"}\n")))))))
|
||||
doi-utils-bibtex-type-generators))
|
||||
|
||||
(doi-utils-def-bibtex-type article ("journal-article" "article-journal")
|
||||
(doi-utils-def-bibtex-type article ("journal-article" "article-journal" "article")
|
||||
author title journal year volume number pages doi url)
|
||||
|
||||
(doi-utils-def-bibtex-type inproceedings ("proceedings-article" "paper-conference")
|
||||
@@ -1576,7 +1576,8 @@ Get a list of possible matches. Choose one with completion."
|
||||
(doi-utils-add-bibtex-entry-from-doi
|
||||
(replace-regexp-in-string
|
||||
"^https?://\\(dx.\\)?doi.org/" "" doi)
|
||||
bibtex-file)))))
|
||||
bibtex-file)
|
||||
(save-buffer)))))
|
||||
|
||||
(defalias 'crossref-add-bibtex-entry 'doi-utils-add-entry-from-crossref-query
|
||||
"Alias function for convenience.")
|
||||
|
||||
@@ -200,7 +200,9 @@ Returns a formatted BibTeX entry."
|
||||
(completing-read
|
||||
"Bibfile: "
|
||||
(append (f-entries "." (lambda (f) (f-ext? f "bib")))
|
||||
bibtex-completion-bibliography))))
|
||||
(if (stringp bibtex-completion-bibliography)
|
||||
(list bibtex-completion-bibliography)
|
||||
bibtex-completion-bibliography)))))
|
||||
(save-window-excursion
|
||||
(find-file bibfile)
|
||||
(goto-char (point-max))
|
||||
|
||||
@@ -172,7 +172,7 @@ Optional argument BACKEND is the export backend."
|
||||
(save-window-excursion
|
||||
(bibtex-completion-show-entry (list key))
|
||||
(buffer-file-name))))))
|
||||
(insert (format "bibliography:%s" (string-join files ",")))))
|
||||
(insert (format "[[bibliography:%s]]" (string-join files ",")))))
|
||||
|
||||
|
||||
(defun org-ref-bibliography-complete (&optional arg)
|
||||
|
||||
@@ -359,6 +359,20 @@ title-case by org-ref-title-case."
|
||||
:group 'org-ref-bibtex)
|
||||
|
||||
|
||||
(defcustom org-ref-bibtex-pdf-download-dir
|
||||
(cond
|
||||
((stringp bibtex-completion-library-path)
|
||||
bibtex-completion-library-path)
|
||||
(t
|
||||
(car bibtex-completion-library-path)))
|
||||
"Default directory to look for downloaded pdfs.
|
||||
Used in `org-ref-bibtex-assoc-pdf-with-entry' when looking for a
|
||||
PDF to associate with an entry. Defaults to the first entry in
|
||||
`bibtex-completion-library-path'."
|
||||
:group 'org-ref-bibtex
|
||||
:type 'directory)
|
||||
|
||||
|
||||
;; * Modifying journal titles
|
||||
;;;###autoload
|
||||
(defun org-ref-bibtex-generate-longtitles ()
|
||||
@@ -777,7 +791,9 @@ a directory. Optional PREFIX argument toggles between
|
||||
(interactive "P")
|
||||
(save-excursion
|
||||
(bibtex-beginning-of-entry)
|
||||
(let* ((file (read-file-name "Select file associated with entry: "))
|
||||
(let* ((file (read-file-name
|
||||
"Select file associated with entry: "
|
||||
org-ref-bibtex-pdf-download-dir))
|
||||
(bibtex-expand-strings t)
|
||||
(entry (bibtex-parse-entry t))
|
||||
(key (cdr (assoc "=key=" entry)))
|
||||
|
||||
@@ -96,6 +96,14 @@ This is mostly for multicites and natbib."
|
||||
:group 'org-ref-faces)
|
||||
|
||||
|
||||
(defcustom org-ref-activate-cite-links t
|
||||
"If non-nil use font-lock to activate citations.
|
||||
In large documents with many citations activation can be slow.
|
||||
Set this to nil to turn that off, which increase performance."
|
||||
:type 'boolean
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defcustom org-ref-default-citation-link
|
||||
"cite"
|
||||
"The default type of citation link to use."
|
||||
@@ -106,9 +114,9 @@ This is mostly for multicites and natbib."
|
||||
(defcustom org-ref-natbib-types
|
||||
'(("cite" "basic citation")
|
||||
("nocite" "add key to bibliography, but do not cite it in the text")
|
||||
("citet" "textual, Jones et al. (1990")
|
||||
("citet" "textual, Jones et al. (1990)")
|
||||
("citet*" "textual, full author list Jones, Baker, and Williams (1990)")
|
||||
("citep" "parenthetical citation (Jones et al. (1990)")
|
||||
("citep" "parenthetical citation (Jones et al. (1990))")
|
||||
("citep*" "parenthetical, full author list, (Jones, Baker, and Williams, 1990)")
|
||||
("citealt" "same as citet, but without parentheses")
|
||||
("citealt*" "same as citet, with full author list but without parentheses")
|
||||
@@ -143,7 +151,7 @@ This is mostly for multicites and natbib."
|
||||
("Parencite" "similar to cite with parentheses and capitalization")
|
||||
("footcite" "Put the citation in a footnote")
|
||||
("footcitetext" "Put the citation in a footnote using \footnotetext")
|
||||
|
||||
|
||||
("textcite" "print the authors or editors as a subject of the sentence")
|
||||
("Textcite" "print the authors or editors as a subject of the sentence with capitalization")
|
||||
("smartcite" "like parencite in a footnote, and footcite in the body")
|
||||
@@ -151,29 +159,29 @@ This is mostly for multicites and natbib."
|
||||
("cite*" "similar to cite, but prints the year or title")
|
||||
("parencite*" "similar to parencite, but prints the year or title")
|
||||
("supercite" "superscripted numeric citation (only in numberic styles)")
|
||||
|
||||
|
||||
("autocite" "handles some punctuation nuances")
|
||||
("Autocite" "handles some punctuation nuances with punctuation")
|
||||
("autocite*" "same as autocite but * is passed to the backend")
|
||||
("Autocite*" "same as Autocite but * is passed to the backend")
|
||||
|
||||
|
||||
("citetitle" "the shorttitle or title field")
|
||||
("citetitle*" "the full title")
|
||||
|
||||
|
||||
("citeyear" "the year field")
|
||||
("citeyear*" "the year field and extradate information if available")
|
||||
|
||||
|
||||
("citedate" "the full date or year")
|
||||
("citedate*" "the full date or year, including extradate information if available")
|
||||
|
||||
|
||||
("citeurl" "the url field")
|
||||
|
||||
|
||||
("fullcite" "create a full citation similar to what is in the bibliography")
|
||||
("footfullcite" "create a full citation as a footnote")
|
||||
;; "volcite" "Volcite" cannot support the syntax
|
||||
("notecite" "print prenote and postnote, but no citation")
|
||||
("Notecite" "print prenote and postnote, but no citation with capitalization")
|
||||
|
||||
|
||||
("pnotecite" "similar to notecite with parentheses")
|
||||
("Pnotecite" "similar to Notecite with parentheses")
|
||||
("fnotecite" "similar to notecite in a footnote"))
|
||||
@@ -256,7 +264,8 @@ This is mostly for multicites and natbib."
|
||||
|
||||
|
||||
(defvar org-ref-citation-key-re
|
||||
(rx "&" (group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~"))))
|
||||
(rx-to-string
|
||||
'(seq "&" (group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~")))))
|
||||
"Numbered regular expression for a version 3 cite key.
|
||||
Key is in group 1.
|
||||
Adapted from the expression in org-cite.")
|
||||
@@ -365,7 +374,7 @@ to a path string."
|
||||
"Return a list of valid bibtex keys for this buffer.
|
||||
This is used a lot in `org-ref-cite-activate' so it needs to be
|
||||
fast, but also up to date."
|
||||
|
||||
|
||||
;; this seems to be needed, but we don't want to do this every time
|
||||
(unless bibtex-completion-display-formats-internal
|
||||
(bibtex-completion-init))
|
||||
@@ -376,7 +385,7 @@ fast, but also up to date."
|
||||
collect (assoc file bibtex-completion-cache)))
|
||||
;; We have a cache for each file
|
||||
;; bibtex-completion-cache contains (filename md5hash entries)
|
||||
(cl-loop for entry in
|
||||
(cl-loop for entry in
|
||||
(cl-loop
|
||||
for file in files
|
||||
append (cddr (assoc file bibtex-completion-cache)))
|
||||
@@ -404,100 +413,105 @@ fast, but also up to date."
|
||||
(puthash entry t org-ref-valid-keys-cache))))
|
||||
org-ref-valid-keys-cache)
|
||||
|
||||
|
||||
(defun org-ref-cite-activate (start end path _bracketp)
|
||||
"Activation function for a cite link.
|
||||
START and END are the bounds of the link.
|
||||
PATH has the citations in it."
|
||||
(let* ((valid-keys (org-ref-valid-keys-cached))
|
||||
valid-key
|
||||
substrings)
|
||||
(goto-char start)
|
||||
(pcase (org-ref-cite-version path)
|
||||
(2
|
||||
;; This makes the brackets visible, but we only need it when there is a
|
||||
;; description.
|
||||
(when (looking-at "\\[\\[\\(.*\\)\\]\\[\\(.*\\)\\]\\]")
|
||||
(remove-text-properties start end '(invisible nil)))
|
||||
(setq substrings (split-string path ","))
|
||||
(cl-loop for key in substrings
|
||||
do
|
||||
;; get to the substring
|
||||
(search-forward key end)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'keymap
|
||||
org-ref-cite-keymap)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'cite-key
|
||||
key)
|
||||
(unless (gethash (string-trim key) valid-keys nil)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'face 'org-ref-bad-cite-key-face)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'help-echo "Key not found"))
|
||||
))
|
||||
(3
|
||||
(setq substrings (split-string path ";"))
|
||||
(cl-loop for i from 0 for s in substrings
|
||||
do
|
||||
;; get to the substring
|
||||
(search-forward s end)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'keymap
|
||||
org-ref-cite-keymap)
|
||||
(let* (key-begin
|
||||
key-end
|
||||
key)
|
||||
(when (and org-ref-activate-cite-links
|
||||
;; Try avoid fontifying org-cite elements. this is based on the
|
||||
;; path containing @ which makes it likely to be an org-cite. Maybe
|
||||
;; a text property is better, in case this is an issue in the
|
||||
;; future.
|
||||
(not (s-contains-p "@" path)))
|
||||
(let* ((valid-keys (org-ref-valid-keys))
|
||||
valid-key
|
||||
substrings)
|
||||
(goto-char start)
|
||||
(pcase (org-ref-cite-version path)
|
||||
(2
|
||||
;; This makes the brackets visible, but we only need it when there is a
|
||||
;; description.
|
||||
(when (looking-at "\\[\\[\\(.*\\)\\]\\[\\(.*\\)\\]\\]")
|
||||
(remove-text-properties start end '(invisible nil)))
|
||||
(setq substrings (split-string path ","))
|
||||
(cl-loop for key in substrings
|
||||
do
|
||||
;; get to the substring
|
||||
(search-forward key end)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'keymap
|
||||
org-ref-cite-keymap)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'cite-key
|
||||
key)
|
||||
(unless (member (string-trim key) valid-keys)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'face 'org-ref-bad-cite-key-face)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'help-echo "Key not found"))))
|
||||
(3
|
||||
(setq substrings (split-string path ";"))
|
||||
(cl-loop for i from 0 for s in substrings
|
||||
do
|
||||
;; get to the substring
|
||||
(search-forward s end)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'keymap
|
||||
org-ref-cite-keymap)
|
||||
(let* (key-begin
|
||||
key-end
|
||||
key)
|
||||
|
||||
;; Look for a key. common pre/post notes do not have keys in them.
|
||||
(save-match-data
|
||||
(when (string-match org-ref-citation-key-re s)
|
||||
(setq key (match-string-no-properties 1 s)
|
||||
valid-key (gethash key valid-keys nil)
|
||||
)))
|
||||
;; Look for a key. common pre/post notes do not have keys in them.
|
||||
(save-match-data
|
||||
(when (string-match org-ref-citation-key-re s)
|
||||
(setq key (match-string-no-properties 1 s)
|
||||
valid-key (member key valid-keys))))
|
||||
|
||||
;; these are global prefix/suffixes
|
||||
(when (and (or (= i 0)
|
||||
(= i (- (length substrings) 1)))
|
||||
(null key))
|
||||
(put-text-property (match-beginning 0) (match-end 0)
|
||||
'face 'org-ref-cite-global-prefix/suffix-face)
|
||||
(put-text-property (match-beginning 0) (match-end 0)
|
||||
'help-echo "Global prefix/suffix"))
|
||||
;; these are global prefix/suffixes
|
||||
(when (and (or (= i 0)
|
||||
(= i (- (length substrings) 1)))
|
||||
(null key))
|
||||
(put-text-property (match-beginning 0) (match-end 0)
|
||||
'face 'org-ref-cite-global-prefix/suffix-face)
|
||||
(put-text-property (match-beginning 0) (match-end 0)
|
||||
'help-echo "Global prefix/suffix"))
|
||||
|
||||
;; we have a key. we have to re-search to get its position
|
||||
(when key
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(search-backward (concat "&" key))
|
||||
(setq key-begin (match-beginning 0)
|
||||
key-end (match-end 0))))
|
||||
;; mark the &
|
||||
(put-text-property key-begin (+ 1 key-begin)
|
||||
'face 'org-ref-cite-&-face)
|
||||
;; store key on the whole thing
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'cite-key
|
||||
key)
|
||||
;; we have a key. we have to re-search to get its position
|
||||
(when key
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(search-backward (concat "&" key))
|
||||
(setq key-begin (match-beginning 0)
|
||||
key-end (match-end 0))))
|
||||
;; mark the &
|
||||
(put-text-property key-begin (+ 1 key-begin)
|
||||
'face 'org-ref-cite-&-face)
|
||||
;; store key on the whole thing
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'cite-key
|
||||
key)
|
||||
|
||||
;; fontify any prefix /suffix text
|
||||
(put-text-property (match-beginning 0) key-begin
|
||||
'face 'org-ref-cite-local-prefix/suffix-face)
|
||||
;; fontify any prefix /suffix text
|
||||
(put-text-property (match-beginning 0) key-begin
|
||||
'face 'org-ref-cite-local-prefix/suffix-face)
|
||||
|
||||
(put-text-property key-end (match-end 0)
|
||||
'face 'org-ref-cite-local-prefix/suffix-face)
|
||||
(put-text-property key-end (match-end 0)
|
||||
'face 'org-ref-cite-local-prefix/suffix-face)
|
||||
|
||||
;; bad key activation
|
||||
(unless valid-key
|
||||
(put-text-property key-begin key-end
|
||||
'face 'font-lock-warning-face)
|
||||
(put-text-property key-begin key-end
|
||||
'help-echo "Key not found")))))))))
|
||||
;; bad key activation
|
||||
(unless valid-key
|
||||
(put-text-property key-begin key-end
|
||||
'face 'font-lock-warning-face)
|
||||
(put-text-property key-begin key-end
|
||||
'help-echo "Key not found"))))))))))
|
||||
|
||||
|
||||
;; * Following citation links
|
||||
@@ -632,6 +646,15 @@ Use with apply-partially."
|
||||
("prefix" . ,(if (= 1 (length references))
|
||||
;; single reference
|
||||
(cond
|
||||
;; global and common prefixes exist, combine them
|
||||
((and (plist-get cite :prefix)
|
||||
(plist-get (car references) :prefix))
|
||||
|
||||
(concat "["
|
||||
(plist-get cite :prefix)
|
||||
";" ;; add this back as a separator
|
||||
(plist-get (car references) :prefix)
|
||||
"]"))
|
||||
;; local prefix is not empty, we use it.
|
||||
((plist-get (car references) :prefix)
|
||||
(concat "["
|
||||
@@ -660,7 +683,8 @@ Use with apply-partially."
|
||||
(concat "["
|
||||
(string-trim (plist-get (car references) :prefix))
|
||||
"]"))
|
||||
;; if you have a suffix, you need an empty prefix
|
||||
;; if you get here, the prefix is empty.
|
||||
;; if you have a suffix, you need an empty prefix placeholder
|
||||
((plist-get cite :suffix)
|
||||
"[]")
|
||||
(t
|
||||
@@ -668,15 +692,25 @@ Use with apply-partially."
|
||||
("suffix" . ,(if (= 1 (length references))
|
||||
;; Single reference
|
||||
(cond
|
||||
;; local prefix is not empty, so use it
|
||||
;; local suffix is not empty, so use it
|
||||
((plist-get (car references) :suffix)
|
||||
(format "[%s]"
|
||||
(string-trim (plist-get (car references) :suffix))))
|
||||
;; global prefix is not empty
|
||||
;; global suffix is not empty
|
||||
((plist-get cite :suffix)
|
||||
(format "[%s]" (string-trim (plist-get cite :suffix))))
|
||||
(t
|
||||
""))
|
||||
;; If there is a prefix, then this should
|
||||
;; be an empty bracket, and if not it
|
||||
;; should am empty string. You need an
|
||||
;; empty bracket, at least for biblatex
|
||||
;; commands. With just one set of
|
||||
;; brackets it is interpreted as a
|
||||
;; suffix.
|
||||
(if (or (plist-get cite :prefix)
|
||||
(plist-get (car references) :prefix))
|
||||
"[]"
|
||||
"")))
|
||||
;; Multiple references
|
||||
(cond
|
||||
;; this is a common suffix
|
||||
@@ -786,7 +820,7 @@ Use with apply-partially."
|
||||
|
||||
|
||||
(org-link-set-parameters
|
||||
"bibentry"
|
||||
"bibentry"
|
||||
:complete (apply-partially #'org-ref-cite-link-complete "bibentry")
|
||||
:follow #'org-ref-cite-follow
|
||||
:face 'org-ref-cite-face
|
||||
@@ -874,7 +908,7 @@ arg COMMON, edit the common prefixes instead."
|
||||
(data (org-ref-parse-cite-path (org-element-property :path cite)))
|
||||
prefix suffix
|
||||
(delta 0))
|
||||
|
||||
|
||||
(if (or (null key) common)
|
||||
(progn
|
||||
(setq prefix (read-string "prenote: " (plist-get data :prefix))
|
||||
@@ -883,7 +917,7 @@ arg COMMON, edit the common prefixes instead."
|
||||
|
||||
(plist-put data :prefix (if (string= "" prefix)
|
||||
nil prefix))
|
||||
|
||||
|
||||
(plist-put data :suffix (if (string= "" suffix)
|
||||
nil suffix)))
|
||||
|
||||
@@ -893,7 +927,7 @@ arg COMMON, edit the common prefixes instead."
|
||||
(lambda (el1 key-at-point)
|
||||
(string= key-at-point (plist-get el1 :key))))))
|
||||
;; Pad with spaces after prefix and before suffix
|
||||
(setq prefix (concat
|
||||
(setq prefix (concat
|
||||
(read-string "prenote: "
|
||||
(string-trim
|
||||
(plist-get
|
||||
@@ -914,13 +948,13 @@ arg COMMON, edit the common prefixes instead."
|
||||
(nth index (plist-get data :references))
|
||||
:prefix (if (string= "" prefix)
|
||||
nil prefix))
|
||||
|
||||
|
||||
(plist-put
|
||||
(nth index (plist-get data :references))
|
||||
:suffix (if (string= "" suffix)
|
||||
nil suffix))))
|
||||
|
||||
|
||||
|
||||
|
||||
(setf (buffer-substring (org-element-property :begin cite) (org-element-property :end cite))
|
||||
(format "[[%s:%s]]" type (org-ref-interpret-cite-data data)))
|
||||
|
||||
@@ -1182,7 +1216,10 @@ Rules:
|
||||
(cl-second item))))))
|
||||
(completion-extra-properties `(:annotation-function ,type-annotation)))
|
||||
|
||||
|
||||
(cond
|
||||
((derived-mode-p 'latex-mode)
|
||||
(insert (bibtex-completion-format-citation-cite (list key))))
|
||||
(t
|
||||
(cond
|
||||
;; Not on a link, so we just insert a cite
|
||||
((null (assoc type org-ref-cite-types))
|
||||
@@ -1251,12 +1288,16 @@ Rules:
|
||||
(3 (cl--set-buffer-substring
|
||||
(org-element-property :begin object)
|
||||
(org-element-property :end object)
|
||||
(concat "[[" type ":" (org-ref-interpret-cite-data data) "]]"))))))
|
||||
(concat "[["
|
||||
type ":"
|
||||
(org-ref-interpret-cite-data data)
|
||||
"]]"
|
||||
(make-string (org-element-property :post-blank object) ? )))))))
|
||||
|
||||
;; Now get to the end of the key you just put in.
|
||||
(setq object (org-element-context))
|
||||
(goto-char (org-element-property :end object))
|
||||
(skip-chars-backward " ")))
|
||||
(skip-chars-backward " ")))))
|
||||
|
||||
|
||||
(defun org-ref-insert-cite-keys (keys &optional set-type)
|
||||
|
||||
@@ -283,6 +283,11 @@ provide their own version."
|
||||
(beginning-of-line)
|
||||
(forward-char)))
|
||||
"New acronym term" :column "Glossary")
|
||||
|
||||
("bd" doi-add-bibtex-entry "Add bibtex entry from a DOI" :column "Bibtex")
|
||||
("bc" crossref-add-bibtex-entry "Add bibtex entry from Crossref" :column "Bibtex")
|
||||
("bo" (find-file (completing-read "Bibliography: " (org-ref-find-bibliography)))
|
||||
"Open bibtex file" :column "Bibtex")
|
||||
|
||||
("t" (insert "[[list-of-tables:]]\n") "List of tables" :column "Misc")
|
||||
("f" (insert "[[list-of-figures:]]\n") "List of figures" :column "Misc")
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
(defvar hfy-user-sheet-assoc) ; to quiet compiler
|
||||
|
||||
(require 'ox-org)
|
||||
(if (executable-find "pandoc")
|
||||
(require 'ox-pandoc))
|
||||
|
||||
(require 'citeproc)
|
||||
|
||||
@@ -56,14 +58,15 @@
|
||||
(md . plain)
|
||||
(org . org)
|
||||
(ascii . plain)
|
||||
(odt . org-odt))
|
||||
(odt . org-odt)
|
||||
(docx . org))
|
||||
"Mapping of export backend to csl-backends."
|
||||
:type '(alist :key-type (symbol) :value-type (symbol))
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defcustom org-ref-cite-internal-links 'auto
|
||||
"Should be on of
|
||||
"Should be one of
|
||||
- 'bib-links :: link cites to bibliography entries
|
||||
- 'no-links :: do not link cites to bibliography entries
|
||||
- nil or 'auto :: add links based on the style."
|
||||
@@ -120,6 +123,19 @@ See https://github.com/citation-style-language/documentation/blob/master/specifi
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defcustom org-ref-export-suppress-affix-types
|
||||
'("citet"
|
||||
"citet*"
|
||||
"citetitle"
|
||||
"citeyear"
|
||||
"citeauthor"
|
||||
"citenum"
|
||||
"textcite")
|
||||
"List of cite types to suppress affixes (usually parentheses) on."
|
||||
:type '(list (repeat string))
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defun org-ref-dealias-label (alias)
|
||||
"Return the full, de-aliased label for ALIAS.
|
||||
Looked up from `org-ref-csl-label-aliases'.
|
||||
@@ -164,17 +180,18 @@ REF is a plist data structure returned from `org-ref-parse-cite-path'."
|
||||
;; e.g. {5, 6 and 12}, because he had 3 books.
|
||||
|
||||
(if (and (string-match
|
||||
(rx
|
||||
;; optional label
|
||||
(group-n 1 (optional
|
||||
(regexp (regexp-opt (cl-loop for (abbrvs . full)
|
||||
in org-ref-csl-label-aliases
|
||||
append (append abbrvs (list full)))))))
|
||||
(optional (one-or-more space))
|
||||
;; number or numeric ranges
|
||||
(group-n 2 (one-or-more digit) (optional "-" (one-or-more digit)))
|
||||
;; everything else
|
||||
(group-n 3 (* ".")))
|
||||
(rx-to-string
|
||||
`(seq
|
||||
;; optional label
|
||||
(group-n 1 (optional
|
||||
(regexp ,(regexp-opt (cl-loop for (abbrvs . full)
|
||||
in org-ref-csl-label-aliases
|
||||
append (append abbrvs (list full)))))))
|
||||
(optional (one-or-more space))
|
||||
;; number or numeric ranges
|
||||
(group-n 2 (one-or-more digit) (optional "-" (one-or-more digit)))
|
||||
;; everything else
|
||||
(group-n 3 (* "."))))
|
||||
full-suffix)
|
||||
(match-string 2 full-suffix)
|
||||
(not (string= "" (match-string 2 full-suffix))))
|
||||
@@ -233,7 +250,7 @@ BACKEND is the org export backend."
|
||||
((file-exists-p style)
|
||||
style)
|
||||
;; In a user-dir
|
||||
((and (boundp 'org-cite-csl-styles-dir)
|
||||
((and (bound-and-true-p org-cite-csl-styles-dir)
|
||||
(file-exists-p (f-join org-cite-csl-styles-dir style)))
|
||||
(f-join org-cite-csl-styles-dir style))
|
||||
;; provided by org-ref
|
||||
@@ -249,15 +266,13 @@ BACKEND is the org export backend."
|
||||
(error "%s not found" style)))
|
||||
;; item-getter
|
||||
;; (citeproc-itemgetter-from-bibtex (org-ref-find-bibliography))
|
||||
(citeproc-hash-itemgetter-from-any (org-ref-find-bibliography))
|
||||
(citeproc-hash-itemgetter-from-any (org-ref-find-bibliography) t)
|
||||
;; locale getter
|
||||
(citeproc-locale-getter-from-dir (cond
|
||||
((boundp 'org-cite-csl-locales-dir)
|
||||
org-cite-csl-locales-dir)
|
||||
(t
|
||||
(citeproc-locale-getter-from-dir (if (bound-and-true-p org-cite-csl-locales-dir)
|
||||
org-cite-csl-locales-dir
|
||||
(f-join (file-name-directory
|
||||
(locate-library "org-ref"))
|
||||
"citeproc/csl-locales"))))
|
||||
"citeproc/csl-locales")))
|
||||
;; the actual locale
|
||||
locale))
|
||||
|
||||
@@ -292,12 +307,9 @@ BACKEND is the org export backend."
|
||||
;; https://github.com/andras-simonyi/citeproc-el#creating-citation-structures
|
||||
(citeproc-citation-create
|
||||
:cites cites
|
||||
;; TODO: proof of concept, incomplete if this is
|
||||
;; true, the citation is not parenthetical
|
||||
:suppress-affixes (let ((type (org-element-property :type cl)))
|
||||
(when (member type '("citet"
|
||||
"citet*"
|
||||
"citenum"))
|
||||
(when (member type
|
||||
org-ref-export-suppress-affix-types)
|
||||
t))
|
||||
|
||||
;; TODO: this is proof of concept, and not complete.
|
||||
@@ -324,14 +336,17 @@ BACKEND is the org export backend."
|
||||
(org-element-property :type cl) 0 1))
|
||||
;; I don't know where this information would come from.
|
||||
:note-index nil
|
||||
:ignore-et-al nil))))
|
||||
:ignore-et-al nil
|
||||
:grouped nil))))
|
||||
|
||||
(rendered-citations (progn (citeproc-append-citations cites proc)
|
||||
(citeproc-render-citations proc csl-backend org-ref-cite-internal-links)))
|
||||
;; I only use the returned bibliography string. citeproc returns a
|
||||
;; bunch of other things related to offsets and linespacing, but I
|
||||
;; don't know what you do with these, so just ignore them here.
|
||||
(rendered-bib (car (citeproc-render-bib proc csl-backend)))
|
||||
(bibdata (citeproc-render-bib proc csl-backend))
|
||||
(rendered-bib (car bibdata))
|
||||
(bib-parameters (cdr bibdata))
|
||||
;; The idea is we will wrap each citation and the bibliography in
|
||||
;; org-code so it exports appropriately.
|
||||
(cite-formatters '((html . "@@html:%s@@")
|
||||
@@ -357,6 +372,42 @@ BACKEND is the org export backend."
|
||||
(org-element-property :post-blank cl) 0)
|
||||
? )))))
|
||||
|
||||
;; Decorate the bibliography for different outputs adapted from
|
||||
;; `org-cite-csl-render-bibliography' in oc-csl I don't know what all
|
||||
;; these do or how to use them in the CSS for html, or LaTeX. This is to
|
||||
;; fix an annoying HTML feature that has an extra line in the numbering.
|
||||
;; This seems to do the right thing. I don't support hanging-indent like
|
||||
;; oc-csl does, and I don't currently support LaTeX here. It already does
|
||||
;; a good job there.
|
||||
;;
|
||||
;; (find-library "oc-csl")
|
||||
;;
|
||||
;; Here are some examples of what is in the bib-parameters.
|
||||
;; (max-offset . 2) (hanging-indent) (second-field-align . flush)
|
||||
;; (entry-spacing . 0)
|
||||
;; (line-spacing . 2)
|
||||
;;
|
||||
;; Here we add style css for html output.
|
||||
(cond
|
||||
((eq 'html backend)
|
||||
(let ((s1 "")
|
||||
(s2 ""))
|
||||
(when (cdr (assq 'second-field-align bib-parameters))
|
||||
(setq s1 (format
|
||||
"<style>.csl-left-margin{float: left; padding-right: 0em;}
|
||||
.csl-right-inline{margin: 0 0 0 %dem;}</style>"
|
||||
;; I hard coded this factor of 0.6 from the oc-csl code.
|
||||
(* 0.6 (or (cdr (assq 'max-offset bib-parameters)) 0)))))
|
||||
|
||||
;; hard-coded the hanging indent. oc-csl uses a variable for this. I
|
||||
;; guess we could too, but this seems simpler.
|
||||
(when (cdr (assq 'hanging-indent bib-parameters))
|
||||
(setq s2 "<style>.csl-entry{text-indent: -1.5em; margin-left: 1.5em;}</style>"))
|
||||
|
||||
(setq rendered-bib (concat
|
||||
s1 s2
|
||||
rendered-bib)))))
|
||||
|
||||
;; replace the bibliography
|
||||
(org-element-map (org-element-parse-buffer) 'link
|
||||
(lambda (lnk)
|
||||
@@ -391,6 +442,7 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
(extensions '((html . ".html")
|
||||
(latex . ".tex")
|
||||
(ascii . ".txt")
|
||||
(md . ".md")
|
||||
(odt . ".odf")))
|
||||
(cp (point))
|
||||
(mm) ;marker to save place
|
||||
@@ -407,7 +459,6 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
(org-export-expand-include-keyword)
|
||||
(goto-char (marker-position mm))
|
||||
(org-ref-process-buffer backend subtreep)
|
||||
(message-box (buffer-substring (line-beginning-position) (line-end-position)))
|
||||
(set-marker mm nil)
|
||||
|
||||
(pcase backend
|
||||
@@ -415,6 +466,11 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
('odt (org-open-file (org-odt-export-to-odt async subtreep visible-only
|
||||
info)
|
||||
'system))
|
||||
;; for pandoc, we mean make a docx via pandoc
|
||||
('docx (org-open-file (plist-get (org-pandoc-export-to-docx async subtreep visible-only
|
||||
body-only info)
|
||||
'output-file)
|
||||
'system))
|
||||
(_
|
||||
(org-open-file (org-export-to-file backend export-name
|
||||
async subtreep visible-only
|
||||
@@ -443,14 +499,25 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
body-only info))
|
||||
|
||||
|
||||
(defun org-ref-export-to-md (&optional async subtreep visible-only
|
||||
body-only info)
|
||||
"Export the buffer to md and open.
|
||||
See `org-export-as' for the meaning of ASYNC SUBTREEP
|
||||
VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
(org-ref-export-to 'md async subtreep visible-only
|
||||
body-only info))
|
||||
|
||||
|
||||
(defun org-ref-export-to-pdf (&optional async subtreep visible-only
|
||||
body-only info)
|
||||
"Export the buffer to PDF via LaTeX and open.
|
||||
See `org-export-as' for the meaning of ASYNC SUBTREEP
|
||||
VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
(let ((org-export-before-parsing-hook '(org-ref-csl-preprocess-buffer)))
|
||||
(let ((org-export-before-parsing-hook (append
|
||||
org-export-before-parsing-hook
|
||||
'(org-ref-csl-preprocess-buffer))))
|
||||
(org-open-file (org-latex-export-to-pdf async subtreep visible-only
|
||||
body-only info))))
|
||||
body-only info))))
|
||||
|
||||
|
||||
(defun org-ref-export-to-latex (&optional async subtreep visible-only
|
||||
@@ -473,6 +540,15 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
body-only info))
|
||||
|
||||
|
||||
(defun org-ref-export-to-docx (&optional async subtreep visible-only
|
||||
body-only info)
|
||||
"Export the buffer to docx via pandoc and open.
|
||||
See `org-export-as' for the meaning of ASYNC SUBTREEP
|
||||
VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
(org-ref-export-to 'docx async subtreep visible-only
|
||||
body-only info))
|
||||
|
||||
|
||||
(defun org-ref-export-as-org (&optional _async subtreep visible-only
|
||||
body-only info)
|
||||
"Export the buffer to an ORG buffer and open.
|
||||
@@ -510,12 +586,14 @@ VISIBLE-ONLY BODY-ONLY and INFO."
|
||||
:menu-entry
|
||||
'(?r "Org-ref export"
|
||||
((?a "to Ascii" org-ref-export-to-ascii)
|
||||
(?m "to markdown" org-ref-export-to-md)
|
||||
(?h "to html" org-ref-export-to-html)
|
||||
(?l "to LaTeX" org-ref-export-to-latex)
|
||||
(?p "to PDF" org-ref-export-to-pdf)
|
||||
(?o "to ODT" org-ref-export-to-odt)
|
||||
(?O "to Org buffer" org-ref-export-as-org)
|
||||
(?e "to email" org-ref-export-to-message))))
|
||||
(?e "to email" org-ref-export-to-message)
|
||||
(?w "to docx" org-ref-export-to-docx))))
|
||||
|
||||
;; An alternative to this exporter is to use an `org-export-before-parsing-hook'
|
||||
;; (add-hook 'org-export-before-parsing-hook 'org-ref-csl-preprocess-buffer)
|
||||
|
||||
@@ -94,10 +94,26 @@
|
||||
:group 'org)
|
||||
|
||||
|
||||
(defcustom org-ref-activate-glossary-links t
|
||||
"If non-nil activate acronym and glossary links.
|
||||
Checks in `org-ref-glossary-face-fn' and `org-ref-acronym-face-fn'.
|
||||
This is not always fast, so we provide a way to disable it."
|
||||
:type 'boolean
|
||||
:group 'org-ref-glossary)
|
||||
|
||||
|
||||
(defvar org-ref-glsentries '()
|
||||
"Variable to hold locations of glsentries load files.")
|
||||
|
||||
|
||||
(defvar-local org-ref-glossary-cache nil
|
||||
"Buffer-local variable for glossary entry cache.")
|
||||
|
||||
|
||||
(defvar-local org-ref-acronym-cache nil
|
||||
"Buffer-local variable for acronym entry cache.")
|
||||
|
||||
|
||||
(defun or-find-closing-curly-bracket (&optional limit)
|
||||
"Find closing bracket for the bracket at point and move point to it.
|
||||
Go up to LIMIT or `point-max'. This is a parsing function. I
|
||||
@@ -122,107 +138,127 @@ there is an escaped \" for example. This seems pretty robust."
|
||||
;;* Glossary
|
||||
(defun or-parse-glossary-entry (entry)
|
||||
"Parse a LaTeX glossary ENTRY definition to a p-list of key=value.
|
||||
Typically:
|
||||
(:name name :description description)
|
||||
but there could be other :key value pairs."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let* (end-of-entry
|
||||
data
|
||||
(external (when (re-search-forward "\\loadglsentries\\(\\[.*\\]\\){\\(?1:.*\\)}" nil t)
|
||||
(match-string 1)))
|
||||
(glsentries (and external
|
||||
(or (cdr (assoc external org-ref-glsentries))
|
||||
(progn
|
||||
(cl-pushnew (cons external (s-trim (shell-command-to-string
|
||||
(format "kpsewhich tex %s" external))))
|
||||
org-ref-glsentries)
|
||||
(cdr (assoc external org-ref-glsentries))))))
|
||||
key value p1 p2)
|
||||
(catch 'data
|
||||
;; look inside first for latex-headers
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "\\newglossaryentry{%s}" entry) nil t)
|
||||
(re-search-forward "{")
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq end-of-entry (point)))
|
||||
ENTRY is the label we are looking for.
|
||||
Typically returns (:name name :description description)
|
||||
but there could be other :key value pairs.
|
||||
|
||||
(while (re-search-forward "\\(\\w+?\\)=" end-of-entry t)
|
||||
(setq key (match-string 1))
|
||||
;; get value
|
||||
(goto-char (+ 1 (match-end 1)))
|
||||
(setq p1 (point))
|
||||
(if (looking-at "{")
|
||||
;; value is wrapped in {}
|
||||
(progn
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq p2 (point)
|
||||
value (buffer-substring (+ 1 p1) p2)))
|
||||
;; value is up to the next comma
|
||||
(re-search-forward "," end-of-entry 'mv)
|
||||
(setq value (buffer-substring p1 (- (point) 1))))
|
||||
;; remove #+latex_header_extra:
|
||||
(setq value (replace-regexp-in-string
|
||||
"#\\+latex_header_extra: " "" value))
|
||||
(setq value (replace-regexp-in-string
|
||||
"\n +" " " value))
|
||||
(setq data (append data
|
||||
(list :label entry)
|
||||
(list (intern (format ":%s" key)))
|
||||
(list value))))
|
||||
(throw 'data data))
|
||||
This is a source of performance loss, because this is search
|
||||
based and it is done on each fontification. It is easy to cache
|
||||
the results, but not easy to invalidate them, e.g. to reflect
|
||||
changes."
|
||||
(if (and org-ref-glossary-cache (gethash entry org-ref-glossary-cache))
|
||||
;; We have the cache, and an entry and use it
|
||||
(gethash entry org-ref-glossary-cache)
|
||||
;; We don't have a cache, or an entry in it, so we find it.
|
||||
;; No cache? we make one
|
||||
(unless org-ref-glossary-cache
|
||||
(setq-local org-ref-glossary-cache (make-hash-table)))
|
||||
|
||||
;; check for a glossary table
|
||||
(let* ((entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (string= "glossary" (org-element-property :name el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table)))))))))
|
||||
(result (assoc entry entries)))
|
||||
(when result
|
||||
(throw 'data (list :label entry :name (cl-second result) :description (cl-third result)))))
|
||||
;; Now we search to get the data
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let* (end-of-entry
|
||||
data
|
||||
(external (when (re-search-forward
|
||||
"\\loadglsentries\\(\\[.*\\]\\){\\(?1:.*\\)}" nil t)
|
||||
(match-string 1)))
|
||||
(glsentries (and external
|
||||
(or (cdr (assoc external org-ref-glsentries))
|
||||
(progn
|
||||
(cl-pushnew (cons external (s-trim
|
||||
(shell-command-to-string
|
||||
(format "kpsewhich tex %s"
|
||||
external))))
|
||||
org-ref-glsentries)
|
||||
(cdr (assoc external org-ref-glsentries))))))
|
||||
key value p1 p2)
|
||||
(setq data
|
||||
(catch 'data
|
||||
;; look inside first for latex-headers
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "\\newglossaryentry{%s}" entry) nil t)
|
||||
(re-search-forward "{")
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq end-of-entry (point)))
|
||||
|
||||
;; then external
|
||||
(when (and glsentries
|
||||
(file-exists-p glsentries))
|
||||
(while (re-search-forward "\\(\\w+?\\)=" end-of-entry t)
|
||||
(setq key (match-string 1))
|
||||
;; get value
|
||||
(goto-char (+ 1 (match-end 1)))
|
||||
(setq p1 (point))
|
||||
(if (looking-at "{")
|
||||
;; value is wrapped in {}
|
||||
(progn
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq p2 (point)
|
||||
value (buffer-substring (+ 1 p1) p2)))
|
||||
;; value is up to the next comma
|
||||
(re-search-forward "," end-of-entry 'mv)
|
||||
(setq value (buffer-substring p1 (- (point) 1))))
|
||||
;; remove #+latex_header_extra:
|
||||
(setq value (replace-regexp-in-string
|
||||
"#\\+latex_header_extra: " "" value))
|
||||
(setq value (replace-regexp-in-string
|
||||
"\n +" " " value))
|
||||
(setq data (append data
|
||||
(list :label entry)
|
||||
(list (intern (format ":%s" key)))
|
||||
(list value))))
|
||||
(throw 'data data))
|
||||
|
||||
(with-current-buffer (find-file-noselect glsentries)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "\\newglossaryentry{%s}" entry) nil t)
|
||||
(re-search-forward "{")
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq end-of-entry (point)))
|
||||
;; check for a glossary table
|
||||
(let* ((entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (string= "glossary" (org-element-property :name el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table)))))))))
|
||||
(result (assoc entry entries)))
|
||||
(when result
|
||||
(throw 'data (list :label entry :name (cl-second result) :description (cl-third result)))))
|
||||
|
||||
(while (re-search-forward "\\(\\w+?\\)=" end-of-entry t)
|
||||
(setq key (match-string 1))
|
||||
;; get value
|
||||
(goto-char (+ 1 (match-end 1)))
|
||||
(setq p1 (point))
|
||||
(if (looking-at "{")
|
||||
;; value is wrapped in {}
|
||||
(progn
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq p2 (point)
|
||||
value (buffer-substring (+ 1 p1) p2)))
|
||||
;; value is up to the next comma
|
||||
(re-search-forward "," end-of-entry 'mv)
|
||||
(setq value (buffer-substring p1 (- (point) 1))))
|
||||
(setq data (append data
|
||||
(list :label entry)
|
||||
(list (intern (format ":%s" key)))
|
||||
(list value))))
|
||||
(throw 'data data))))))))
|
||||
;; then external
|
||||
(when (and glsentries
|
||||
(file-exists-p glsentries))
|
||||
|
||||
(with-current-buffer (find-file-noselect glsentries)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "\\newglossaryentry{%s}" entry) nil t)
|
||||
(re-search-forward "{")
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq end-of-entry (point)))
|
||||
|
||||
(while (re-search-forward "\\(\\w+?\\)=" end-of-entry t)
|
||||
(setq key (match-string 1))
|
||||
;; get value
|
||||
(goto-char (+ 1 (match-end 1)))
|
||||
(setq p1 (point))
|
||||
(if (looking-at "{")
|
||||
;; value is wrapped in {}
|
||||
(progn
|
||||
(or-find-closing-curly-bracket)
|
||||
(setq p2 (point)
|
||||
value (buffer-substring (+ 1 p1) p2)))
|
||||
;; value is up to the next comma
|
||||
(re-search-forward "," end-of-entry 'mv)
|
||||
(setq value (buffer-substring p1 (- (point) 1))))
|
||||
(setq data (append data
|
||||
(list :label entry)
|
||||
(list (intern (format ":%s" key)))
|
||||
(list value))))
|
||||
(throw 'data data))))))
|
||||
(puthash entry data org-ref-glossary-cache)
|
||||
data))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
@@ -251,12 +287,14 @@ manually add them to the glossary table."
|
||||
|
||||
(defun org-ref-glossary-face-fn (label)
|
||||
"Return a face for a glossary link."
|
||||
(save-match-data
|
||||
(cond
|
||||
((or-parse-glossary-entry label)
|
||||
'org-ref-glossary-face)
|
||||
(t
|
||||
'font-lock-warning-face))))
|
||||
(if org-ref-activate-glossary-links
|
||||
(save-match-data
|
||||
(cond
|
||||
((or-parse-glossary-entry label)
|
||||
'org-ref-glossary-face)
|
||||
(t
|
||||
'font-lock-warning-face)))
|
||||
'org-ref-glossary-face))
|
||||
|
||||
|
||||
;;** Glossary links
|
||||
@@ -371,31 +409,33 @@ names are arbitrary, but three columns are expected, and the
|
||||
hline is expected.
|
||||
|
||||
This is intended to be run in `org-export-before-parsing-hook'."
|
||||
(let* (begin
|
||||
end
|
||||
(entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (and (org-element-property :name el)
|
||||
(stringp (org-element-property :name el))
|
||||
(string= "glossary" (org-element-property :name el)))
|
||||
(setq begin (org-element-property :begin el)
|
||||
end (org-element-property :end el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table))))))))))
|
||||
;; Delete the table
|
||||
(when entries
|
||||
(setf (buffer-substring begin end) "")
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let* (begin
|
||||
end
|
||||
(entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (and (org-element-property :name el)
|
||||
(stringp (org-element-property :name el))
|
||||
(string= "glossary" (org-element-property :name el)))
|
||||
(setq begin (org-element-property :begin el)
|
||||
end (org-element-property :end el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table))))))))))
|
||||
;; Delete the table
|
||||
(when entries
|
||||
(setf (buffer-substring begin end) "")
|
||||
|
||||
(goto-char (point-min))
|
||||
(cl-loop for (label name description) in entries
|
||||
do
|
||||
(insert (format "#+latex_header_extra: \\newglossaryentry{%s}{name=%s,description={{%s}}}\n"
|
||||
label name description))))))
|
||||
(goto-char (point-min))
|
||||
(cl-loop for (label name description) in entries
|
||||
do
|
||||
(insert (format "#+latex_header_extra: \\newglossaryentry{%s}{name=%s,description={{%s}}}\n"
|
||||
label name description)))))))
|
||||
|
||||
|
||||
;;* Acronyms
|
||||
@@ -422,65 +462,85 @@ them manually to the acroynms table."
|
||||
|
||||
(defun or-parse-acronym-entry (label)
|
||||
"Parse an acronym entry LABEL to a plist.
|
||||
(:abbrv abbrv :full full :label label)
|
||||
Returns (:abbrv abbrv :full full :label label)
|
||||
The plist maps to \newacronym{<label>}{<abbrv>}{<full>}"
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let* (abbrv
|
||||
full p1
|
||||
(external (when (re-search-forward "\\loadglsentries\\(\\[.*\\]\\){\\(?1:.*\\)}" nil t)
|
||||
(match-string 1)))
|
||||
(glsentries (and external
|
||||
(or (cdr (assoc external org-ref-glsentries))
|
||||
(progn
|
||||
(cl-pushnew (cons external
|
||||
(s-trim (shell-command-to-string
|
||||
(format "kpsewhich tex %s" external))))
|
||||
org-ref-glsentries)
|
||||
(cdr (assoc external org-ref-glsentries)))))))
|
||||
(catch 'data
|
||||
(goto-char (point-min))
|
||||
;; check in the definitions of newacronym
|
||||
(when (re-search-forward (format "\\newacronym{%s}" label) nil t)
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq abbrv (buffer-substring p1 (- (point) 1)))
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq full (buffer-substring p1 (- (point) 1)))
|
||||
(throw 'data
|
||||
(list :label label :abbrv abbrv :full full)))
|
||||
(if (and org-ref-acronym-cache (gethash label org-ref-acronym-cache))
|
||||
;; We have the cache, and an entry and use it
|
||||
(gethash label org-ref-acronym-cache)
|
||||
;; We don't have a cache, or an label in it, so we find it.
|
||||
;; No cache? we make one
|
||||
(unless org-ref-acronym-cache
|
||||
(setq-local org-ref-acronym-cache (make-hash-table)))
|
||||
|
||||
;; look for acronyms table
|
||||
(let* ((entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (string= "acronyms" (org-element-property :name el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table)))))))))
|
||||
(result (assoc label entries)))
|
||||
(when result
|
||||
(throw 'data (list :label label
|
||||
:abbrv (cl-second result) :full (cl-third result)))))
|
||||
;; Now search for the data
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let* (abbrv
|
||||
full p1
|
||||
(external (when (re-search-forward "\\loadglsentries\\(\\[.*\\]\\){\\(?1:.*\\)}" nil t)
|
||||
(match-string 1)))
|
||||
(glsentries (and external
|
||||
(or (cdr (assoc external org-ref-glsentries))
|
||||
(progn
|
||||
(cl-pushnew (cons external
|
||||
(s-trim (shell-command-to-string
|
||||
(format "kpsewhich tex %s" external))))
|
||||
org-ref-glsentries)
|
||||
(cdr (assoc external org-ref-glsentries))))))
|
||||
data)
|
||||
(setq data
|
||||
(catch 'data
|
||||
(goto-char (point-min))
|
||||
;; check in the definitions of newacronym
|
||||
(when (re-search-forward (format "\\newacronym{%s}" label) nil t)
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq abbrv (buffer-substring p1 (- (point) 1)))
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq full (buffer-substring p1 (- (point) 1)))
|
||||
(throw 'data
|
||||
(list :label label :abbrv abbrv :full full)))
|
||||
|
||||
;; look external
|
||||
(when (and glsentries
|
||||
(file-exists-p glsentries))
|
||||
(with-current-buffer (find-file-noselect glsentries)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward (format "\\newacronym{%s}" label) nil t)
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq abbrv (buffer-substring p1 (- (point) 1)))
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq full (buffer-substring p1 (- (point) 1)))
|
||||
(throw 'data
|
||||
(list :label label :abbrv abbrv :full full )))))))))
|
||||
;; look for acronyms table
|
||||
(let* ((entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (string= "acronyms" (org-element-property :name el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table)))))))))
|
||||
(result (assoc label entries)))
|
||||
(when result
|
||||
(throw 'data (list :label label
|
||||
:abbrv (cl-second result) :full (cl-third result)))))
|
||||
|
||||
;; look external
|
||||
(when (and glsentries
|
||||
(file-exists-p glsentries))
|
||||
(with-current-buffer (find-file-noselect glsentries)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward (format "\\newacronym{%s}" label) nil t)
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq abbrv (buffer-substring p1 (- (point) 1)))
|
||||
(setq p1 (+ 1 (point)))
|
||||
(forward-list)
|
||||
(setq full (buffer-substring p1 (- (point) 1)))
|
||||
(throw 'data
|
||||
(list :label label :abbrv abbrv :full full )))))))
|
||||
(puthash label data org-ref-acronym-cache)
|
||||
data))))
|
||||
|
||||
|
||||
(defun org-ref-glossary-invalidate-caches ()
|
||||
"Function to invalidate the caches."
|
||||
(interactive)
|
||||
(setq-local org-ref-acronym-cache (make-hash-table))
|
||||
(setq-local org-ref-glossary-cache (make-hash-table)))
|
||||
|
||||
;;** Acronym links
|
||||
(defun or-follow-acronym (label)
|
||||
@@ -520,7 +580,7 @@ The plist maps to \newacronym{<label>}{<abbrv>}{<full>}"
|
||||
("Acrfull" "Capitalized both the acronym and its definition")
|
||||
("Acrfullpl" "Capitalized both the acronym and its definition in plural")
|
||||
("ACRfull" "Both the acronym and its definition in ALL-CAPS")
|
||||
("ACRfullpl" "Both the acronym and its definition in plurall ALL-CAPS"))
|
||||
("ACRfullpl" "Both the acronym and its definition in plural ALL-CAPS"))
|
||||
"list of acronym types (type description)")
|
||||
|
||||
|
||||
@@ -545,12 +605,14 @@ The plist maps to \newacronym{<label>}{<abbrv>}{<full>}"
|
||||
|
||||
(defun org-ref-acronym-face-fn (label)
|
||||
"Return a face for an acronym link."
|
||||
(save-match-data
|
||||
(cond
|
||||
((or-parse-acronym-entry label)
|
||||
'org-ref-acronym-face)
|
||||
(t
|
||||
'font-lock-warning-face))))
|
||||
(if org-ref-activate-glossary-links
|
||||
(save-match-data
|
||||
(cond
|
||||
((or-parse-acronym-entry label)
|
||||
'org-ref-acronym-face)
|
||||
(t
|
||||
'font-lock-warning-face)))
|
||||
'org-ref-acronym-face))
|
||||
|
||||
|
||||
(defun or-acronym-tooltip (_window _object position)
|
||||
@@ -586,31 +648,33 @@ This assumes a table like
|
||||
is in the org-buffer, and will add the relevant latex_header items if there is. The table is deleted in a copy of the buffer before the export.
|
||||
|
||||
This will run in `org-export-before-parsing-hook'."
|
||||
(let* (begin
|
||||
end
|
||||
(entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (and (org-element-property :name el)
|
||||
(stringp (org-element-property :name el))
|
||||
(string= "acronyms" (org-element-property :name el)))
|
||||
(setq begin (org-element-property :begin el)
|
||||
end (org-element-property :end el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table))))))))))
|
||||
(when entries
|
||||
;; Delete the table
|
||||
(setf (buffer-substring begin end) "")
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let* (begin
|
||||
end
|
||||
(entries (save-excursion
|
||||
(catch 'found
|
||||
(org-element-map
|
||||
(org-element-parse-buffer)
|
||||
'table
|
||||
(lambda (el)
|
||||
(when (and (org-element-property :name el)
|
||||
(stringp (org-element-property :name el))
|
||||
(string= "acronyms" (org-element-property :name el)))
|
||||
(setq begin (org-element-property :begin el)
|
||||
end (org-element-property :end el))
|
||||
(goto-char (org-element-property :contents-begin el))
|
||||
(throw 'found
|
||||
(nthcdr 2 (org-babel-read-table))))))))))
|
||||
(when entries
|
||||
;; Delete the table
|
||||
(setf (buffer-substring begin end) "")
|
||||
|
||||
(goto-char (point-min))
|
||||
(cl-loop for (label name description) in entries
|
||||
do
|
||||
(insert (format "#+latex_header_extra: \\newacronym{%s}{%s}{%s}\n"
|
||||
label name description))))))
|
||||
(goto-char (point-min))
|
||||
(cl-loop for (label name description) in entries
|
||||
do
|
||||
(insert (format "#+latex_header_extra: \\newacronym{%s}{%s}{%s}\n"
|
||||
label name description)))))))
|
||||
|
||||
|
||||
;; * Interactive command to insert acroynm/glossary links
|
||||
@@ -794,7 +858,7 @@ This will run in `org-export-before-parsing-hook'."
|
||||
("acrfull" (format "%s (%s)"
|
||||
(plist-get entry :full)
|
||||
(plist-get entry :abbrv)))
|
||||
("acrfullpl" (format "%s (%s)s"
|
||||
("acrfullpl" (format "%ss (%ss)"
|
||||
(plist-get entry :full)
|
||||
(plist-get entry :abbrv)))
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;; org-ref-helm.el --- org-ref interface to helm-bibtex -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright(C) 2014-2016 John Kitchin
|
||||
;; Copyright(C) 2014-2022 John Kitchin
|
||||
|
||||
;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
|
||||
;; URL: https://github.com/jkitchin/org-ref
|
||||
@@ -106,6 +106,9 @@ frequent searches (e.g. your own publications)."
|
||||
:bibtex-local-bib local-bib)))
|
||||
|
||||
|
||||
(setq org-ref-insert-cite-function 'org-ref-cite-insert-helm)
|
||||
|
||||
|
||||
(provide 'org-ref-helm)
|
||||
|
||||
;;; org-ref-helm.el ends here
|
||||
|
||||
@@ -140,13 +140,12 @@ file."
|
||||
|
||||
|
||||
;; Here we get isbn metadata and build a bibtex entry.
|
||||
;; http://xisbn.worldcat.org/xisbnadmin/doc/api.htm#getmetadata
|
||||
|
||||
;;;###autoload
|
||||
(defun isbn-to-bibtex (isbn bibfile)
|
||||
"Get bibtex entry for ISBN and insert it into BIBFILE.
|
||||
Nothing happens if an entry with the generated key already exists
|
||||
in the file. Data comes from worldcat."
|
||||
in the file. Data comes from www.ebook.de."
|
||||
(interactive
|
||||
(list
|
||||
(read-string
|
||||
@@ -167,7 +166,7 @@ in the file. Data comes from worldcat."
|
||||
nil)))
|
||||
(completing-read "Bibfile: " (org-ref-possible-bibfiles))))
|
||||
|
||||
(let* ((url (format "https://www.ottobib.com/isbn/%s/bibtex" isbn))
|
||||
(let* ((url (format "https://www.ebook.de/de/tools/isbn2bibtex?isbn=%s" isbn))
|
||||
(entry))
|
||||
(with-current-buffer (url-retrieve-synchronously url t t)
|
||||
(goto-char (point-min))
|
||||
|
||||
@@ -145,6 +145,9 @@
|
||||
:caller 'org-ref-cite-insert-ivy)))
|
||||
|
||||
|
||||
(setq org-ref-insert-cite-function 'org-ref-cite-insert-ivy)
|
||||
|
||||
|
||||
(provide 'org-ref-ivy)
|
||||
|
||||
;;; org-ref-ivy.el ends here
|
||||
|
||||
@@ -67,7 +67,8 @@ The clickable part are the keys.")
|
||||
(setq font-lock-extra-managed-props (delq 'help-echo font-lock-extra-managed-props))
|
||||
(goto-char (match-beginning 0))
|
||||
(let ((end (match-end 0)))
|
||||
(cl-loop for key in (split-string (match-string-no-properties 4) ",")
|
||||
(cl-loop for key in (mapcar #'s-trim (split-string (match-string-no-properties 4) ","))
|
||||
unless (string-empty-p key)
|
||||
do
|
||||
(save-match-data
|
||||
(search-forward key)
|
||||
@@ -84,7 +85,9 @@ The clickable part are the keys.")
|
||||
(bibtex-beginning-of-entry))))
|
||||
map)
|
||||
help-echo ,(let* ((bibtex-completion-bibliography (org-ref-latex-get-bibliography)))
|
||||
(bibtex-completion-apa-format-reference key))))))
|
||||
(condition-case nil
|
||||
(bibtex-completion-apa-format-reference key)
|
||||
(error (display-warning :warning (format "Key %s missing." key)))))))))
|
||||
(goto-char end))))
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ strings, or nil."
|
||||
;; I don't know how to avoid a trailing . on some dois with the
|
||||
;; expression above, so if it is there, I chomp it off here.
|
||||
(let ((doi (match-string 0)))
|
||||
(when (s-ends-with? "." doi)
|
||||
(when (or (s-ends-with? "." doi) (s-ends-with? ";" doi))
|
||||
(setq doi (substring doi 0 (- (length doi) 1))))
|
||||
(cl-pushnew doi matches :test #'equal)))
|
||||
matches)))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(define-package "org-ref" "20220101.1941" "citations, cross-references and bibliographies in org-mode"
|
||||
'((dash "0")
|
||||
(define-package "org-ref" "20221129.1925" "citations, cross-references and bibliographies in org-mode"
|
||||
'((org "9.4")
|
||||
(dash "0")
|
||||
(s "0")
|
||||
(f "0")
|
||||
(htmlize "0")
|
||||
@@ -7,8 +8,9 @@
|
||||
(avy "0")
|
||||
(parsebib "0")
|
||||
(bibtex-completion "0")
|
||||
(citeproc "0"))
|
||||
:commit "429733150548a847966685680bca0a20ec3b1ad9" :authors
|
||||
(citeproc "0")
|
||||
(ox-pandoc "0"))
|
||||
:commit "26735e914f09559c7b9753462a596e62595b135e" :authors
|
||||
'(("John Kitchin" . "jkitchin@andrew.cmu.edu"))
|
||||
:maintainer
|
||||
'("John Kitchin" . "jkitchin@andrew.cmu.edu")
|
||||
|
||||
@@ -31,6 +31,14 @@
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defcustom org-ref-activate-ref-links t
|
||||
"If non-nil use font lock to activate ref links.
|
||||
Activation can be slow in large documents with a lot of ref
|
||||
links. Set this to nil to turn off activation."
|
||||
:type 'boolean
|
||||
:group 'org-ref)
|
||||
|
||||
|
||||
(defface org-ref-ref-face
|
||||
`((t (:inherit org-link :foreground "dark red")))
|
||||
"Face for ref links in org-ref."
|
||||
@@ -38,12 +46,14 @@
|
||||
|
||||
|
||||
(defvar org-ref-label-re
|
||||
(rx (group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~"))))
|
||||
(rx-to-string
|
||||
'(group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~"))))
|
||||
"Regexp for labels.")
|
||||
|
||||
|
||||
(defvar org-ref-label-link-re
|
||||
(rx "label:" (group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~"))))
|
||||
(rx-to-string
|
||||
`(seq "label:" (group-n 1 (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~")))))
|
||||
"Regexp for label links.")
|
||||
|
||||
|
||||
@@ -112,6 +122,14 @@ The label should always be in group 1.")
|
||||
(goto-char (+ begin deltap (- (length new-type) (length old-type))))))
|
||||
|
||||
|
||||
(defvar-local org-ref-label-cache nil
|
||||
"Buffer-local cache variable for labels.")
|
||||
|
||||
|
||||
(defvar-local org-ref-buffer-chars-modified-tick nil
|
||||
"Buffer-local variable to hold `buffer-chars-modified-tick'.")
|
||||
|
||||
|
||||
(defun org-ref-get-labels ()
|
||||
"Return a list of referenceable labels in the document.
|
||||
You can reference:
|
||||
@@ -128,21 +146,55 @@ Returns a list of cons cells (label . context).
|
||||
|
||||
It is important for this function to be fast, since we use it in
|
||||
font-lock."
|
||||
(let ((case-fold-search t)
|
||||
(rx (string-join org-ref-ref-label-regexps "\\|"))
|
||||
(labels '())
|
||||
context)
|
||||
(save-excursion
|
||||
(org-with-wide-buffer
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward rx nil t)
|
||||
(setq context (buffer-substring
|
||||
(save-excursion (forward-line -1) (point))
|
||||
(save-excursion (forward-line +2) (point))))
|
||||
(cl-pushnew (cons (match-string-no-properties 1) context)
|
||||
labels))))
|
||||
;; reverse so they are in the order we find them.
|
||||
(delete-dups (reverse labels))))
|
||||
(if (or
|
||||
;; if we have not checked we have to check
|
||||
(null org-ref-buffer-chars-modified-tick)
|
||||
;; Now check if buffer has changed since last time we looked. We check
|
||||
;; this with the buffer-chars-modified-tick which keeps track of changes.
|
||||
;; If this hasn't changed, no chars have been modified.
|
||||
(not (= (buffer-chars-modified-tick)
|
||||
org-ref-buffer-chars-modified-tick)))
|
||||
;; We need to search for all the labels either because we don't have them,
|
||||
;; or the buffer has changed since we looked last time.
|
||||
(let ((case-fold-search t)
|
||||
(rx (string-join org-ref-ref-label-regexps "\\|"))
|
||||
(labels '())
|
||||
oe ;; org-element
|
||||
context
|
||||
data)
|
||||
(save-excursion
|
||||
(org-with-wide-buffer
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward rx nil t)
|
||||
(save-match-data
|
||||
;; Here we try to get some relevant context for different things you
|
||||
;; might reference.
|
||||
(setq oe (org-element-context)
|
||||
context (string-trim
|
||||
(pcase (car oe)
|
||||
('latex-environment (buffer-substring
|
||||
(org-element-property :begin oe)
|
||||
(org-element-property :end oe)))
|
||||
;; figure
|
||||
('paragraph (buffer-substring
|
||||
(org-element-property :begin oe)
|
||||
(org-element-property :end oe)))
|
||||
('table (buffer-substring
|
||||
(org-element-property :begin oe)
|
||||
(org-element-property :end oe)))
|
||||
;; Headings fall here.
|
||||
(_ (buffer-substring (line-beginning-position)
|
||||
(line-end-position)))))))
|
||||
(cl-pushnew (cons (match-string-no-properties 1) context)
|
||||
labels))))
|
||||
|
||||
;; reverse so they are in the order we find them.
|
||||
(setq
|
||||
org-ref-buffer-chars-modified-tick (buffer-chars-modified-tick)
|
||||
org-ref-label-cache (delete-dups (reverse labels))))
|
||||
|
||||
;; retrieve the cached data
|
||||
org-ref-label-cache))
|
||||
|
||||
|
||||
(defun org-ref-ref-jump-to (&optional path)
|
||||
@@ -184,26 +236,27 @@ POSITION is the point under the mouse I think."
|
||||
The PATH should be a comma-separated list of labels.
|
||||
Argument START is the start of the link.
|
||||
Argument END is the end of the link."
|
||||
(let ((labels (mapcar 'car (org-ref-get-labels))))
|
||||
(goto-char start)
|
||||
(cl-loop for label in (split-string path ",") do
|
||||
(search-forward label)
|
||||
;; store property so we can follow it later.
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'org-ref-ref-label
|
||||
label)
|
||||
(when org-ref-activate-ref-links
|
||||
(let ((labels (mapcar 'car (org-ref-get-labels))))
|
||||
(goto-char start)
|
||||
(cl-loop for label in (split-string path ",") do
|
||||
(search-forward label)
|
||||
;; store property so we can follow it later.
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'org-ref-ref-label
|
||||
label)
|
||||
|
||||
(unless (member label labels)
|
||||
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'face
|
||||
'font-lock-warning-face)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'help-echo
|
||||
"Label not found")))))
|
||||
(unless (member label labels)
|
||||
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'face
|
||||
'font-lock-warning-face)
|
||||
(put-text-property (match-beginning 0)
|
||||
(match-end 0)
|
||||
'help-echo
|
||||
"Label not found"))))))
|
||||
|
||||
|
||||
(defun org-ref-ref-export (cmd keyword _desc backend)
|
||||
|
||||
@@ -255,9 +255,10 @@ Jabref, Mendeley and Zotero. See `bibtex-completion-find-pdf'."
|
||||
(0
|
||||
(message "no pdf found for %s" key))
|
||||
(1
|
||||
(org-open-file (car pdf-file)))
|
||||
(funcall bibtex-completion-pdf-open-function (car pdf-file)))
|
||||
(_
|
||||
(org-open-file (completing-read "pdf: " pdf-file))))))
|
||||
(funcall bibtex-completion-pdf-open-function
|
||||
(completing-read "pdf: " pdf-file))))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
;; URL: https://github.com/jkitchin/org-ref
|
||||
;; Version: 3.0
|
||||
;; Keywords: org-mode, cite, ref, label
|
||||
;; Package-Requires: ((dash "0") (s "0") (f "0") (htmlize "0") (hydra "0") (avy "0") (parsebib "0") (bibtex-completion "0") (citeproc "0"))
|
||||
;; Package-Requires: ((org "9.4") (dash "0") (s "0") (f "0") (htmlize "0") (hydra "0") (avy "0") (parsebib "0") (bibtex-completion "0") (citeproc "0") (ox-pandoc "0"))
|
||||
;; This file is not currently part of GNU Emacs.
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
|
||||
@@ -562,10 +562,10 @@ This library adds two extremely useful tools for getting bibtex entries and pdf
|
||||
This provides two important commands:
|
||||
|
||||
- ~doi-utils-add-bibtex-entry-from-doi~
|
||||
This will prompt you for a DOI, and a bibtex file, and then try to get the bibtex entry, and pdf of the article.
|
||||
This will prompt you for a DOI, and a bibtex file, and then try to get the bibtex entry. Adds the entry to the bibtex file if successful. Automatically calls ~org-ref-clean-bibtex-entry~.
|
||||
|
||||
- ~doi-utils-add-entry-from-crossref-query~
|
||||
This will prompt you for a query string, which is usually the title of an article, or a free-form text citation of an article. Then you will get a helm buffer of matching items, which you can choose from to insert a new bibtex entry into a bibtex file.
|
||||
This will prompt you for a query string, which is usually the title of an article, or a free-form text citation of an article. Searches using [[https://www.crossref.org/][Crossref.org]], then prompts in the minibuffer with a list of matching items, which you can choose from to insert a new bibtex entry into a bibtex file. Also calls ~org-ref-clean-bibtex-entry~.
|
||||
|
||||
This library also redefines the org-mode doi link. Now, when you click on this link you will get a menu of options, e.g. to open a bibtex entry or a pdf if you have it, or to search the doi in some scientific search engines. Try it out doi:10.1021/jp511426q.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user