Browse Source

org-element: Fix babel call parser

* lisp/org-element.el (org-element-babel-call-parser): Handle complex
  arguments.
* testing/lisp/test-org-element.el (test-org-element/babel-call-parser):
Add test.

Reported-by: Eric S Fraga <e.fraga@ucl.ac.uk>
<http://lists.gnu.org/archive/html/emacs-orgmode/2017-06/msg00366.html>
Nicolas Goaziou 7 years ago
parent
commit
7fe9ae6bd2
2 changed files with 35 additions and 18 deletions
  1. 23 16
      lisp/org-element.el
  2. 12 2
      testing/lisp/test-org-element.el

+ 23 - 16
lisp/org-element.el

@@ -1638,30 +1638,37 @@ containing `:call', `:inside-header', `:arguments',
   (save-excursion
     (let* ((begin (car affiliated))
 	   (post-affiliated (point))
-	   (value (progn (search-forward ":" nil t)
+	   (before-blank (line-beginning-position 2))
+	   (value (progn (search-forward ":" before-blank t)
+			 (skip-chars-forward " \t")
 			 (org-trim
 			  (buffer-substring-no-properties
 			   (point) (line-end-position)))))
-	   (pos-before-blank (progn (forward-line) (point)))
-	   (end (progn (skip-chars-forward " \r\t\n" limit)
-		       (if (eobp) (point) (line-beginning-position))))
-	   (valid-value
-	    (string-match
-	     "\\([^()\n]+?\\)\\(?:\\[\\(.*?\\)\\]\\)?(\\(.*\\))[ \t]*\\(.*\\)"
-	     value)))
+	   (call
+	    (or (org-string-nw-p
+		 (buffer-substring-no-properties
+		  (point) (progn (skip-chars-forward "^[]()" before-blank)
+				 (point))))))
+	   (inside-header (org-element--parse-paired-brackets ?\[))
+	   (arguments (org-string-nw-p
+		       (org-element--parse-paired-brackets ?\()))
+	   (end-header
+	    (org-string-nw-p
+	     (org-trim
+	      (buffer-substring-no-properties (point) (line-end-position)))))
+	   (end (progn (forward-line)
+		       (skip-chars-forward " \r\t\n" limit)
+		       (if (eobp) (point) (line-beginning-position)))))
       (list 'babel-call
 	    (nconc
-	     (list :call (and valid-value (match-string 1 value))
-		   :inside-header (and valid-value
-				       (org-string-nw-p (match-string 2 value)))
-		   :arguments (and valid-value
-				   (org-string-nw-p (match-string 3 value)))
-		   :end-header (and valid-value
-				    (org-string-nw-p (match-string 4 value)))
+	     (list :call call
+		   :inside-header inside-header
+		   :arguments arguments
+		   :end-header end-header
 		   :begin begin
 		   :end end
 		   :value value
-		   :post-blank (count-lines pos-before-blank end)
+		   :post-blank (count-lines before-blank end)
 		   :post-affiliated post-affiliated)
 	     (cdr affiliated))))))
 

+ 12 - 2
testing/lisp/test-org-element.el

@@ -429,12 +429,18 @@ Some other text
    (equal "test"
 	  (org-test-with-temp-text "#+CALL: test()"
 	    (org-element-property :call (org-element-at-point)))))
-  ;; Parse inside header.
+  ;; Parse inside header.  It may contain paired square brackets.
   (should
    (equal ":results output"
 	  (org-test-with-temp-text "#+CALL: test[:results output]()"
 	    (org-element-property :inside-header (org-element-at-point)))))
-  ;; Parse arguments, which can be nested.
+  (should
+   (equal ":results output, a=table[1:2], b=2"
+	  (org-test-with-temp-text
+	      "#+CALL: test[:results output, a=table[1:2], b=2]()"
+	    (org-element-property :inside-header (org-element-at-point)))))
+  ;; Parse arguments, which can be nested.  However, stop at paired
+  ;; parenthesis, even when, e.g.,end header contains some.
   (should
    (equal "n=4"
 	  (org-test-with-temp-text "#+CALL: test(n=4)"
@@ -443,6 +449,10 @@ Some other text
    (equal "test()"
 	  (org-test-with-temp-text "#+CALL: test(test())"
 	    (org-element-property :arguments (org-element-at-point)))))
+  (should
+   (equal "a=1"
+	  (org-test-with-temp-text "#+CALL: test(a=1) :post another-call()"
+	    (org-element-property :arguments (org-element-at-point)))))
   ;; Parse end header.
   (should
    (equal ":results html"