it misses unit tests, I need to make the collapse optional, and I need
to hear from users what they think of it. this patch allows me to write
a table like the following, having a three-lines header:
| n | data | prove, | casi, | ratio | prove, | casi, |
| | | valore | valore | | media | media |
| | | diario | diario | | corrente | corrente |
|----+------+--------+--------+-------+----------+----------|
and this is seen as a single header line.
| n | data | prove, valore diario | casi, valore diario | ratio |
prove, media corrente | casi, media corrente |
|----+------+----------------------+---------------------+-------+-----------------------+----------------------|
I find it helpful, because this way my columns stay narrower.
as it is, ¡it fails on headerless tables!
I have not yet clear what's the best approach to handling headerless
tables, was thinking of a org-table-max-collapse-header variable, which
you would set to the number of lines which you are maximally expecting
to collapse into the leading header line. Or maybe an extra option to
org-plot, where you would state if headers need be collapsed.
or we already had ways to achieve this same thing, and I missed them all?
best regards,
MF
>From 649f46a591474afb6cef8b9d5151ff6b0bae38aa Mon Sep 17 00:00:00 2001
From: mfrasca <ma...@anche.no>
Date: Fri, 12 Jun 2020 11:42:34 -0500
Subject: [PATCH] lisp/org-table.el: Allow collapsing header into single line
* lisp/org-table.el (org-table-collapse-header): new function
that collapses multiple header lines into one list.
(org-table-to-lisp): simplify code, changing a `while' to a
`cl-loop', remove leading `hline' symbols from result, edit
documentation to reflect change.
* lisp/org-plot.el (org-plot/gnuplot): use
org-table-collapse-header and trust there's no leading `hline'
symbols in lisp table.
---
lisp/org-plot.el | 6 ++---
lisp/org-table.el | 59 ++++++++++++++++++++++++++++++++---------------
2 files changed, 43 insertions(+), 22 deletions(-)
diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index a23195d2a..662d38e54 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -289,11 +289,9 @@ line directly before or after the table."
(setf params (plist-put params (car pair) (cdr pair)))))
;; collect table and table information
(let* ((data-file (make-temp-file "org-plot"))
- (table (org-table-to-lisp))
- (num-cols (length (if (eq (nth 0 table) 'hline) (nth 1 table)
- (nth 0 table)))))
+ (table (org-table-collapse-header (org-table-to-lisp)))
+ (num-cols (length (nth 0 table))))
(run-with-idle-timer 0.1 nil #'delete-file data-file)
- (while (eq 'hline (car table)) (setf table (cdr table)))
(when (eq (cadr table) 'hline)
(setf params
(plist-put params :labels (nth 0 table))) ; headers to labels
diff --git a/lisp/org-table.el b/lisp/org-table.el
index 6462b99c4..6549e178a 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -5433,30 +5433,53 @@ a radio table."
(defun org-table-to-lisp (&optional txt)
"Convert the table at point to a Lisp structure.
-The structure will be a list. Each item is either the symbol `hline'
-for a horizontal separator line, or a list of field values as strings.
-The table is taken from the parameter TXT, or from the buffer at point."
+The returned structure is a list, where each item is either the
+symbol `hline', for a horizontal separator line, or a list of
+field values as strings. The table is taken from the parameter
+TXT, or from the buffer at point. Leading `hline' symbols are
+trimmed, so the first item in the result is a list"
(if txt
(with-temp-buffer
(insert txt)
- (goto-char (point-min))
(org-table-to-lisp))
(save-excursion
(goto-char (org-table-begin))
- (let ((table nil))
- (while (re-search-forward "\\=[ \t]*|" nil t)
- (let ((row nil))
- (if (looking-at "-")
- (push 'hline table)
- (while (not (progn (skip-chars-forward " \t") (eolp)))
- (push (buffer-substring
- (point)
- (progn (re-search-forward "[ \t]*\\(|\\|$\\)")
- (match-beginning 0)))
- row))
- (push (nreverse row) table)))
- (forward-line))
- (nreverse table)))))
+ (let ((table (cl-loop
+ until (not (re-search-forward "\\=[ \t]*|" nil t))
+ collect (if (looking-at "-")
+ 'hline
+ (cl-loop
+ do (skip-chars-forward " \t")
+ collect (buffer-substring
+ (point)
+ (progn (re-search-forward "[ \t]*\\(|\\|$\\)")
+ (match-beginning 0)))
+ until (looking-at "$")))
+ do (forward-line))))
+ (while (equal 'hline (car table))
+ (setq table (cdr table)))
+ table))))
+
+(defun org-table-collapse-header (table &optional glue)
+ "Collapse the lines before 'hline into a single header.
+
+The given TABLE is a list of lists as returned by `org-table-to-lisp'.
+The leading lines before the first `hline' symbol are considered
+forming the table header. This function collapses all leading header
+lines into a single header line, followed by the `hline' symbol, and
+the rest of the TABLE. Header cells are GLUEd together with a space,
+or the given character."
+ (setq glue (or glue " "))
+ (let* ((header (cl-loop for i in table
+ until (equal i 'hline)
+ collect i))
+ (position (length header)))
+ (cons (apply #'cl-mapcar
+ #'(lambda (&rest x)
+ (string-trim
+ (mapconcat #'identity x glue)))
+ header)
+ (nthcdr position table))))
(defun orgtbl-send-table (&optional maybe)
"Send a transformed version of table at point to the receiver position.
--
2.20.1