emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] [PATCH 3/4] Allow functions for some orgtbl parameters.


From: Jason Riedy
Subject: [Orgmode] [PATCH 3/4] Allow functions for some orgtbl parameters.
Date: Wed, 16 Apr 2008 14:39:53 -0700

Functions and dynamic binding permit some fun uses, including
gathering up header names for use in SQL insert statements.

Signed-off-by: Jason Riedy <address@hidden>
---
 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  <address@hidden>
 
+       * 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  <address@hidden>
+
        * 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 "address@hidden@}$" 4 "address@hidden@}$")}.  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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]