From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jason Riedy Subject: [PATCH 1/4] Refactor orgtbl-to-generic; explicitly separate heading from body. Date: Wed, 16 Apr 2008 14:39:51 -0700 Message-ID: <1208381994-7893-2-git-send-email-jason@acm.org> References: <1208381994-7893-1-git-send-email-jason@acm.org> Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JmFMN-0000HR-BQ for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:07 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JmFMK-0000Fi-Cw for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:05 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JmFMJ-0000FT-Oy for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:04 -0400 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 1JmFMI-0007em-77 for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:02 -0400 Received: from localhost.localdomain (209-204-163-7.vpn.sonic.net [209.204.163.7]) (authenticated bits=0) by a.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with ESMTP id m3GLduO4002451 for ; Wed, 16 Apr 2008 14:40:00 -0700 In-Reply-To: <1208381994-7893-1-git-send-email-jason@acm.org> 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: emacs-orgmode@gnu.org Parameters are fluidly bound as early as possible. Added one helper function, orgtbl-format-section, and removed one, org-get-param. Also cleaned org-format-line. Signed-off-by: Jason Riedy --- ChangeLog | 16 +++++++ lisp/org-table.el | 124 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ae71a9..4569d3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-04-15 Jason Riedy + + * lisp/org-table.el (*orgtbl-table*, *orgtbl-rtn*): Dynamically + bound variables to hold the input collection of lines and output + formatted text. + (*orgtbl-hline*, *orgtbl-sep*, *orgtbl-fmt*, *orgtbl-efmt*, + (*orgtbl-lfmt*, *orgtbl-lstart*, *orgtbl-lend*): Dynamically bound + format parameters. + (orgtbl-format-line): New function encapsulating formatting for a + single line. + (orgtbl-format-section): Similar for each section. Rebinding the + dynamic vars customizes the formatting for each section. + (orgtbl-to-generic): Use orgtbl-format-line and + orgtbl-format-section. + (org-get-param): Now unused, so delete. + 2008-04-15 Carsten Dominik * lisp/org-agenda.el (org-agenda-columns-show-summaries) diff --git a/lisp/org-table.el b/lisp/org-table.el index 1e1bd85..3cc70c1 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -3602,15 +3602,51 @@ First element has index 0, or I0 if given." (insert txt) (goto-char pos))) -(defun org-get-param (params header i sym &optional hsym) - "Get parameter value for symbol SYM. -If this is a header line, actually get the value for the symbol with an -additional \"h\" inserted after the colon. -If the value is a protperty list, get the element for the current column. -Assumes variables VAL, PARAMS, HEAD and I to be scoped into the function." - (let ((val (plist-get params sym))) - (and hsym header (setq val (or (plist-get params hsym) val))) - (if (consp val) (plist-get val i) val))) +;; Dynamically bound input and output for table formatting. +(defvar *orgtbl-table* nil + "Carries the current table through formatting routines.") +(defvar *orgtbl-rtn* nil + "Formatting routines push the output lines here.") +;; Formatting parameters for the current table section. +(defvar *orgtbl-hline* nil "Text used for horizontal lines") +(defvar *orgtbl-sep* nil "Text used as a column separator") +(defvar *orgtbl-fmt* nil "Format for each entry") +(defvar *orgtbl-efmt* nil "Format for numbers") +(defvar *orgtbl-lfmt* nil "Format for an entire line, overrides fmt") +(defvar *orgtbl-lstart* nil "Text starting a row") +(defvar *orgtbl-lend* nil "Text ending a row") + +(defun orgtbl-format-line (line) + "Format LINE as a table row." + (if (eq line 'hline) (if *orgtbl-hline* (push *orgtbl-hline* *orgtbl-rtn*)) + (let* ((i 0) + (line + (mapcar + (lambda (f) + (setq i (1+ i)) + (let* ((*orgtbl-fmt* (if (consp *orgtbl-fmt*) + (plist-get *orgtbl-fmt* i) + *orgtbl-fmt*)) + (*orgtbl-efmt* (if (consp *orgtbl-efmt*) + (plist-get *orgtbl-efmt* i) + *orgtbl-efmt*)) + (f (if (and *orgtbl-efmt* + (string-match orgtbl-exp-regexp f)) + (format *orgtbl-efmt* (match-string 1 f) + (match-string 2 f)) + f))) + (if *orgtbl-fmt* (format *orgtbl-fmt* f) f))) + line))) + (push (if *orgtbl-lfmt* (apply 'format *orgtbl-lfmt* line) + (concat *orgtbl-lstart* (mapconcat 'identity line *orgtbl-sep*) + *orgtbl-lend*)) + *orgtbl-rtn*)))) + +(defun orgtbl-format-section (section-stopper) + "Format lines until the first occurrence of SECTION-STOPPER." + (progn + (while (not (eq (car *orgtbl-table*) section-stopper)) + (orgtbl-format-line (pop *orgtbl-table*))))) (defun orgtbl-to-generic (table params) "Convert the orgtbl-mode TABLE to some other format. @@ -3658,51 +3694,43 @@ Valid parameters are In addition to this, the parameters :skip and :skipcols are always handled directly by `orgtbl-send-table'. See manual." (interactive) - (let* ((p params) - (splicep (plist-get p :splice)) - (hline (plist-get p :hline)) - rtn line i fm efm lfmt h) - - ;; Do we have a header? - (if (and (not splicep) (listp (car table)) (memq 'hline table)) - (setq h t)) + (let* ((splicep (plist-get params :splice)) + (hline (plist-get params :hline)) + (*orgtbl-table* table) + (*orgtbl-sep* (plist-get params :sep)) + (*orgtbl-efmt* (plist-get params :efmt)) + (*orgtbl-lstart* (plist-get params :lstart)) + (*orgtbl-lend* (plist-get params :lend)) + (*orgtbl-lfmt* (plist-get params :lfmt)) + (*orgtbl-fmt* (plist-get params :fmt)) + *orgtbl-rtn*) ;; Put header (unless splicep - (push (or (plist-get p :tstart) "ERROR: no :tstart") rtn)) - - ;; Now loop over all lines - (while (setq line (pop table)) - (if (eq line 'hline) - ;; A horizontal separator line - (progn (if hline (push hline rtn)) - (setq h nil)) ; no longer in header - ;; A normal line. Convert the fields, push line onto the result list - (setq i 0) - (setq line - (mapcar - (lambda (f) - (setq i (1+ i) - fm (org-get-param p h i :fmt :hfmt) - efm (org-get-param p h i :efmt)) - (if (and efm (string-match orgtbl-exp-regexp f)) - (setq f (format - efm (match-string 1 f) (match-string 2 f)))) - (if fm (setq f (format fm f))) - f) - line)) - (if (setq lfmt (org-get-param p h i :lfmt :hlfmt)) - (push (apply 'format lfmt line) rtn) - (push (concat - (org-get-param p h i :lstart :hlstart) - (mapconcat 'identity line (org-get-param p h i :sep :hsep)) - (org-get-param p h i :lend :hlend)) - rtn)))) + (push (or (plist-get params :tstart) "ERROR: no :tstart") *orgtbl-rtn*)) + + ;; Do we have a heading section? If so, format it and handle the + ;; trailing hline. + (if (and (not splicep) (listp (car *orgtbl-table*)) + (memq 'hline *orgtbl-table*)) + (progn + (let* ((*orgtbl-lstart* (or (plist-get params :hlstart) + *orgtbl-lstart*)) + (*orgtbl-lend* (or (plist-get params :hlend) *orgtbl-lend*)) + (*orgtbl-lfmt* (or (plist-get params :hlfmt) *orgtbl-lfmt*)) + (*orgtbl-sep* (or (plist-get params :hlsep) *orgtbl-sep*)) + (*orgtbl-fmt* (or (plist-get params :hfmt) *orgtbl-fmt*))) + (orgtbl-format-section 'hline)) + (if hline (push hline *orgtbl-rtn*)) + (pop *orgtbl-table*))) + + ;; Now format the main section. + (orgtbl-format-section nil) (unless splicep - (push (or (plist-get p :tend) "ERROR: no :tend") rtn)) + (push (or (plist-get params :tend) "ERROR: no :tend") *orgtbl-rtn*)) - (mapconcat 'identity (nreverse rtn) "\n"))) + (mapconcat 'identity (nreverse *orgtbl-rtn*) "\n"))) (defun orgtbl-to-latex (table params) "Convert the orgtbl-mode TABLE to LaTeX. -- 1.5.5.rc1.121.g1594