From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jason Riedy Subject: [PATCH 3/4] Allow functions for some orgtbl parameters. Date: Wed, 16 Apr 2008 14:39:53 -0700 Message-ID: <1208381994-7893-4-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 1JmFMP-0000IE-OQ for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:10 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JmFMM-0000GS-AI for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:07 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JmFMK-0000GB-T9 for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:05 -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 1JmFMJ-0007ev-3A for emacs-orgmode@gnu.org; Wed, 16 Apr 2008 17:40:03 -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 m3GLduO6002451 for ; Wed, 16 Apr 2008 14:40:01 -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 Functions and dynamic binding permit some fun uses, including gathering up header names for use in SQL insert statements. Signed-off-by: Jason Riedy --- ChangeLog | 14 +++++++++++ doc/org.texi | 5 +++- lisp/org-table.el | 67 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13980bf..1347715 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2008-04-15 Jason Riedy + * lisp/org-table.el (orgtbl-get-fmt): New inline function for + picking apart formats that may be lists. + (orgtbl-apply-fmt): New inline function for applying formats that + may be functions. + (orgtbl-eval-str): New inline function for strings that may be + functions. + (orgtbl-format-line, orgtbl-to-generic): Use and document. + (orgtbl-to-latex, orgtbl-to-texinfo): Document. + + * doc/org.texi (A LaTeX example): Note that fmt may be a + one-argument function, and efmt may be a two-argument function. + +2008-04-15 Jason Riedy + * lisp/org-table.el (*orgtbl-llfmt*, *orgtbl-llstart*) (*orgtbl-llend*): Dynamic variables for last-line formatting. (orgtbl-format-section): Shift formatting to support detecting the diff --git a/doc/org.texi b/doc/org.texi index c9eaab9..9c9b081 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -8528,6 +8528,8 @@ A format to be used to wrap each field, should contain @code{%s} for the original field value. For example, to wrap each field value in dollars, you could use @code{:fmt "$%s$"}. This may also be a property list with column numbers and formats. for example @code{:fmt (2 "$%s$" 4 "%s\\%%")}. +A function of one argument can be used in place of the strings; the +function must return a formatted string. @item :efmt efmt Use this format to print numbers with exponentials. The format should @@ -8536,7 +8538,8 @@ have @code{%s} twice for inserting mantissa and exponent, for example may also be a property list with column numbers and formats, for example @code{:efmt (2 "$%s\\times10^@{%s@}$" 4 "$%s\\cdot10^@{%s@}$")}. After @code{efmt} has been applied to a value, @code{fmt} will also be -applied. +applied. Similar to @code{fmt}, functions of two arguments can be +supplied instead of strings. @end table @node Translator functions, Radio lists, A LaTeX example, Tables in arbitrary syntax diff --git a/lisp/org-table.el b/lisp/org-table.el index 2eb9938..4ae90e3 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -3619,6 +3619,25 @@ First element has index 0, or I0 if given." (defvar *orgtbl-lend* nil "Text ending a row") (defvar *orgtbl-llend* nil "Specializes lend for the last row") +(defsubst orgtbl-get-fmt (fmt i) + "Retrieve the format from FMT corresponding to the Ith column." + (if (and (not (functionp fmt)) (consp fmt)) + (plist-get fmt i) + fmt)) + +(defsubst orgtbl-apply-fmt (fmt &rest args) + "Apply format FMT to the arguments. NIL FMTs return the first argument." + (cond ((functionp fmt) (apply fmt args)) + (fmt (apply 'format fmt args)) + (args (car args)) + (t args))) + +(defsubst orgtbl-eval-str (str) + "If STR is a function, evaluate it with no arguments." + (if (functionp str) + (funcall str) + str)) + (defun orgtbl-format-line (line) "Format LINE as a table row." (if (eq line 'hline) (if *orgtbl-hline* (push *orgtbl-hline* *orgtbl-rtn*)) @@ -3627,22 +3646,18 @@ First element has index 0, or I0 if given." (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)) + (let* ((efmt (orgtbl-get-fmt *orgtbl-efmt* i)) + (f (if (and efmt (string-match orgtbl-exp-regexp f)) + (orgtbl-apply-fmt efmt (match-string 1 f) + (match-string 2 f)) f))) - (if *orgtbl-fmt* (format *orgtbl-fmt* f) f))) + (orgtbl-apply-fmt (orgtbl-get-fmt *orgtbl-fmt* i) f))) line))) - (push (if *orgtbl-lfmt* (apply 'format *orgtbl-lfmt* line) - (concat *orgtbl-lstart* (mapconcat 'identity line *orgtbl-sep*) - *orgtbl-lend*)) + (push (if *orgtbl-lfmt* + (orgtbl-apply-fmt *orgtbl-lfmt* line) + (concat (orgtbl-eval-str *orgtbl-lstart*) + (mapconcat 'identity line *orgtbl-sep*) + (orgtbl-eval-str *orgtbl-lend*))) *orgtbl-rtn*)))) (defun orgtbl-format-section (section-stopper) @@ -3669,20 +3684,27 @@ specify either :lfmt, or all of (:lstart :lend :sep). If you do not use Valid parameters are -:tstart String to start the table. Ignored when :splice is t. -:tend String to end the table. Ignored when :splice is t. - :splice When set to t, return only table body lines, don't wrap them into :tstart and :tend. Default is nil. :hline String to be inserted on horizontal separation lines. May be nil to ignore hlines. +:sep Separator between two fields + + Each in the following group may be either a string or a function + of no arguments returning a string: +:tstart String to start the table. Ignored when :splice is t. +:tend String to end the table. Ignored when :splice is t. :lstart String to start a new table line. :llstart String to start the last table line, defaults to :lstart. :lend String to end a table line :llend String to end the last table line, defaults to :lend. :sep Separator between two fields + + Each in the following group may be a string, a function of one + argument (the field or line) returning a string, or a plist + mapping columns to either of the above: :lfmt Format for entire line, with enough %s to capture all fields. If this is present, :lstart, :lend, and :sep are ignored. :llfmt Format for the entire last line, defaults to :lfmt. @@ -3697,6 +3719,7 @@ Valid parameters are All lines before the first hline are treated as header. If any of these is not present, the data line value is used. + This may be either a string or a function of two arguments: :efmt Use this format to print numbers with exponentials. The format should have %s twice for inserting mantissa and exponent, for example \"%s\\\\times10^{%s}\". This @@ -3722,7 +3745,8 @@ directly by `orgtbl-send-table'. See manual." ;; Put header (unless splicep - (push (or (plist-get params :tstart) "ERROR: no :tstart") *orgtbl-rtn*)) + (push (or (orgtbl-eval-str (plist-get params :tstart)) + "ERROR: no :tstart") *orgtbl-rtn*)) ;; Do we have a heading section? If so, format it and handle the ;; trailing hline. @@ -3749,7 +3773,8 @@ directly by `orgtbl-send-table'. See manual." (orgtbl-format-section nil) (unless splicep - (push (or (plist-get params :tend) "ERROR: no :tend") *orgtbl-rtn*)) + (push (or (orgtbl-eval-str (plist-get params :tend)) + "ERROR: no :tend") *orgtbl-rtn*)) (mapconcat 'identity (nreverse *orgtbl-rtn*) "\n"))) @@ -3768,11 +3793,13 @@ LaTeX are: original field value. For example, to wrap everything in dollars, use :fmt \"$%s$\". This may also be a property list with column numbers and formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\") + The format may also be a function that formats its one argument. :efmt Format for transforming numbers with exponentials. The format should have %s twice for inserting mantissa and exponent, for example \"%s\\\\times10^{%s}\". LaTeX default is \"%s\\\\,(%s)\". This may also be a property list with column numbers and formats. + The format may also be a function that formats its two arguments. :llend If you find too much space below the last line of a table, pass a value of \"\" for :llend to suppress the final \\\\. @@ -3834,6 +3861,8 @@ TeXInfo are: everything in @kbd{}, you could use :fmt \"@kbd{%s}\". This may also be a property list with column numbers and formats. For example :fmt (2 \"@kbd{%s}\" 4 \"@code{%s}\"). + Each format also may be a function that formats its one + argument. :cf \"f1 f2..\" The column fractions for the table. By default these are computed automatically from the width of the columns -- 1.5.5.rc1.121.g1594