* ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
@ 2016-08-08 1:31 Jake Romer
2016-08-08 13:35 ` Nicolas Goaziou
0 siblings, 1 reply; 10+ messages in thread
From: Jake Romer @ 2016-08-08 1:31 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1.1: Type: text/plain, Size: 478 bytes --]
Hi all,
I notice that in Org 8.3, `org-md-export-as-markdown` and
`org-md-export-to-markdown` render a document's Table of Contents and
Footnotes sections as HTML rather than Markdown.
I have a couple of patches that change this behavior so that both are
rendered as Markdown. I'd love to hear any thoughts or suggestions for
improvement if you think this would be useful to include in ox-md.el.
A description of the changes is attached in the accompanying Org doc.
Thanks!
[-- Attachment #1.2: Type: text/html, Size: 604 bytes --]
[-- Attachment #2: render-toc-and-fn-as-md.org --]
[-- Type: application/octet-stream, Size: 7772 bytes --]
* Summary of Changes
#+TITLE: Render TOC and Footnotes as Markdown
#+AUTHOR: Jake Romer
#+EMAIL: jkrmr@github.com
#+DATE: 2016-08-07
The included patch updates ox-md.el so that it generates Table of Contents and
Footnotes sections in Markdown. Currently it generates these in HTML.
* Render footnotes section as Markdown
An example footnotes section, in the Org source:
#+BEGIN_SRC org
* Footnotes
[fn:1] for example, when an issue has received no activity in over three months.
(We can perhaps make that threshold configurable.)
[fn:2] Another footnote
#+END_SRC
The exported Markdown before and after the patch is applied follows:
** Before
#+BEGIN_SRC html
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara">for example, when an issue has received no activity in over three months.
(We can perhaps make that threshold configurable.)</div></div>
<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> <div class="footpara">Another footnote</div></div>
</div>
</div>
#+END_SRC
** Patch
Previously, ~org-md-inner-template~ delegated to ~org-html-inner-template~ and
just modified how ~contents~ was parsed. Since my ultimate aim was to render
the entire document as Markdown and not just the main body, I departed from that
approach and transcoded each section (TOC, body, Footnotes) to Markdown strings,
using the approach taken by Lars Tveito in his [[https://github.com/larstvei/ox-gfm][ox-gfm]] exporter.
#+BEGIN_SRC diff
(defun org-md-inner-template (contents info)
@@ -474,7 +536,15 @@ CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
;; Make sure CONTENTS is separated from table of contents and
;; footnotes with at least a blank line.
- (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
+ (let* ((depth (plist-get info :with-toc))
+ (headlines (and depth (org-export-collect-headlines info depth)))
+ (toc-string (org-html-toc depth info))
+ (toc-tail (if headlines "\n\n" ""))
+ (footnotes (org-md-footnote-section info)))
+ (org-trim (concat toc-string
+ toc-tail
+ contents
+ footnotes))))
#+END_SRC
The key addition here is ~org-md-footnote-section~, which modifies
~org-html-footnote-section~ from [[http://orgmode.org/w/?p=org-mode.git;a=blob_plain;f=lisp/ox-html.el;hb=HEAD][ox-html.el]], removing unnecessary HTML tags and
invoking ~org-md-footnote-section-header~ (in the listing below) to generate the
section heading.
#+BEGIN_SRC emacs-lisp
;;;; Footnotes Section
(defun org-md-footnote-section (info)
"Format the footnote section as Markdown.
INFO is a plist used as a communication channel."
(let* ((fn-alist (org-export-collect-footnote-definitions info))
(fn-alist
(loop for (n type raw) in fn-alist collect
(cons n (org-trim (org-export-data raw info))))))
(when fn-alist
(format
(org-md-footnote-section-header info)
(format
"\n%s\n"
(mapconcat
(lambda (fn)
(let ((n (car fn)) (def (cdr fn)))
(format
"%s %s\n"
(format
(plist-get info :md-footnote-format)
(org-html--anchor
(format "fn.%d" n)
n
(format " href=\"#fnr.%d\"" n)
info))
def)))
fn-alist
"\n"))))))
#+END_SRC
#+BEGIN_SRC emacs-lisp
;;;; Footnotes Section Header
(defun org-md-footnote-section-header (info)
"Renders a template for the footnotes section header in the preferred style.
INFO is used as a communication channel."
(let ((style (plist-get info :md-headline-style))
(section-title (plist-get info :md-footnote-section-title)))
(cond
((equal style 'atx) (format "\n%s %s\n%%s\n" "##" section-title))
((equal style 'setext) (format "\n%s\n%s\n%%s\n"
section-title
(make-string (length section-title) ?-))))))
#+END_SRC
Note that the footnote section title and the footnote format are both
user-customizable, and the footnote section header is rendered in the preferred
style (atx or setext).
#+BEGIN_SRC emacs-lisp
(defcustom org-md-footnote-format "<sup>%s</sup>"
"The format for the footnote reference.
%s will be replaced by the footnote reference itself."
:group 'org-export-md
:type 'string)
(defcustom org-md-footnote-section-title "Footnotes"
"The title for the Footnotes section.
Example: `Footnotes', `References', `Sources', etc."
:group 'org-export-md
:type 'string)
#+END_SRC
** After
#+BEGIN_SRC markdown
## Footnotes
<sup><a id="fn.1" href="#fnr.1">1</a></sup> for example, when an issue has received no activity in over three months.
(We can perhaps make that threshold configurable.)
<sup><a id="fn.2" href="#fnr.2">2</a></sup> Another footnote
#+END_SRC
* Render table of contents as Markdown
An example table of contents, in the Org source:
#+BEGIN_SRC org
* Feature: Issue Reaping
* Motivation
* Scenarios
* Tasks
* Prior art
** Org settings panel left nav
** Viewing an organization's Member privileges
** Updating an organization's Repository creation setting
* TODO Implementation notes
#+END_SRC
The exported Markdown before and after the patch is applied follows:
** Before
#+BEGIN_SRC html
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgheadline1">1. Feature: Issue Reaping</a></li>
<li><a href="#orgheadline2">2. Motivation</a></li>
<li><a href="#orgheadline3">3. Scenarios</a></li>
<li><a href="#orgheadline4">4. Tasks</a></li>
<li><a href="#orgheadline8">5. Prior art</a>
<ul>
<li><a href="#orgheadline5">5.1. Org settings panel left nav</a></li>
<li><a href="#orgheadline6">5.2. Viewing an organization's Member privileges</a></li>
<li><a href="#orgheadline7">5.3. Updating an organization's Repository creation setting</a></li>
</ul>
</li>
<li><a href="#orgheadline9">6. <span class="todo TODO">TODO</span> Implementation notes</a></li>
</ul>
</div>
</div>
#+END_SRC
** Patch
In ~org-md-inner-template~, we replace ~org-html-toc~ with a string generated by
applying ~org-md-format-toc~ (credit to [[https://github.com/larstvei/ox-gfm/blob/master/ox-gfm.el#L233-L242][Lars Tveito]] again) across the set of
~headlines~.
#+BEGIN_SRC diff
- (toc-string (org-html-toc depth info))
+ (toc-string (or (mapconcat 'org-md-format-toc headlines "\n") ""))
(toc-tail (if headlines "\n\n" ""))
#+END_SRC
#+BEGIN_SRC emacs-lisp
;;;; Table of contents
(defun org-md-format-toc (headline)
"Return an appropriate table of contents entry for HEADLINE.
INFO is a plist used as a communication channel."
(let* ((title (org-export-data (org-export-get-alt-title headline info) info))
(level (1- (org-element-property :level headline)))
(indent (concat (make-string (* level 2) ? )))
(anchor (or (org-element-property :CUSTOM_ID headline)
(org-export-get-reference headline info))))
(concat indent "- [" title "]" "(#" anchor ")")))
#+END_SRC
** After
#+BEGIN_SRC markdown
- [Feature: Issue Reaping](#orgheadline1)
- [Motivation](#orgheadline2)
- [Scenarios](#orgheadline3)
- [Tasks](#orgheadline4)
- [Prior art](#orgheadline8)
- [Org settings panel left nav](#orgheadline5)
- [Viewing an organization's Member privileges](#orgheadline6)
- [Updating an organization's Repository creation setting](#orgheadline7)
- [Implementation notes](#orgheadline9)
#+END_SRC
[-- Attachment #3: render-toc-and-fn-as-md.patch --]
[-- Type: application/octet-stream, Size: 5562 bytes --]
From b64d21e6b5bb35b6446abf37233463e40df040c3 Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sun, 7 Aug 2016 16:04:39 -0400
Subject: [PATCH 1/2] Export Footnotes section as Markdown
---
ox-md.el | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 72 insertions(+), 2 deletions(-)
diff --git a/ox-md.el b/ox-md.el
index 0aaade6..865e123 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -50,6 +50,20 @@ This variable can be set to either `atx' or `setext'."
(const :tag "Use \"atx\" style" atx)
(const :tag "Use \"Setext\" style" setext)))
+;;;; Footnotes
+
+(defcustom org-md-footnote-format "<sup>%s</sup>"
+ "The format for the footnote reference.
+%s will be replaced by the footnote reference itself."
+ :group 'org-export-md
+ :type 'string)
+
+(defcustom org-md-footnote-section-title "Footnotes"
+ "The title for the Footnotes section.
+Example: `Footnotes', `References', `Sources', etc."
+ :group 'org-export-md
+ :type 'string)
+
\f
;;; Define Back-End
@@ -90,7 +104,10 @@ This variable can be set to either `atx' or `setext'."
(src-block . org-md-example-block)
(template . org-md-template)
(verbatim . org-md-verbatim))
- :options-alist '((:md-headline-style nil nil org-md-headline-style)))
+ :options-alist
+ '((:md-headline-style nil nil org-md-headline-style)
+ (:md-footnote-format nil nil org-md-footnote-format)
+ (:md-footnote-section-title nil nil org-md-footnote-section-title)))
\f
;;; Filters
@@ -466,6 +483,51 @@ a communication channel."
contents)
+;;;; Footnotes Section Header
+
+(defun org-md-footnote-section-header (info)
+ "Renders a template for the footnotes section header in the preferred style.
+INFO is used as a communication channel."
+ (let ((style (plist-get info :md-headline-style))
+ (section-title (plist-get info :md-footnote-section-title)))
+ (cond
+ ((equal style 'atx) (format "\n%s %s\n%%s\n" "##" section-title))
+ ((equal style 'setext) (format "\n%s\n%s\n%%s\n"
+ section-title
+ (make-string (length section-title) ?-))))))
+
+
+;;;; Footnotes Section
+
+(defun org-md-footnote-section (info)
+ "Format the footnote section as Markdown.
+INFO is a plist used as a communication channel."
+ (let* ((fn-alist (org-export-collect-footnote-definitions info))
+ (fn-alist
+ (loop for (n type raw) in fn-alist collect
+ (cons n (org-trim (org-export-data raw info))))))
+ (when fn-alist
+ (format
+ (org-md-footnote-section-header info)
+ (format
+ "\n%s\n"
+ (mapconcat
+ (lambda (fn)
+ (let ((n (car fn)) (def (cdr fn)))
+ (format
+ "%s %s\n"
+ (format
+ (plist-get info :md-footnote-format)
+ (org-html--anchor
+ (format "fn.%d" n)
+ n
+ (format " href=\"#fnr.%d\"" n)
+ info))
+ def)))
+ fn-alist
+ "\n"))))))
+
+
;;;; Template
(defun org-md-inner-template (contents info)
@@ -474,7 +536,15 @@ CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
;; Make sure CONTENTS is separated from table of contents and
;; footnotes with at least a blank line.
- (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
+ (let* ((depth (plist-get info :with-toc))
+ (headlines (and depth (org-export-collect-headlines info depth)))
+ (toc-string (org-html-toc depth info))
+ (toc-tail (if headlines "\n\n" ""))
+ (footnotes (org-md-footnote-section info)))
+ (org-trim (concat toc-string
+ toc-tail
+ contents
+ footnotes))))
(defun org-md-template (contents info)
"Return complete document string after Markdown conversion.
--
2.9.2
From 31091e4bd4b48d1394482a1542e6d90abf04b32d Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sun, 7 Aug 2016 16:15:50 -0400
Subject: [PATCH 2/2] Export Table of Contents as Markdown
---
ox-md.el | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/ox-md.el b/ox-md.el
index 865e123..0e2a499 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -528,6 +528,19 @@ INFO is a plist used as a communication channel."
"\n"))))))
+;;;; Table of contents
+
+(defun org-md-format-toc (headline)
+ "Return an appropriate table of contents entry for HEADLINE.
+INFO is a plist used as a communication channel."
+ (let* ((title (org-export-data (org-export-get-alt-title headline info) info))
+ (level (1- (org-element-property :level headline)))
+ (indent (concat (make-string (* level 2) ? )))
+ (anchor (or (org-element-property :CUSTOM_ID headline)
+ (org-export-get-reference headline info))))
+ (concat indent "- [" title "]" "(#" anchor ")")))
+
+
;;;; Template
(defun org-md-inner-template (contents info)
@@ -538,7 +551,7 @@ holding export options."
;; footnotes with at least a blank line.
(let* ((depth (plist-get info :with-toc))
(headlines (and depth (org-export-collect-headlines info depth)))
- (toc-string (org-html-toc depth info))
+ (toc-string (or (mapconcat 'org-md-format-toc headlines "\n") ""))
(toc-tail (if headlines "\n\n" ""))
(footnotes (org-md-footnote-section info)))
(org-trim (concat toc-string
--
2.9.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-08 1:31 ox-md.el: Export TOC and Footnotes as Markdown rather than HTML Jake Romer
@ 2016-08-08 13:35 ` Nicolas Goaziou
2016-08-13 17:52 ` Jake Romer
0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2016-08-08 13:35 UTC (permalink / raw)
To: Jake Romer; +Cc: emacs-orgmode
Hello,
Jake Romer <jkrmr.io@gmail.com> writes:
> I notice that in Org 8.3, `org-md-export-as-markdown` and
> `org-md-export-to-markdown` render a document's Table of Contents and
> Footnotes sections as HTML rather than Markdown.
Correct.
> I have a couple of patches that change this behavior so that both are
> rendered as Markdown. I'd love to hear any thoughts or suggestions for
> improvement if you think this would be useful to include in ox-md.el.
That's very interesting. Thank you. Some comments follow.
However, AFAIU, rendering for footnote section is still HTML, albeit
a lightweight one.
> From b64d21e6b5bb35b6446abf37233463e40df040c3 Mon Sep 17 00:00:00 2001
> From: Jake Romer <jkrmr@github.com>
> Date: Sun, 7 Aug 2016 16:04:39 -0400
> Subject: [PATCH 1/2] Export Footnotes section as Markdown
The commit message has to contain the name of new and modified
functions. See commit log for examples.
>
> ---
> ox-md.el | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/ox-md.el b/ox-md.el
> index 0aaade6..865e123 100644
> --- a/ox-md.el
> +++ b/ox-md.el
> @@ -50,6 +50,20 @@ This variable can be set to either `atx' or `setext'."
> (const :tag "Use \"atx\" style" atx)
> (const :tag "Use \"Setext\" style" setext)))
>
> +;;;; Footnotes
> +
> +(defcustom org-md-footnote-format "<sup>%s</sup>"
> + "The format for the footnote reference.
> +%s will be replaced by the footnote reference itself."
> + :group 'org-export-md
> + :type 'string)
> +
> +(defcustom org-md-footnote-section-title "Footnotes"
> + "The title for the Footnotes section.
> +Example: `Footnotes', `References', `Sources', etc."
> + :group 'org-export-md
> + :type 'string)
I suggest to ignore the variable above and use an equivalent of
(org-html--translate "Table of Contents" info)
instead.
> +(defun org-md-footnote-section-header (info)
> + "Renders a template for the footnotes section header in the preferred style.
> +INFO is used as a communication channel."
> + (let ((style (plist-get info :md-headline-style))
> + (section-title (plist-get info :md-footnote-section-title)))
> + (cond
> + ((equal style 'atx) (format "\n%s %s\n%%s\n" "##" section-title))
> + ((equal style 'setext) (format "\n%s\n%s\n%%s\n"
> + section-title
> + (make-string (length section-title) ?-))))))
(if (eq style 'atx)
...
...)
I think this function should not be specific to footnote section header,
i.e., it could factor out the following code in `org-md-headline'
;; Use "Setext" style.
((eq style 'setext)
(concat heading tags anchor "\n"
(make-string (length heading) (if (= level 1) ?= ?-))
"\n\n"
contents))
;; Use "atx" style.
(t (concat (make-string level ?#) " " heading tags anchor "\n\n"
contents))
> +;;;; Footnotes Section
> +
> +(defun org-md-footnote-section (info)
> + "Format the footnote section as Markdown.
> +INFO is a plist used as a communication channel."
> + (let* ((fn-alist (org-export-collect-footnote-definitions info))
> + (fn-alist
> + (loop for (n type raw) in fn-alist collect
> + (cons n (org-trim (org-export-data raw info))))))
> + (when fn-alist
> + (format
> + (org-md-footnote-section-header info)
> + (format
> + "\n%s\n"
> + (mapconcat
> + (lambda (fn)
> + (let ((n (car fn)) (def (cdr fn)))
> + (format
> + "%s %s\n"
> + (format
> + (plist-get info :md-footnote-format)
> + (org-html--anchor
> + (format "fn.%d" n)
> + n
> + (format " href=\"#fnr.%d\"" n)
> + info))
> + def)))
> + fn-alist
> + "\n"))))))
> +
> +
> ;;;; Template
>
> (defun org-md-inner-template (contents info)
> @@ -474,7 +536,15 @@ CONTENTS is the transcoded contents string. INFO is a plist
> holding export options."
> ;; Make sure CONTENTS is separated from table of contents and
> ;; footnotes with at least a blank line.
> - (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
> + (let* ((depth (plist-get info :with-toc))
> + (headlines (and depth (org-export-collect-headlines info depth)))
> + (toc-string (org-html-toc depth info))
> + (toc-tail (if headlines "\n\n" ""))
> + (footnotes (org-md-footnote-section info)))
> + (org-trim (concat toc-string
> + toc-tail
> + contents
> + footnotes))))
>
> (defun org-md-template (contents info)
> "Return complete document string after Markdown conversion.
> --
> 2.9.2
>
>
> From 31091e4bd4b48d1394482a1542e6d90abf04b32d Mon Sep 17 00:00:00 2001
> From: Jake Romer <jkrmr@github.com>
> Date: Sun, 7 Aug 2016 16:15:50 -0400
> Subject: [PATCH 2/2] Export Table of Contents as Markdown
This commit message is also incomplete.
>
> ---
> ox-md.el | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/ox-md.el b/ox-md.el
> index 865e123..0e2a499 100644
> --- a/ox-md.el
> +++ b/ox-md.el
> @@ -528,6 +528,19 @@ INFO is a plist used as a communication channel."
> "\n"))))))
>
>
> +;;;; Table of contents
> +
> +(defun org-md-format-toc (headline)
Ideally, this should handethe level and a scope so as to handle toc:3
or #+TOC: headlines local.
> + "Return an appropriate table of contents entry for HEADLINE.
> +INFO is a plist used as a communication channel."
> + (let* ((title (org-export-data (org-export-get-alt-title headline info) info))
> + (level (1- (org-element-property :level headline)))
> + (indent (concat (make-string (* level 2) ? )))
"? " -> "?\s"
Besides, the indentation is slightly wrong. IIRC, 4 spaces are expected
between two levels. See, e.g., `org-md-item'.
> + (anchor (or (org-element-property :CUSTOM_ID headline)
> + (org-export-get-reference headline info))))
> + (concat indent "- [" title "]" "(#" anchor ")")))
> +
> +
> ;;;; Template
>
> (defun org-md-inner-template (contents info)
> @@ -538,7 +551,7 @@ holding export options."
> ;; footnotes with at least a blank line.
> (let* ((depth (plist-get info :with-toc))
> (headlines (and depth (org-export-collect-headlines info depth)))
> - (toc-string (org-html-toc depth info))
> + (toc-string (or (mapconcat 'org-md-format-toc headlines "\n") ""))
#'org-md-format-toc
> (toc-tail (if headlines "\n\n" ""))
Maybe a better abstraction would be to let `org-md-format-toc' handle
toc-string and toc-tail.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-08 13:35 ` Nicolas Goaziou
@ 2016-08-13 17:52 ` Jake Romer
2016-08-15 15:34 ` Nicolas Goaziou
0 siblings, 1 reply; 10+ messages in thread
From: Jake Romer @ 2016-08-13 17:52 UTC (permalink / raw)
To: Jake Romer, emacs-orgmode
[-- Attachment #1.1: Type: text/plain, Size: 8665 bytes --]
Hi Nicolas,
Thanks for the quick feedback! Notes on your notes:
> However, AFAIU, rendering for footnote section is still HTML, albeit a
> lightweight one.
Ah yes, that's true—the enclosing section can be rendered in Markdown, but
the footnotes themselves (and their references) are in HTML. I think that
make sense because footnotes, afaik, aren't part of "vanilla" Markdown,
although some variants do support them.
I think this function should not be specific to footnote section header, i.e.,
> it could factor out the following code in `org-md-headline'
Good point -- I implemented this in the attached revision.
Ideally, this should handle the level and a scope so as to handle toc:3 or
> #+TOC: headlines local.
I'm not as familiar with Org's TOC facilities as I should be, so I'll
update to handle these cases after some research. I want to avoid letting
these patches get too big, too.
Here's the patch for generating the footnotes section as Markdown, let me
know what you think.
Cheers,
Jake
On Mon, Aug 8, 2016 at 9:35 AM, Nicolas Goaziou <mail@nicolasgoaziou.fr>
wrote:
> Hello,
>
> Jake Romer <jkrmr.io@gmail.com> writes:
>
> > I notice that in Org 8.3, `org-md-export-as-markdown` and
> > `org-md-export-to-markdown` render a document's Table of Contents and
> > Footnotes sections as HTML rather than Markdown.
>
> Correct.
>
> > I have a couple of patches that change this behavior so that both are
> > rendered as Markdown. I'd love to hear any thoughts or suggestions for
> > improvement if you think this would be useful to include in ox-md.el.
>
> That's very interesting. Thank you. Some comments follow.
>
> However, AFAIU, rendering for footnote section is still HTML, albeit
> a lightweight one.
>
> > From b64d21e6b5bb35b6446abf37233463e40df040c3 Mon Sep 17 00:00:00 2001
> > From: Jake Romer <jkrmr@github.com>
> > Date: Sun, 7 Aug 2016 16:04:39 -0400
> > Subject: [PATCH 1/2] Export Footnotes section as Markdown
>
> The commit message has to contain the name of new and modified
> functions. See commit log for examples.
> >
> > ---
> > ox-md.el | 74 ++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++--
> > 1 file changed, 72 insertions(+), 2 deletions(-)
> >
> > diff --git a/ox-md.el b/ox-md.el
> > index 0aaade6..865e123 100644
> > --- a/ox-md.el
> > +++ b/ox-md.el
> > @@ -50,6 +50,20 @@ This variable can be set to either `atx' or `setext'."
> > (const :tag "Use \"atx\" style" atx)
> > (const :tag "Use \"Setext\" style" setext)))
> >
> > +;;;; Footnotes
> > +
> > +(defcustom org-md-footnote-format "<sup>%s</sup>"
> > + "The format for the footnote reference.
> > +%s will be replaced by the footnote reference itself."
> > + :group 'org-export-md
> > + :type 'string)
> > +
>
> > +(defcustom org-md-footnote-section-title "Footnotes"
> > + "The title for the Footnotes section.
> > +Example: `Footnotes', `References', `Sources', etc."
> > + :group 'org-export-md
> > + :type 'string)
>
> I suggest to ignore the variable above and use an equivalent of
>
> (org-html--translate "Table of Contents" info)
>
> instead.
>
> > +(defun org-md-footnote-section-header (info)
> > + "Renders a template for the footnotes section header in the preferred
> style.
> > +INFO is used as a communication channel."
> > + (let ((style (plist-get info :md-headline-style))
> > + (section-title (plist-get info :md-footnote-section-title)))
> > + (cond
> > + ((equal style 'atx) (format "\n%s %s\n%%s\n" "##" section-title))
> > + ((equal style 'setext) (format "\n%s\n%s\n%%s\n"
> > + section-title
> > + (make-string (length section-title)
> ?-))))))
>
> (if (eq style 'atx)
> ...
> ...)
>
> I think this function should not be specific to footnote section header,
> i.e., it could factor out the following code in `org-md-headline'
>
> ;; Use "Setext" style.
> ((eq style 'setext)
> (concat heading tags anchor "\n"
> (make-string (length heading) (if (= level 1) ?= ?-))
> "\n\n"
> contents))
> ;; Use "atx" style.
> (t (concat (make-string level ?#) " " heading tags anchor "\n\n"
> contents))
>
> > +;;;; Footnotes Section
> > +
> > +(defun org-md-footnote-section (info)
> > + "Format the footnote section as Markdown.
> > +INFO is a plist used as a communication channel."
> > + (let* ((fn-alist (org-export-collect-footnote-definitions info))
> > + (fn-alist
> > + (loop for (n type raw) in fn-alist collect
> > + (cons n (org-trim (org-export-data raw info))))))
> > + (when fn-alist
> > + (format
> > + (org-md-footnote-section-header info)
> > + (format
> > + "\n%s\n"
> > + (mapconcat
> > + (lambda (fn)
> > + (let ((n (car fn)) (def (cdr fn)))
> > + (format
> > + "%s %s\n"
> > + (format
> > + (plist-get info :md-footnote-format)
> > + (org-html--anchor
> > + (format "fn.%d" n)
> > + n
> > + (format " href=\"#fnr.%d\"" n)
> > + info))
> > + def)))
> > + fn-alist
> > + "\n"))))))
> > +
> > +
> > ;;;; Template
> >
> > (defun org-md-inner-template (contents info)
> > @@ -474,7 +536,15 @@ CONTENTS is the transcoded contents string. INFO
> is a plist
> > holding export options."
> > ;; Make sure CONTENTS is separated from table of contents and
> > ;; footnotes with at least a blank line.
> > - (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
> > + (let* ((depth (plist-get info :with-toc))
> > + (headlines (and depth (org-export-collect-headlines info
> depth)))
> > + (toc-string (org-html-toc depth info))
> > + (toc-tail (if headlines "\n\n" ""))
> > + (footnotes (org-md-footnote-section info)))
> > + (org-trim (concat toc-string
> > + toc-tail
> > + contents
> > + footnotes))))
> >
> > (defun org-md-template (contents info)
> > "Return complete document string after Markdown conversion.
> > --
> > 2.9.2
> >
> >
> > From 31091e4bd4b48d1394482a1542e6d90abf04b32d Mon Sep 17 00:00:00 2001
> > From: Jake Romer <jkrmr@github.com>
> > Date: Sun, 7 Aug 2016 16:15:50 -0400
> > Subject: [PATCH 2/2] Export Table of Contents as Markdown
>
> This commit message is also incomplete.
> >
> > ---
> > ox-md.el | 15 ++++++++++++++-
> > 1 file changed, 14 insertions(+), 1 deletion(-)
> >
> > diff --git a/ox-md.el b/ox-md.el
> > index 865e123..0e2a499 100644
> > --- a/ox-md.el
> > +++ b/ox-md.el
> > @@ -528,6 +528,19 @@ INFO is a plist used as a communication channel."
> > "\n"))))))
> >
> >
> > +;;;; Table of contents
> > +
> > +(defun org-md-format-toc (headline)
>
> Ideally, this should handethe level and a scope so as to handle toc:3
> or #+TOC: headlines local.
>
> > + "Return an appropriate table of contents entry for HEADLINE.
> > +INFO is a plist used as a communication channel."
> > + (let* ((title (org-export-data (org-export-get-alt-title headline
> info) info))
> > + (level (1- (org-element-property :level headline)))
> > + (indent (concat (make-string (* level 2) ? )))
>
> "? " -> "?\s"
>
> Besides, the indentation is slightly wrong. IIRC, 4 spaces are expected
> between two levels. See, e.g., `org-md-item'.
>
> > + (anchor (or (org-element-property :CUSTOM_ID headline)
> > + (org-export-get-reference headline info))))
> > + (concat indent "- [" title "]" "(#" anchor ")")))
> > +
> > +
> > ;;;; Template
> >
> > (defun org-md-inner-template (contents info)
> > @@ -538,7 +551,7 @@ holding export options."
> > ;; footnotes with at least a blank line.
> > (let* ((depth (plist-get info :with-toc))
> > (headlines (and depth (org-export-collect-headlines info
> depth)))
> > - (toc-string (org-html-toc depth info))
> > + (toc-string (or (mapconcat 'org-md-format-toc headlines "\n")
> ""))
>
> #'org-md-format-toc
>
> > (toc-tail (if headlines "\n\n" ""))
>
> Maybe a better abstraction would be to let `org-md-format-toc' handle
> toc-string and toc-tail.
>
> Regards,
>
> --
> Nicolas Goaziou
>
[-- Attachment #1.2: Type: text/html, Size: 11880 bytes --]
[-- Attachment #2: render-fn-as-md.patch --]
[-- Type: application/octet-stream, Size: 8416 bytes --]
From 63d985425d3995985bd340fe195d8e25bd7f2cc6 Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sat, 13 Aug 2016 11:45:34 -0400
Subject: [PATCH 1/4] Extract org-md-headline-title to generate title
In order to generate a headline title in the preferred Markdown
style ('atx or 'setext), I extracted this bit of logic from
`org-md-headline'.
Since `org-md-headline' doesn't process the headline for the footnotes
section, extracting `org-md-headline-title' will allow us to generate
the Footnote section header in the preferred Markdown style without
duplicating the logic for doing so.
As an enhancement, `org-md-headline-title' places the anchor tag above
the section header. This makes it so that in a browser, clicking on the
TOC entry for that section scrolls to the section header without
obscuring it.
Example generated section title:
<a id="orgheadline1"></a>
Summary of Changes
==================
---
ox-md.el | 37 +++++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/ox-md.el b/ox-md.el
index 0aaade6..4bd445c 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -216,20 +216,29 @@ a communication channel."
(car (last (org-export-get-headline-number
headline info))))
"."))))
- (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags
- "\n\n"
- (and contents
- (replace-regexp-in-string "^" " " contents)))))
- ;; Use "Setext" style.
- ((eq style 'setext)
- (concat heading tags anchor "\n"
- (make-string (length heading) (if (= level 1) ?= ?-))
- "\n\n"
- contents))
- ;; Use "atx" style.
- (t (concat (make-string level ?#) " " heading tags anchor "\n\n"
- contents))))))
-
+ (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags "\n\n"
+ (and contents (replace-regexp-in-string "^" " " contents)))))
+ (t (concat (org-md-headline-title style level title anchor tags) contents))))))
+
+
+;; Headline Title
+
+(defun org-md-headline-title (style level title &optional anchor tags)
+ "Generate a headline title in the preferred Markdown headline style.
+STYLE is the preferred style ('atx or 'setext)
+LEVEL is the header level.
+TITLE is the headline title.
+ANCHOR is the HTML anchor tag for the section as a string.
+TAGS are the tags set on the section."
+ (let ((anchor-lines (if anchor (concat anchor "\n\n") nil)))
+ ;; Use "Setext" style
+ (if (and (eq style 'setext) (< level 3))
+ (let* ((underline-char (if (= level 1) ?= ?-))
+ (underline (concat (make-string (length title) underline-char) "\n")))
+ (concat "\n" anchor-lines title tags "\n" underline "\n"))
+ ;; Use "Atx" style
+ (let ((level-mark (make-string level ?#)))
+ (concat "\n" anchor-lines level-mark " " title tags "\n\n")))))
;;;; Horizontal Rule
--
2.9.2
From 10351a0eda50e921978329c0ecf94540188215b1 Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sat, 13 Aug 2016 11:50:28 -0400
Subject: [PATCH 2/4] Add customizable footnotes-related variables
Taking a cue from `ox-html.el', this patch adds
`org-md-footnotes-section' and `org-md-footnote-format' to allow user
customization of the formatting for the footnotes section and individual
footnotes, respectively.
---
ox-md.el | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ox-md.el b/ox-md.el
index 4bd445c..9a7182a 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -51,6 +51,21 @@ This variable can be set to either `atx' or `setext'."
(const :tag "Use \"Setext\" style" setext)))
+;;;; Footnotes
+
+(defcustom org-md-footnotes-section "%s%s"
+ "Format for the footnotes section.
+The first %s placeholder will be replaced with the localized Footnotes section
+heading, the second with the contents of the Footnotes section."
+ :group 'org-export-md
+ :type 'string)
+
+(defcustom org-md-footnote-format "<sup>%s</sup>"
+ "The format for the footnote reference.
+The %s will be replaced by the footnote reference itself."
+ :group 'org-export-md
+ :type 'string)
+
\f
;;; Define Back-End
--
2.9.2
From 4f6f932930f18228aa57c02ae8855ba96f5fce95 Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sat, 13 Aug 2016 11:52:33 -0400
Subject: [PATCH 3/4] Add footnote-generating functions
Introduces the following functions:
* `org-md-footnote-formatted'
* `org-md-footnote-section'
`org-md-footnote-formatted' formats a single footnote entry using the
user-customizable template string `org-md-footnote-format'.
Example:
<sup><a id="fn.1" href="#fnr.1">1</a></sup> This is a footnote.
`org-md-footnote-section' formats the entire footnote section using the
user-customizable template string `org-md-footnotes-section'.
Example:
Footnotes
=========
<sup><a id="fn.1" href="#fnr.1">1</a></sup> This is a footnote.
<sup><a id="fn.2" href="#fnr.2">2</a></sup> This is another footnote.
---
ox-md.el | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/ox-md.el b/ox-md.el
index 9a7182a..19b8912 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -490,6 +490,34 @@ a communication channel."
contents)
+;;;; Footnote Section
+
+(defun org-md-footnote-formatted (footnote info)
+ "Formats a single footnote entry FOOTNOTE.
+INFO is a plist with contextual information."
+ (let* ((fn-num (car footnote))
+ (fn-text (cdr footnote))
+ (fn-format (plist-get info :md-footnote-format))
+ (fn-anchor (format "fn.%d" fn-num))
+ (fn-href (format " href=\"#fnr.%d\"" fn-num))
+ (fn-link-to-ref (org-html--anchor fn-anchor fn-num fn-href info)))
+ (concat (format fn-format fn-link-to-ref) " " fn-text "\n")))
+
+(defun org-md-footnote-section (info)
+ "Format the footnote section.
+INFO is a plist used as a communication channel."
+ (let* ((fn-alist (org-export-collect-footnote-definitions info))
+ (fn-alist (loop for (n type raw) in fn-alist collect
+ (cons n (org-trim (org-export-data raw info)))))
+ (headline-style (plist-get info :md-headline-style))
+ (section-title (org-html--translate "Footnotes" info)))
+ (when fn-alist
+ (format (plist-get info :md-footnotes-section)
+ (org-md-headline-title headline-style 1 section-title)
+ (mapconcat #'(lambda (fn) (org-md-footnote-formatted fn info))
+ fn-alist
+ "\n")))))
+
;;;; Template
(defun org-md-inner-template (contents info)
--
2.9.2
From a2e353da09d0db9bbde14641bd94e12e156a143c Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sat, 13 Aug 2016 13:11:26 -0400
Subject: [PATCH 4/4] Update org-md-inner-template to Markdown footnotes
Updates `org-md-inner-template' to use `org-md-footnotes-section' to
generate a Markdown version of the footnotes section.
Also appends `:md-footnote-format' and `md-footnotes-section' to the
exporter :options-alist.
---
ox-md.el | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/ox-md.el b/ox-md.el
index 19b8912..7d78ff7 100644
--- a/ox-md.el
+++ b/ox-md.el
@@ -105,7 +105,10 @@ The %s will be replaced by the footnote reference itself."
(src-block . org-md-example-block)
(template . org-md-template)
(verbatim . org-md-verbatim))
- :options-alist '((:md-headline-style nil nil org-md-headline-style)))
+ :options-alist
+ '((:md-headline-style nil nil org-md-headline-style)
+ (:md-footnote-format nil nil org-md-footnote-format)
+ (:md-footnotes-section nil nil org-md-footnotes-section)))
\f
;;; Filters
@@ -526,7 +529,15 @@ CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
;; Make sure CONTENTS is separated from table of contents and
;; footnotes with at least a blank line.
- (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
+ (org-trim (concat
+ ;; Table of contents.
+ (let ((depth (plist-get info :with-toc)))
+ (when depth (org-html-toc depth info)))
+ ;; Document contents.
+ contents
+ "\n"
+ ;; Footnotes section.
+ (org-md-footnote-section info))))
(defun org-md-template (contents info)
"Return complete document string after Markdown conversion.
--
2.9.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-13 17:52 ` Jake Romer
@ 2016-08-15 15:34 ` Nicolas Goaziou
2016-08-22 5:31 ` Jake Romer
0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2016-08-15 15:34 UTC (permalink / raw)
To: Jake Romer; +Cc: emacs-orgmode
Hello,
Jake Romer <jkrmr.io@gmail.com> writes:
> I'm not as familiar with Org's TOC facilities as I should be, so I'll
> update to handle these cases after some research. I want to avoid letting
> these patches get too big, too.
See `org-html-toc' and `org-html--toc-text' for an illustration.
> Here's the patch for generating the footnotes section as Markdown, let me
> know what you think.
It looks good. However, I'm not able to apply them, they seem to be
created from a subdirectory instead of the root dir.
> From 63d985425d3995985bd340fe195d8e25bd7f2cc6 Mon Sep 17 00:00:00 2001
> From: Jake Romer <jkrmr@github.com>
> Date: Sat, 13 Aug 2016 11:45:34 -0400
> Subject: [PATCH 1/4] Extract org-md-headline-title to generate title
>
> In order to generate a headline title in the preferred Markdown
> style ('atx or 'setext), I extracted this bit of logic from
> `org-md-headline'.
>
> Since `org-md-headline' doesn't process the headline for the footnotes
> section, extracting `org-md-headline-title' will allow us to generate
> the Footnote section header in the preferred Markdown style without
> duplicating the logic for doing so.
>
> As an enhancement, `org-md-headline-title' places the anchor tag above
> the section header. This makes it so that in a browser, clicking on the
> TOC entry for that section scrolls to the section header without
> obscuring it.
>
> Example generated section title:
>
> <a id="orgheadline1"></a>
Great. However, you need to supply modified variables and functions
names in the commit message, e.g.,
* lisp/ox-md.el (org-md-headline-title): New function.
(org-md-headline): Use new function.
> Summary of Changes
> ==================
> ---
> ox-md.el | 37 +++++++++++++++++++++++--------------
> 1 file changed, 23 insertions(+), 14 deletions(-)
>
> diff --git a/ox-md.el b/ox-md.el
> index 0aaade6..4bd445c 100644
> --- a/ox-md.el
> +++ b/ox-md.el
> @@ -216,20 +216,29 @@ a communication channel."
> (car (last (org-export-get-headline-number
> headline info))))
> "."))))
> - (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags
> - "\n\n"
> - (and contents
> - (replace-regexp-in-string "^" " " contents)))))
> - ;; Use "Setext" style.
> - ((eq style 'setext)
> - (concat heading tags anchor "\n"
> - (make-string (length heading) (if (= level 1) ?= ?-))
> - "\n\n"
> - contents))
> - ;; Use "atx" style.
> - (t (concat (make-string level ?#) " " heading tags anchor "\n\n"
> - contents))))))
> -
> + (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags "\n\n"
> + (and contents (replace-regexp-in-string "^" " " contents)))))
> + (t (concat (org-md-headline-title style level title anchor tags) contents))))))
> +
> +
> +;; Headline Title
> +
> +(defun org-md-headline-title (style level title &optional anchor tags)
I suggest to name it `org-md--headline-title' to highlight the fact that
it is an internal function.
> + "Generate a headline title in the preferred Markdown headline style.
> +STYLE is the preferred style ('atx or 'setext)
> +LEVEL is the header level.
> +TITLE is the headline title.
> +ANCHOR is the HTML anchor tag for the section as a string.
> +TAGS are the tags set on the section."
> + (let ((anchor-lines (if anchor (concat anchor "\n\n") nil)))
(and anchor (concat anchor "\n\n"))
> Subject: [PATCH 2/4] Add customizable footnotes-related variables
>
> Taking a cue from `ox-html.el', this patch adds
> `org-md-footnotes-section' and `org-md-footnote-format' to allow user
> customization of the formatting for the footnotes section and individual
> footnotes, respectively.
Ditto (variable names...)
> +(defcustom org-md-footnotes-section "%s%s"
> + "Format for the footnotes section.
Format string for...
> +The first %s placeholder will be replaced with the localized Footnotes section
> +heading, the second with the contents of the Footnotes section."
> + :group 'org-export-md
> + :type 'string)
You need to provide additional keywords, i.e.,
:version "25.1"
:package-version '(Org . "9.0")
> +(defcustom org-md-footnote-format "<sup>%s</sup>"
> + "The format for the footnote reference.
> +The %s will be replaced by the footnote reference itself."
> + :group 'org-export-md
> + :type 'string)
Ditto.
> Subject: [PATCH 3/4] Add footnote-generating functions
>
> Introduces the following functions:
>
> * `org-md-footnote-formatted'
> * `org-md-footnote-section'
See above.
> +;;;; Footnote Section
> +
> +(defun org-md-footnote-formatted (footnote info)
Suggestion: `org-md--footnote-formatted'
> + "Formats a single footnote entry FOOTNOTE.
You should specify the data type for FOOTNOTE, i.e., a cons cell
(number . definition)
> +INFO is a plist with contextual information."
> + (let* ((fn-num (car footnote))
> + (fn-text (cdr footnote))
> + (fn-format (plist-get info :md-footnote-format))
> + (fn-anchor (format "fn.%d" fn-num))
> + (fn-href (format " href=\"#fnr.%d\"" fn-num))
> + (fn-link-to-ref (org-html--anchor fn-anchor fn-num fn-href info)))
> + (concat (format fn-format fn-link-to-ref) " " fn-text "\n")))
> +
> +(defun org-md-footnote-section (info)
> + "Format the footnote section.
> +INFO is a plist used as a communication channel."
> + (let* ((fn-alist (org-export-collect-footnote-definitions info))
> + (fn-alist (loop for (n type raw) in fn-alist collect
> + (cons n (org-trim (org-export-data raw info)))))
`cl-loop'
> + (headline-style (plist-get info :md-headline-style))
> + (section-title (org-html--translate "Footnotes" info)))
> + (when fn-alist
> + (format (plist-get info :md-footnotes-section)
> + (org-md-headline-title headline-style 1 section-title)
> + (mapconcat #'(lambda (fn) (org-md-footnote-formatted fn info))
(mapconcat (lambda (fn) ...) ...)
> + fn-alist
> + "\n")))))
> +
> ;;;; Template
>
> (defun org-md-inner-template (contents info)
> --
> 2.9.2
>
>
> From a2e353da09d0db9bbde14641bd94e12e156a143c Mon Sep 17 00:00:00 2001
> From: Jake Romer <jkrmr@github.com>
> Date: Sat, 13 Aug 2016 13:11:26 -0400
> Subject: [PATCH 4/4] Update org-md-inner-template to Markdown footnotes
>
> Updates `org-md-inner-template' to use `org-md-footnotes-section' to
> generate a Markdown version of the footnotes section.
>
> Also appends `:md-footnote-format' and `md-footnotes-section' to the
> exporter :options-alist.
> ---
> ox-md.el | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/ox-md.el b/ox-md.el
> index 19b8912..7d78ff7 100644
> --- a/ox-md.el
> +++ b/ox-md.el
> @@ -105,7 +105,10 @@ The %s will be replaced by the footnote reference itself."
> (src-block . org-md-example-block)
> (template . org-md-template)
> (verbatim . org-md-verbatim))
> - :options-alist '((:md-headline-style nil nil org-md-headline-style)))
> + :options-alist
> + '((:md-headline-style nil nil org-md-headline-style)
> + (:md-footnote-format nil nil org-md-footnote-format)
> + (:md-footnotes-section nil nil org-md-footnotes-section)))
These new parameters need to be documented in the manual: (info "(org)
Publishing options").
Would you mind providing an entry in ORG-NEWS and send again the patches
from root directory so I can apply them?
Thank you!
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-15 15:34 ` Nicolas Goaziou
@ 2016-08-22 5:31 ` Jake Romer
2016-08-22 8:47 ` Nicolas Goaziou
0 siblings, 1 reply; 10+ messages in thread
From: Jake Romer @ 2016-08-22 5:31 UTC (permalink / raw)
To: emacs-orgmode, Nicolas Goaziou
[-- Attachment #1.1: Type: text/plain, Size: 8407 bytes --]
Thanks for the pointers! I appreciate your patience -- I'm still a noob
with Org :-)
Here's the updated patch with entries in ORG-NEWS and the manual.
Cheers,
Jake
On Mon, Aug 15, 2016 at 8:34 AM, Nicolas Goaziou <mail@nicolasgoaziou.fr>
wrote:
> Hello,
>
> Jake Romer <jkrmr.io@gmail.com> writes:
>
> > I'm not as familiar with Org's TOC facilities as I should be, so I'll
> > update to handle these cases after some research. I want to avoid letting
> > these patches get too big, too.
>
> See `org-html-toc' and `org-html--toc-text' for an illustration.
>
> > Here's the patch for generating the footnotes section as Markdown, let me
> > know what you think.
>
> It looks good. However, I'm not able to apply them, they seem to be
> created from a subdirectory instead of the root dir.
>
> > From 63d985425d3995985bd340fe195d8e25bd7f2cc6 Mon Sep 17 00:00:00 2001
> > From: Jake Romer <jkrmr@github.com>
> > Date: Sat, 13 Aug 2016 11:45:34 -0400
> > Subject: [PATCH 1/4] Extract org-md-headline-title to generate title
> >
> > In order to generate a headline title in the preferred Markdown
> > style ('atx or 'setext), I extracted this bit of logic from
> > `org-md-headline'.
> >
> > Since `org-md-headline' doesn't process the headline for the footnotes
> > section, extracting `org-md-headline-title' will allow us to generate
> > the Footnote section header in the preferred Markdown style without
> > duplicating the logic for doing so.
> >
> > As an enhancement, `org-md-headline-title' places the anchor tag above
> > the section header. This makes it so that in a browser, clicking on the
> > TOC entry for that section scrolls to the section header without
> > obscuring it.
> >
> > Example generated section title:
> >
> > <a id="orgheadline1"></a>
>
> Great. However, you need to supply modified variables and functions
> names in the commit message, e.g.,
>
> * lisp/ox-md.el (org-md-headline-title): New function.
> (org-md-headline): Use new function.
>
> > Summary of Changes
> > ==================
> > ---
> > ox-md.el | 37 +++++++++++++++++++++++--------------
> > 1 file changed, 23 insertions(+), 14 deletions(-)
> >
> > diff --git a/ox-md.el b/ox-md.el
> > index 0aaade6..4bd445c 100644
> > --- a/ox-md.el
> > +++ b/ox-md.el
> > @@ -216,20 +216,29 @@ a communication channel."
> > (car (last (org-export-get-headline-number
> > headline info))))
> > "."))))
> > - (concat bullet (make-string (- 4 (length bullet)) ?\s) heading
> tags
> > - "\n\n"
> > - (and contents
> > - (replace-regexp-in-string "^" " " contents)))))
> > - ;; Use "Setext" style.
> > - ((eq style 'setext)
> > - (concat heading tags anchor "\n"
> > - (make-string (length heading) (if (= level 1) ?= ?-))
> > - "\n\n"
> > - contents))
> > - ;; Use "atx" style.
> > - (t (concat (make-string level ?#) " " heading tags anchor "\n\n"
> > - contents))))))
> > -
> > + (concat bullet (make-string (- 4 (length bullet)) ?\s) heading
> tags "\n\n"
> > + (and contents (replace-regexp-in-string "^" " "
> contents)))))
> > + (t (concat (org-md-headline-title style level title anchor tags)
> contents))))))
> > +
> > +
> > +;; Headline Title
> > +
> > +(defun org-md-headline-title (style level title &optional anchor tags)
>
> I suggest to name it `org-md--headline-title' to highlight the fact that
> it is an internal function.
>
> > + "Generate a headline title in the preferred Markdown headline style.
> > +STYLE is the preferred style ('atx or 'setext)
> > +LEVEL is the header level.
> > +TITLE is the headline title.
> > +ANCHOR is the HTML anchor tag for the section as a string.
> > +TAGS are the tags set on the section."
> > + (let ((anchor-lines (if anchor (concat anchor "\n\n") nil)))
>
> (and anchor (concat anchor "\n\n"))
>
> > Subject: [PATCH 2/4] Add customizable footnotes-related variables
> >
> > Taking a cue from `ox-html.el', this patch adds
> > `org-md-footnotes-section' and `org-md-footnote-format' to allow user
> > customization of the formatting for the footnotes section and individual
> > footnotes, respectively.
>
> Ditto (variable names...)
>
> > +(defcustom org-md-footnotes-section "%s%s"
> > + "Format for the footnotes section.
>
> Format string for...
>
> > +The first %s placeholder will be replaced with the localized Footnotes
> section
> > +heading, the second with the contents of the Footnotes section."
> > + :group 'org-export-md
> > + :type 'string)
>
> You need to provide additional keywords, i.e.,
>
> :version "25.1"
> :package-version '(Org . "9.0")
>
>
> > +(defcustom org-md-footnote-format "<sup>%s</sup>"
> > + "The format for the footnote reference.
> > +The %s will be replaced by the footnote reference itself."
> > + :group 'org-export-md
> > + :type 'string)
>
> Ditto.
>
> > Subject: [PATCH 3/4] Add footnote-generating functions
> >
> > Introduces the following functions:
> >
> > * `org-md-footnote-formatted'
> > * `org-md-footnote-section'
>
> See above.
>
> > +;;;; Footnote Section
> > +
> > +(defun org-md-footnote-formatted (footnote info)
>
> Suggestion: `org-md--footnote-formatted'
>
> > + "Formats a single footnote entry FOOTNOTE.
>
> You should specify the data type for FOOTNOTE, i.e., a cons cell
>
> (number . definition)
>
> > +INFO is a plist with contextual information."
> > + (let* ((fn-num (car footnote))
> > + (fn-text (cdr footnote))
> > + (fn-format (plist-get info :md-footnote-format))
> > + (fn-anchor (format "fn.%d" fn-num))
> > + (fn-href (format " href=\"#fnr.%d\"" fn-num))
> > + (fn-link-to-ref (org-html--anchor fn-anchor fn-num fn-href
> info)))
> > + (concat (format fn-format fn-link-to-ref) " " fn-text "\n")))
> > +
> > +(defun org-md-footnote-section (info)
> > + "Format the footnote section.
> > +INFO is a plist used as a communication channel."
> > + (let* ((fn-alist (org-export-collect-footnote-definitions info))
> > + (fn-alist (loop for (n type raw) in fn-alist collect
> > + (cons n (org-trim (org-export-data raw
> info)))))
>
> `cl-loop'
>
> > + (headline-style (plist-get info :md-headline-style))
> > + (section-title (org-html--translate "Footnotes" info)))
> > + (when fn-alist
> > + (format (plist-get info :md-footnotes-section)
> > + (org-md-headline-title headline-style 1 section-title)
> > + (mapconcat #'(lambda (fn) (org-md-footnote-formatted fn
> info))
>
> (mapconcat (lambda (fn) ...) ...)
>
> > + fn-alist
> > + "\n")))))
> > +
> > ;;;; Template
> >
> > (defun org-md-inner-template (contents info)
> > --
> > 2.9.2
> >
> >
> > From a2e353da09d0db9bbde14641bd94e12e156a143c Mon Sep 17 00:00:00 2001
> > From: Jake Romer <jkrmr@github.com>
> > Date: Sat, 13 Aug 2016 13:11:26 -0400
> > Subject: [PATCH 4/4] Update org-md-inner-template to Markdown footnotes
> >
> > Updates `org-md-inner-template' to use `org-md-footnotes-section' to
> > generate a Markdown version of the footnotes section.
> >
> > Also appends `:md-footnote-format' and `md-footnotes-section' to the
> > exporter :options-alist.
> > ---
> > ox-md.el | 15 +++++++++++++--
> > 1 file changed, 13 insertions(+), 2 deletions(-)
> >
> > diff --git a/ox-md.el b/ox-md.el
> > index 19b8912..7d78ff7 100644
> > --- a/ox-md.el
> > +++ b/ox-md.el
> > @@ -105,7 +105,10 @@ The %s will be replaced by the footnote reference
> itself."
> > (src-block . org-md-example-block)
> > (template . org-md-template)
> > (verbatim . org-md-verbatim))
> > - :options-alist '((:md-headline-style nil nil org-md-headline-style)))
> > + :options-alist
> > + '((:md-headline-style nil nil org-md-headline-style)
> > + (:md-footnote-format nil nil org-md-footnote-format)
> > + (:md-footnotes-section nil nil org-md-footnotes-section)))
>
> These new parameters need to be documented in the manual: (info "(org)
> Publishing options").
>
> Would you mind providing an entry in ORG-NEWS and send again the patches
> from root directory so I can apply them?
>
> Thank you!
>
> Regards,
>
> --
> Nicolas Goaziou
>
[-- Attachment #1.2: Type: text/html, Size: 11166 bytes --]
[-- Attachment #2: render-fn-as-md.patch --]
[-- Type: application/octet-stream, Size: 8350 bytes --]
From c1d86d872800d35dc13e9523335154a6cc9a11ca Mon Sep 17 00:00:00 2001
From: Jake Romer <jkrmr@github.com>
Date: Sun, 21 Aug 2016 14:08:29 -0700
Subject: [PATCH] ox-md.el: Export footnotes section as Markdown
* lisp/ox-md.el (org-md--headline-title): New function. Extract logic
used to generate section header in the preferred style of
Markdown (i.e., setext or atx).
(org-md-headline): Use `org-md-headline-title' to generate section
headers.
(org-md--footnote-formatted): New function. Format a single footnote
entry as Markdown, using HTML only where necessary.
(org-md-footnote-section): New function. Format the footnote section,
including the section title using `org-md--headline-title' and
individual entries using `org-md--footnote-formatted'.
(org-md-inner-template): Update to use `org-md-footnote-section'.
(org-md-footnotes-section): New customizable variable. Format string for
footnotes section.
(org-md-footnote-format): New customizable variable. Format string for
individual footnote.
Update ox-md.el to export the Footnotes section as Markdown, using HTML
only where necessary - namely, in footnote and footnote reference links.
---
doc/org.texi | 2 ++
etc/ORG-NEWS | 11 +++++++
lisp/ox-md.el | 100 ++++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 97 insertions(+), 16 deletions(-)
diff --git a/doc/org.texi b/doc/org.texi
index 9868113..26ef376 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -14444,6 +14444,8 @@ however, override everything.
@multitable {@code{:md-headline-style}} {@code{org-md-headline-style}}
@item @code{:md-headline-style} @tab @code{org-md-headline-style}
+@item @code{:md-footnote-format} @tab @code{org-md-footnote-format}
+@item @code{:md-footnotes-section} @tab @code{org-md-footnotes-section}
@end multitable
@subsubheading ODT specific properties
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 27b6ac9..91a458b 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -373,6 +373,12 @@ It replaces the deprecated ~next~ argument to ~org-previous-line-empty-p~.
*** ~org-show-children~
It is a faster implementation of ~outline-show-children~.
+*** ~org-md-headline~
+Generates a Markdown section headline in the preferred style (Setext or Atx).
+
+*** ~org-md-footnote-section~
+Exports a footnote section as Markdown.
+
** Removed functions
*** ~org-agenda-filter-by-tag-refine~ has been removed.
Use ~org-agenda-filter-by-tag~ instead.
@@ -503,6 +509,11 @@ modified anyway.
They are still supported in Org 9.0 but will eventually be removed in
a later release. Use ~file~ link type along with universal arguments
to force opening it in either Emacs or with system application.
+*** Markdown footnote export customization
+Variables ~org-md-footnotes-section~ and ~org-md-footnote-format~
+introduced for ox-md.el. Both new variables define template strings
+which can be used to customize the format of the exported footnotes
+section and individual footnotes, respectively.
* Version 8.3
** Incompatible changes
diff --git a/lisp/ox-md.el b/lisp/ox-md.el
index 7635fc7..467fe73 100644
--- a/lisp/ox-md.el
+++ b/lisp/ox-md.el
@@ -51,6 +51,25 @@ This variable can be set to either `atx' or `setext'."
(const :tag "Use \"Setext\" style" setext)))
+;;;; Footnotes
+
+(defcustom org-md-footnotes-section "%s%s"
+ "Format string for the footnotes section.
+The first %s placeholder will be replaced with the localized Footnotes section
+heading, the second with the contents of the Footnotes section."
+ :group 'org-export-md
+ :type 'string
+ :version "25.1"
+ :package-version '(Org . "9.0"))
+
+(defcustom org-md-footnote-format "<sup>%s</sup>"
+ "Format string for the footnote reference.
+The %s will be replaced by the footnote reference itself."
+ :group 'org-export-md
+ :type 'string
+ :version "25.1"
+ :package-version '(Org . "9.0"))
+
\f
;;; Define Back-End
@@ -89,7 +108,10 @@ This variable can be set to either `atx' or `setext'."
(src-block . org-md-example-block)
(template . org-md-template)
(verbatim . org-md-verbatim))
- :options-alist '((:md-headline-style nil nil org-md-headline-style)))
+ :options-alist
+ '((:md-headline-style nil nil org-md-headline-style)
+ (:md-footnote-format nil nil org-md-footnote-format)
+ (:md-footnotes-section nil nil org-md-footnotes-section)))
\f
;;; Filters
@@ -215,20 +237,29 @@ a communication channel."
(car (last (org-export-get-headline-number
headline info))))
"."))))
- (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags
- "\n\n"
- (and contents
- (replace-regexp-in-string "^" " " contents)))))
- ;; Use "Setext" style.
- ((eq style 'setext)
- (concat heading tags anchor "\n"
- (make-string (length heading) (if (= level 1) ?= ?-))
- "\n\n"
- contents))
- ;; Use "atx" style.
- (t (concat (make-string level ?#) " " heading tags anchor "\n\n"
- contents))))))
-
+ (concat bullet (make-string (- 4 (length bullet)) ?\s) heading tags "\n\n"
+ (and contents (replace-regexp-in-string "^" " " contents)))))
+ (t (concat (org-md--headline-title style level title anchor tags) contents))))))
+
+
+;; Headline Title
+
+(defun org-md--headline-title (style level title &optional anchor tags)
+ "Generate a headline title in the preferred Markdown headline style.
+STYLE is the preferred style ('atx or 'setext)
+LEVEL is the header level.
+TITLE is the headline title.
+ANCHOR is the HTML anchor tag for the section as a string.
+TAGS are the tags set on the section."
+ (let ((anchor-lines (and anchor (concat anchor "\n\n"))))
+ ;; Use "Setext" style
+ (if (and (eq style 'setext) (< level 3))
+ (let* ((underline-char (if (= level 1) ?= ?-))
+ (underline (concat (make-string (length title) underline-char) "\n")))
+ (concat "\n" anchor-lines title tags "\n" underline "\n"))
+ ;; Use "Atx" style
+ (let ((level-mark (make-string level ?#)))
+ (concat "\n" anchor-lines level-mark " " title tags "\n\n")))))
;;;; Horizontal Rule
@@ -465,6 +496,35 @@ a communication channel."
contents)
+;;;; Footnote Section
+
+(defun org-md--footnote-formatted (footnote info)
+ "Formats a single footnote entry FOOTNOTE.
+FOOTNOTE is a cons cell of the form (number . definition).
+INFO is a plist with contextual information."
+ (let* ((fn-num (car footnote))
+ (fn-text (cdr footnote))
+ (fn-format (plist-get info :md-footnote-format))
+ (fn-anchor (format "fn.%d" fn-num))
+ (fn-href (format " href=\"#fnr.%d\"" fn-num))
+ (fn-link-to-ref (org-html--anchor fn-anchor fn-num fn-href info)))
+ (concat (format fn-format fn-link-to-ref) " " fn-text "\n")))
+
+(defun org-md-footnote-section (info)
+ "Format the footnote section.
+INFO is a plist used as a communication channel."
+ (let* ((fn-alist (org-export-collect-footnote-definitions info))
+ (fn-alist (cl-loop for (n type raw) in fn-alist collect
+ (cons n (org-trim (org-export-data raw info)))))
+ (headline-style (plist-get info :md-headline-style))
+ (section-title (org-html--translate "Footnotes" info)))
+ (when fn-alist
+ (format (plist-get info :md-footnotes-section)
+ (org-md--headline-title headline-style 1 section-title)
+ (mapconcat (lambda (fn) (org-md--footnote-formatted fn info))
+ fn-alist
+ "\n")))))
+
;;;; Template
(defun org-md-inner-template (contents info)
@@ -473,7 +533,15 @@ CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
;; Make sure CONTENTS is separated from table of contents and
;; footnotes with at least a blank line.
- (org-trim (org-html-inner-template (concat "\n" contents "\n") info)))
+ (org-trim (concat
+ ;; Table of contents.
+ (let ((depth (plist-get info :with-toc)))
+ (when depth (org-html-toc depth info)))
+ ;; Document contents.
+ contents
+ "\n"
+ ;; Footnotes section.
+ (org-md-footnote-section info))))
(defun org-md-template (contents _info)
"Return complete document string after Markdown conversion.
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-22 5:31 ` Jake Romer
@ 2016-08-22 8:47 ` Nicolas Goaziou
2016-08-25 17:35 ` Jake Romer
0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2016-08-22 8:47 UTC (permalink / raw)
To: Jake Romer; +Cc: emacs-orgmode
Hello,
Jake Romer <jkrmr.io@gmail.com> writes:
> Thanks for the pointers! I appreciate your patience -- I'm still a noob
> with Org :-)
>
> Here's the updated patch with entries in ORG-NEWS and the manual.
It looks good. However, I realized this is not a "tiny change" (per
<http://orgmode.org/worg/org-contribute.html#orgheadline14>), so you
need to sign FSF papers before I can apply it.
Have you done so already ? If not, would you be willing to do it ?
Details are given at
<http://orgmode.org/worg/org-contribute.html#orgheadline1>.
Thank you.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-22 8:47 ` Nicolas Goaziou
@ 2016-08-25 17:35 ` Jake Romer
2016-08-26 14:32 ` Nicolas Goaziou
0 siblings, 1 reply; 10+ messages in thread
From: Jake Romer @ 2016-08-25 17:35 UTC (permalink / raw)
To: emacs-orgmode, Nicolas Goaziou
[-- Attachment #1: Type: text/plain, Size: 827 bytes --]
>
> Have you done so already ? If not, would you be willing to do it ?
I just submitted it. Thanks!
Cheers,
Jake
On Mon, Aug 22, 2016 at 1:47 AM, Nicolas Goaziou <mail@nicolasgoaziou.fr>
wrote:
> Hello,
>
> Jake Romer <jkrmr.io@gmail.com> writes:
>
> > Thanks for the pointers! I appreciate your patience -- I'm still a noob
> > with Org :-)
> >
> > Here's the updated patch with entries in ORG-NEWS and the manual.
>
> It looks good. However, I realized this is not a "tiny change" (per
> <http://orgmode.org/worg/org-contribute.html#orgheadline14>), so you
> need to sign FSF papers before I can apply it.
>
> Have you done so already ? If not, would you be willing to do it ?
> Details are given at
> <http://orgmode.org/worg/org-contribute.html#orgheadline1>.
>
>
> Thank you.
>
> Regards,
>
> --
> Nicolas Goaziou
>
[-- Attachment #2: Type: text/html, Size: 2082 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-25 17:35 ` Jake Romer
@ 2016-08-26 14:32 ` Nicolas Goaziou
2016-08-31 1:25 ` Jake Romer
0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2016-08-26 14:32 UTC (permalink / raw)
To: Jake Romer; +Cc: emacs-orgmode
Hello,
Jake Romer <jkrmr.io@gmail.com> writes:
> I just submitted it. Thanks!
Great! Let me know when the process is over so I can apply the changes.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-26 14:32 ` Nicolas Goaziou
@ 2016-08-31 1:25 ` Jake Romer
2016-09-01 16:45 ` Nicolas Goaziou
0 siblings, 1 reply; 10+ messages in thread
From: Jake Romer @ 2016-08-31 1:25 UTC (permalink / raw)
To: emacs-orgmode, Nicolas Goaziou
[-- Attachment #1: Type: text/plain, Size: 353 bytes --]
All set, thanks! Just got the confirmation.
Cheers,
Jake Romer
On Fri, Aug 26, 2016 at 10:32 AM, Nicolas Goaziou <mail@nicolasgoaziou.fr>
wrote:
> Hello,
>
> Jake Romer <jkrmr.io@gmail.com> writes:
>
> > I just submitted it. Thanks!
>
> Great! Let me know when the process is over so I can apply the changes.
>
> Regards,
>
> --
> Nicolas Goaziou
>
[-- Attachment #2: Type: text/html, Size: 887 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: ox-md.el: Export TOC and Footnotes as Markdown rather than HTML
2016-08-31 1:25 ` Jake Romer
@ 2016-09-01 16:45 ` Nicolas Goaziou
0 siblings, 0 replies; 10+ messages in thread
From: Nicolas Goaziou @ 2016-09-01 16:45 UTC (permalink / raw)
To: Jake Romer; +Cc: emacs-orgmode
Hello,
Jake Romer <jkrmr.io@gmail.com> writes:
> All set, thanks! Just got the confirmation.
Perfect! I applied the patch.
Thank you.
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2016-09-01 16:45 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-08 1:31 ox-md.el: Export TOC and Footnotes as Markdown rather than HTML Jake Romer
2016-08-08 13:35 ` Nicolas Goaziou
2016-08-13 17:52 ` Jake Romer
2016-08-15 15:34 ` Nicolas Goaziou
2016-08-22 5:31 ` Jake Romer
2016-08-22 8:47 ` Nicolas Goaziou
2016-08-25 17:35 ` Jake Romer
2016-08-26 14:32 ` Nicolas Goaziou
2016-08-31 1:25 ` Jake Romer
2016-09-01 16:45 ` Nicolas Goaziou
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.