Bläddra i källkod

ob: Ignore data in COMMENTed headings

* lisp/ob-core.el (org-babel-read-element): New function.
* lisp/ob-ref.el (org-babel-ref-resolve): Use new function.  Refactor
  code.
(org-babel-ref-at-ref-p): Remove function.

* testing/lisp/test-ob.el (test-ob/ignore-reference-in-commented-headings):
  New test.
* testing/lisp/test-ob.el (test-ob/resolve-code-blocks-before-data-blocks):
  Remove test

The second test is removed because names are expected to be unique.
There is no order to expect when more than one uses the same name.

Reported-by: myq <myqlarson@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/102464>
Nicolas Goaziou 9 år sedan
förälder
incheckning
02c7850147
3 ändrade filer med 116 tillägg och 102 borttagningar
  1. 33 0
      lisp/ob-core.el
  2. 66 89
      lisp/ob-ref.el
  3. 17 13
      testing/lisp/test-ob.el

+ 33 - 0
lisp/ob-core.el

@@ -1993,6 +1993,39 @@ following the source block."
 	(when hash (org-babel-hide-hash))
 	(point)))))
 
+(defun org-babel-read-element (element)
+  "Read ELEMENT into emacs-lisp.
+Return nil if ELEMENT cannot be read."
+  (org-with-wide-buffer
+   (goto-char (org-element-property :post-affiliated element))
+   (pcase (org-element-type element)
+     (`fixed-width
+      (let ((v (org-babel-trim (org-element-property :value element))))
+	(or (org-babel-number-p v) v)))
+     (`table (org-babel-read-table))
+     (`plain-list (org-babel-read-list))
+     ((or `example-block `export-block)
+      (org-remove-indentation (org-element-property :value element)))
+     (`paragraph
+      ;; Treat paragraphs containing a single link specially.
+      (skip-chars-forward " \t")
+      (if (and (looking-at org-bracket-link-regexp)
+	       (save-excursion
+		 (goto-char (match-end 0))
+		 (skip-chars-forward " \r\t\n")
+		 (<= (org-element-property :end element)
+		     (point))))
+	  (org-babel-read-link)
+	(buffer-substring-no-properties
+	 (org-element-property :contents-begin element)
+	 (org-element-property :contents-end element))))
+     ((or `center-block `paragraph `quote-block `verse-block `special-block)
+      (org-remove-indentation
+       (buffer-substring-no-properties
+	(org-element-property :contents-begin element)
+	(org-element-property :contents-end element))))
+     (_ nil))))
+
 (defvar org-block-regexp)
 (defun org-babel-read-result ()
   "Read the result at `point' into emacs-lisp."

+ 66 - 89
lisp/ob-ref.el

@@ -53,20 +53,25 @@
 (eval-when-compile
   (require 'cl))
 
+(declare-function org-at-item-p "org-list" ())
+(declare-function org-at-table-p "org" (&optional table-type))
+(declare-function org-babel-lob-execute "ob-lob" (info))
+(declare-function org-babel-lob-get-info "ob-lob" nil)
+(declare-function org-count "org" (cl-item cl-seq))
+(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-type "org-element" (element))
 (declare-function org-end-of-meta-data "org" (&optional full))
 (declare-function org-find-property "org" (property &optional value))
-(declare-function org-remove-if-not "org" (predicate seq))
-(declare-function org-at-table-p "org" (&optional table-type))
-(declare-function org-count "org" (CL-ITEM CL-SEQ))
-(declare-function org-at-item-p "org-list" ())
-(declare-function org-narrow-to-subtree "org" ())
-(declare-function org-id-find-id-in-file "org-id" (id file &optional markerp))
 (declare-function org-id-find-id-file "org-id" (id))
+(declare-function org-id-find-id-in-file "org-id" (id file &optional markerp))
+(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
+(declare-function org-narrow-to-subtree "org" ())
+(declare-function org-pop-to-buffer-same-window "org-compat"
+		  (&optional buffer-or-name norecord label))
+(declare-function org-remove-if-not "org" (predicate seq))
 (declare-function org-show-context "org" (&optional key))
-(declare-function org-pop-to-buffer-same-window
-		  "org-compat" (&optional buffer-or-name norecord label))
-(declare-function org-babel-lob-execute "ob-lob" (info))
-(declare-function org-babel-lob-get-info "ob-lob" nil)
+
 
 (defvar org-babel-ref-split-regexp
   "[ \f\t\n\r\v]*\\(.+?\\)[ \f\t\n\r\v]*=[ \f\t\n\r\v]*\\(.+\\)[ \f\t\n\r\v]*")
@@ -129,8 +134,8 @@ the variable."
     (with-current-buffer (or org-babel-exp-reference-buffer (current-buffer))
       (save-excursion
 	(let ((case-fold-search t)
-	      type args new-refere new-header-args new-referent result
-	      lob-info split-file split-ref index id)
+	      args new-refere new-header-args new-referent split-file split-ref
+	      index)
 	  ;; if ref is indexed grab the indices -- beware nested indices
 	  (when (and (string-match "\\[\\([^\\[]+\\)\\]$" ref)
 		     (let ((str (substring ref 0 (match-beginning 0))))
@@ -154,71 +159,55 @@ the variable."
 	  (when (string-match "^\\(.+\\):\\(.+\\)$" ref)
 	    (setq split-file (match-string 1 ref))
 	    (setq split-ref (match-string 2 ref))
-	    (find-file split-file) (setq ref split-ref))
-	  (save-restriction
-	    (widen)
-	    (goto-char (point-min))
-	    (if (let ((src-rx (org-babel-named-src-block-regexp-for-name ref))
-		      (res-rx (org-babel-named-data-regexp-for-name ref)))
-		  ;; goto ref in the current buffer
-		  (or
-		   ;; check for code blocks
-		   (re-search-forward src-rx nil t)
-		   ;; check for named data
-		   (re-search-forward res-rx nil t)
-		   ;; check for local or global headlines by id
-		   (setq id (org-babel-ref-goto-headline-id ref))
-		   ;; check the Library of Babel
-		   (setq lob-info (cdr (assoc (intern ref)
-					      org-babel-library-of-babel)))))
-		(unless (or lob-info id) (goto-char (match-beginning 0)))
-	      ;; ;; TODO: allow searching for names in other buffers
-	      ;; (setq id-loc (org-id-find ref 'marker)
-	      ;;       buffer (marker-buffer id-loc)
-	      ;;       loc (marker-position id-loc))
-	      ;; (move-marker id-loc nil)
-	      (error "Reference `%s' not found in this buffer" ref))
-	    (cond
-	     (lob-info (setq type 'lob))
-	     (id (setq type 'id))
-	     ((and (looking-at org-babel-src-name-regexp)
-		   (save-excursion
-		     (forward-line 1)
-		     (or (looking-at org-babel-src-block-regexp)
-			 (looking-at org-babel-multi-line-header-regexp))))
-	      (setq type 'source-block))
-	     ((and (looking-at org-babel-src-name-regexp)
-		   (save-excursion
-		     (forward-line 1)
-		     (looking-at org-babel-lob-one-liner-regexp)))
-	      (setq type 'call-line))
-	     (t (while (not (setq type (org-babel-ref-at-ref-p)))
-		  (forward-line 1)
-		  (beginning-of-line)
-		  (if (or (= (point) (point-min)) (= (point) (point-max)))
-		      (error "Reference not found")))))
-	    (let ((params (append args '((:results . "silent")))))
-	      (setq result
-		    (case type
-		      (results-line (org-babel-read-result))
-		      (table        (org-babel-read-table))
-		      (list         (org-babel-read-list))
-		      (file         (org-babel-read-link))
-		      (source-block (org-babel-execute-src-block
-				     nil nil (if org-babel-update-intermediate
-						 nil params)))
-		      (call-line (save-excursion
-				   (forward-line 1)
-				   (org-babel-lob-execute
-				    (org-babel-lob-get-info))))
-		      (lob          (org-babel-execute-src-block
-				     nil lob-info params))
-		      (id           (org-babel-ref-headline-body)))))
-	    (if (symbolp result)
-		(format "%S" result)
-	      (if (and index (listp result))
-		  (org-babel-ref-index-list index result)
-		result))))))))
+	    (find-file split-file)
+	    (setq ref split-ref))
+	  (org-with-wide-buffer
+	   (goto-char (point-min))
+	   (let* ((params (append args '((:results . "silent"))))
+		  (regexp (org-babel-named-data-regexp-for-name ref))
+		  lob-info
+		  (result
+		   (cond
+		    ;; Check for code blocks or named data.
+		    ((catch :found
+		       (while (re-search-forward regexp nil t)
+			 ;; Ignore COMMENTed headings and orphaned
+			 ;; affiliated keywords.
+			 (unless (org-in-commented-heading-p)
+			   (let ((e (org-element-at-point)))
+			     (when (equal (org-element-property :name e) ref)
+			       (goto-char
+				(org-element-property :post-affiliated e))
+			       (pcase (org-element-type e)
+				 (`babel-call
+				  (throw :found
+					 (org-babel-lob-execute
+					  (org-babel-lob-get-info))))
+				 (`src-block
+				  (throw :found
+					 (org-babel-execute-src-block
+					  nil nil
+					  (and
+					   (not org-babel-update-intermediate)
+					   params))))
+				 ((and (let v (org-babel-read-element e))
+				       (guard v))
+				  (throw :found v))
+				 (_ (error "Reference not found")))))))
+		       nil))
+		    ;; Check for local or global headlines by ID.
+		    ((org-babel-ref-goto-headline-id ref)
+		     (org-babel-ref-headline-body))
+		    ;; Check the Library of Babel.
+		    ((setq lob-info
+			   (cdr (assq (intern ref) org-babel-library-of-babel)))
+		     (org-babel-execute-src-block nil lob-info params))
+		    (t (error "Reference `%s' not found in this buffer" ref)))))
+	     (cond
+	      ((symbolp result) (format "%S" result))
+	      ((and index (listp result))
+	       (org-babel-ref-index-list index result))
+	      (t result)))))))))
 
 (defun org-babel-ref-index-list (index lis)
   "Return the subset of LIS indexed by INDEX.
@@ -263,19 +252,7 @@ to \"0:-1\"."
   "Split ARG-STRING into top-level arguments of balanced parenthesis."
   (mapcar #'org-babel-trim (org-babel-balanced-split arg-string 44)))
 
-(defvar org-bracket-link-regexp)
-(defun org-babel-ref-at-ref-p ()
-  "Return the type of reference located at point.
-Return nil if none of the supported reference types are found.
-Supported reference types are tables and source blocks."
-  (cond ((org-at-table-p) 'table)
-	((org-at-item-p) 'list)
-        ((looking-at "^[ \t]*#\\+BEGIN_SRC") 'source-block)
-        ((looking-at org-bracket-link-regexp) 'file)
-        ((looking-at org-babel-result-regexp) 'results-line)))
 
 (provide 'ob-ref)
 
-
-
 ;;; ob-ref.el ends here

+ 17 - 13
testing/lisp/test-ob.el

@@ -602,21 +602,25 @@ on two lines
     (should (string= (org-babel-execute-src-block)
 		     "A literal example\non two lines\n for me."))))
 
-(ert-deftest test-ob/resolve-code-blocks-before-data-blocks ()
-  (org-test-with-temp-text "
-#+name: foo
-: bar
+(ert-deftest test-ob/ignore-reference-in-commented-headings ()
+  (should
+   (= 2
+      (org-test-with-temp-text
+	  "
+* COMMENT H1
+#+NAME: n
+: 1
 
-#+name: foo
-#+begin_src emacs-lisp
-  \"baz\"
-#+end_src
+* H2
+#+NAME: n
+: 2
 
-#+begin_src emacs-lisp :var foo=foo
-  foo
-#+end_src"
-    (org-babel-next-src-block 2)
-    (should (string= (org-babel-execute-src-block) "baz"))))
+* Code
+
+<point>#+BEGIN_SRC emacs-lisp :var x=n
+x
+#+END_SRC"
+	(org-babel-execute-src-block)))))
 
 (ert-deftest test-ob/do-not-resolve-to-partial-names-data ()
   (org-test-with-temp-text "