Browse Source

ox: Throw an error on unresolved coderef

* lisp/ox.el (org-export-resolve-coderef): Throw an error on
  unresolved coderef.

* testing/lisp/test-ox.el (test-org-export/resolve-coderef): Update
  test.
Nicolas Goaziou 10 years ago
parent
commit
a886b23476
2 changed files with 91 additions and 63 deletions
  1. 22 20
      lisp/ox.el
  2. 69 43
      testing/lisp/test-ox.el

+ 22 - 20
lisp/ox.el

@@ -3983,26 +3983,28 @@ This only applies to links without a description."
 INFO is a plist used as a communication channel.
 
 Return associated line number in source code, or REF itself,
-depending on src-block or example element's switches."
-  (org-element-map (plist-get info :parse-tree) '(example-block src-block)
-    (lambda (el)
-      (with-temp-buffer
-	(insert (org-trim (org-element-property :value el)))
-	(let* ((label-fmt (regexp-quote
-			   (or (org-element-property :label-fmt el)
-			       org-coderef-label-format)))
-	       (ref-re
-		(format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
-			(replace-regexp-in-string "%s" ref label-fmt nil t))))
-	  ;; Element containing REF is found.  Resolve it to either
-	  ;; a label or a line number, as needed.
-	  (when (re-search-backward ref-re nil t)
-	    (cond
-	     ((org-element-property :use-labels el) ref)
-	     ((eq (org-element-property :number-lines el) 'continued)
-	      (+ (org-export-get-loc el info) (line-number-at-pos)))
-	     (t (line-number-at-pos)))))))
-    info 'first-match))
+depending on src-block or example element's switches.  Throw an
+error if no block contains REF."
+  (or (org-element-map (plist-get info :parse-tree) '(example-block src-block)
+	(lambda (el)
+	  (with-temp-buffer
+	    (insert (org-trim (org-element-property :value el)))
+	    (let* ((label-fmt (regexp-quote
+			       (or (org-element-property :label-fmt el)
+				   org-coderef-label-format)))
+		   (ref-re
+		    (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
+			    (format label-fmt ref))))
+	      ;; Element containing REF is found.  Resolve it to
+	      ;; either a label or a line number, as needed.
+	      (when (re-search-backward ref-re nil t)
+		(cond
+		 ((org-element-property :use-labels el) ref)
+		 ((eq (org-element-property :number-lines el) 'continued)
+		  (+ (org-export-get-loc el info) (line-number-at-pos)))
+		 (t (line-number-at-pos)))))))
+	info 'first-match)
+      (user-error "Unable to resolve code reference: %s" ref)))
 
 (defun org-export-resolve-fuzzy-link (link info)
   "Return LINK destination.

+ 69 - 43
testing/lisp/test-ox.el

@@ -2372,46 +2372,66 @@ Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
 (ert-deftest test-org-export/resolve-coderef ()
   "Test `org-export-resolve-coderef' specifications."
   (let ((org-coderef-label-format "(ref:%s)"))
-    ;; 1. A link to a "-n -k -r" block returns line number.
-    (org-test-with-parsed-data
-	"#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    (org-test-with-parsed-data
-	"#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    ;; 2. A link to a "-n -r" block returns line number.
-    (org-test-with-parsed-data
-	"#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    (org-test-with-parsed-data
-	"#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    ;; 3. A link to a "-n" block returns coderef.
-    (org-test-with-parsed-data
-	"#+BEGIN_SRC emacs-lisp -n\n(+ 1 1) (ref:coderef)\n#+END_SRC"
-      (should (equal (org-export-resolve-coderef "coderef" info) "coderef")))
-    (org-test-with-parsed-data
-	"#+BEGIN_EXAMPLE -n\nText (ref:coderef)\n#+END_EXAMPLE"
-      (should (equal (org-export-resolve-coderef "coderef" info) "coderef")))
-    ;; 4. A link to a "-r" block returns line number.
-    (org-test-with-parsed-data
-	"#+BEGIN_SRC emacs-lisp -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    (org-test-with-parsed-data
-	"#+BEGIN_EXAMPLE -r\nText (ref:coderef)\n#+END_EXAMPLE"
-      (should (= (org-export-resolve-coderef "coderef" info) 1)))
-    ;; 5. A link to a block without a switch returns coderef.
-    (org-test-with-parsed-data
-	"#+BEGIN_SRC emacs-lisp\n(+ 1 1) (ref:coderef)\n#+END_SRC"
-      (should (equal (org-export-resolve-coderef "coderef" info) "coderef")))
+    ;; A link to a "-n -k -r" block returns line number.
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE"
+	  (org-export-resolve-coderef "coderef" info))))
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
+	  (org-export-resolve-coderef "coderef" info))))
+    ;; A link to a "-n -r" block returns line number.
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE"
+	  (org-export-resolve-coderef "coderef" info))))
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
+	  (org-export-resolve-coderef "coderef" info))))
+    ;; A link to a "-n" block returns coderef.
+    (should
+     (equal "coderef"
+	    (org-test-with-parsed-data
+		"#+BEGIN_SRC emacs-lisp -n\n(+ 1 1) (ref:coderef)\n#+END_SRC"
+	      (org-export-resolve-coderef "coderef" info))))
+    (should
+     (equal "coderef"
+	    (org-test-with-parsed-data
+		"#+BEGIN_EXAMPLE -n\nText (ref:coderef)\n#+END_EXAMPLE"
+	      (org-export-resolve-coderef "coderef" info))))
+    ;; A link to a "-r" block returns line number.
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
+	  (org-export-resolve-coderef "coderef" info))))
+    (should
+     (= 1
+	(org-test-with-parsed-data
+	    "#+BEGIN_EXAMPLE -r\nText (ref:coderef)\n#+END_EXAMPLE"
+	  (org-export-resolve-coderef "coderef" info))))
+    ;; A link to a block without a switch returns coderef.
+    (should
+     (equal "coderef"
+	    (org-test-with-parsed-data
+		"#+BEGIN_SRC emacs-lisp\n(+ 1 1) (ref:coderef)\n#+END_SRC"
+	      (org-export-resolve-coderef "coderef" info))))
     (org-test-with-parsed-data
 	"#+BEGIN_EXAMPLE\nText (ref:coderef)\n#+END_EXAMPLE"
       (should (equal (org-export-resolve-coderef "coderef" info) "coderef")))
-    ;; 6. Correctly handle continued line numbers.  A "+n" switch
-    ;;    should resume numbering from previous block with numbered
-    ;;    lines, ignoring blocks not numbering lines in the process.
-    ;;    A "-n" switch resets count.
-    (org-test-with-parsed-data "
+    ;; Correctly handle continued line numbers.  A "+n" switch should
+    ;; resume numbering from previous block with numbered lines,
+    ;; ignoring blocks not numbering lines in the process.  A "-n"
+    ;; switch resets count.
+    (should
+     (equal '(2 1)
+	    (org-test-with-parsed-data "
 #+BEGIN_EXAMPLE -n
 Text.
 #+END_EXAMPLE
@@ -2427,12 +2447,18 @@ Text.
 #+BEGIN_EXAMPLE -n -r
 Another text. (ref:text)
 #+END_EXAMPLE"
-      (should (= (org-export-resolve-coderef "addition" info) 2))
-      (should (= (org-export-resolve-coderef "text" info) 1)))
-    ;; 7. Recognize coderef with user-specified syntax.
-    (org-test-with-parsed-data
-	"#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
-      (should (equal (org-export-resolve-coderef "text" info) "text")))))
+	      (list (org-export-resolve-coderef "addition" info)
+		    (org-export-resolve-coderef "text" info)))))
+    ;; Recognize coderef with user-specified syntax.
+    (should
+     (equal "text"
+	    (org-test-with-parsed-data
+		"#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
+	      (org-export-resolve-coderef "text" info))))
+    ;; Unresolved coderefs throw an error.
+    (should-error
+     (org-test-with-parsed-data "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
+       (org-export-resolve-coderef "unknown" info)))))
 
 (ert-deftest test-org-export/resolve-fuzzy-link ()
   "Test `org-export-resolve-fuzzy-link' specifications."