emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Achim Gratz <Stromeko@nexgo.de>
To: emacs-orgmode@gnu.org
Subject: Re: [Feature Request] Cross headings in tables
Date: Sun, 16 Jan 2011 19:44:05 +0100	[thread overview]
Message-ID: <87d3nwzo22.fsf@Rainer.invalid> (raw)
In-Reply-To: 87eic4le49.fsf@Rainer.invalid

[-- Attachment #1: Type: text/plain, Size: 4325 bytes --]

Achim Gratz <Stromeko@nexgo.de> writes:
[...]
> So I'd like to have first-class cross headings, maybe like this:
>
> |----------+-----------+-----------------|
> | Header   | some more | and more        |
> |----------+-----------+-----------------|
> | item     | stuff     | things          |
> | etc.     | pp.       | ad nauseam      |
> |----------+-----------+-----------------|
> |> Header  | to keep   | things together |
> |----------+-----------+-----------------|
> |          | ...       |                 |
> |----------+-----------+-----------------|
>
> So, the first heading would be determined by the first horizontal
> separator inside the table (for backwards compatibility) and any
> following heading would need get some special syntax (like the "|>"
> above, but anything that doesn't collide with existing syntax will
> just be fine I think).  If there's a heading marker before the first
> horizontal separation, it should probably take precedence over the
> backwards-compatible markup.  That would also enable to have table
> headings without a separator, something that's not possible today.

I've spent some time on this and have developed a patch that gets
halfway there.  You can have consecutive headers, headers inside the
table and even headers at the end of the table:

--8<---------------cut here---------------start------------->8---
  |-------------+
  | unrelated 1 |
  |~~~~~~~~~~~~~|
  | Test1       |
  |-------------+
  | unrelated 2 |
  | Test2       |
  | unrelated 3 |
  |~~~~~~~~~~~~~|
  | Test3       |
  |-------------+
  | unrelated 4 |
  | Test4       |
  | unrelated 5 |
  | Test5       |
  |~~~~~~~~~~~~~|
  | unrelated 6 |
  | Test6       |
  |-------------+
--8<---------------cut here---------------end--------------->8---

The first header is still determined like it always was.  Headers inside
table need to get a special "hline", the choice of "~" for this was
dictated by most of the other characters already being used for various
markup inside or outside tables.  When I say "halfway there", I mean
that the export is working and the lines are recognized as hlines
everywhere I could find (there may still be some regexpressions floating
around that don't).  However, aligning tables will replace the wigglies
with plain dashes since I have not yet found a way to inject the correct
character for the currently hardcoded "-".  The HTML export for the
above table looks like this:

--8<---------------cut here---------------start------------->8---
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption></caption>
<colgroup><col class="left" /><col class="left" />
</colgroup>
<thead>
<tr><th scope="col" class="left">unrelated 1</th><th scope="col" class="left">&gt;=</th></tr>
</thead>
<thead>
<tr><th scope="col" class="left">Test1</th><th scope="col" class="left">=</th></tr>
</thead>
<tbody>
<tr><td class="left">unrelated 2</td><td class="left">&lt;=</td></tr>
<tr><td class="left">Test2</td><td class="left">==</td></tr>
<tr><td class="left">unrelated 3</td><td class="left">-=</td></tr>
</tbody>
<thead>
<tr><th scope="col" class="left">Test3</th><th scope="col" class="left">:=</th></tr>
</thead>
<tbody>
<tr><td class="left">unrelated 4</td><td class="left">&gt;=</td></tr>
<tr><td class="left">Test4</td><td class="left">=</td></tr>
<tr><td class="left">unrelated 5</td><td class="left">&lt;=</td></tr>
<tr><td class="left">Test5</td><td class="left">==</td></tr>
</tbody>
<thead>
<tr><th scope="col" class="left">unrelated 6</th><th scope="col" class="left">-=</th></tr>
<tr><th scope="col" class="left">Test6</th><th scope="col" class="left">:=</th></tr>
</thead>
</table>
--8<---------------cut here---------------end--------------->8---


And ASCII:
--8<---------------cut here---------------start------------->8---
    unrelated 1 
   -------------
    Test1       
   -------------
    unrelated 2 
    Test2       
    unrelated 3 
   -------------
    Test3       
   -------------
    unrelated 4 
    Test4       
    unrelated 5 
    Test5       
   -------------
    unrelated 6 
    Test6       
--8<---------------cut here---------------end--------------->8---

If somebody has an idea how to make the table alignment work, please
lend me a hand.  Experimental patch is attached, comments are 
welcome.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Table-Headings --]
[-- Type: text/x-patch, Size: 7699 bytes --]

From 0fd4e39641ab17ae1586747396acbe1e9fa48321 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sun, 16 Jan 2011 19:06:13 +0100
Subject: [PATCH] Allow headings inside tables without splicing them.

*EXPERIMENTAL*

This patch is an incomplete implementation, most notably,
table (re-)alignment does not work.
---
 lisp/org-html.el  |   15 +++++++++++++--
 lisp/org-table.el |   30 +++++++++++++++---------------
 lisp/org.el       |    4 ++--
 3 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/lisp/org-html.el b/lisp/org-html.el
index 9a5d225..d69d037 100644
--- a/lisp/org-html.el
+++ b/lisp/org-html.el
@@ -1899,7 +1899,7 @@ for formatting.  This is required for the DocBook exporter."
 			  html-table-tag attributes))
 	 (head (and org-export-highlight-first-table-line
 		    (delq nil (mapcar
-			       (lambda (x) (string-match "^[ \t]*|-" x))
+			       (lambda (x) (string-match "^[ \t]*|[-~]" x))
 			       (cdr lines)))))
 	 (nline 0) fnum nfields i (cnt 0)
 	 tbopen line fields html gr colgropen rowstart rowend
@@ -1913,7 +1913,7 @@ for formatting.  This is required for the DocBook exporter."
     (setq tbopen t)
     (while (setq line (pop lines))
       (catch 'next-line
-	(if (string-match "^[ \t]*|-" line)
+	(if (string-match "^[ \t]*|[-]" line)
 	    (progn
 	      (unless splice
 		(push (if head "</thead>" "</tbody>") html)
@@ -1921,6 +1921,16 @@ for formatting.  This is required for the DocBook exporter."
 	      (setq head nil)   ;; head ends here, first time around
 	      ;; ignore this line
 	      (throw 'next-line t)))
+	; interspersed heading
+	(if (string-match "^[ \t]*|[~]" line)
+	    (progn
+	      (unless splice
+		(push (if head "</thead>" "</tbody>") html)
+		(push "<thead>" html)
+		(setq tbopen nil))
+	      (setq head t) ; head starts again here, until the next |- hline
+	      ;; ignore this line
+	      (throw 'next-line t)))
 	;; Break the line into fields
 	(setq fields (org-split-string line "[ \t]*|[ \t]*"))
 	(unless fnum (setq fnum (make-vector (length fields) 0)
@@ -1955,6 +1965,7 @@ for formatting.  This is required for the DocBook exporter."
 		       fields "")
 		      rowend)
 	      html)))
+    (unless splice (if head (push "</thead>" html)))
     (unless splice (if tbopen (push "</tbody>" html)))
     (unless splice (push "</table>\n" html))
     (setq html (nreverse html))
diff --git a/lisp/org-table.el b/lisp/org-table.el
index 951bff7..9437ae1 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -567,7 +567,7 @@ property, locally or anywhere up in the hierarchy."
 			 (if (string-match org-table-hline-regexp x)
 			     'hline
 			   (org-remove-by-index
-			    (org-split-string (org-trim x) "\\s-*|\\s-*")
+			    (org-split-string (org-trim x) "\\s[-~]*|\\s[-~]*")
 			    skipcols i0)))
 		       lines))
 	       (fun (if (= i0 2) 'cdr 'identity))
@@ -680,7 +680,7 @@ When nil, simply write \"#ERROR\" in corrupted fields.")
     ;; Mark the hlines by setting the corresponding element to nil
     ;; At the same time, we remove trailing space.
     (setq lines (mapcar (lambda (l)
-			  (if (string-match "^ *|-" l)
+			  (if (string-match "^ *|[-~]" l)
 			      nil
 			    (if (string-match "[ \t]+$" l)
 				(substring l 0 (match-beginning 0))
@@ -897,9 +897,9 @@ Before doing so, re-align the table if necessary."
 	      (re-search-forward "|" end))
 	  (if (and (looking-at "-")
 		   org-table-tab-jumps-over-hlines
-		   (re-search-forward "^[ \t]*|\\([^-]\\)" end t))
+		   (re-search-forward "^[ \t]*|\\([^-~]\\)" end t))
 	      (goto-char (match-beginning 1)))
-	  (if (looking-at "-")
+	  (if (looking-at "[-~]")
 	      (progn
 		(beginning-of-line 0)
 		(org-table-insert-row 'below))
@@ -1417,7 +1417,7 @@ With prefix ABOVE, insert above the current line."
     (org-table-maybe-recalculate-line)
     (org-table-insert-hline)
     (end-of-line 2)
-    (if (looking-at "\n[ \t]*|-")
+    (if (looking-at "\n[ \t]*|[-~]")
 	(progn (insert "\n|") (org-table-align))
       (org-table-next-field))
     (if same-column (org-table-goto-column col))))
@@ -1425,7 +1425,7 @@ With prefix ABOVE, insert above the current line."
 (defun org-table-clean-line (s)
   "Convert a table line S into a string with only \"|\" and space.
 In particular, this does handle wide and invisible characters."
-  (if (string-match "^[ \t]*|-" s)
+  (if (string-match "^[ \t]*|[-~]" s)
       ;; It's a hline, just map the characters
       (setq s (mapconcat (lambda (x) (if (member x '(?| ?+)) "|" " ")) s ""))
     (while (string-match "|\\([ \t]*?[^ \t\r\n|][^\r\n|]*\\)|" s)
@@ -1630,7 +1630,7 @@ blindly applies a recipe that works for simple tables."
 	      (end (move-marker (make-marker) (org-table-end))))
 	  ;; first, get rid of all horizontal lines
 	  (goto-char beg)
-	  (while (re-search-forward "^\\([ \t]*\\)|-.*\n" end t)
+	  (while (re-search-forward "^\\([ \t]*\\)|[-~].*\n" end t)
 	    (replace-match ""))
 	  ;; insert a hline before first
 	  (goto-char beg)
@@ -1642,11 +1642,11 @@ blindly applies a recipe that works for simple tables."
 	  (goto-char beg)
 	  (setq end (move-marker end (org-table-end)))
 	  ;; replace "+" at beginning and ending of hlines
-	  (while (re-search-forward "^\\([ \t]*\\)|-" end t)
-	    (replace-match "\\1+-"))
+	  (while (re-search-forward "^\\([ \t]*\\)|\\([-~]\\)" end t)
+	    (replace-match "\\1+\\2"))
 	  (goto-char beg)
-	  (while (re-search-forward "-|[ \t]*$" end t)
-	    (replace-match "-+"))
+	  (while (re-search-forward "\\([-~]\\)|[ \t]*$" end t)
+	    (replace-match "\\1+"))
 	  (goto-char beg)))))
 
 (defun org-table-wrap-region (arg)
@@ -1801,12 +1801,12 @@ If NLAST is a number, only the NLAST fields will actually be summed."
        (t
 	(setq col (org-table-current-column))
 	(goto-char (org-table-begin))
-	(unless (re-search-forward "^[ \t]*|[^-]" nil t)
+	(unless (re-search-forward "^[ \t]*|[^-~]" nil t)
 	  (error "No table data"))
 	(org-table-goto-column col)
 	(setq beg (point))
 	(goto-char (org-table-end))
-	(unless (re-search-backward "^[ \t]*|[^-]" nil t)
+	(unless (re-search-backward "^[ \t]*|[^-~]" nil t)
 	  (error "No table data"))
 	(org-table-goto-column col)
 	(setq end (point))))
@@ -2067,7 +2067,7 @@ For all numbers larger than LIMIT, shift them by DELTA."
       (setq org-table-current-begin-line (org-current-line)
 	    org-table-current-begin-pos (point)
 	    l org-table-current-begin-line)
-      (while (looking-at "[ \t]*|\\(-\\)?")
+      (while (looking-at "[ \t]*|\\([-~]\\)?")
 	(push (if (match-end 1) 'hline 'dline) types)
 	(if (match-end 1) (push l hlines) (push l dlines))
 	(beginning-of-line 2)
@@ -2142,7 +2142,7 @@ of the new mark."
 	 (have-col
 	  (save-excursion
 	    (goto-char beg)
-	    (not (re-search-forward "^[ \t]*|[^-|][^|]*[^#!$*_^| \t][^|]*|" end t))))
+	    (not (re-search-forward "^[ \t]*|[^-~|][^|]*[^#!$*_^| \t][^|]*|" end t))))
 	 (col (org-table-current-column))
 	 (forcenew (car (assoc newchar org-recalc-marks)))
 	 epos new)
diff --git a/lisp/org.el b/lisp/org.el
index 6e8aeac..5721b53 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3599,9 +3599,9 @@ Normal means, no org-mode-specific context."
   "Detect an org-type or table-type table.")
 (defconst org-table-line-regexp "^[ \t]*|"
   "Detect an org-type table line.")
-(defconst org-table-dataline-regexp "^[ \t]*|[^-]"
+(defconst org-table-dataline-regexp "^[ \t]*|[^-~]"
   "Detect an org-type table line.")
-(defconst org-table-hline-regexp "^[ \t]*|-"
+(defconst org-table-hline-regexp "^[ \t]*|[-~]"
   "Detect an org-type table hline.")
 (defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]"
   "Detect a table-type table hline.")
-- 
1.7.1


[-- Attachment #3: Type: text/plain, Size: 190 bytes --]



Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf Blofeld:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

[-- Attachment #4: Type: text/plain, Size: 201 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

  reply	other threads:[~2011-01-16 18:44 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-04 17:46 Quoting formula "cookies" in table? Achim Gratz
2010-10-05  1:25 ` Carsten Dominik
2010-10-05 17:10   ` Achim Gratz
2010-10-05 17:24     ` Carsten Dominik
2010-10-06 17:37       ` Achim Gratz
2010-10-05 17:54 ` [Feature Request] Cross headings in tables Achim Gratz
2011-01-16 18:44   ` Achim Gratz [this message]
2011-02-02 12:30     ` Lawrence Mitchell
2011-02-02 20:49       ` Achim Gratz
2011-02-08 21:52         ` Achim Gratz
2011-03-20  9:16           ` Achim Gratz
2011-05-29 18:18           ` [Orgmode] " Carsten Dominik
2011-05-30 21:02             ` Achim Gratz
2011-05-31  7:21               ` Carsten Dominik
2011-05-31  8:07                 ` Lawrence Mitchell
2011-05-31 18:01                 ` Achim Gratz
2011-05-31 18:44                   ` Jambunathan K
2011-06-02 16:12                   ` Carsten Dominik
2011-06-07 19:42                 ` Achim Gratz
2013-02-16 19:21                   ` Achim Gratz
2013-02-17  8:35                     ` Nicolas Goaziou
2013-02-17 19:41                       ` Achim Gratz
2013-02-17 21:06                         ` Achim Gratz
2013-02-22 12:31                       ` Carsten Dominik
2013-02-22 20:33                         ` Achim Gratz
2013-02-22 20:59                           ` Carsten Dominik
2013-02-23  8:10                           ` Bastien
2013-02-23 12:26                       ` Achim Gratz

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=87d3nwzo22.fsf@Rainer.invalid \
    --to=stromeko@nexgo.de \
    --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).