org-e-odt.el: Support for indented tables (first cut)
This commit is contained in:
parent
7be6352932
commit
03fbf6b161
|
@ -171,13 +171,12 @@ structure of the values.")
|
|||
;; separator
|
||||
"<text:p text:style-name=\"OrgSubtitle\"/>")))))
|
||||
|
||||
(defun org-e-odt-begin-section (style &optional name)
|
||||
(defun org-e-odt-format-section (text style &optional name)
|
||||
(let ((default-name (car (org-e-odt-add-automatic-style "Section"))))
|
||||
(format "<text:section text:style-name=\"%s\" text:name=\"%s\">"
|
||||
style (or name default-name))))
|
||||
|
||||
(defun org-e-odt-end-section ()
|
||||
"</text:section>")
|
||||
(format "\n<text:section text:style-name=\"%s\" %s>\n%s</text:section>"
|
||||
style
|
||||
(format "text:name=\"%s\"" (or name default-name))
|
||||
text)))
|
||||
|
||||
(defun org-e-odt-begin-paragraph (&optional style)
|
||||
(format "<text:p%s>" (org-e-odt-get-extra-attrs-for-paragraph-style style)))
|
||||
|
@ -2948,10 +2947,6 @@ contextual information."
|
|||
|
||||
;;;; Inlinetask
|
||||
|
||||
(defun org-e-odt-format-section (text class &optional id)
|
||||
(let ((extra (concat (when id (format " id=\"%s\"" id)))))
|
||||
(concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
|
||||
|
||||
(defun org-e-odt-inlinetask (inlinetask contents info)
|
||||
"Transcode an INLINETASK element from Org to ODT.
|
||||
CONTENTS holds the contents of the block. INFO is a plist
|
||||
|
@ -3000,10 +2995,18 @@ contextual information."
|
|||
(tag (let ((tag (org-element-property :tag item)))
|
||||
(and tag (org-export-data tag info)))))
|
||||
(case type
|
||||
(ordered
|
||||
(format "\n<text:list-item>\n%s\n</text:list-item>" contents))
|
||||
(unordered
|
||||
(format "\n<text:list-item>\n%s\n</text:list-item>" contents))
|
||||
((ordered unordered)
|
||||
(format "\n<text:list-item>\n%s\n%s"
|
||||
contents
|
||||
(let* ((--element-has-a-table-p
|
||||
(function
|
||||
(lambda (element info)
|
||||
(loop for el in (org-element-contents element)
|
||||
thereis (equal (org-element-type el) 'table))))))
|
||||
(cond
|
||||
((funcall --element-has-a-table-p item info)
|
||||
"</text:list-header>")
|
||||
(t "</text:list-item>")))))
|
||||
(descriptive
|
||||
(concat
|
||||
(let ((term (or tag "(no term)")))
|
||||
|
@ -3017,7 +3020,7 @@ contextual information."
|
|||
"text:continue-numbering=\"false\""
|
||||
(format "\n<text:list-item>\n%s\n</text:list-item>"
|
||||
contents)))))))
|
||||
(t (error "Unknown list type")))))
|
||||
(t (error "Unknown list type: %S" type)))))
|
||||
|
||||
|
||||
;;;; Keyword
|
||||
|
@ -3430,15 +3433,20 @@ the plist used as a communication channel."
|
|||
"Transcode a PLAIN-LIST element from Org to ODT.
|
||||
CONTENTS is the contents of the list. INFO is a plist holding
|
||||
contextual information."
|
||||
(let* (arg1 ;; FIXME
|
||||
(type (org-element-property :type plain-list))
|
||||
(attr (mapconcat #'identity
|
||||
(org-element-property :attr_odt plain-list)
|
||||
" ")))
|
||||
(let* ((type (org-element-property :type plain-list))
|
||||
(continue-numbering nil))
|
||||
(assert (member type '(ordered unordered descriptive)))
|
||||
(org-e-odt--wrap-label
|
||||
plain-list (format "%s\n%s%s"
|
||||
(org-e-odt-begin-plain-list type)
|
||||
contents "</text:list>"))))
|
||||
plain-list
|
||||
(format "\n<text:list text:style-name=\"%s\" %s>\n%s</text:list>"
|
||||
(org-e-odt-get-style-name-for-entity 'list type)
|
||||
;; If top-level list, re-start numbering. Otherwise,
|
||||
;; continue numbering.
|
||||
(format "text:continue-numbering=\"%s\""
|
||||
(let* ((parent (org-export-get-parent plain-list info)))
|
||||
(if (and parent (equal (org-element-type parent) 'item))
|
||||
"true" "false")))
|
||||
contents))))
|
||||
|
||||
;;;; Plain Text
|
||||
|
||||
|
@ -3818,9 +3826,9 @@ contextual information."
|
|||
table-cell info) 0))))
|
||||
(org-e-odt-make-string
|
||||
width
|
||||
(org-e-odt-format-tags
|
||||
"<table:table-column table:style-name=\"%s\"/>"
|
||||
"" column-style))))
|
||||
(format
|
||||
"\n<table:table-column table:style-name=\"%s\"/>"
|
||||
column-style))))
|
||||
(org-e-odt-table-first-row-data-cells table info) "\n"))))))
|
||||
(concat
|
||||
;; caption.
|
||||
|
@ -3829,7 +3837,7 @@ contextual information."
|
|||
(let* ((automatic-name
|
||||
(org-e-odt-add-automatic-style "Table" attributes)))
|
||||
(format
|
||||
"\n<table:table table:name=\"%s\" table:style-name=\"%s\">\n"
|
||||
"\n<table:table table:name=\"%s\" table:style-name=\"%s\">"
|
||||
(or short-caption (car automatic-name))
|
||||
(or custom-table-style (cdr automatic-name) "OrgTable")))
|
||||
;; column specification.
|
||||
|
@ -3839,54 +3847,66 @@ contextual information."
|
|||
;; end table.
|
||||
"</table:table>")))))
|
||||
|
||||
|
||||
(defun org-e-odt-table (table contents info)
|
||||
"Transcode a TABLE element from Org to ODT.
|
||||
CONTENTS is the contents of the table. INFO is a plist holding
|
||||
contextual information."
|
||||
(let* ((transcoded-table (org-e-odt--table table contents info))
|
||||
(genealogy (org-export-get-genealogy table info))
|
||||
(list-genealogy (and (equal (org-element-type (car genealogy)) 'item)
|
||||
(loop for element in genealogy
|
||||
when (member (org-element-type element)
|
||||
'(item plain-list))
|
||||
collect element))))
|
||||
(when (and transcoded-table list-genealogy)
|
||||
(let ((parent-list (nth 1 list-genealogy)))
|
||||
(assert (equal (org-element-type parent-list) 'plain-list))
|
||||
(assert
|
||||
(not (equal (org-element-property :type parent-list) 'descriptive))
|
||||
nil "ODT export doesn't support tables within description list."))
|
||||
|
||||
;; 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, put
|
||||
;; the table in an indented section and then re-continue
|
||||
;; the list.
|
||||
|
||||
;; Put the Table in an indented section.
|
||||
(setq transcoded-table
|
||||
(let ((level (/ (length list-genealogy) 2)))
|
||||
(concat (org-e-odt-begin-section
|
||||
(format "OrgIndentedSection-Level-%d" level))
|
||||
transcoded-table (org-e-odt-end-section))))
|
||||
|
||||
(loop for element in list-genealogy
|
||||
when (equal (org-element-type element) 'plain-list)
|
||||
do (setq transcoded-table
|
||||
(concat
|
||||
;; Discontinue this list.
|
||||
"\n</text:list-item>"
|
||||
"\n</text:list>"
|
||||
;; Embed the table.
|
||||
transcoded-table
|
||||
;; Continute the this list.
|
||||
(org-e-odt-begin-plain-list
|
||||
(org-element-property :type element)
|
||||
'continue-numbering)
|
||||
(if (cdr element) "\n<text:list-item>"
|
||||
"\n<text:list-header>")))))
|
||||
transcoded-table))
|
||||
(let* ((--get-previous-elements
|
||||
(function
|
||||
(lambda (blob info)
|
||||
(let ((parent (org-export-get-parent blob info)))
|
||||
(cdr (member blob (reverse (org-element-contents parent))))))))
|
||||
(--element-preceded-by-table-p
|
||||
(function
|
||||
(lambda (element info)
|
||||
(loop for el in (funcall --get-previous-elements element info)
|
||||
thereis (equal (org-element-type el) 'table)))))
|
||||
(--walk-list-genealogy-and-collect-tags
|
||||
(function
|
||||
(lambda (table info)
|
||||
(let* ((genealogy (org-export-get-genealogy table info))
|
||||
(list-genealogy
|
||||
(when (equal (org-element-type (car genealogy)) 'item)
|
||||
(loop for el in genealogy
|
||||
when (member (org-element-type el)
|
||||
'(item plain-list))
|
||||
collect el))))
|
||||
(loop for el in list-genealogy
|
||||
with parent-list collect
|
||||
(case (org-element-type el)
|
||||
(plain-list
|
||||
(setq parent-list el)
|
||||
`("</text:list>"
|
||||
. ,(let ((type (org-element-property :type el)))
|
||||
(format
|
||||
"<text:list text:style-name=\"%s\" %s>"
|
||||
(org-e-odt-get-style-name-for-entity 'list type)
|
||||
"text:continue-numbering=\"true\""))))
|
||||
(item
|
||||
(cond
|
||||
((not parent-list)
|
||||
(if (funcall --element-preceded-by-table-p table info)
|
||||
'("</text:list-header>" . "<text:list-header>")
|
||||
'("</text:list-item>" . "<text:list-header>")))
|
||||
((funcall --element-preceded-by-table-p
|
||||
parent-list info)
|
||||
'("</text:list-header>" . "<text:list-header>"))
|
||||
(t '("</text:list-item>" . "<text:list-item>"))))))))))
|
||||
(close-open-tags (funcall --walk-list-genealogy-and-collect-tags
|
||||
table info)))
|
||||
;; OpenDocument schema does not permit table to occur within a
|
||||
;; list item. So, to typeset an indented table, we make use of
|
||||
;; list continuations.
|
||||
(concat "\n"
|
||||
;; Discontinue the list.
|
||||
(mapconcat 'car close-open-tags "\n")
|
||||
;; Put the table in an indented section.
|
||||
(let* ((table (org-e-odt--table table contents info))
|
||||
(level (/ (length (mapcar 'car close-open-tags)) 2))
|
||||
(style (format "OrgIndentedSection-Level-%d" level)))
|
||||
(when table (org-e-odt-format-section table style)))
|
||||
;; Continue the list.
|
||||
(mapconcat 'cdr (nreverse close-open-tags) "\n"))))
|
||||
|
||||
|
||||
;;;; Target
|
||||
|
@ -3997,9 +4017,7 @@ Return output file's name."
|
|||
(file-name-directory
|
||||
(org-export-output-file-name ".odt" subtreep nil)))
|
||||
|
||||
(org-export-to-buffer
|
||||
'e-odt outbuf
|
||||
(memq 'subtree optns) (memq 'visible optns) (memq 'body optns))
|
||||
(org-export-to-buffer 'e-odt outbuf subtreep visible-only body-only)
|
||||
|
||||
(setq org-lparse-opt-plist nil) ; FIXME
|
||||
(org-e-odt-save-as-outfile target ;; info
|
||||
|
@ -4129,6 +4147,10 @@ using `org-open-file'."
|
|||
|
||||
;;; FIXMES, TODOS, FOR REVIEW etc
|
||||
|
||||
;;;; Support listified headline
|
||||
;;;; Handle tables within a description list
|
||||
;;; Handle tables within a listified headline
|
||||
|
||||
;;;; org-solidify-link-text
|
||||
;;;; coding system
|
||||
;;;; org-e-odt-table-caption-above
|
||||
|
|
Loading…
Reference in New Issue