Browse Source

Backport commit d21412df0 from Emacs

* lisp/ox.el (org-export-resolve-id-link): Pre-cache all the ids in
the parse tree for faster lookup.

org-export-resolve-id-link: Pre-cache all the ids in the parse tree
d21412df06b99b551e67d39c097d95e8a284de73
Ihor Radchenko
Thu Jun 16 10:52:54 2022 +0300

[ km: This ported commit comes from main's 84c89ea7c.  I'm applying it
  here too for bookkeeping/traceability purposes.  ]
Ihor Radchenko 2 years ago
parent
commit
4f8ea50604
1 changed files with 21 additions and 9 deletions
  1. 21 9
      lisp/ox.el

+ 21 - 9
lisp/ox.el

@@ -4395,15 +4395,27 @@ tree or a file name.  Assume LINK type is either \"id\" or
 \"custom-id\".  Throw an error if no match is found."
   (let ((id (org-element-property :path link)))
     ;; First check if id is within the current parse tree.
-    (or (org-element-map (plist-get info :parse-tree) 'headline
-	  (lambda (headline)
-	    (when (or (equal (org-element-property :ID headline) id)
-		      (equal (org-element-property :CUSTOM_ID headline) id))
-	      headline))
-	  info 'first-match)
-	;; Otherwise, look for external files.
-	(cdr (assoc id (plist-get info :id-alist)))
-	(signal 'org-link-broken (list id)))))
+    (or (let ((local-ids (or (plist-get info :id-local-cache)
+                             (let ((table (make-hash-table :test #'equal)))
+                               (org-element-map
+                                   (plist-get info :parse-tree)
+                                   'headline
+                                 (lambda (headline)
+                                   (let ((id (org-element-property :ID headline))
+                                         (custom-id (org-element-property :CUSTOM_ID headline)))
+                                     (when id
+                                       (unless (gethash id table)
+                                         (puthash id headline table)))
+                                     (when custom-id
+                                       (unless (gethash custom-id table)
+                                         (puthash custom-id headline table)))))
+                                 info)
+                               (plist-put info :id-local-cache table)
+                               table))))
+          (gethash id local-ids))
+        ;; Otherwise, look for external files.
+        (cdr (assoc id (plist-get info :id-alist)))
+        (signal 'org-link-broken (list id)))))
 
 (defun org-export-resolve-radio-link (link info)
   "Return radio-target object referenced as LINK destination.