mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-11-26 07:33:39 +00:00
org-export: Correctly resolve fuzzy links whose path starts with *
* contrib/lisp/org-export.el (org-export-resolve-fuzzy-link): Correctly resolve fuzzy links whose path starts with * * testing/lisp/test-org-export.el: Add tests.
This commit is contained in:
parent
ad235400a6
commit
451191bc41
@ -2949,18 +2949,19 @@ Return value can be an object, an element, or nil:
|
||||
- Otherwise, return nil.
|
||||
|
||||
Assume LINK type is \"fuzzy\"."
|
||||
(let ((path (org-element-property :path link)))
|
||||
(let* ((path (org-element-property :path link))
|
||||
(match-title-p (eq (aref path 0) ?*)))
|
||||
(cond
|
||||
;; First try to find a matching "<<path>>" unless user specified
|
||||
;; he was looking for an headline (path starts with a *
|
||||
;; character).
|
||||
((and (not (eq (substring path 0 1) ?*))
|
||||
((and (not match-title-p)
|
||||
(loop for target in (plist-get info :target-list)
|
||||
when (string= (org-element-property :value target) path)
|
||||
return target)))
|
||||
;; Then try to find an element with a matching "#+NAME: path"
|
||||
;; affiliated keyword.
|
||||
((and (not (eq (substring path 0 1) ?*))
|
||||
((and (not match-title-p)
|
||||
(org-element-map
|
||||
(plist-get info :parse-tree) org-element-all-elements
|
||||
(lambda (el)
|
||||
@ -2972,29 +2973,31 @@ Assume LINK type is \"fuzzy\"."
|
||||
;; is found, return it, otherwise return nil.
|
||||
(t
|
||||
(let ((find-headline
|
||||
(function
|
||||
;; Return first headline whose `:raw-value' property
|
||||
;; is NAME in parse tree DATA, or nil.
|
||||
(lambda (name data)
|
||||
(org-element-map
|
||||
data 'headline
|
||||
(lambda (headline)
|
||||
(when (string=
|
||||
(org-element-property :raw-value headline)
|
||||
name)
|
||||
headline))
|
||||
info 'first-match)))))
|
||||
;; Search among headlines sharing an ancestor with link,
|
||||
;; from closest to farthest.
|
||||
(or (catch 'exit
|
||||
(mapc
|
||||
(lambda (parent)
|
||||
(when (eq (org-element-type parent) 'headline)
|
||||
(let ((foundp (funcall find-headline path parent)))
|
||||
(when foundp (throw 'exit foundp)))))
|
||||
(org-export-get-genealogy link info)) nil)
|
||||
;; No match with a common ancestor: try the full parse-tree.
|
||||
(funcall find-headline path (plist-get info :parse-tree))))))))
|
||||
(function
|
||||
;; Return first headline whose `:raw-value' property
|
||||
;; is NAME in parse tree DATA, or nil.
|
||||
(lambda (name data)
|
||||
(org-element-map
|
||||
data 'headline
|
||||
(lambda (headline)
|
||||
(when (string=
|
||||
(org-element-property :raw-value headline)
|
||||
name)
|
||||
headline))
|
||||
info 'first-match)))))
|
||||
;; Search among headlines sharing an ancestor with link,
|
||||
;; from closest to farthest.
|
||||
(or (catch 'exit
|
||||
(mapc
|
||||
(lambda (parent)
|
||||
(when (eq (org-element-type parent) 'headline)
|
||||
(let ((foundp (funcall find-headline path parent)))
|
||||
(when foundp (throw 'exit foundp)))))
|
||||
(org-export-get-genealogy link info)) nil)
|
||||
;; No match with a common ancestor: try the full parse-tree.
|
||||
(funcall find-headline
|
||||
(if match-title-p (substring path 1) path)
|
||||
(plist-get info :parse-tree))))))))
|
||||
|
||||
(defun org-export-resolve-id-link (link info)
|
||||
"Return headline referenced as LINK destination.
|
||||
|
@ -478,6 +478,73 @@ Paragraph[fn:1]"
|
||||
|
||||
;;; Links
|
||||
|
||||
(ert-deftest test-org-export/fuzzy-link ()
|
||||
"Test fuzzy links specifications."
|
||||
;; 1. Links to invisible (keyword) targets should be ignored.
|
||||
(org-test-with-parsed-data
|
||||
"Paragraph.\n#+TARGET: Test\n[[Test]]"
|
||||
(should-not
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info)))
|
||||
;; 2. Link to an headline should return headline's number.
|
||||
(org-test-with-parsed-data
|
||||
"Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
|
||||
(should
|
||||
;; Note: Headline's number is in fact a list of numbers.
|
||||
(equal '(2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 3. Link to a target in an item should return item's number.
|
||||
(org-test-with-parsed-data
|
||||
"- Item1\n - Item11\n - <<test>>Item12\n- Item2\n\n\n[[test]]"
|
||||
(should
|
||||
;; Note: Item's number is in fact a list of numbers.
|
||||
(equal '(1 2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 4. Link to a target in a footnote should return footnote's
|
||||
;; number.
|
||||
(org-test-with-parsed-data "
|
||||
Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
|
||||
(should
|
||||
(equal '(2 3)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info))))
|
||||
;; 5. Link to a named element should return sequence number of that
|
||||
;; element.
|
||||
(org-test-with-parsed-data
|
||||
"#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
|
||||
(should
|
||||
(= 2
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 6. Link to a target not within an item, a table, a footnote
|
||||
;; reference or definition should return section number.
|
||||
(org-test-with-parsed-data
|
||||
"* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
|
||||
(should
|
||||
(equal '(2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t)))))
|
||||
|
||||
(ert-deftest test-org-export/resolve-coderef ()
|
||||
"Test `org-export-resolve-coderef' specifications."
|
||||
(let ((org-coderef-label-format "(ref:%s)"))
|
||||
@ -543,72 +610,59 @@ Another text. (ref:text)
|
||||
"#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
|
||||
(should (equal (org-export-resolve-coderef "text" info) "text")))))
|
||||
|
||||
(ert-deftest test-org-export/resolve-fuzzy-link ()
|
||||
(ert-deftest test-org-exprot/resolve-fuzzy-link ()
|
||||
"Test `org-export-resolve-fuzzy-link' specifications."
|
||||
;; 1. Links to invisible (keyword) targets should be ignored.
|
||||
;; 1. Match target objects.
|
||||
(org-test-with-parsed-data "<<target>> [[target]]"
|
||||
(should
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))
|
||||
;; 2. Match target elements.
|
||||
(org-test-with-parsed-data "#+TARGET: target\n[[target]]"
|
||||
(should
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))
|
||||
;; 3. Match named elements.
|
||||
(org-test-with-parsed-data "#+NAME: target\nParagraph\n\n[[target]]"
|
||||
(should
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))
|
||||
;; 4. Match exact headline's name.
|
||||
(org-test-with-parsed-data "* My headline\n[[My headline]]"
|
||||
(should
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))
|
||||
;; 5. Targets objects have priority over named elements and headline
|
||||
;; titles.
|
||||
(org-test-with-parsed-data
|
||||
"Paragraph.\n#+TARGET: Test\n[[Test]]"
|
||||
"* target\n#+NAME: target\n<<target>>\n\n[[target]]"
|
||||
(should
|
||||
(eq 'target
|
||||
(org-element-type
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))))
|
||||
;; 6. Named elements have priority over headline titles.
|
||||
(org-test-with-parsed-data
|
||||
"* target\n#+NAME: target\nParagraph\n\n[[target]]"
|
||||
(should
|
||||
(eq 'paragraph
|
||||
(org-element-type
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))))
|
||||
;; 7. If link's path starts with a "*", only match headline titles,
|
||||
;; though.
|
||||
(org-test-with-parsed-data
|
||||
"* target\n#+NAME: target\n<<target>>\n\n[[*target]]"
|
||||
(should
|
||||
(eq 'headline
|
||||
(org-element-type
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info)))))
|
||||
;; 8. Return nil if no match.
|
||||
(org-test-with-parsed-data "[[target]]"
|
||||
(should-not
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info)))
|
||||
;; 2. Link to an headline should return headline's number.
|
||||
(org-test-with-parsed-data
|
||||
"Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
|
||||
(should
|
||||
;; Note: Headline's number is in fact a list of numbers.
|
||||
(equal '(2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 3. Link to a target in an item should return item's number.
|
||||
(org-test-with-parsed-data
|
||||
"- Item1\n - Item11\n - <<test>>Item12\n- Item2\n\n\n[[test]]"
|
||||
(should
|
||||
;; Note: Item's number is in fact a list of numbers.
|
||||
(equal '(1 2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 4. Link to a target in a footnote should return footnote's
|
||||
;; number.
|
||||
(org-test-with-parsed-data "
|
||||
Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
|
||||
(should
|
||||
(equal '(2 3)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info))))
|
||||
;; 5. Link to a named element should return sequence number of that
|
||||
;; element.
|
||||
(org-test-with-parsed-data
|
||||
"#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
|
||||
(should
|
||||
(= 2
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t))))
|
||||
;; 6. Link to a target not within an item, a table, a footnote
|
||||
;; reference or definition should return section number.
|
||||
(org-test-with-parsed-data
|
||||
"* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
|
||||
(should
|
||||
(equal '(2)
|
||||
(org-element-map
|
||||
tree 'link
|
||||
(lambda (link)
|
||||
(org-export-get-ordinal
|
||||
(org-export-resolve-fuzzy-link link info) info)) info t)))))
|
||||
(org-export-resolve-fuzzy-link
|
||||
(org-element-map tree 'link 'identity info t) info))))
|
||||
|
||||
(ert-deftest test-org-export/resolve-id-link ()
|
||||
"Test `org-export-resolve-id-link' specifications."
|
||||
|
Loading…
Reference in New Issue
Block a user