>From 3342137359f122ed7168dc75096c6a5d3839a0c2 Mon Sep 17 00:00:00 2001 Message-Id: <3342137359f122ed7168dc75096c6a5d3839a0c2.1655362876.git.yantar92@gmail.com> From: Ihor Radchenko Date: Sun, 12 Jun 2022 13:05:16 +0800 Subject: [PATCH 1/8] 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 2a3edaa50..7f90dc36f 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -3748,28 +3748,33 @@ (defun org-export-get-footnote-definition (footnote-reference info) (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)))))) -- 2.35.1