From f51c286716e75c7f70b599df59e66aa7cbc67e96 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Sun, 12 Jun 2022 13:05:16 +0800 Subject: [PATCH] org-export-get-footnote-definition: Pre-cache references in parse tree * lisp/ox.el (org-export-get-footnote-definition): Pre-process parse tree once to filter out all non-footnote elements. This speeds up subsequent footnote definition searches. --- lisp/ox.el | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 9a8e63046..d655c621d 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -3754,28 +3754,33 @@ definition can be found, raise an error." (if (not label) (org-element-contents footnote-reference) (let ((cache (or (plist-get info :footnote-definition-cache) (let ((hash (make-hash-table :test #'equal))) + ;; Cache all the footnotes in document for + ;; later search. + (org-element-map (plist-get info :parse-tree) + '(footnote-definition footnote-reference) + (lambda (f) + ;; Skip any standard footnote reference + ;; since those cannot contain a + ;; definition. + (unless (eq (org-element-property :type f) 'standard) + (puthash + (cons :element (org-element-property :label f)) + f + hash))) + info) (plist-put info :footnote-definition-cache hash) hash)))) (or (gethash label cache) (puthash label - (org-element-map (plist-get info :parse-tree) - '(footnote-definition footnote-reference) - (lambda (f) - (cond - ;; Skip any footnote with a different label. - ;; Also skip any standard footnote reference - ;; with the same label since those cannot - ;; contain a definition. - ((not (equal (org-element-property :label f) label)) nil) - ((eq (org-element-property :type f) 'standard) nil) - ((org-element-contents f)) - ;; Even if the contents are empty, we can not - ;; return nil since that would eventually raise - ;; the error. Instead, return the equivalent - ;; empty string. - (t ""))) - info t) + (let ((hashed (gethash (cons :element label) cache))) + (when hashed + (or (org-element-contents hashed) + ;; Even if the contents are empty, we can not + ;; return nil since that would eventually raise + ;; the error. Instead, return the equivalent + ;; empty string. + ""))) cache) (error "Definition not found for footnote %s" label))))))