From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id yCZ4Fve5417/VgAA0tVLHw (envelope-from ) for ; Fri, 12 Jun 2020 17:23:03 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id upg6Eve54146GAAAB5/wlQ (envelope-from ) for ; Fri, 12 Jun 2020 17:23:03 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 5BF5194042C for ; Fri, 12 Jun 2020 17:23:02 +0000 (UTC) Received: from localhost ([::1]:48986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jjnON-0003p7-T2 for larch@yhetil.org; Fri, 12 Jun 2020 13:22:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34594) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jjnNk-0003ib-UP for emacs-orgmode@gnu.org; Fri, 12 Jun 2020 13:22:21 -0400 Received: from latitanza.investici.org ([2001:888:2000:56::19]:63103) by eggs.gnu.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jjnNi-0006T0-0W for emacs-orgmode@gnu.org; Fri, 12 Jun 2020 13:22:20 -0400 Received: from mx3.investici.org (unknown [127.0.0.1]) by latitanza.investici.org (Postfix) with ESMTP id 8FE1E120171; Fri, 12 Jun 2020 17:14:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anche.no; s=stigmate; t=1591982083; bh=f8PB9Wn3xcUOzFzMA9yjajHJYcw8qQIHIB+itFz7lEs=; h=To:From:Subject:Date:From; b=SRIcwFW7Fv79d8+AYOjs/8b+htsgZguvBz3GXodWsvKsJwElNJLh0uqF7zi+IDMAt rChGERXsixApXS2MXQ2tZyXGaRhwBWeozx1nUxjilglPgSv0xILJcHYk6cCpCk+WKV kCG3o73Psd+fIFKbIM+blpmGWksqLtSLQOuwRk4Q= Received: from [82.94.249.234] (mx3.investici.org [82.94.249.234]) (Authenticated sender: mariotomo@inventati.org) by localhost (Postfix) with ESMTPSA id 799B212015C; Fri, 12 Jun 2020 17:14:42 +0000 (UTC) To: emacs-orgmode@gnu.org From: Mario Frasca Subject: [PATCH] allow for multiline headers Message-ID: Date: Fri, 12 Jun 2020 12:14:17 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------6E00D92E97B4E9D74B6534C1" Content-Language: en-US Received-SPF: pass client-ip=2001:888:2000:56::19; envelope-from=mario@anche.no; helo=latitanza.investici.org X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=anche.no header.s=stigmate header.b=SRIcwFW7; dmarc=none; spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Spam-Score: -1.21 X-TUID: G/NKLXOZ5LMu This is a multi-part message in MIME format. --------------6E00D92E97B4E9D74B6534C1 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit 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 --------------6E00D92E97B4E9D74B6534C1 Content-Type: text/x-patch; charset=UTF-8; name="0001-lisp-org-table.el-Allow-collapsing-header-into-singl.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-lisp-org-table.el-Allow-collapsing-header-into-singl.pa"; filename*1="tch" >From 649f46a591474afb6cef8b9d5151ff6b0bae38aa Mon Sep 17 00:00:00 2001 From: mfrasca 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 --------------6E00D92E97B4E9D74B6534C1--