org-export: Change output from org-export-resolve-fuzzy-link

* contrib/lisp/org-export.el (org-export-resolve-fuzzy-link): Now
  return the full object (for a target) or element (for an headline)
  when a match is found.  Also rewrite internals so it doesn't rely
  on :headline-alist.
(org-export-collect-tree-properties): Remove :headline-alist property
  from communication channel, since `org-export-resolve-fuzzy-link'
  doesn't use it anymore. Also store full target objects
  in :target-list property, not only raw names. Fix an argument name
  mismatch, too.

Previous version of org-export-resolve-fuzzy-link returned beginning
position as the identifier for the headline found, which is pretty
weak when files are included in the parsed buffer.
This commit is contained in:
Nicolas Goaziou 2012-01-14 00:01:22 +01:00
parent b93ed753ff
commit b03ec00a0e
1 changed files with 48 additions and 70 deletions

View File

@ -614,12 +614,6 @@ standard mode."
;; - category :: local ;; - category :: local
;; - type :: list of elements and objects ;; - type :: list of elements and objects
;; + `headline-alist' :: Alist between headlines raw name and their
;; boundaries. It is used to resolve "fuzzy" links
;; (cf. `org-export-resolve-fuzzy-link').
;; - category :: tree
;; - type :: alist (STRING INTEGER INTEGER)
;; + `headline-levels' :: Maximum level being exported as an ;; + `headline-levels' :: Maximum level being exported as an
;; headline. Comparison is done with the relative level of ;; headline. Comparison is done with the relative level of
;; headlines in the parse tree, not necessarily with their ;; headlines in the parse tree, not necessarily with their
@ -681,9 +675,8 @@ standard mode."
;; - category :: option ;; - category :: option
;; - type :: list of strings ;; - type :: list of strings
;; + `target-list' :: List of targets raw names encoutered in the ;; + `target-list' :: List of targets encountered in the parse tree.
;; parse tree. This is used to partly resolve ;; This is used to partly resolve "fuzzy" links
;; "fuzzy" links
;; (cf. `org-export-resolve-fuzzy-link'). ;; (cf. `org-export-resolve-fuzzy-link').
;; - category :: tree ;; - category :: tree
;; - type :: list of strings ;; - type :: list of strings
@ -1100,20 +1093,16 @@ retrieved."
;; Eventually `org-export-collect-headline-numbering' builds an alist ;; Eventually `org-export-collect-headline-numbering' builds an alist
;; between headlines' beginning position and their numbering. ;; between headlines' beginning position and their numbering.
(defun org-export-collect-tree-properties (data options backend) (defun org-export-collect-tree-properties (data info backend)
"Extract tree properties from parse tree. "Extract tree properties from parse tree.
DATA is the parse tree from which information is retrieved. DATA is the parse tree from which information is retrieved. INFO
OPTIONS is a list holding export options. BACKEND is the is a list holding export options. BACKEND is the back-end called
back-end called for transcoding, as a symbol. for transcoding, as a symbol.
Following tree properties are set: Following tree properties are set:
`:back-end' Back-end used for transcoding. `:back-end' Back-end used for transcoding.
`:headline-alist' Alist of all headlines' name as key and a list
holding beginning and ending positions as
value.
`:headline-offset' Offset between true level of headlines and `:headline-offset' Offset between true level of headlines and
local level. An offset of -1 means an headline local level. An offset of -1 means an headline
of level 2 should be considered as a level of level 2 should be considered as a level
@ -1126,7 +1115,7 @@ Following tree properties are set:
`:point-max' Last position in the parse tree `:point-max' Last position in the parse tree
`:target-list' List of all targets' raw name in the parse tree. `:target-list' List of all targets in the parse tree.
`:use-select-tags' Non-nil when parsed tree use a special tag to `:use-select-tags' Non-nil when parsed tree use a special tag to
enforce transcoding of the headline." enforce transcoding of the headline."
@ -1143,16 +1132,7 @@ Following tree properties are set:
:headline-offset ,(- 1 (org-export-get-min-level data info)) :headline-offset ,(- 1 (org-export-get-min-level data info))
:point-max ,(org-export-get-point-max data info) :point-max ,(org-export-get-point-max data info)
:target-list :target-list
,(org-element-map ,(org-element-map data 'target (lambda (target local) target) info)
data 'target
(lambda (target info) (org-element-get-property :raw-value target)))
:headline-alist
,(org-element-map
data 'headline
(lambda (headline info)
(list (org-element-get-property :raw-value headline)
(org-element-get-property :begin headline)
(org-element-get-property :end headline))))
:headline-numbering ,(org-export-collect-headline-numbering data info) :headline-numbering ,(org-export-collect-headline-numbering data info)
:back-end ,backend) :back-end ,backend)
info)) info))
@ -2279,55 +2259,53 @@ list is provided \(cf. `org-image-file-name-regexp'\)."
INFO is a plist holding contextual information. INFO is a plist holding contextual information.
Return value can be a string, an buffer position, or nil: Return value can be an object, an element, or nil:
- If LINK path exactly matches any target, return its name as the - If LINK path exactly matches any target, return the target
identifier. object.
- If LINK path exactly matches any headline name, return - If LINK path exactly matches any headline name, return that
headline's beginning position as the identifier. If more than element. If more than one headline share that name, priority
one headline share that name, priority will be given to the one will be given to the one with the closest common ancestor, if
with the closest common ancestor, if any, or the first one in any, or the first one in the parse tree otherwise.
the parse tree otherwise.
- Otherwise, return nil. - Otherwise, return nil.
Assume LINK type is \"fuzzy\"." Assume LINK type is \"fuzzy\"."
(let ((path (org-element-get-property :path link))) (let ((path (org-element-get-property :path link)))
(if (member path (plist-get info :target-list)) ;; Link points to a target: return it.
;; Link points to a target: return its name as a string. (or (loop for target in (plist-get info :target-list)
path when (string= (org-element-get-property :raw-value target) path)
;; Link either points to an headline or nothing. Try to find return target)
;; the source, with priority given to headlines with the closest ;; Link either points to an headline or nothing. Try to find
;; common ancestor. If such candidate is found, return its ;; the source, with priority given to headlines with the closest
;; beginning position as an unique identifier, otherwise return ;; common ancestor. If such candidate is found, return its
;; nil. ;; beginning position as an unique identifier, otherwise return
(let* ((head-alist (plist-get info :headline-alist)) ;; nil.
(link-begin (org-element-get-property :begin link)) (let ((find-headline
(link-end (org-element-get-property :end link)) (function
;; Store candidates as a list of cons cells holding their ;; Return first headline whose `:raw-value' property
;; beginning and ending position. ;; is NAME in parse tree DATA, or nil.
(cands (loop for head in head-alist (lambda (name data)
when (string= (car head) path) (org-element-map
collect (cons (nth 1 head) (nth 2 head))))) data 'headline
(cond (lambda (headline local)
;; No candidate: return nil. (when (string=
((not cands) nil) (org-element-get-property :raw-value headline)
;; If one or more candidates share common ancestors with name)
;; LINK, return beginning position of the first one matching headline))
;; the closer ancestor shared. info 'first-match)))))
((let ((ancestors (loop for head in head-alist ;; Search among headlines sharing an ancestor with link,
when (and (> link-begin (nth 1 head)) ;; from closest to farthest.
(<= link-end (nth 2 head))) (or (catch 'exit
collect (cons (nth 1 head) (nth 2 head))))) (mapc
(loop named main for ancestor in (nreverse ancestors) do (lambda (parent)
(loop for candidate in cands (when (eq (car parent) 'headline)
when (and (>= (car candidate) (car ancestor)) (let ((foundp (funcall find-headline path parent)))
(<= (cdr candidate) (cdr ancestor))) (when foundp (throw 'exit foundp)))))
do (return-from main (car candidate)))))) (plist-get info :genealogy)) nil)
;; No candidate have a common ancestor with link: First match ;; No match with a common ancestor: try the full parse-tree.
;; will do. Return its beginning position. (funcall find-headline path (plist-get info :parse-tree)))))))
(t (caar cands)))))))
(defun org-export-resolve-coderef (ref info) (defun org-export-resolve-coderef (ref info)
"Resolve a code reference REF. "Resolve a code reference REF.