From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jason Riedy Subject: [PATCH] Support multiple destinations for each radio table. Date: Sun, 02 Mar 2008 17:46:30 -0800 Message-ID: <878x10inpl.fsf_-_@sparse.yi.org> References: <87prugs4jy.fsf@sparse.yi.org> <27C4F608-C27A-4E97-B20F-907F7134CDC6@science.uva.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JVzlC-0004w4-Fa for emacs-orgmode@gnu.org; Sun, 02 Mar 2008 20:46:34 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JVzlA-0004vi-S3 for emacs-orgmode@gnu.org; Sun, 02 Mar 2008 20:46:33 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JVzlA-0004vW-K1 for emacs-orgmode@gnu.org; Sun, 02 Mar 2008 20:46:32 -0500 Received: from a.mail.sonic.net ([64.142.16.245]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JVzlA-00024W-6X for emacs-orgmode@gnu.org; Sun, 02 Mar 2008 20:46:32 -0500 In-Reply-To: <27C4F608-C27A-4E97-B20F-907F7134CDC6@science.uva.nl> (Carsten Dominik's message of "Fri, 29 Feb 2008 11:09:34 +0100") List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Carsten Dominik Cc: emacs-orgmode@gnu.org You can slice a single table full of calculations in different ways into separate destinations. Or you can format the table differently. There are many fun and exciting possible uses. Signed-off-by: Jason Riedy --- > I think the easiest would be to write a little lisp program that > switches the SEND lines above the table through a number of states > and then calls the exporter. Tricking out the exporter was surprisingly simple once I thought about it... org.el | 127 ++++++++++++++++++++++++++++++++++++-------------------------- org.texi | 6 ++- 2 files changed, 78 insertions(+), 55 deletions(-) diff --git a/org.el b/org.el index 4e27ecc..6d52fdf 100644 --- a/org.el +++ b/org.el @@ -11660,6 +11660,41 @@ overwritten, and the table is not marked as requiring realignment." (push (> (/ (apply '+ (mapcar (lambda (x) (if (string-match org-table-number-regexp x) 1 0)) column)) maxcol) org-table-number-fraction) org-table-last-alignment)) (funcall func table nil))) +(defun orgtbl-gather-send-defs () + "Gathers a plist of :name, :transform, :params for each destination before +a radio table." + (save-excursion + (goto-char (org-table-begin)) + (let (rtn) + (beginning-of-line 0) + (while (looking-at "#\\+ORGTBL: *SEND +\\([a-zA-Z0-9_]+\\) +\\([^ \t\r\n]+\\)\\( +.*\\)?") + (let ((name (org-no-properties (match-string 1))) + (transform (intern (match-string 2))) + (params (if (match-end 3) + (read (concat "(" (match-string 3) ")"))))) + (push (list :name name :transform transform :params params) + rtn) + (beginning-of-line 0))) + rtn))) + +(defun orgtbl-send-replace-tbl (name txt) + "Find and replace table NAME with TXT." + (save-excursion + (goto-char (point-min)) + (unless (re-search-forward + (concat "BEGIN RECEIVE ORGTBL +" name "\\([ \t]\\|$\\)") nil t) + (error "Don't know where to insert translated table")) + (goto-char (match-beginning 0)) + (beginning-of-line 2) + (save-excursion + (let ((beg (point))) + (unless (re-search-forward + (concat "END RECEIVE ORGTBL +" name) nil t) + (error "Cannot find end of insertion region")) + (beginning-of-line 1) + (delete-region beg (point)))) + (insert txt "\n"))) + (defun orgtbl-send-table (&optional maybe) "Send a tranformed version of this table to the receiver position. With argument MAYBE, fail quietly if no transformation is defined for @@ -11669,59 +11704,45 @@ this table." (unless (org-at-table-p) (error "Not at a table")) ;; when non-interactive, we assume align has just happened. (when (interactive-p) (org-table-align)) - (save-excursion - (goto-char (org-table-begin)) - (beginning-of-line 0) - (unless (looking-at "#\\+ORGTBL: *SEND +\\([a-zA-Z0-9_]+\\) +\\([^ \t\r\n]+\\)\\( +.*\\)?") - (if maybe - (throw 'exit nil) - (error "Don't know how to transform this table.")))) - (let* ((name (match-string 1)) - beg - (transform (intern (match-string 2))) - (params (if (match-end 3) (read (concat "(" (match-string 3) ")")))) - (skip (plist-get params :skip)) - (skipcols (plist-get params :skipcols)) - (txt (buffer-substring-no-properties - (org-table-begin) (org-table-end))) - (lines (nthcdr (or skip 0) (org-split-string txt "[ \t]*\n[ \t]*"))) - (lines (org-table-clean-before-export lines)) - (i0 (if org-table-clean-did-remove-column 2 1)) - (table (mapcar - (lambda (x) - (if (string-match org-table-hline-regexp x) - 'hline - (org-remove-by-index - (org-split-string (org-trim x) "\\s-*|\\s-*") - skipcols i0))) - lines)) - (fun (if (= i0 2) 'cdr 'identity)) - (org-table-last-alignment - (org-remove-by-index (funcall fun org-table-last-alignment) - skipcols i0)) - (org-table-last-column-widths - (org-remove-by-index (funcall fun org-table-last-column-widths) - skipcols i0))) - - (unless (fboundp transform) - (error "No such transformation function %s" transform)) - (setq txt (funcall transform table params)) - ;; Find the insertion place - (save-excursion - (goto-char (point-min)) - (unless (re-search-forward - (concat "BEGIN RECEIVE ORGTBL +" name "\\([ \t]\\|$\\)") nil t) - (error "Don't know where to insert translated table")) - (goto-char (match-beginning 0)) - (beginning-of-line 2) - (setq beg (point)) - (unless (re-search-forward (concat "END RECEIVE ORGTBL +" name) nil t) - (error "Cannot find end of insertion region")) - (beginning-of-line 1) - (delete-region beg (point)) - (goto-char beg) - (insert txt "\n")) - (message "Table converted and installed at receiver location")))) + (let ((dests (orgtbl-gather-send-defs)) + (txt (buffer-substring-no-properties (org-table-begin) + (org-table-end))) + (ntbl 0)) + (unless dests (if maybe (throw 'exit nil) + (error "Don't know how to transform this table."))) + (dolist (dest dests) + (let* ((name (plist-get dest :name)) + (transform (plist-get dest :transform)) + (params (plist-get dest :params)) + (skip (plist-get params :skip)) + (skipcols (plist-get params :skipcols)) + beg + (lines (org-table-clean-before-export + (nthcdr (or skip 0) + (org-split-string txt "[ \t]*\n[ \t]*")))) + (i0 (if org-table-clean-did-remove-column 2 1)) + (table (mapcar + (lambda (x) + (if (string-match org-table-hline-regexp x) + 'hline + (org-remove-by-index + (org-split-string (org-trim x) "\\s-*|\\s-*") + skipcols i0))) + lines)) + (fun (if (= i0 2) 'cdr 'identity)) + (org-table-last-alignment + (org-remove-by-index (funcall fun org-table-last-alignment) + skipcols i0)) + (org-table-last-column-widths + (org-remove-by-index (funcall fun org-table-last-column-widths) + skipcols i0)) + (txt (if (fboundp transform) + (funcall transform table params) + (error "No such transformation function %s" transform)))) + (orgtbl-send-replace-tbl name txt)) + (setq ntbl (1+ ntbl))) + (message "Table converted and installed at %d receiver location%s" + ntbl (if (> ntbl 1) "s" ""))))) (defun org-remove-by-index (list indices &optional i0) "Remove the elements in LIST with indices in INDICES. diff --git a/org.texi b/org.texi index eae2db0..ac58508 100644 --- a/org.texi +++ b/org.texi @@ -8124,8 +8124,10 @@ in the receiver lines. @code{translation_function} is the Lisp function that does the translation. Furthermore, the line can contain a list of arguments (alternating key and value) at the end. The arguments will be passed as a property list to the translation function for -interpretation. A few standard parameters are already recognized and -acted upon before the translation function is called: +interpretation. Multiple @code{#+ORGTBL: SEND} lines with different +@code{table_name}s send the table's data to separate destinations. A +few standard parameters are already recognized and acted upon before the +translation function is called: @table @code @item :skip N -- 1.5.4.3