ox: Cache locations of fuzzy links

* ox.el (org-export-resolve-fuzzy-link): Look for fuzzy link in a
  cache before trying to resolve it in the parse tree.

When a document contains a large number of identical fuzzy links, it
doesn't make sense to continually search for them.  Instead, cache the
locations in the position independent case.
This commit is contained in:
Lawrence Mitchell 2013-05-02 10:03:13 +01:00 committed by Nicolas Goaziou
parent af51c11ba9
commit b7301bd639
1 changed files with 29 additions and 13 deletions

View File

@ -3976,27 +3976,43 @@ significant."
;; Split PATH at white spaces so matches are space
;; insensitive.
(path (org-split-string
(if match-title-p (substring raw-path 1) raw-path))))
(if match-title-p (substring raw-path 1) raw-path)))
;; Cache for locations of fuzzy links that are not position dependent
(link-cache
(or (plist-get info :fuzzy-link-cache)
(plist-get (setq info (plist-put info :fuzzy-link-cache
(make-hash-table :test 'equal)))
:fuzzy-link-cache)))
(found-in-cache (gethash path link-cache 'fuzzy-link-not-found)))
(cond
;; First try to find a matching "<<path>>" unless user specified
;; he was looking for a headline (path starts with a "*"
;; character).
((and (not match-title-p)
(org-element-map (plist-get info :parse-tree) 'target
(lambda (blob)
(and (equal (org-split-string (org-element-property :value blob))
path)
blob))
info t)))
(or (not (eq found-in-cache 'fuzzy-link-not-found))
(puthash path
(org-element-map (plist-get info :parse-tree) 'target
(lambda (blob)
(and (equal (org-split-string
(org-element-property :value blob))
path)
blob))
info t)
link-cache))))
;; Then try to find an element with a matching "#+NAME: path"
;; affiliated keyword.
((and (not match-title-p)
(org-element-map (plist-get info :parse-tree)
org-element-all-elements
(lambda (el)
(let ((name (org-element-property :name el)))
(when (and name (equal (org-split-string name) path)) el)))
info 'first-match)))
(or (not (eq found-in-cache 'fuzzy-link-not-found))
(puthash path
(org-element-map (plist-get info :parse-tree)
org-element-all-elements
(lambda (el)
(let ((name (org-element-property :name el)))
(when (and name
(equal (org-split-string name) path))
el)))
info 'first-match)
link-cache))))
;; Last case: link either points to a headline or to nothingness.
;; Try to find the source, with priority given to headlines with
;; the closest common ancestor. If such candidate is found,