summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJambunathan K <kjambunathan@gmail.com>2012-01-17 02:25:47 +0530
committerJambunathan K <kjambunathan@gmail.com>2012-01-17 02:25:47 +0530
commitbf1d5cfe95e58b1ed96a7164c45214c2a1ed01d0 (patch)
treed91e060bda1af41abb677c72ab760d87f08cb925
parent812d0a53758d36424cf2c2044b0e43c14cde33fd (diff)
downloadorg-mode-bf1d5cfe95e58b1ed96a7164c45214c2a1ed01d0.tar.gz
Add support for indented tables in ODT export
* etc/styles/OrgOdtContentTemplate.xml (OrgIndentedSection-Level-*): New section styles. These sections are indented to the same level as the corresponding list entries. These sections hold tables that occur within a list. (OrgTable): Increased relative width from 90% to 96% for aesthetic reasons. * lisp/org-odt.el (org-odt-table-indentedp): New variable (org-odt-begin-table): Modified. If the table is within a list, temporarily leave the list and begin an indented section before emitting the table. (org-odt-end-table): Modified. If the table was within a list, close the indented section and re-open the list immediately after ending the table. (org-odt-continue-list, org-odt-discontinue-list): Helper routines to temporarily discontinue and continue a list. (org-odt-list-stack-stashed): New variable to hold the state of a pending list. (org-odt-begin-list, org-odt-begin-list-item) (org-odt-end-list-item): Modified. Handle nitty-gritties for continuing a list and list item. (org-odt-section-count): New variable that keeps track of section count. Used in conjunction with naming of sections. (org-odt-begin-section, org-odt-end-section): New defuns. (org-odt-init-outfile): Initialize `org-odt-list-stack-stashed' and `org-odt-section-count'. * lisp/org-lparse.el (org-lparse-list-item-count): Removed. Was a superfluous variable. (org-lparse-list-level): Removed. Now derived from `org-lparse-list-stack'. (org-lparse-list-stack): New. List that records the list types - ordered, unordered or descriptive - in the following order: self, parent, grand-parent etc. (org-do-lparse): Added, removed above let-bound vars. Disallowed regular tables within list-table block. (org-lparse-begin-list, org-lparse-end-list) (org-lparse-begin-list-item, org-lparse-end-list-item): Propagate above changes. OpenDocument doesn't permit tables to occur in the middle of a list. Use list continuations and indented sections to typeset indented tables. Fixes the following bug: http://lists.gnu.org/archive/html/emacs-orgmode/2012-01/msg00515.html
-rw-r--r--etc/styles/OrgOdtContentTemplate.xml55
-rw-r--r--lisp/org-lparse.el129
-rw-r--r--lisp/org-odt.el65
3 files changed, 172 insertions, 77 deletions
diff --git a/etc/styles/OrgOdtContentTemplate.xml b/etc/styles/OrgOdtContentTemplate.xml
index f50588b..cd7ff0e 100644
--- a/etc/styles/OrgOdtContentTemplate.xml
+++ b/etc/styles/OrgOdtContentTemplate.xml
@@ -46,8 +46,61 @@
<!-- automatic styles -->
<office:automatic-styles>
+ <!-- Section styles -->
+ <style:style style:name="OrgIndentedSection-Level-1" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="1.281cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-2" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="1.905cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-3" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="2.54cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-4" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="3.175cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-5" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="3.81cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-6" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="4.445cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-7" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="5.08cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-8" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="5.715cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-9" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="6.35cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="OrgIndentedSection-Level-10" style:family="section">
+ <style:section-properties text:dont-balance-text-columns="false" fo:margin-left="6.985cm" fo:margin-right="0cm" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </style:style>
+
+ <!-- Table styles -->
<style:style style:name="OrgTable" style:family="table">
- <style:table-properties style:rel-width="90%" fo:margin-top="0cm" fo:margin-bottom="0.20cm" table:align="center"/>
+ <style:table-properties style:rel-width="96%" fo:margin-top="0cm" fo:margin-bottom="0.20cm" table:align="center"/>
</style:style>
<style:style style:name="OrgTableColumn" style:family="table-column">
diff --git a/lisp/org-lparse.el b/lisp/org-lparse.el
index 229135e..6448b0f 100644
--- a/lisp/org-lparse.el
+++ b/lisp/org-lparse.el
@@ -598,11 +598,7 @@ version."
(org-lparse-par-open-stashed 0)
;; list related vars
- (org-lparse-list-level 0) ; list level starts at 1. A
- ; value of 0 implies we are
- ; outside of any list
- (org-lparse-list-item-count 0)
- org-lparse-list-stack
+ (org-lparse-list-stack '())
;; list-table related vars
org-lparse-list-table-p
@@ -1081,10 +1077,11 @@ version."
table-buffer (nreverse table-buffer)
table-orig-buffer (nreverse table-orig-buffer))
(org-lparse-end-paragraph)
+ (when org-lparse-list-table-p
+ (error "Regular tables are not allowed in a list-table block"))
(org-lparse-insert 'TABLE table-buffer table-orig-buffer)))
;; Normal lines
-
(t
;; This line either is list item or end a list.
(when (get-text-property 0 'list-item line)
@@ -2104,8 +2101,6 @@ When TITLE is nil, just close all open levels."
("d" . description)))))
;; following vars are bound during `org-do-lparse'
-(defvar org-lparse-list-level)
-(defvar org-lparse-list-item-count)
(defvar org-lparse-list-stack)
(defvar org-lparse-list-table:table-row)
(defvar org-lparse-list-table:lines)
@@ -2147,73 +2142,69 @@ When TITLE is nil, just close all open levels."
;; https://lists.gnu.org/archive/html/emacs-orgmode/2011-03/msg01101.html
(defun org-lparse-begin-list (ltype)
- (incf org-lparse-list-level)
- (push org-lparse-list-item-count org-lparse-list-stack)
- (setq org-lparse-list-item-count 0)
- (cond
- ((not org-lparse-list-table-p)
- (org-lparse-begin 'LIST ltype))
- ;; process LIST-TABLE
- ((= 1 org-lparse-list-level)
- ;; begin LIST-TABLE
- (setq org-lparse-list-table:lines nil)
- (setq org-lparse-list-table:table-row nil))
- ((= 2 org-lparse-list-level)
- (ignore))
- (t
- (org-lparse-begin 'LIST ltype))))
+ (push ltype org-lparse-list-stack)
+ (let ((list-level (length org-lparse-list-stack)))
+ (cond
+ ((not org-lparse-list-table-p)
+ (org-lparse-begin 'LIST ltype))
+ ;; process LIST-TABLE
+ ((= 1 list-level)
+ ;; begin LIST-TABLE
+ (setq org-lparse-list-table:lines nil)
+ (setq org-lparse-list-table:table-row nil))
+ ((= 2 list-level)
+ (ignore))
+ (t
+ (org-lparse-begin 'LIST ltype)))))
(defun org-lparse-end-list (ltype)
- (setq org-lparse-list-item-count (pop org-lparse-list-stack))
- (decf org-lparse-list-level)
- (cond
- ((not org-lparse-list-table-p)
- (org-lparse-end 'LIST ltype))
- ;; process LIST-TABLE
- ((= 0 org-lparse-list-level)
- ;; end LIST-TABLE
- (insert (org-lparse-format-list-table
- (nreverse org-lparse-list-table:lines))))
- ((= 1 org-lparse-list-level)
- (ignore))
- (t
- (org-lparse-end 'LIST ltype))))
+ (pop org-lparse-list-stack)
+ (let ((list-level (length org-lparse-list-stack)))
+ (cond
+ ((not org-lparse-list-table-p)
+ (org-lparse-end 'LIST ltype))
+ ;; process LIST-TABLE
+ ((= 0 list-level)
+ ;; end LIST-TABLE
+ (insert (org-lparse-format-list-table
+ (nreverse org-lparse-list-table:lines))))
+ ((= 1 list-level)
+ (ignore))
+ (t
+ (org-lparse-end 'LIST ltype)))))
(defun org-lparse-begin-list-item (ltype &optional arg headline)
- (incf org-lparse-list-item-count)
- (cond
- ((not org-lparse-list-table-p)
- (org-lparse-begin 'LIST-ITEM ltype arg headline))
- ;; process LIST-TABLE
- ((and (= 1 org-lparse-list-level)
- (= 1 org-lparse-list-item-count))
- ;; begin TABLE-ROW for LIST-TABLE
- (setq org-lparse-list-table:table-row nil)
- (org-lparse-begin-list-table:table-cell))
- ((and (= 2 org-lparse-list-level)
- (= 1 org-lparse-list-item-count))
- ;; begin TABLE-CELL for LIST-TABLE
- (org-lparse-begin-list-table:table-cell))
- (t
- (org-lparse-begin 'LIST-ITEM ltype arg headline))))
+ (let ((list-level (length org-lparse-list-stack)))
+ (cond
+ ((not org-lparse-list-table-p)
+ (org-lparse-begin 'LIST-ITEM ltype arg headline))
+ ;; process LIST-TABLE
+ ((= 1 list-level)
+ ;; begin TABLE-ROW for LIST-TABLE
+ (setq org-lparse-list-table:table-row nil)
+ (org-lparse-begin-list-table:table-cell))
+ ((= 2 list-level)
+ ;; begin TABLE-CELL for LIST-TABLE
+ (org-lparse-begin-list-table:table-cell))
+ (t
+ (org-lparse-begin 'LIST-ITEM ltype arg headline)))))
(defun org-lparse-end-list-item (ltype)
- (decf org-lparse-list-item-count)
- (cond
- ((not org-lparse-list-table-p)
- (org-lparse-end 'LIST-ITEM ltype))
- ;; process LIST-TABLE
- ((and (= 1 org-lparse-list-level)
- (= 0 org-lparse-list-item-count))
- ;; end TABLE-ROW for LIST-TABLE
- (org-lparse-end-list-table:table-cell)
- (push (nreverse org-lparse-list-table:table-row)
- org-lparse-list-table:lines))
- ((= 2 org-lparse-list-level)
- ;; end TABLE-CELL for LIST-TABLE
- (org-lparse-end-list-table:table-cell))
- (t
- (org-lparse-end 'LIST-ITEM ltype))))
+ (let ((list-level (length org-lparse-list-stack)))
+ (cond
+ ((not org-lparse-list-table-p)
+ (org-lparse-end 'LIST-ITEM ltype))
+ ;; process LIST-TABLE
+ ((= 1 list-level)
+ ;; end TABLE-ROW for LIST-TABLE
+ (org-lparse-end-list-table:table-cell)
+ (push (nreverse org-lparse-list-table:table-row)
+ org-lparse-list-table:lines))
+ ((= 2 list-level)
+ ;; end TABLE-CELL for LIST-TABLE
+ (org-lparse-end-list-table:table-cell))
+ (t
+ (org-lparse-end 'LIST-ITEM ltype)))))
(defvar org-lparse-list-table:table-cell-open)
(defun org-lparse-begin-list-table:table-cell ()
diff --git a/lisp/org-odt.el b/lisp/org-odt.el
index c8fa7ea..e0a267a 100644
--- a/lisp/org-odt.el
+++ b/lisp/org-odt.el
@@ -646,6 +646,15 @@ PUB-DIR is set, use this as the publishing directory."
(defun org-odt-end-outline-text ()
(ignore))
+(defvar org-odt-section-count 0)
+(defun org-odt-begin-section (style &optional name)
+ (setq name (or name (format "Section-%d" (incf org-odt-section-count))))
+ (org-lparse-insert-tag
+ "<text:section text:style-name=\"%s\" text:name=\"%s\">" style name))
+
+(defun org-odt-end-section ()
+ (org-lparse-insert-tag "</text:section>"))
+
(defun org-odt-begin-paragraph (&optional style)
(org-lparse-insert-tag
"<text:p%s>" (org-odt-get-extra-attrs-for-paragraph-style style)))
@@ -729,13 +738,17 @@ PUB-DIR is set, use this as the publishing directory."
(list))
(t (error "Unknown environment %s" style))))
-(defvar org-lparse-list-level) ; dynamically bound in org-do-lparse
+(defvar org-lparse-list-stack) ; dynamically bound in org-do-lparse
+(defvar org-odt-list-stack-stashed)
(defun org-odt-begin-list (ltype)
(setq ltype (or (org-lparse-html-list-type-to-canonical-list-type ltype)
ltype))
(let* ((style-name (org-odt-get-style-name-for-entity 'list ltype))
- (extra (concat (when (= org-lparse-list-level 1)
- " text:continue-numbering=\"false\"")
+ (extra (concat (if (or org-lparse-list-table-p
+ (and (= 1 (length org-lparse-list-stack))
+ (null org-odt-list-stack-stashed)))
+ " text:continue-numbering=\"false\""
+ " text:continue-numbering=\"true\"")
(when style-name
(format " text:style-name=\"%s\"" style-name)))))
(case ltype
@@ -758,11 +771,15 @@ PUB-DIR is set, use this as the publishing directory."
(ordered
(assert (not headline) t)
(let* ((counter arg) (extra ""))
- (org-lparse-insert-tag "<text:list-item>")
+ (org-lparse-insert-tag (if (= (length org-lparse-list-stack)
+ (length org-odt-list-stack-stashed))
+ "<text:list-header>" "<text:list-item>"))
(org-lparse-begin-paragraph)))
(unordered
(let* ((id arg) (extra ""))
- (org-lparse-insert-tag "<text:list-item>")
+ (org-lparse-insert-tag (if (= (length org-lparse-list-stack)
+ (length org-odt-list-stack-stashed))
+ "<text:list-header>" "<text:list-item>"))
(org-lparse-begin-paragraph)
(insert (if headline (org-odt-format-target headline id)
(org-odt-format-bookmark "" id)))))
@@ -783,13 +800,30 @@ PUB-DIR is set, use this as the publishing directory."
ltype))
(case ltype
((ordered unordered)
- (org-lparse-insert-tag "</text:list-item>"))
+ (org-lparse-insert-tag (if (= (length org-lparse-list-stack)
+ (length org-odt-list-stack-stashed))
+ (prog1 "</text:list-header>"
+ (setq org-odt-list-stack-stashed nil))
+ "</text:list-item>")))
(description
(org-lparse-end-list-item-1)
(org-lparse-end-list 'description)
(org-lparse-end-list-item-1))
(t (error "Unknown list type"))))
+(defun org-odt-discontinue-list ()
+ (let ((stashed-stack org-lparse-list-stack))
+ (loop for list-type in stashed-stack
+ do (org-lparse-end-list-item-1 list-type)
+ (org-lparse-end-list list-type))
+ (setq org-odt-list-stack-stashed stashed-stack)))
+
+(defun org-odt-continue-list ()
+ (setq org-odt-list-stack-stashed (nreverse org-odt-list-stack-stashed))
+ (loop for list-type in org-odt-list-stack-stashed
+ do (org-lparse-begin-list list-type)
+ (org-lparse-begin-list-item list-type)))
+
;; Following variables are let bound when table emission is in
;; progress. See org-lparse.el.
(defvar org-lparse-table-begin-marker)
@@ -897,7 +931,19 @@ style from the list."
:key-type symbol
:value-type (const :tag "True" t))))))
+(defvar org-odt-table-indentedp nil)
(defun org-odt-begin-table (caption label attributes)
+ (setq org-odt-table-indentedp (not (null org-lparse-list-stack)))
+ (when org-odt-table-indentedp
+ ;; Within the Org file, the table is appearing within a list item.
+ ;; OpenDocument doesn't allow table to appear within list items.
+ ;; Temporarily terminate the list, emit the table and then
+ ;; re-continue the list.
+ (org-odt-discontinue-list)
+ ;; Put the Table in an indented section.
+ (let ((level (length org-odt-list-stack-stashed)))
+ (org-odt-begin-section (format "OrgIndentedSection-Level-%d" level))))
+
(setq org-odt-table-style attributes)
(setq org-odt-table-style-spec
(assoc org-odt-table-style org-export-odt-table-styles))
@@ -940,7 +986,10 @@ style from the list."
((equal spec "table-cell:style-name")
(replace-match table-cell-style t t))))))
(goto-char (point-max))
- (org-lparse-insert-tag "</table:table>"))
+ (org-lparse-insert-tag "</table:table>")
+ (when org-odt-table-indentedp
+ (org-odt-end-section)
+ (org-odt-continue-list)))
(defun org-odt-begin-table-rowgroup (&optional is-header-row)
(when org-lparse-table-rowgrp-open
@@ -2053,7 +2102,9 @@ CATEGORY-HANDLE is used. See
(setq org-odt-manifest-file-entries nil
org-odt-embedded-images-count 0
org-odt-embedded-formulas-count 0
+ org-odt-section-count 0
org-odt-entity-labels-alist nil
+ org-odt-list-stack-stashed nil
org-odt-entity-counts-plist nil)
content-file))