diff options
author | Lawrence Mitchell <wence@gmx.li> | 2013-05-02 10:03:13 +0100 |
---|---|---|
committer | Nicolas Goaziou <n.goaziou@gmail.com> | 2013-05-02 14:50:42 +0200 |
commit | b7301bd639aa557dd9b57e77df8a8e45ff618740 (patch) | |
tree | 78c13cff49cf48856ecc8493c5fb8219c61091b3 | |
parent | af51c11ba96fb2d925722a0e3353b9af5b60a3e6 (diff) | |
download | org-mode-b7301bd639aa557dd9b57e77df8a8e45ff618740.tar.gz |
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.
-rw-r--r-- | lisp/ox.el | 42 |
1 files changed, 29 insertions, 13 deletions
@@ -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, |