emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATCH] Support last-line specializers.
@ 2008-03-03  0:37 Jason Riedy
  2008-03-03  5:36 ` [respun PATCH 2/3] " jason
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Riedy @ 2008-03-03  0:37 UTC (permalink / raw)
  To: emacs-orgmode

Each of lstart, lend, and lfmt permits a last-line specialization
called llstart, etc. with corresponding heading versions.

Signed-off-by: Jason Riedy <jason@acm.org>
---
   I forgot to save the message id for my rearrangement patch, but
   this patch relies on that one.

 org.el |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/org.el b/org.el
index 64121c9..44c19d4 100644
--- a/org.el
+++ b/org.el
@@ -11792,9 +11792,13 @@ First element has index 0, or I0 if given."
 
 (defun orgtbl-format-section (section-stopper)
   "Format lines until the first occurrence of SECTION-STOPPER."
-  (progn
-    (while (not (eq (car table) section-stopper))
-      (orgtbl-format-line (pop table)))))
+  (let (prevline)
+    (progn
+      (while (not (eq (car table) section-stopper))
+	(if prevline (orgtbl-format-line prevline))
+	(setq prevline (pop table)))
+      (if prevline (let ((lstart llstart) (lend llend) (lfmt llfmt))
+		     (orgtbl-format-line prevline))))))
 
 (defun orgtbl-to-generic (table params)
   "Convert the orgtbl-mode TABLE to some other format.
@@ -11818,17 +11822,20 @@ Valid parameters are
             May be nil to ignore hlines.
 
 :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
 :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.
 :fmt        A format to be used to wrap the field, should contain
             %s for the original field value.  For example, to wrap
             everything in dollars, you could use :fmt \"$%s$\".
             This may also be a property list with column numbers and
             formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\")
 
-:hlstart :hlend :hsep :hlfmt :hfmt
+:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt
             Same as above, specific for the header lines in the table.
             All lines before the first hline are treated as header.
             If any of these is not present, the data line value is used.
@@ -11847,8 +11854,11 @@ directly by `orgtbl-send-table'.  See manual."
 	 (sep (plist-get params :sep))
 	 (efmt (plist-get params :efmt))
 	 (lstart (plist-get params :lstart))
+	 (llstart (or (plist-get params :llstart) lstart))
 	 (lend (plist-get params :lend))
+	 (llend (or (plist-get params :llend) lend))
 	 (lfmt (plist-get params :lfmt))
+	 (llfmt (or (plist-get params :llfmt) lfmt))
 	 (fmt (plist-get params :fmt))
 	 rtn)
 
@@ -11860,10 +11870,13 @@ directly by `orgtbl-send-table'.  See manual."
     ;; trailing hline.
     (if (and (not splicep) (listp (car table)) (memq 'hline table))
 	(progn
-	  (let* ((lstart (or (plist-get params :hlstart) lstart))
-		 (lend (or (plist-get params :hlend) lend))
-		 (lfmt (or (plist-get params :hlfmt) lfmt))
-		 (fmt (or (plist-get params :hfmt) fmt)))
+	  (let ((lstart (or (plist-get params :hlstart) lstart))
+		(llstart (or (plist-get params :hllstart) llstart))
+		(lend (or (plist-get params :hlend) lend))
+		(llend (or (plist-get params :hllend) llend))
+		(lfmt (or (plist-get params :hlfmt) lfmt))
+		(llfmt (or (plist-get params :hllfmt) llfmt))
+		(fmt (or (plist-get params :hfmt) fmt)))
 	    (orgtbl-format-section 'hline))
 	  (if hline (push hline rtn))
 	  (pop table)))
@@ -11897,6 +11910,9 @@ LaTeX are:
            example \"%s\\\\times10^{%s}\".  LaTeX default is \"%s\\\\,(%s)\".
            This may also be a property list with column numbers and formats.
 
+:llend     If you find too much space below the last line of a table,
+           pass a value of \"\" for :llend to suppress the final \\\\.
+
 The general parameters :skip and :skipcols have already been applied when
 this function is called."
   (let* ((alignment (mapconcat (lambda (x) (if x "r" "l"))
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [respun PATCH 2/3] Support last-line specializers.
  2008-03-03  0:37 [PATCH] Support last-line specializers Jason Riedy
@ 2008-03-03  5:36 ` jason
  2008-03-03  5:51   ` [PATCH 3/3] Allow functions for some orgtbl parameters Jason Riedy
  0 siblings, 1 reply; 4+ messages in thread
From: jason @ 2008-03-03  5:36 UTC (permalink / raw)
  To: emacs-orgmode

Each of lstart, lend, and lfmt permits a last-line specialization
called llstart, etc. with corresponding heading versions.

Signed-off-by: Jason Riedy <jason@acm.org>
---
  Argh.  Already found one problem: I didn't fall back to non-last-line
  properties when appropriate.

 org.el |   34 ++++++++++++++++++++++++++--------
 1 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/org.el b/org.el
index 64121c9..f38f6ae 100644
--- a/org.el
+++ b/org.el
@@ -11792,9 +11792,13 @@ First element has index 0, or I0 if given."
 
 (defun orgtbl-format-section (section-stopper)
   "Format lines until the first occurrence of SECTION-STOPPER."
-  (progn
-    (while (not (eq (car table) section-stopper))
-      (orgtbl-format-line (pop table)))))
+  (let (prevline)
+    (progn
+      (while (not (eq (car table) section-stopper))
+	(if prevline (orgtbl-format-line prevline))
+	(setq prevline (pop table)))
+      (if prevline (let ((lstart llstart) (lend llend) (lfmt llfmt))
+		     (orgtbl-format-line prevline))))))
 
 (defun orgtbl-to-generic (table params)
   "Convert the orgtbl-mode TABLE to some other format.
@@ -11818,17 +11822,20 @@ Valid parameters are
             May be nil to ignore hlines.
 
 :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
 :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.
 :fmt        A format to be used to wrap the field, should contain
             %s for the original field value.  For example, to wrap
             everything in dollars, you could use :fmt \"$%s$\".
             This may also be a property list with column numbers and
             formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\")
 
-:hlstart :hlend :hsep :hlfmt :hfmt
+:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt
             Same as above, specific for the header lines in the table.
             All lines before the first hline are treated as header.
             If any of these is not present, the data line value is used.
@@ -11847,8 +11854,11 @@ directly by `orgtbl-send-table'.  See manual."
 	 (sep (plist-get params :sep))
 	 (efmt (plist-get params :efmt))
 	 (lstart (plist-get params :lstart))
+	 (llstart (or (plist-get params :llstart) lstart))
 	 (lend (plist-get params :lend))
+	 (llend (or (plist-get params :llend) lend))
 	 (lfmt (plist-get params :lfmt))
+	 (llfmt (or (plist-get params :llfmt) lfmt))
 	 (fmt (plist-get params :fmt))
 	 rtn)
 
@@ -11860,10 +11870,15 @@ directly by `orgtbl-send-table'.  See manual."
     ;; trailing hline.
     (if (and (not splicep) (listp (car table)) (memq 'hline table))
 	(progn
-	  (let* ((lstart (or (plist-get params :hlstart) lstart))
-		 (lend (or (plist-get params :hlend) lend))
-		 (lfmt (or (plist-get params :hlfmt) lfmt))
-		 (fmt (or (plist-get params :hfmt) fmt)))
+	  (let ((lstart (or (plist-get params :hlstart) lstart))
+		(llstart (or (plist-get params :hllstart) llstart))
+		(lend (or (plist-get params :hlend) lend))
+		(llend (or (plist-get params :hllend)
+			   (plist-get params :hlend) llend))
+		(lfmt (or (plist-get params :hlfmt) lfmt))
+		(llfmt (or (plist-get params :hllfmt)
+			   (plist-get params :hlfmt) llfmt))
+		(fmt (or (plist-get params :hfmt) fmt)))
 	    (orgtbl-format-section 'hline))
 	  (if hline (push hline rtn))
 	  (pop table)))
@@ -11897,6 +11912,9 @@ LaTeX are:
            example \"%s\\\\times10^{%s}\".  LaTeX default is \"%s\\\\,(%s)\".
            This may also be a property list with column numbers and formats.
 
+:llend     If you find too much space below the last line of a table,
+           pass a value of \"\" for :llend to suppress the final \\\\.
+
 The general parameters :skip and :skipcols have already been applied when
 this function is called."
   (let* ((alignment (mapconcat (lambda (x) (if x "r" "l"))
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] Allow functions for some orgtbl parameters.
  2008-03-03  5:36 ` [respun PATCH 2/3] " jason
@ 2008-03-03  5:51   ` Jason Riedy
  2008-03-03  6:06     ` How I'm using these: Generating SQL insert statements Jason Riedy
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Riedy @ 2008-03-03  5:51 UTC (permalink / raw)
  To: emacs-orgmode

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>
---
 org.el   |   38 ++++++++++++++++++++++++++++++--------
 org.texi |    5 ++++-
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/org.el b/org.el
index f38f6ae..6f17f1e 100644
--- a/org.el
+++ b/org.el
@@ -11778,16 +11778,26 @@ First element has index 0, or I0 if given."
 	    (mapcar
 	     (lambda (f)
 	       (setq i (1+ i))
-	       (let* ((fmt (if (consp fmt) (plist-get fmt i) fmt))
-		      (efmt (if (consp efmt) (plist-get efmt i) efmt))
+	       (let* ((fmt (if (and (not (functionp fmt)) (consp fmt))
+			       (plist-get fmt i) fmt))
+		      (efmt (if (and (not (functionp efmt)) (consp efmt))
+				(plist-get efmt i) efmt))
 		      (f (if (and efmt (string-match orgtbl-exp-regexp f))
-			     (format efmt (match-string 1 f)
-					  (match-string 2 f))
+			     (if (functionp efmt) (funcall efmt
+							   (match-string 1 f)
+							   (match-string 2 f))
+			       (format efmt (match-string 1 f)
+				       (match-string 2 f)))
 			   f)))
-		 (if fmt (format fmt f) f)))
+		 (cond ((functionp fmt) (funcall fmt f))
+		       (fmt (format fmt f))
+		       (t f))))
 	     line)))
-      (push (if lfmt (apply 'format lfmt line)
-	      (concat lstart (mapconcat 'identity line sep) lend))
+      (push (cond ((functionp lfmt) (funcall lfmt line))
+		  (lfmt (apply 'format lfmt line))
+		  (t (concat (if (functionp lstart) (funcall lstart) lstart)
+			     (mapconcat 'identity line sep)
+			     (if (functionp lend) (funcall lend) lend))))
 	    rtn))))
 
 (defun orgtbl-format-section (section-stopper)
@@ -11821,11 +11831,18 @@ Valid parameters are
 :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:
 :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.
@@ -11840,6 +11857,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
@@ -11906,11 +11924,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 \\\\.
@@ -11972,6 +11992,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
diff --git a/org.texi b/org.texi
index eae2db0..2ab0dda 100644
--- a/org.texi
+++ b/org.texi
@@ -8255,6 +8255,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
@@ -8263,7 +8265,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
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* How I'm using these: Generating SQL insert statements.
  2008-03-03  5:51   ` [PATCH 3/3] Allow functions for some orgtbl parameters Jason Riedy
@ 2008-03-03  6:06     ` Jason Riedy
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Riedy @ 2008-03-03  6:06 UTC (permalink / raw)
  To: emacs-orgmode

This code is only partially baked, but it's working for me at the
moment.  I'm using my multi-target changes to generate both a
LaTeX description of the values as well as SQL insert statements
in separate noweb chunks.  The code leaves a spare blank line
in place of the header and cannot handle more than one header line,
but it's all I need...

Jason

(defun ejr/orgtbl-to-sqlinsert (table params)
  "Convert the orgtbl-mode TABLE to SQL insert statements.
TABLE is a list, each entry either the symbol `hline' for a horizontal
separator line, or a list of fields for that line.
PARAMS is a property list of parameters that can influence the conversion.
Supports all parameters from `orgtbl-to-generic'.  Most important for
SQL are:

:splice    When set to t, return only insert statements, don't wrap
           them in a transaction.  Default is nil.

:sqlname   The name of the database table; defaults to the name of the
           target region.

:tstart, :tend
           The strings used to begin and commit the transaction.

:fmt       A format to be used to wrap the field value, should contain %s
           for the original field value.  The default wraps the
           value in the non-standard [] quote marks but does not
           protect against ] characters in the header name.  The
           format may also be a function that formats its one
           argument.

:hfmt      A function that gathers the []-quoted header names into a
           dynamically scoped variable HDRLIST.

The general parameters :skip and :skipcols have already been applied when
this function is called."
  (let* (hdrlist
	 (alignment (mapconcat (lambda (x) (if x "r" "l"))
			       org-table-last-alignment ""))
	 (params2
	  (list
	   :sqlname name
	   :tstart "BEGIN TRANSACTION;"
	   :tend "COMMIT;"
	   :fmt "[%s]"
	   :hfmt (lambda (f) (push (concat "[" f "]") hdrlist) "")
	   :hlfmt (lambda (lst) nil)
	   :lstart (lambda () (concat "INSERT INTO "
				      (plist-get params :sqlname) "( "
				      (mapconcat 'identity (reverse hdrlist)
						 ", ")
				      " ) VALUES ( "))
	   :lend " );"
	   :sep " , "
	   :hline nil)))
    (orgtbl-to-generic table (org-combine-plists params2 params))))

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-03-03  6:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-03  0:37 [PATCH] Support last-line specializers Jason Riedy
2008-03-03  5:36 ` [respun PATCH 2/3] " jason
2008-03-03  5:51   ` [PATCH 3/3] Allow functions for some orgtbl parameters Jason Riedy
2008-03-03  6:06     ` How I'm using these: Generating SQL insert statements Jason Riedy

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).