summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIhor Radchenko <yantar92@gmail.com>2022-06-16 10:43:29 +0800
committerEli Zaretskii <eliz@gnu.org>2022-06-16 10:55:05 +0300
commitf94e93a6eec92d834a6b545d8d4b68280b0993b0 (patch)
treec9532be580b468bb22665a704b1634f2f68509e0
parent4f37a3b299bcec71a0e9bdd84b7b226494006fe4 (diff)
downloademacs-f94e93a6eec92d834a6b545d8d4b68280b0993b0.tar.gz
emacs-f94e93a6eec92d834a6b545d8d4b68280b0993b0.tar.bz2
emacs-f94e93a6eec92d834a6b545d8d4b68280b0993b0.zip
org-cite-list-citations: Cache footnote-definition searches
* lisp/org/oc.el (org-cite-list-citations): Avoid quadratic complexity. Pre-calculate list of all footnote definitions and cache the footnote label search hits. Do not make `org-element-map' accumulate unused result.
-rw-r--r--lisp/org/oc.el25
1 files changed, 19 insertions, 6 deletions
diff --git a/lisp/org/oc.el b/lisp/org/oc.el
index eb5f519cb64..c4cd0268c7c 100644
--- a/lisp/org/oc.el
+++ b/lisp/org/oc.el
@@ -808,6 +808,8 @@ INFO is the export communication channel, as a property list."
(or (plist-get info :citations)
(letrec ((cites nil)
(tree (plist-get info :parse-tree))
+ (definition-cache (make-hash-table :test #'equal))
+ (definition-list nil)
(find-definition
;; Find definition for standard reference LABEL. At
;; this point, it is impossible to rely on
@@ -816,11 +818,21 @@ INFO is the export communication channel, as a property list."
;; un-processed citation objects. So we use
;; a simplified version of the function above.
(lambda (label)
- (org-element-map tree 'footnote-definition
- (lambda (d)
- (and (equal label (org-element-property :label d))
- (or (org-element-contents d) "")))
- info t)))
+ (or (gethash label definition-cache)
+ (org-element-map
+ (or definition-list
+ (setq definition-list
+ (org-element-map
+ tree
+ 'footnote-definition
+ #'identity info)))
+ 'footnote-definition
+ (lambda (d)
+ (and (equal label (org-element-property :label d))
+ (puthash label
+ (or (org-element-contents d) "")
+ definition-cache)))
+ info t))))
(search-cites
(lambda (data)
(org-element-map data '(citation footnote-reference)
@@ -834,7 +846,8 @@ INFO is the export communication channel, as a property list."
(_
(let ((label (org-element-property :label datum)))
(funcall search-cites
- (funcall find-definition label))))))
+ (funcall find-definition label)))))
+ nil)
info nil 'footnote-definition t))))
(funcall search-cites tree)
(let ((result (nreverse cites)))