ox: Throw an error on unresolved id links

* lisp/ox.el (org-export-get-environment): Properly find file
  associated to id link.
(org-export-resolve-id-link): Throw an error on unresolved id links.

Use `org-id-find' instead of `org-id-find-id-file' as the latter may
returns the file attached to current buffer on search failure.

Reported-by: Jacob Gerlach <jacobgerlach@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/96020>
This commit is contained in:
Nicolas Goaziou 2015-03-17 23:24:03 +01:00
parent dc08e98885
commit e0b19dedb9
2 changed files with 34 additions and 25 deletions

View File

@ -1371,7 +1371,7 @@ inferior to file-local settings."
(let ((link (org-element-context)))
(when (eq (org-element-type link) 'link)
(let* ((id (org-element-property :path link))
(file (org-id-find-id-file id)))
(file (car (org-id-find id))))
(when file
(push (cons id (file-relative-name file)) alist)))))))
alist))))
@ -4105,18 +4105,19 @@ significant."
INFO is a plist used as a communication channel.
Return value can be the headline element matched in current parse
tree, a file name or nil. Assume LINK type is either \"id\" or
\"custom-id\"."
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 (string= (org-element-property :ID headline) id)
(string= (org-element-property :CUSTOM_ID headline) id))
(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))))))
(cdr (assoc id (plist-get info :id-alist)))
(user-error "Unable to resolve ID \"%s\"" id))))
(defun org-export-resolve-radio-link (link info)
"Return radio-target object referenced as LINK destination.

View File

@ -2518,42 +2518,50 @@ Another text. (ref:text)
(ert-deftest test-org-export/resolve-id-link ()
"Test `org-export-resolve-id-link' specifications."
;; 1. Regular test for custom-id link.
(org-test-with-parsed-data "* Headline1
;; Regular test for custom-id link.
(should
(equal '("Headline1")
(org-test-with-parsed-data "* Headline1
:PROPERTIES:
:CUSTOM_ID: test
:END:
* Headline 2
\[[#test]]"
(should
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t) info)))
;; 2. Failing test for custom-id link.
(org-test-with-parsed-data "* Headline1
(org-element-property
:title
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t) info)))))
;; Throw an error on failing searches.
(should-error
(org-test-with-parsed-data "* Headline1
:PROPERTIES:
:CUSTOM_ID: test
:END:
* Headline 2
\[[#no-match]]"
(should-not
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t) info)))
;; 3. Test for internal id target.
(org-test-with-parsed-data "* Headline1
;; Test for internal id target.
(should
(equal '("Headline1")
(org-test-with-parsed-data "* Headline1
:PROPERTIES:
:ID: aaaa
:END:
* Headline 2
\[[id:aaaa]]"
(should
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t) info)))
;; 4. Test for external id target.
(org-test-with-parsed-data "[[id:aaaa]]"
(should
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t)
(org-combine-plists info '(:id-alist (("aaaa" . "external-file"))))))))
(org-element-property
:title
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t) info)))))
;; Test for external id target.
(should
(equal
"external-file"
(org-test-with-parsed-data "[[id:aaaa]]"
(org-export-resolve-id-link
(org-element-map tree 'link 'identity info t)
(org-combine-plists info '(:id-alist (("aaaa" . "external-file")))))))))
(ert-deftest test-org-export/resolve-radio-link ()
"Test `org-export-resolve-radio-link' specifications."