emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Re: [Feature Request] Cross headings in tables


From: Achim Gratz
Subject: [Orgmode] Re: [Feature Request] Cross headings in tables
Date: Sun, 16 Jan 2011 19:44:05 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Achim Gratz <address@hidden> 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.

>From 0fd4e39641ab17ae1586747396acbe1e9fa48321 Mon Sep 17 00:00:00 2001
From: Achim Gratz <address@hidden>
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


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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]