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>
This commit is contained in:
Nicolas Goaziou 2016-08-28 11:45:39 +02:00
parent 6b52bc6a21
commit 3b3fc520aa
4 changed files with 55 additions and 25 deletions

View File

@ -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)))

View File

@ -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)

View File

@ -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)

View File

@ -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)