pkg update and first config fix

org-brain not working, add org-roam
This commit is contained in:
2022-12-19 23:02:34 +01:00
parent 02b3e07185
commit 82f05baffe
885 changed files with 356098 additions and 36993 deletions

73
lisp/org-ref/contrib.el Normal file
View 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

View File

@@ -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.")

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)))

View File

@@ -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)

View File

@@ -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")

View File

@@ -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)

View File

@@ -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)))

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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))))

View File

@@ -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)))

View File

@@ -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")

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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.