Browse Source

Fix remote references that contain pointers to first/last rows/columns

* lisp/org-table.el (org-table-formula-handle-first/last-rc): Do not
expand pointers to first/last row/column that are inside a call
to `remote'.
(org-table-get-remote-range): Expand pointers to first/last
row/column.

Wu Feng writes:

> Hello,
>
> First, please check below simple example, I defined two tables (T1 and
> T2). In table-2, I remotely refer to the @>$1 (last row, column 1) and
> $LR2 (last row, column 2) of T1.
>
> #+TBLNAME: T1
> | 11 | 12 |
> | 21 | 22 |
> | 31 | 32 |
>
> #+TBLNAME: T2
> | xxx | xxx | xxx | xxx |
> | #   |  21 |  32 |     |
> #+TBLFM: @>$3=remote(T1,$LR2)::@>$2=remote(T1,@>$1)
>
> Obviously, the expected results are:
>
> - remote(T1,@>$1) is replaced by 31
> - remote(T1,$LR2) is replaced by 32
>
> But I got 21 for remote(T1,@>$1). The $LR version works perfectly
> (though the manual says $LR is out-dated)
>
> Below are debug info when evaluating remote(T1,@>$1). Looks like @> in
> the remote reference is mapped to the last row of the current table, not
> of the remote table.
>
> Substitution history of formula
> Orig:   remote(T1,@2$1)
> $xyz->  remote(T1,@2$1)
> @r$c->  (21)
> $1->    (21)
> Result: 21
> Format: NONE
> Final:  21
>
> Emacs  : GNU Emacs 23.3.1 (i686-pc-linux-gnu, GTK+ Version 2.24.6)
> of 2011-09-13 on shirley
> Package: Org-mode version 7.7
Carsten Dominik 13 years ago
parent
commit
1432e4bc79
1 changed files with 22 additions and 15 deletions
  1. 22 15
      lisp/org-table.el

+ 22 - 15
lisp/org-table.el

@@ -2986,20 +2986,24 @@ when a line/row is swaped out of that privileged position.  So for
 formulas that use a range of rows or columns, it may often be better
 formulas that use a range of rows or columns, it may often be better
 to anchor the formula with \"I\" row markers, or to offset from the
 to anchor the formula with \"I\" row markers, or to offset from the
 borders of the table using the @< @> $< $> makers."
 borders of the table using the @< @> $< $> makers."
-  (let (n nmax len char)
-    (while (string-match "\\([@$]\\)\\(<+\\|>+\\)" s)
-      (setq nmax (if (equal (match-string 1 s) "@")
-		     (1- (length org-table-dlines))
-		   org-table-current-ncol)
-	    len (- (match-end 2) (match-beginning 2))
-	    char (string-to-char (match-string 2 s))
-	    n (if (= char ?<)
-		  len
-		(- nmax len -1)))
-      (if (or (< n 1) (> n nmax))
-	  (error "Reference \"%s\" in expression \"%s\" points outside table"
-		 (match-string 0 s) s))
-      (setq s (replace-match (format "%s%d" (match-string 1 s) n) t t s))))
+  (let (n nmax len char (start 0))
+    (while (string-match "\\([@$]\\)\\(<+\\|>+\\)\\|\\(remote([^\)]+)\\)"
+			 s start)
+      (if (match-end 3)
+	  (setq start (match-end 3))
+	(setq nmax (if (equal (match-string 1 s) "@")
+		       (1- (length org-table-dlines))
+		     org-table-current-ncol)
+	      len (- (match-end 2) (match-beginning 2))
+	      char (string-to-char (match-string 2 s))
+	      n (if (= char ?<)
+		    len
+		  (- nmax len -1)))
+	(if (or (< n 1) (> n nmax))
+	    (error "Reference \"%s\" in expression \"%s\" points outside table"
+		   (match-string 0 s) s))
+	(setq start (match-beginning 0))
+	(setq s (replace-match (format "%s%d" (match-string 1 s) n) t t s)))))
   s)
   s)
 
 
 (defun org-table-formula-substitute-names (f)
 (defun org-table-formula-substitute-names (f)
@@ -4668,6 +4672,8 @@ The return value is either a single string for a single field, or a
 list of the fields in the rectangle ."
 list of the fields in the rectangle ."
   (save-match-data
   (save-match-data
     (let ((id-loc nil)
     (let ((id-loc nil)
+	  ;; Protect a bunch of variables from being overwritten
+	  ;; by the context of the remote table
 	  org-table-column-names org-table-column-name-regexp
 	  org-table-column-names org-table-column-name-regexp
 	  org-table-local-parameters org-table-named-field-locations
 	  org-table-local-parameters org-table-named-field-locations
 	  org-table-current-line-types org-table-current-begin-line
 	  org-table-current-line-types org-table-current-begin-line
@@ -4704,7 +4710,8 @@ list of the fields in the rectangle ."
 		  (error "Cannot find a table at NAME or ID %s" name-or-id))
 		  (error "Cannot find a table at NAME or ID %s" name-or-id))
 		(setq tbeg (point-at-bol))
 		(setq tbeg (point-at-bol))
 		(org-table-get-specials)
 		(org-table-get-specials)
-		(setq form (org-table-formula-substitute-names form))
+		(setq form (org-table-formula-substitute-names
+			    (org-table-formula-handle-first/last-rc form)))
 		(if (and (string-match org-table-range-regexp form)
 		(if (and (string-match org-table-range-regexp form)
 			 (> (length (match-string 0 form)) 1))
 			 (> (length (match-string 0 form)) 1))
 		    (save-match-data
 		    (save-match-data