kjambunathan / org-mode-ox-odt

The Authoritative fork of Org mode's ODT exporter
GNU General Public License v3.0
45 stars 9 forks source link

Feature proposal: margin notes #169

Open ouboub opened 2 years ago

ouboub commented 2 years ago

Hi

LO offers the possibility to add comments, as margin notes. Any change to support this (at least margin notes) when exporting from org?

regards

Uwe Brauer

kjambunathan commented 2 years ago

LO Bug#44597 – FORMATTING: Margin notes (similar to footnotes, but vertically linked to content) should be enabled

See if this is what you want. marginnotes.zip

The babel block does the plumbing. The idea is to use the footnote label as a clue to decide if a note is a margin note, and if yes where it goes and how it is anchored.

As an aside, there is a built in support for endnote which uses the "use the footnote label as a clue to the note-type" strategy. See https://github.com/kjambunathan/org-mode-ox-odt/blob/master/notes/SNIPPETS.org#support-for-generating-endnotes-see-org-odt-endnote-regexp)

marginnotes

(cl-defun org-odt--sidenote (text &key width height style
                                    x y extra anchor)
  (org-odt--textbox text width height style (mapconcat #'identity
                                                       (list extra (when x
                                                                     (format " svg:x=\"%.2fcm\"" x))
                                                             (when y
                                                               (format " svg:y=\"%.2fcm\"" y)))
                                                       " ")
                    anchor))

(advice-add 'org-odt-footnote-reference :around
            (defun my-org-odt-footnote-reference (orig-fun &rest args)
              (pcase-let ((`(,footnote-reference ,_contents ,info) args))
                (let* ((margin-note-alist '((margin-note/left/paragraph . (:style "OrgMarginNote"
                                                                                  :width 3
                                                                                  :x 2))
                                            (margin-note/right/paragraph . (:style "OrgMarginNote"
                                                                                   :width 3
                                                                                   :x 15.8))
                                            (margin-note/paragraph . (:style "OrgMarginNote"
                                                                             :width 3
                                                                             :x 15.8))
                                            (margin-note/left/character . (:style "OrgMarginNote"
                                                                                  :width 3
                                                                                  :x 2
                                                                                  :anchor "char"))
                                            (margin-note/right/character . (:style "OrgMarginNote"
                                                                                   :width 3
                                                                                   :x 15.8
                                                                                   :anchor "char"))
                                            (margin-note/character . (:style "OrgMarginNote"
                                                                             :width 3
                                                                             :x 15.8
                                                                             :anchor "char"))))
                       (label (org-element-property :label footnote-reference))
                       (sidenote-type (when (stringp label)
                                        (cond
                                         ((string-match-p "^lmnc" label)
                                          'margin-note/left/character)
                                         ((string-match-p "^rmnc" label)
                                          'margin-note/right/character)
                                         ((string-match-p "^mnc" label)
                                          'margin-note/character)
                                         ((string-match-p "^lmn" label)
                                          'margin-note/left/paragraph)
                                         ((string-match-p "^rmn" label)
                                          'margin-note/right/paragraph)
                                         ((string-match-p "^mn" label)
                                          'margin-note/paragraph))))
                       (def (org-export-get-footnote-definition
                             footnote-reference info)))
                  (cond
                   (sidenote-type
                    (when (org-export-footnote-first-reference-p footnote-reference info nil t)
                      (apply #'org-odt--sidenote (cons (org-trim (org-export-data def
                                                                                  info))
                                                       (alist-get sidenote-type margin-note-alist)))))
                   (t (apply orig-fun args)))))))
#+title: Margin Notes

#+odt_preferred_output_format: png
#+odt_validate: abort
#+odt_prettify_xml:

#+odt_extra_styles: <style:style style:name="Footnote"
#+odt_extra_styles:              style:parent-style-name="Text_20_body"
#+odt_extra_styles:              style:family="paragraph" />

#+odt_extra_styles: <style:style style:name="MyFooter"
#+odt_extra_styles:              style:parent-style-name="Footer"
#+odt_extra_styles:              style:family="paragraph">
#+odt_extra_styles:   <style:paragraph-properties fo:text-align="center"
#+odt_extra_styles:                               style:justify-single-word="false" />
#+odt_extra_styles: </style:style>

#+odt_extra_automatic_styles: <style:page-layout style:name="MyPage"
#+odt_extra_automatic_styles:                    style:page-usage="mirrored">
#+odt_extra_automatic_styles:   <style:page-layout-properties fo:margin-bottom="2cm"
#+odt_extra_automatic_styles:                           fo:margin-left="5.399cm"
#+odt_extra_automatic_styles:                           fo:margin-right="5.399cm"
#+odt_extra_automatic_styles:                           fo:margin-top="2cm"
#+odt_extra_automatic_styles:                           fo:page-height="29.7cm"
#+odt_extra_automatic_styles:                           fo:page-width="21.001cm"
#+odt_extra_automatic_styles:                           style:footnote-max-height="0cm"
#+odt_extra_automatic_styles:                           style:layout-grid-base-height="0.706cm"
#+odt_extra_automatic_styles:                           style:layout-grid-color="#c0c0c0"
#+odt_extra_automatic_styles:                           style:layout-grid-display="false"
#+odt_extra_automatic_styles:                           style:layout-grid-lines="20"
#+odt_extra_automatic_styles:                           style:layout-grid-mode="none"
#+odt_extra_automatic_styles:                           style:layout-grid-print="false"
#+odt_extra_automatic_styles:                           style:layout-grid-ruby-below="false"
#+odt_extra_automatic_styles:                           style:layout-grid-ruby-height="0.353cm"
#+odt_extra_automatic_styles:                           style:num-format="1"
#+odt_extra_automatic_styles:                           style:print-orientation="portrait"
#+odt_extra_automatic_styles:                           style:writing-mode="lr-tb">
#+odt_extra_automatic_styles:     <style:footnote-sep style:adjustment="left"
#+odt_extra_automatic_styles:                   style:color="#000000"
#+odt_extra_automatic_styles:                   style:distance-after-sep="0.101cm"
#+odt_extra_automatic_styles:                   style:distance-before-sep="0.101cm"
#+odt_extra_automatic_styles:                   style:line-style="solid"
#+odt_extra_automatic_styles:                   style:rel-width="25%"
#+odt_extra_automatic_styles:                   style:width="0.018cm" />
#+odt_extra_automatic_styles:   </style:page-layout-properties>
#+odt_extra_automatic_styles:   <style:header-style />
#+odt_extra_automatic_styles:   <style:footer-style>
#+odt_extra_automatic_styles:     <style:header-footer-properties fo:margin-left="0cm"
#+odt_extra_automatic_styles:                                     fo:margin-right="0cm"
#+odt_extra_automatic_styles:                                     fo:margin-top="0.499cm"
#+odt_extra_automatic_styles:                                     fo:min-height="0.6cm"
#+odt_extra_automatic_styles:                                     style:dynamic-spacing="false" />
#+odt_extra_automatic_styles:   </style:footer-style>
#+odt_extra_automatic_styles: </style:page-layout>

#+odt_master_styles: <style:master-page style:name="Standard"
#+odt_master_styles:                    style:page-layout-name="MyPage">
#+odt_master_styles:   <style:footer>
#+odt_master_styles:     <text:p text:style-name="MyFooter">
#+odt_master_styles:       <text:page-number text:select-page="current">1</text:page-number>
#+odt_master_styles:     </text:p>
#+odt_master_styles:   </style:footer>
#+odt_master_styles: </style:master-page>

#+odt_extra_styles: <style:style style:name="OrgMarginNote"
#+odt_extra_styles:              style:parent-style-name="Frame"
#+odt_extra_styles:              style:family="graphic">
#+odt_extra_styles:   <style:graphic-properties draw:shadow-opacity="100%"
#+odt_extra_styles:                             fo:border="none"
#+odt_extra_styles:                             fo:min-height="0.041cm"
#+odt_extra_styles:                             fo:padding="0cm"
#+odt_extra_styles:                             style:horizontal-pos="from-left"
#+odt_extra_styles:                             style:horizontal-rel="page-start-margin"
#+odt_extra_styles:                             style:shadow="none"
#+odt_extra_styles:                             style:vertical-pos="top"
#+odt_extra_styles:                             style:vertical-rel="paragraph-content"
#+odt_extra_styles:                             svg:width="3cm"
#+odt_extra_styles:                             svg:x="0cm"
#+odt_extra_styles:                             svg:y="0cm"
#+odt_extra_styles:                             text:anchor-type="paragraph" />
#+odt_extra_styles: </style:style>

See [[https://bugs.documentfoundation.org/show_bug.cgi?id=44597][lo bug#44597 – FORMATTING: Margin notes (similar to footnotes, but vertically linked to content) should be enabled]]

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce
tristique luctus nulla vel dictum. Sed consectetur vestibulum elit
eget placerat. Etiam commodo porttitor diam. Quisque quam turpis,
tristique nec imperdiet quis, aliquam ut libero. Praesent non ipsum
quis nisl ullamcorper fermentum. Mauris ultrices elit at sapien
scelerisque fringilla. In id purus eget lorem tempus pulvinar vitae
sed leo. Fusce varius est ullamcorper urna vestibulum
bibendum. Curabitur diam elit, rutrum sit amet auctor non, consequat
eget tortor. Phasellus sem elit, tempus ultrices auctor ac, pretium ut
lectus. Nunc tortor metus, tempor in scelerisque quis, vulputate in
arcu. Etiam rutrum, neque eget hendrerit bibendum, neque metus
hendrerit leo, sit amet vehicula magna enim a orci. Nulla eget nulla
ipsum, at faucibus diam. Donec est nibh, auctor vel molestie id,
viverra eu odio. Sed ac erat sit amet felis mattis tempor.[fn:lmn1][fn:rmn2]

In sit amet orci vel quam tincidunt feugiat. Sed ut nisl quis
orci feugiat bibendum rutrum sit amet mauris. [fn:rmnc4] Nullam at mi et
dolor dictum rutrum eu non libero. Ut egestas, ipsum nec vulputate
laoreet, libero augue porttitor urna, ac porta purus velit id
neque. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Vivamus at risus a magna ornare
egestas pellentesque et ligula. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia Curae; Fusce nec urna
id enim tempus molestie sed id velit. Curabitur dictum aliquet
mi. Donec congue dignissim pharetra. Donec at turpis dolor. Aenean
ornare suscipit arcu vitae luctus. Nam eget arcu eget nulla tempor
porta. Integer ac augue orci, ac mollis mi. Integer mauris dui,
accumsan nec commodo eu, facilisis faucibus dui. Morbi varius placerat
interdum.[fn:lmn3]

Integer a metus sed tellus fringilla pharetra. Curabitur consequat
lobortis felis vitae tristique. Duis augue justo, imperdiet vitae
consectetur sit amet, ultricies vitae orci. Morbi feugiat justo at
nibh ornare quis tincidunt arcu dictum. Vestibulum ac sem eu nisl
laoreet ultricies.

[fn:lmn1]

#+ATTR_ODT: :p-style "Text_20_body_20"
#+begin_marginnote
Hello, I'm a margin note in the left margin.
#+end_marginnote

[fn:rmn2]

I'm a right margin note. To insert me, or my friend on the
left, use Insert→Frame.

[fn:lmn3]

I can be anchored to the paragraph, page, or a character (like in
LaΤεΧ)

[fn:rmnc4]

This note is anchored to the “N” in “nullam”—just like in LaΤεΧ.
kjambunathan commented 2 years ago

You can comment out the following lines

#+odt_preferred_output_format: png
#+odt_validate: abort
#+odt_prettify_xml:

if you haven't installed tidy, odfvalidator and odt->png converter.

ouboub commented 2 years ago

You can comment out the following lines

#+odt_preferred_output_format: png
#+odt_validate: abort
#+odt_prettify_xml:

if you haven't installed tidy, odfvalidator and odt->png converter.

ok I did commen these out, and it works very nicely. I have tidy installed, so I would be interested in a pointer to odfvalidador and odt->png.

thanks again, very very useful

bc-abe commented 2 years ago

When I attempt to convert the marginnotes.org I get this error:

org-odt--textbox: Keyword argument 3 not one of (:width :height :rel-width :style :extra :anchor)

kjambunathan commented 2 years ago

Use the below mentioned snippet .... No need to change the org file contents or style.

Do you think it will be useful to have marginotes right in the git repo ... I will be happy to hear feedback

(cl-defun org-odt--sidenote (text &key width height style
                  x y extra anchor)
  (org-odt--textbox text
            :width width
            :height height
            :style style
            :extra (mapconcat #'identity
                      (list extra (when x
                            (format " svg:x=\"%.2fcm\"" x))
                        (when y
                          (format " svg:y=\"%.2fcm\"" y)))
                      " ")
            :anchor anchor))

(defun my-org-odt-footnote-reference (orig-fun &rest args)
  (pcase-let ((`(,footnote-reference ,_contents ,info) args))
    (let* ((margin-note-alist
        '((margin-note/left/paragraph . (:style "OrgMarginNote"
                            :width 3
                            :x 2))
          (margin-note/right/paragraph . (:style "OrgMarginNote"
                             :width 3
                             :x 15.8))
          (margin-note/paragraph . (:style "OrgMarginNote"
                           :width 3
                           :x 15.8))
          (margin-note/left/character . (:style "OrgMarginNote"
                            :width 3
                            :x 2
                            :anchor "char"))
          (margin-note/right/character . (:style "OrgMarginNote"
                             :width 3
                             :x 15.8
                             :anchor "char"))
          (margin-note/character . (:style "OrgMarginNote"
                           :width 3
                           :x 15.8
                           :anchor "char"))))
       (label (org-element-property :label footnote-reference))
       (sidenote-type
        (when (stringp label)
          (cond
           ((string-match-p "^lmnc" label) 'margin-note/left/character)
           ((string-match-p "^rmnc" label) 'margin-note/right/character)
           ((string-match-p "^mnc" label) 'margin-note/character)
           ((string-match-p "^lmn" label) 'margin-note/left/paragraph)
           ((string-match-p "^rmn" label) 'margin-note/right/paragraph)
           ((string-match-p "^mn" label) 'margin-note/paragraph))))
       (def (org-export-get-footnote-definition
         footnote-reference info)))
      (cond
       (sidenote-type
    (when (org-export-footnote-first-reference-p footnote-reference info nil t)
      (apply #'org-odt--sidenote (cons (org-trim (org-export-data def
                                      info))
                       (alist-get sidenote-type margin-note-alist)))))
       (t (apply orig-fun args))))))

(advice-add 'org-odt-footnote-reference :around
        #'my-org-odt-footnote-reference)
kjambunathan commented 2 years ago

You can remove these /comment out from the top of the org snippet.


#+odt_preferred_output_format: png
#+odt_validate: abort
#+odt_prettify_xml:

I am not sure how well the marginnotes show up on Microsoft Word. I don't have access to Microsoft Word. If by any chance, you have access to MS Word, and the export via odt -> doc (or docx) and then subsequent MS Word / Google Docs has problems, I will be happy to investigate the compatibility issues. Just giving you a headsup on what you can expect on MS Word side of things. If you (or your congregation?) are using LO only then no need to bother about compatibility at all. It should just work.

bc-abe commented 2 years ago

Using LO. Worked. Thanks! I'm not sure about margin notes in the repo, but I'm very thankful that this works now.

I wouldn't know how many people would use it, and those who would probably will will find this issue easy enough.