emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Jason Riedy <jason@acm.org>
To: emacs-orgmode@gnu.org
Subject: [PATCH 3/4] Allow functions for some orgtbl parameters.
Date: Wed, 16 Apr 2008 14:39:53 -0700	[thread overview]
Message-ID: <1208381994-7893-4-git-send-email-jason@acm.org> (raw)
In-Reply-To: <1208381994-7893-1-git-send-email-jason@acm.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 <jason@acm.org>
---
 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  <jason@acm.org>
 
+	* 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  <jason@acm.org>
+
 	* 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

  parent reply	other threads:[~2008-04-16 21:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-16 21:39 [PATCH 0/4] Generalize orgtbl formatting with functions Jason Riedy
2008-04-16 21:39 ` [PATCH 1/4] Refactor orgtbl-to-generic; explicitly separate heading from body Jason Riedy
2008-04-16 21:39 ` [PATCH 2/4] Support last-line specializers Jason Riedy
2008-04-16 21:39 ` Jason Riedy [this message]
2008-04-16 21:39 ` [PATCH 4/4] Add a :remove-nil-lines parameter to orgtbl-to-generic Jason Riedy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1208381994-7893-4-git-send-email-jason@acm.org \
    --to=jason@acm.org \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).