Browse Source

org-element: Handle multiple TBLFM keywords

* contrib/lisp/org-element.el (org-element-table-parser,
  org-element-table-interpreter): Handle multiple TBLFM keywords.
(org-element-collect-affiliated-keywords): Minor changes to
docstring.
* testing/lisp/test-org-element.el: Add test.
Nicolas Goaziou 13 years ago
parent
commit
d71464c0d3
2 changed files with 35 additions and 13 deletions
  1. 11 8
      contrib/lisp/org-element.el
  2. 24 5
      testing/lisp/test-org-element.el

+ 11 - 8
contrib/lisp/org-element.el

@@ -1584,9 +1584,11 @@ Assume point is at the beginning of the table."
 	   (keywords (org-element-collect-affiliated-keywords))
 	   (begin (car keywords))
 	   (table-end (goto-char (marker-position (org-table-end t))))
-	   (tblfm (when (looking-at "[ \t]*#\\+TBLFM: +\\(.*\\)[ \t]*$")
-		    (prog1 (org-match-string-no-properties 1)
-		      (forward-line))))
+	   (tblfm (let (acc)
+		    (while (looking-at "[ \t]*#\\+TBLFM: +\\(.*\\)[ \t]*$")
+		      (push (org-match-string-no-properties 1) acc)
+		      (forward-line))
+		    acc))
 	   (pos-before-blank (point))
 	   (end (progn (org-skip-whitespace)
 		       (if (eobp) (point) (point-at-bol)))))
@@ -1614,8 +1616,9 @@ CONTENTS is nil."
     (concat (with-temp-buffer (insert contents)
 			      (org-table-align)
 			      (buffer-string))
-	    (when (org-element-property :tblfm table)
-	      (concat "#+TBLFM: " (org-element-property :tblfm table))))))
+	    (mapconcat (lambda (fm) (concat "#+TBLFM: " fm))
+		       (reverse (org-element-property :tblfm table))
+		       "\n"))))
 
 
 ;;;; Table Row
@@ -3197,12 +3200,12 @@ it's value will be a list of parsed strings.  It defaults to
 
 DUALS is a list of strings.  Any keyword member of this list can
 have two parts: one mandatory and one optional.  Its value is
-a cons cell whose car is the former, and the cdr the latter.  If
+a cons cell whose CAR is the former, and the CDR the latter.  If
 a keyword is a member of both PARSED and DUALS, both values will
 be parsed.  It defaults to `org-element-dual-keywords'.
 
-Return a list whose car is the position at the first of them and
-cdr a plist of keywords and values."
+Return a list whose CAR is the position at the first of them and
+CDR a plist of keywords and values."
   (save-excursion
     (let ((case-fold-search t)
 	  (key-re (or key-re org-element--affiliated-re))

+ 24 - 5
testing/lisp/test-org-element.el

@@ -1279,7 +1279,21 @@ Outside list"
   "Test `table' parser."
   (should
    (org-test-with-temp-text "| a |"
-     (org-element-map (org-element-parse-buffer) 'table 'identity))))
+     (org-element-map (org-element-parse-buffer) 'table 'identity)))
+  ;; TBLFM keyword is case insensitive.
+  (should
+   (org-test-with-temp-text "| a |\n#+tblfm: test"
+     (org-element-property
+      :tblfm
+      (org-element-map (org-element-parse-buffer) 'table 'identity nil t))))
+  ;; Handle multiple TBLFM lines.
+  (should
+   (= 2
+      (org-test-with-temp-text "| a |\n#+TBLFM: test1\n#+TBLFM: test2"
+	(length (org-element-property
+		 :tblfm
+		 (org-element-map
+		  (org-element-parse-buffer) 'table 'identity nil t)))))))
 
 
 ;;;; Table Cell
@@ -1293,7 +1307,7 @@ Outside list"
 
 ;;;; Table Row
 
-(ert-deftest test-org-element/table-parser ()
+(ert-deftest test-org-element/table-row-parser ()
   "Test `table-row' parser."
   (should
    (equal '(standard rule)
@@ -1702,18 +1716,23 @@ CLOSED: <2012-01-01> DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
   ;; 1. Simple table.
   (should (equal (org-test-parse-and-interpret "| a | b |\n| c | d |")
 		 "| a | b |\n| c | d |\n"))
-  ;; 2. Table with horizontal rules.
+  ;; 2. With horizontal rules.
   (should (equal (org-test-parse-and-interpret
 		  "| a | b |\n|---+---|\n| c | d |")
 		 "| a | b |\n|---+---|\n| c | d |\n"))
-  ;; 3. Table with meta-data.
+  ;; 3. With meta-data.
   (should (equal (org-test-parse-and-interpret "| / | < | > |\n| * | 1 | 2 |")
 		 "| / | < | > |\n| * | 1 | 2 |\n"))
   ;; 4. With a formula.
   (should
    (equal (org-test-parse-and-interpret
 	   "| 2 |\n| 4 |\n| 3 |\n#+TBLFM: @3=vmean(@1..@2)")
-	  "| 2 |\n| 4 |\n| 3 |\n#+TBLFM: @3=vmean(@1..@2)\n")))
+	  "| 2 |\n| 4 |\n| 3 |\n#+TBLFM: @3=vmean(@1..@2)\n"))
+  ;; 5. With multiple formulas.
+  (should
+   (equal (org-test-parse-and-interpret
+	   "| 2 |\n| 4 |\n| 3 |\n#+TBLFM: test1\n#+TBLFM: test2")
+	  "| 2 |\n| 4 |\n| 3 |\n#+TBLFM: test1\n#+TBLFM: test2\n")))
 
 (ert-deftest test-org-element/verse-block-interpreter ()
   "Test verse block interpretation."