Parcourir la source

Fix coderef handling in source blocks

* lisp/ob-core.el (org-babel--normalize-body): Do not remove coderef.
(org-babel-get-src-block-info): Add coderef label information, when
available, to the return value.
(org-babel-execute-src-block): Expand noweb and remove coderefs
non-destructively.
* lisp/ob-lob.el (org-babel-lob-get-info): Adapt to new INFO.

* testing/lisp/test-ob-exp.el (ob-export/body-with-coderef):
* testing/lisp/test-ob.el (test-ob/evaluate-body-with-coderefs): Add
  tests.

Reported-by: Thibault Marin <thibault.marin@gmx.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/108888>
Nicolas Goaziou il y a 8 ans
Parent
commit
3b3fc520aa
4 fichiers modifiés avec 55 ajouts et 25 suppressions
  1. 26 22
      lisp/ob-core.el
  2. 3 2
      lisp/ob-lob.el
  3. 19 0
      testing/lisp/test-ob-exp.el
  4. 7 1
      testing/lisp/test-ob.el

+ 26 - 22
lisp/ob-core.el

@@ -543,25 +543,21 @@ match group 9.  Other match groups are defined in
 
 (defun org-babel--normalize-body (datum)
   "Normalize body for element or object DATUM.
-In particular, remove spurious indentation, final newline
-character and coderef labels when appropriate."
+DATUM is a source block element or an inline source block object.
+Remove final newline character and spurious indentation."
   (let* ((value (org-element-property :value datum))
-	 (body (if (and (> (length value) 1)
-			(string-match-p "\n\\'" value))
+	 (body (if (string-suffix-p "\n" value)
 		   (substring value 0 -1)
 		 value)))
-    (if (eq (org-element-type datum) 'inline-src-block)
-	;; Newline characters and indentation in an inline src-block
-	;; are not meaningful, since they could come from some
-	;; paragraph filling.  Treat them as a white space.
-	(replace-regexp-in-string "\n[ \t]*" " " body)
-      (let ((body (replace-regexp-in-string
-		   (org-src-coderef-regexp (org-src-coderef-format datum)) ""
-		   body nil nil 1)))
-	(if (or org-src-preserve-indentation
-		(org-element-property :preserve-indent datum))
-	    body
-	  (org-remove-indentation body))))))
+    (cond ((eq (org-element-type datum) 'inline-src-block)
+	   ;; Newline characters and indentation in an inline
+	   ;; src-block are not meaningful, since they could come from
+	   ;; some paragraph filling.  Treat them as a white space.
+	   (replace-regexp-in-string "\n[ \t]*" " " body))
+	  ((or org-src-preserve-indentation
+	       (org-element-property :preserve-indent datum))
+	   body)
+	  (t (org-remove-indentation body)))))
 
 ;;; functions
 (defvar org-babel-current-src-block-location nil
@@ -587,7 +583,7 @@ object instead.
 Return nil if point is not on a source block.  Otherwise, return
 a list with the following pattern:
 
-  (language body header-arguments-alist switches name block-head)"
+  (language body arguments switches name start coderef)"
   (let* ((datum (or datum (org-element-context)))
 	 (type (org-element-type datum))
 	 (inline (eq type 'inline-src-block)))
@@ -616,7 +612,8 @@ a list with the following pattern:
 	       (or (org-element-property :switches datum) "")
 	       name
 	       (org-element-property (if inline :begin :post-affiliated)
-				     datum))))
+				     datum)
+	       (and (not inline) (org-src-coderef-format datum)))))
 	(unless light
 	  (setf (nth 2 info) (org-babel-process-params (nth 2 info))))
 	(setf (nth 2 info) (org-babel-generate-file-param name (nth 2 info)))
@@ -667,10 +664,17 @@ block."
 	 ((org-babel-confirm-evaluate info)
 	  (let* ((lang (nth 0 info))
 		 (result-params (cdr (assq :result-params params)))
-		 (body (setf (nth 1 info)
-			     (if (org-babel-noweb-p params :eval)
-				 (org-babel-expand-noweb-references info)
-			       (nth 1 info))))
+		 ;; Expand noweb references in BODY and remove any
+		 ;; coderef.
+		 (body
+		  (let ((coderef (nth 6 info))
+			(expand
+			 (if (org-babel-noweb-p params :eval)
+			     (org-babel-expand-noweb-references info)
+			   (nth 1 info))))
+		    (if (not coderef) expand
+		      (replace-regexp-in-string
+		       (org-src-coderef-regexp coderef) "" expand nil nil 1))))
 		 (dir (cdr (assq :dir params)))
 		 (default-directory
 		   (or (and dir (file-name-as-directory (expand-file-name dir)))

+ 3 - 2
lisp/ob-lob.el

@@ -113,7 +113,7 @@ compatible with `org-babel-get-src-block-info', which see."
 	 (type (org-element-type context)))
     (when (memq type '(babel-call inline-babel-call))
       (pcase (org-babel-lob--src-info (org-element-property :call context))
-	(`(,language ,body ,header ,_ ,_ ,_)
+	(`(,language ,body ,header ,_ ,_ ,_ ,coderef)
 	 (let ((begin (org-element-property (if (eq type 'inline-babel-call)
 						:begin
 					      :post-affiliated)
@@ -138,7 +138,8 @@ compatible with `org-babel-get-src-block-info', which see."
 			   (org-element-property :end-header context)))))
 		 nil
 		 (org-element-property :name context)
-		 begin)))
+		 begin
+		 coderef)))
 	(_ nil)))))
 
 (provide 'ob-lob)

+ 19 - 0
testing/lisp/test-ob-exp.el

@@ -565,6 +565,25 @@ src_emacs-lisp{(+ 1 1)}"
 	(org-babel-exp-process-buffer))
       (buffer-string)))))
 
+(ert-deftest ob-export/body-with-coderef ()
+  "Test exporting a code block with coderefs."
+  (should
+   (equal "#+BEGIN_SRC emacs-lisp\n0 (ref:foo)\n#+END_SRC"
+	  (org-test-with-temp-text
+	      "#+BEGIN_SRC emacs-lisp :exports code\n0 (ref:foo)\n#+END_SRC"
+	    (let ((org-export-babel-evaluate t)
+		  (org-coderef-label-format "(ref:foo)"))
+	      (org-babel-exp-process-buffer))
+	    (buffer-string))))
+  (should
+   (equal
+    "#+BEGIN_SRC emacs-lisp -l \"r:%s\"\n1 r:foo\n#+END_SRC"
+    (org-test-with-temp-text
+	"#+BEGIN_SRC emacs-lisp -l \"r:%s\" -lisp :exports code\n1 r:foo\n#+END_SRC"
+      (let ((org-export-babel-evaluate t))
+	(org-babel-exp-process-buffer))
+      (buffer-string)))))
+
 
 (provide 'test-ob-exp)
 

+ 7 - 1
testing/lisp/test-ob.el

@@ -1739,7 +1739,13 @@ abc
    (= 2
       (org-test-with-temp-text
 	  "#+begin_src emacs-lisp -l \"#(ref:%s)\"\n2 #(ref:foo)\n#+end_src"
-	(org-babel-execute-src-block)))))
+	(org-babel-execute-src-block))))
+  (should
+   (= 3
+      (org-test-with-temp-text
+	  "#+begin_src emacs-lisp\n3 #(ref:foo)\n#+end_src"
+	(let ((org-coderef-label-format "#(ref:%s)"))
+	  (org-babel-execute-src-block))))))
 
 (provide 'test-ob)