From 9f47b37231b3c45afcd604a191e346200bd76e98 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 8 Aug 2016 14:04:11 +0200 Subject: [PATCH] Ignore coderef labels when evaluating a code block * lisp/ob-core.el (org-babel--normalize-body): New function. (org-babel-get-src-block-info): Use new function. * lisp/org-src.el (org-src-coderef-regexp): New function. * lisp/ox.el (org-export-unravel-code): Use new function. * testing/lisp/test-ob.el (test-ob/evaluate-body-with-coderefs): New test. --- lisp/ob-core.el | 39 ++++++++++++++++++++++----------------- lisp/org-src.el | 14 ++++++++++++++ lisp/ox.el | 11 ++--------- testing/lisp/test-ob.el | 7 +++++++ 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index f6cac3ac3..f33d93ff9 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -542,6 +542,27 @@ match group 9. Other match groups are defined in "This generates a regexp used to match data named NAME." (concat org-babel-name-regexp (regexp-quote name) "[ \t]*$")) +(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." + (let* ((value (org-element-property :value datum)) + (body (if (and (> (length value) 1) + (string-match-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 datum) "" body nil nil 1))) + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent datum)) + body + (org-remove-indentation body)))))) + ;;; functions (defvar org-babel-current-src-block-location nil "Marker pointing to the src block currently being executed. @@ -578,23 +599,7 @@ a list with the following pattern: (info (list lang - ;; Normalize contents. In particular, remove spurious - ;; indentation and final newline character. - (let* ((value (org-element-property :value datum)) - (body (if (and (> (length value) 1) - (string-match-p "\n\\'" value)) - (substring value 0 -1) - value))) - (cond (inline - ;; 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)))) + (org-babel--normalize-body datum) (apply #'org-babel-merge-params (if inline org-babel-default-inline-header-args org-babel-default-header-args) diff --git a/lisp/org-src.el b/lisp/org-src.el index 5f96e1894..45e36078d 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -715,6 +715,20 @@ If BUFFER is non-nil, test it instead." org-src-window-setup) (pop-to-buffer-same-window buffer)))) +(defun org-src-coderef-regexp (element) + "Return regexp matching coderef for ELEMENT. + +ELEMENT has a `src-block' or `example-block' type. + +Match group 1 contains the full coderef string with surrounding +white spaces. Match group 2 contains the same string without any +surrounding space. Match group 3 contains the label." + (let ((label (regexp-quote (or (org-element-property :label-fmt element) + org-coderef-label-format)))) + (format "\\S-\\([ \t]*\\(%s\\)[ \t]*\\)$" + (replace-regexp-in-string + "%s" "\\([-a-zA-Z0-9_ ]+\\)" label nil t)))) + (defun org-edit-footnote-reference () "Edit definition of footnote reference at point." (interactive) diff --git a/lisp/ox.el b/lisp/ox.el index 929aa8c84..ed0a27da8 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4530,15 +4530,8 @@ reference on that line (string)." (org-element-property :preserve-indent element)) value (org-remove-indentation value))))) - ;; Get format used for references. - (label-fmt (regexp-quote - (or (org-element-property :label-fmt element) - org-coderef-label-format))) ;; Build a regexp matching a loc with a reference. - (with-ref-re - (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)[ \t]*\\)$" - (replace-regexp-in-string - "%s" "\\([-a-zA-Z0-9_ ]+\\)" label-fmt nil t)))) + (ref-re (org-src-coderef-regexp element))) ;; Return value. (cons ;; Code with references removed. @@ -4546,7 +4539,7 @@ reference on that line (string)." (mapconcat (lambda (loc) (cl-incf line) - (if (not (string-match with-ref-re loc)) loc + (if (not (string-match ref-re loc)) loc ;; Ref line: remove ref, and signal its position in REFS. (push (cons line (match-string 3 loc)) refs) (replace-match "" nil nil loc 1))) diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el index 943e60be4..ae606d01f 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -1734,6 +1734,13 @@ abc (execute-kbd-macro "\M-xorg-babel-goto-named-src-block\n\n") (should (= 14 (point))))) +(ert-deftest test-ob/evaluate-body-with-coderefs () + (should + (= 2 + (org-test-with-temp-text + "#+begin_src emacs-lisp -l \"#(ref:%s)\"\n2 #(ref:foo)\n#+end_src" + (org-babel-execute-src-block))))) + (provide 'test-ob) ;;; test-ob ends here