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
This commit is contained in:
Carsten Dominik 2011-10-27 17:30:47 +02:00
parent 0c8b9711a3
commit 1432e4bc79
1 changed files with 22 additions and 15 deletions

View File

@ -2986,8 +2986,11 @@ 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) (let (n nmax len char (start 0))
(while (string-match "\\([@$]\\)\\(<+\\|>+\\)" s) (while (string-match "\\([@$]\\)\\(<+\\|>+\\)\\|\\(remote([^\)]+)\\)"
s start)
(if (match-end 3)
(setq start (match-end 3))
(setq nmax (if (equal (match-string 1 s) "@") (setq nmax (if (equal (match-string 1 s) "@")
(1- (length org-table-dlines)) (1- (length org-table-dlines))
org-table-current-ncol) org-table-current-ncol)
@ -2999,7 +3002,8 @@ borders of the table using the @< @> $< $> makers."
(if (or (< n 1) (> n nmax)) (if (or (< n 1) (> n nmax))
(error "Reference \"%s\" in expression \"%s\" points outside table" (error "Reference \"%s\" in expression \"%s\" points outside table"
(match-string 0 s) s)) (match-string 0 s) s))
(setq s (replace-match (format "%s%d" (match-string 1 s) n) t t 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