org-mode-ox-odt icon indicating copy to clipboard operation
org-mode-ox-odt copied to clipboard

Make `org-odt-handled-face-attributes` customizable. Also strip `nxml` blocks that hold styles from other backends. Easy way to create wholly `Landscape` documents

Open ouboub opened this issue 2 years ago • 19 comments

Hi this is an elementary question but searching the documentation, I am unable to find the correct setting. I have table, that is even in landscape a bit too large, so I would like to use a smaller font for the text in the table. I attach both the org and the resulting odt file to show, that I failed. the current font style in the table is 12pt but I'd prefer 11 or 10 pt. I presume that I just did not change the correct style.

regards Uwe Braue Fonts.zip r

ouboub avatar Jul 15 '22 18:07 ouboub

You need to add the small font table style for different table heading and different table contents, which I think is not convenient, I wish the font style and font size can be easily changed without this extra hassle. Then change the paragraph style of the table. table paragraph style setting

#+attr_odt: :p-style "Table_0.8"

extra style:

<style:style style:name="Table_0.8Contents" style:family="paragraph" style:parent-style-name="Standard">
  <style:text-properties fo:font-size="80%"
                         style:font-size-asian="80%"
                         style:font-size-complex="80%"
                         style:class="text"/>
</style:style>
<style:style style:name="Table_0.8Heading" style:family="paragraph" style:parent-style-name="Table_0.8Contents" style:class="extra">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>
  <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Table_0.8HeadingLeft" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="left" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8HeadingRight" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="right" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8HeadingCenter" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsLeft" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="left" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsRight" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="right" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsCenter" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>

I have attached an example. fonts.org.txt

QiangF avatar Jul 16 '22 00:07 QiangF

@QiangF, thanks for reminding me about :p-style attributes for Tables. I have totally forgotten about it .... Without your suggestion, I would have spent some 30 mins looking at the code ... and I would have taken a different track.

Here is something for you to work with. Table styles are complex ... So, I will not describe the details. A simple illustration should suffice. In the example below, change the nxml block to #+... headers., if you are also exporting to other backends.

(This reminds me I need to make sure that the nxml blocks that have ODT styles shouldn't get carried over to other backends)

Attachment:
big-landscape-table-and-extra-emphasis.zip


overview

Remember to execute the following setting ... particularly the org-odt-handled-face-attributes where we say that we want only the foreground and background colour to be carried over, and NOT other attributes, specficially the font size, font family etc..

  (load-file "~/src/org-extra-emphasis/org-extra-emphasis.el")
  (setq org-odt-handled-face-attributes
	'(:background :foreground))

FWIW, the default value of org-odt-handled-face-attributes handles the following attributes of org-extra-emphasis-N faces. T

(This discussion reminds me that I need to make it a defcustom. )

(defvar org-odt-handled-face-attributes
  '(:background
    :family :foreground
    :height
    :overline :slant
    :strike-through :underline :weight))


#+odt_preferred_output_format: pdf

#+begin_src emacs-lisp
  (load-file "~/src/org-extra-emphasis/org-extra-emphasis.el")
  (setq org-odt-handled-face-attributes
	'(:background :foreground))
#+end_src

#+RESULTS:
| :background | :foreground |

#+ATTR_ODT: :target "extra_styles"
#+begin_src nxml
<style:style style:name="MyBigTableContents"
             style:next-style-name="Text_20_body"
             style:family="paragraph"
             style:class="text">
  <style:text-properties fo:font-size="24pt" />
</style:style>
#+end_src

Reprehenderit officia proident, culpa ut fugiat nulla fugiat
exercitation nulla pariatur deserunt cupidatat fugiat nulla ad.

| Status | SUMMARY       | Nr. | Datum        | Rechnungssteller |
|--------+---------------+-----+--------------+------------------|
|        |               |     |              | Rechnungssteller |
| TODO   | !!Nonsense?!! | 583 | [email protected]!@ | Blabla           |
|        |               |     |              |                  |

#+ATTR_ODT: :p-style "MyBigTable" :page-style "Landscape" :page-break t
| Status | SUMMARY       | Nr. | Datum        | Rechnungssteller |
|--------+---------------+-----+--------------+------------------|
|        |               |     |              | Rechnungssteller |
| TODO   | !!Nonsense?!! | 583 | [email protected]!@ | Blabla           |
|        |               |     |              |                  |

#+ATTR_ODT: :page-break t :page-style "Standard"
Esse non velit sed dolor non fugiat sint lorem magna aliqua laborum
consequat eiusmod enim velit pariatur est laborum.  Ut quis magna
officia aute lorem deserunt ex.  In laborum ad eiusmod nulla laborum
laborum adipiscing.  Magna sit sit aliqua exercitation minim anim sed
sunt ullamco ipsum sint dolor ut culpa mollit excepteur nostrud lorem
amet,.  Laboris aliquip sunt sunt excepteur commodo veniam, non sunt
cupidatat sed nostrud reprehenderit commodo nisi quis.  Non sed
occaecat velit nostrud est ea excepteur.  Est commodo qui aliqua
incididunt reprehenderit ex consequat qui consectetur quis magna
adipiscing velit consectetur.

* Proident, pariatur est aliqua laborum commodo
:PROPERTIES:
:ATTR_ODT: :page-break t :page-style "Landscape"
:END:


Ea laborum nostrud officia velit nulla incididunt consectetur pariatur
eiusmod ea anim aliqua.  Lorem dolore est esse amet, magna lorem
pariatur.  Minim dolore consectetur aliqua tempor exercitation
incididunt quis.  Ullamco exercitation lorem qui in dolor ad irure
sunt non deserunt.  Est laborum tempor consequat lorem magna minim
velit.  Deserunt incididunt labore officia ea id quis nisi aute
occaecat.

kjambunathan avatar Jul 16 '22 03:07 kjambunathan

TIP: Convenient way to add ODT styles to an org file

To copy an XML snippet from ODT file to org files, do this

  1. Install HTML tidy
  2. Copy the XML from styles.xml or contents.xml to clipboard.
  3. Visit Org file, and do C-u <C-m> C-y or C-u C-u <C-m> C-y. For most cases, pressing RET on the default choice will insert the XML monster.
(add-hook 'org-mode-hook
	  (defun my-org-mode-hook-1 ()
	    (local-set-key (kbd "<C-m> C-y")  ;; change key to whatever you want.  `<C-m>' is my own keysym.
			   #'org-odt-yank-styles)))

kjambunathan avatar Jul 16 '22 04:07 kjambunathan

Table styles are complex ..

A TableStyle is a prefix ... and it gets added to the Table, TableColumn, TableCell, and Paragraph. So, when you add a style to a Table you need to specify a style for each of these things that make up the table.

In the example below MyBigTable is the base style, and with a suffix of Contents it specifies the style for all paragraphs contained within it. IOW, to define a paragraph style for Table just define a style for <base style> + Contents

#+begin_src nxml
<style:style style:name="MyBigTableContents"
             style:next-style-name="Text_20_body"
             style:family="paragraph"
             style:class="text">
  <style:text-properties fo:font-size="24pt" />
</style:style>
#+end_src

#+ATTR_ODT: :p-style "MyBigTable" :page-style "Landscape" :page-break t
| Status | SUMMARY       | Nr. | Datum        | Rechnungssteller |

kjambunathan avatar Jul 16 '22 04:07 kjambunathan

You need to add the small font table style for different table heading and different table contents, which I think is not convenient, I wish the font style and font size can be easily changed without this extra hassle. Then change the paragraph style of the table. table paragraph style setting

#+attr_odt: :p-style "Table_0.8"

extra style:

<style:style style:name="Table_0.8Contents" style:family="paragraph" style:parent-style-name="Standard">
  <style:text-properties fo:font-size="80%"
                         style:font-size-asian="80%"
                         style:font-size-complex="80%"
                         style:class="text"/>
</style:style>
<style:style style:name="Table_0.8Heading" style:family="paragraph" style:parent-style-name="Table_0.8Contents" style:class="extra">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>
  <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Table_0.8HeadingLeft" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="left" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8HeadingRight" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="right" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8HeadingCenter" style:family="paragraph" style:parent-style-name="Table_0.8Heading">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsLeft" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="left" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsRight" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="right" style:justify-single-word="false"/>
</style:style>
<style:style style:name="Table_0.8ContentsCenter" style:family="paragraph" style:parent-style-name="Table_0.8Contents">
  <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>

I have attached an example. fonts.org.txt

thanks to both of you for the solutions! There is one subtle point, however. If I generate a table by using columnview

#+BEGIN: columnview :maxlevel 2 :skip-empty-rows t :hlines 1 :indent nil  :format " %12TODO(Status) %5SUMMARY(Summary)  %5NUMMER(Nr.) %12DATUM(Datum) %20ITEM(Company)"
| Status | Summary                     | Nr. | Datum        | Company  |
|--------+-----------------------------+-----+--------------+----------|
| TODO   | !!08.12.2022 is nonsense?!! | 583 | !!08.12.22!! | RedCross |
#+END

then

#+attr_odt: :style "GriddedTable" :p-style "Table_0.6"
#+BEGIN: columnview :maxlevel 2 :skip-empty-rows t :hlines 1 :indent nil  :format " %12TODO(Status) %5SUMMARY(Summary)  %5NUMMER(Nr.) %12DATUM(Datum) %20ITEM(Company)"
| Status | Summary                     | Nr. | Datum        | Company  |
|--------+-----------------------------+-----+--------------+----------|
| TODO   | !!08.12.2022 is nonsense?!! | 583 | !!08.12.22!! | RedCross |
#+END

does not work for the font export, however

#+BEGIN: columnview :maxlevel 2 :skip-empty-rows t :hlines 1 :indent nil  :format " %12TODO(Status) %5SUMMARY(Summary)  %5NUMMER(Nr.) %12DATUM(Datum) %20ITEM(Company)"
#+attr_odt: :style "GriddedTable" :p-style "Table_0.6"
| Status | Summary                     | Nr. | Datum        | Company  |
|--------+-----------------------------+-----+--------------+----------|
| TODO   | !!08.12.2022 is nonsense?!! | 583 | !!08.12.22!! | RedCross |
#+END

works, but then in the org file columnview does not work any longer! I attach the org file and odt file just in case thanks again and regards Fonts.zip

ouboub avatar Jul 16 '22 05:07 ouboub

Table styles are complex ..

A TableStyle is a prefix ... and it gets added to the Table, TableColumn, TableCell, and Paragraph. So, when you add a style to a Table you need to specify a style for each of these things that make up the table.

In the example below MyBigTable is the base style, and with a suffix of Contents it specifies the style for all paragraphs contained within it. IOW, to define a paragraph style for Table just define a style for <base style> + Contents

#+begin_src nxml
<style:style style:name="MyBigTableContents"
             style:next-style-name="Text_20_body"
             style:family="paragraph"
             style:class="text">
  <style:text-properties fo:font-size="24pt" />
</style:style>
#+end_src

#+ATTR_ODT: :p-style "MyBigTable" :page-style "Landscape" :page-break t
| Status | SUMMARY       | Nr. | Datum        | Rechnungssteller |

thanks, looking at it I thought I could use it somehow to make my original org file a bit tidier, basically I want landscape as a default, so I deleted most of the style stuff I had in my org file and put your code in, the table indeed is in landscape but not the rest. landscape-default.zip

ouboub avatar Jul 16 '22 06:07 ouboub

#+ATTR_ODT:  :page-style "Landscape" :page-break t
* TODO !!Unclear!!

The attribute applies to the (empty) paragraph before the heading. So the heading will not get a new page style.


This is how you open a headline on new page

* Proident, pariatur est aliqua laborum commodo
:PROPERTIES:
:ATTR_ODT: :page-break t :page-style "Landscape"
:END:

and this is how you open a paragraph on a new page


#+ATTR_ODT: :page-break t :page-style "Standard"
Esse non velit sed dolor non fugiat sint lorem magna aliqua laborum
consequat eiusmod enim velit pariatur est laborum.

It is not the table that is landscape. It is the page that is in landscape, within which the table goes in. So, if you want the table on its own page you want to flank it with page styles on either side, the leading one says "Landscape" and trailing one says "Standard".

In LibreOffice, once a page style is applied it continues on in same style, until you switch over. So, if the table is not followed with a page break, the text following the table will appear on the same page. Experiment with the example I shared with you.

kjambunathan avatar Jul 16 '22 07:07 kjambunathan

Thanks

I modified the example I attached in my earlier message and

I added

  • Proident, pariatur est aliqua laborum commodo :PROPERTIES: :ATTR_ODT: :page-style "Landscape" :END:

which indeed put the following page and all the others landscape, but I obtained also an empty first page (in portrait) I am really sorry for this elementary question

I also tried to put the header at the beginning of the document, before the style part, it did not help?

ouboub avatar Jul 16 '22 07:07 ouboub

Params is basically a emacs-lisp plist without surrounding (..). So, you need to quote the " as you would in your *.el sources. So, append a :content property as you see below to your columnview block

:id "Bills" :content "#+attr_odt: :style \"GriddedTable\" :p-style \"Table_0.6\""

The line is too big. Here is a screenshot. Note that emacs is wrapping the line.

Screenshot: Quote the quotes Screenshot from 2022-07-16 13-41-16


File a bug against org ...

In org-dblock-write:columnview

Change the loop@L1539

  ;; Insert affiliated keywords before the table.
  (when content-lines
    (while (string-match-p "\\`[ \t]*#\\+" (car content-lines))
      (insert (pop content-lines) "\n")))

to

  ;; Insert affiliated keywords before the table.
  (when content-lines
    (while (and content-lines (string-match-p "\\`[ \t]*#\\+" (car content-lines)))
      (insert (pop content-lines) "\n")))

Basically,

diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 829fcbbe3..c1cc7bb76 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -1538,7 +1538,7 @@ PARAMS is a property list of parameters:
 	    recalc)
 	;; Insert affiliated keywords before the table.
 	(when content-lines
-	  (while (string-match-p "\\`[ \t]*#\\+" (car content-lines))
+	  (while (and content-lines (string-match-p "\\`[ \t]*#\\+" (car content-lines)))
 	    (insert (pop content-lines) "\n")))
 	(save-excursion
 	  ;; Insert table at point.

kjambunathan avatar Jul 16 '22 08:07 kjambunathan

This is the way to create a Landscape document ...

The options line should turn off all the metadata. And any metadata that you want, you have to use the pre-defined org macro (as you see below for Title)

#+options: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline
#+options: author:nil broken-links:mark c:nil creator:nil
#+options: d:(not "LOGBOOK") date:nil e:t email:nil f:t inline:t num:t
#+options: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+options: timestamp:t title:nil toc:nil todo:t |:t
#+title: This is a fully landscape document
#+date: <2022-07-16 Sat>
#+author: Jambunathan K
#+email: [email protected]
#+language: en
#+select_tags: export
#+exclude_tags: noexport
#+creator: Emacs 29.0.50 (Org mode 9.5.4)
#+cite_export:

#+ATTR_ODT: :style "OrgTitle" :page-break "before" :page-style "Landscape"
{{{title}}}

Et veniam, nostrud et ea in voluptate excepteur excepteur pariatur
cupidatat.  Nulla nisi culpa exercitation in eu elit, do laboris ut
nisi proident, elit,.  Nostrud aliqua adipiscing et consectetur ea
eiusmod reprehenderit.  Ut laborum aute id mollit qui commodo
incididunt adipiscing aliqua id aliquip lorem reprehenderit occaecat
anim ea quis irure.  Quis veniam, pariatur qui deserunt commodo minim
aliqua.

#+ATTR_ODT: :style "GriddedTable" :rel-width 20
| 1 | 2 |
| 3 | 4 |

kjambunathan avatar Jul 16 '22 08:07 kjambunathan

I am really sorry for this elementary question

That is Ok .....

... but if you are going to use the ODT exporter, you need to spend time learning how LibreOffice works. I have put some references in README of this project.

kjambunathan avatar Jul 16 '22 08:07 kjambunathan

I also tried to put the header at the beginning of the document, before the style part, it did not help?

That is a good suggesteion ... File level :PROPERTIES: block were added s part of org-roam. IOW, it is a very recent development, as recent as last 2-3 years. I will consider the feasibility of adding what you are suggesting here. For now, go with the suggestion in the previous message.

kjambunathan avatar Jul 16 '22 08:07 kjambunathan

thanks, works nicely (I will add this to by Manual Directories)

ouboub avatar Jul 16 '22 12:07 ouboub

I am really sorry for this elementary question

That is Ok .....

... but if you are going to use the ODT exporter, you need to spend time learning how LibreOffice works. I have put some references in README of this project.

right, I usually stick for latex for my work, but very occasionally I need to convert complex org files, (last year August a document with very very complex tables that I could not have managed without your help) so this discontinous workflow is a bit of problem, but it is a lame excuse for not studying the exporter in more detail, I admit

ouboub avatar Jul 16 '22 12:07 ouboub

for not studying the exporter

I didn't mean that you look at the ox-odt.el part. You are welcome to ask question about the exporter, and you will get detailed help with screenshot and sample files every single time.

I was talking about a general familiarity with the LibreOffice app.

Ultimately, stuff like how the page break and page style directives etc are modelled in the odt exporter, is dictated by what the LibreOffice itself does.

For example, your recent "why there is a blank page etc", could have been very well answered by yourself, if you had some familiarity with LibreOffice.

I am happy to help. The ODS stuff will land soon ...

kjambunathan avatar Jul 16 '22 12:07 kjambunathan

The point is I rarely use LO. I write almost my entire work in emacs, either in latex or in org mode, but since sometimes organizations require odt (or docx) I use it as an additional document, but I have to admit that I find emacs so mucho more comfortable, as far as editing is concerned.

I really appreciate you help and more than once saved my day to say the least

ouboub avatar Jul 16 '22 17:07 ouboub

Params is basically a emacs-lisp plist without surrounding (..). So, you need to quote the " as you would in your *.el sources. So, append a :content property as you see below to your columnview block

:id "Bills" :content "#+attr_odt: :style \"GriddedTable\" :p-style \"Table_0.6\""

The line is too big. Here is a screenshot. Note that emacs is wrapping the line.

Screenshot: Quote the quotes Screenshot from 2022-07-16 13-41-16

File a bug against org ...

In org-dblock-write:columnview

Change the loop@L1539

  ;; Insert affiliated keywords before the table.
  (when content-lines
    (while (string-match-p "\\`[ \t]*#\\+" (car content-lines))
      (insert (pop content-lines) "\n")))

to

  ;; Insert affiliated keywords before the table.
  (when content-lines
    (while (and content-lines (string-match-p "\\`[ \t]*#\\+" (car content-lines)))
      (insert (pop content-lines) "\n")))

Basically,

diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 829fcbbe3..c1cc7bb76 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -1538,7 +1538,7 @@ PARAMS is a property list of parameters:
 	    recalc)
 	;; Insert affiliated keywords before the table.
 	(when content-lines
-	  (while (string-match-p "\\`[ \t]*#\\+" (car content-lines))
+	  (while (and content-lines (string-match-p "\\`[ \t]*#\\+" (car content-lines)))
 	    (insert (pop content-lines) "\n")))
 	(save-excursion
 	  ;; Insert table at point.

ah very good, I will send this bug report hopefully today

ouboub avatar Jul 16 '22 17:07 ouboub

+	  (while (and content-lines (string-match-p "\\`[ \t]*#\\+" (car content-lines)))

this diff (patch of yours) against which commit does it apply I am asking because this loop is in line 1542 in the versions I checked. most likely this is of little importance...

ouboub avatar Jul 16 '22 20:07 ouboub

Org has too many branches: https://git.savannah.gnu.org/cgit/emacs/org-mode.git/tree/

Yes. line 1542 here https://git.savannah.gnu.org/cgit/emacs/org-mode.git/tree/lisp/org-colview.el#n1542 (whatever that branch may be)

bugfix | Backport commit 1f6750b53 from Emacs | Stefan Kangas | 3 weeks
-- | -- | -- | --
emacs-sync | Update hard-coded versions for sync with Emacs | Kyle Meyer | 3 weeks
main | org: Add setting for remote file download policy | TEC | 19 hours
 ```

kjambunathan avatar Jul 17 '22 04:07 kjambunathan