Skip to content

Commit

Permalink
Support exporting Org Special Blocks like ox-html
Browse files Browse the repository at this point in the history
It works almost the same way as ox-html, but a little hack is add to
get around a Hugo/Blackfriday limitation that Markdown text cannot be
wrapped in HTML elements like div. Details:
#93.

Fixes #105.
  • Loading branch information
kaushalmodi committed Jan 9, 2018
1 parent 745f458 commit a2e9396
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
36 changes: 36 additions & 0 deletions ox-blackfriday.el
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Note that this variable is *only* for internal use.")
(plain-list . org-blackfriday-plain-list)
(plain-text . org-blackfriday-plain-text)
(quote-block . org-blackfriday-quote-block)
(special-block . org-blackfriday-special-block)
(src-block . org-blackfriday-src-block)
(strike-through . org-blackfriday-strike-through)
(table-cell . org-blackfriday-table-cell)
Expand Down Expand Up @@ -524,6 +525,41 @@ communication channel."
(when next-is-quote
"\n\n<!--quoteend-->"))))

;;;; Special Block
(defun org-blackfriday-special-block (special-block contents _info)
"Transcode a SPECIAL-BLOCK element from Org to HTML.
CONTENTS holds the contents of the block.
This function is adapted from `org-html-special-block'."
(let* ((block-type (org-element-property :type special-block))
(html5-fancy (member block-type org-html-html5-elements))
(attributes (org-export-read-attribute :attr_html special-block)))
(unless html5-fancy
(let ((class (plist-get attributes :class)))
(setq attributes (plist-put attributes :class
(if class
(concat class " " block-type)
block-type)))))
(let* ((contents (or contents ""))
;; If #+NAME is specified, use that for the HTML element
;; "id" attribute.
(name (org-element-property :name special-block))
(attr-str (org-html--make-attribute-string
(if (or (not name) (plist-member attributes :id))
attributes
(plist-put attributes :id name))))
(attr-str (if (org-string-nw-p attr-str)
(concat " " attr-str)
"")))
;; The empty HTML element tags like "<div></div>" is a hack to
;; get around a Blackfriday limitation. Details:
;; https://github.com/kaushalmodi/ox-hugo/issues/93.
(if html5-fancy
(format "<%s%s>\n<%s></%s>\n\n%s\n</%s>"
block-type attr-str block-type block-type contents block-type)
(format "<div%s>\n<div></div>\n\n%s\n</div>"
attr-str contents)))))

;;;; Src Block
(defun org-blackfriday-src-block (src-block _contents info)
"Transcode SRC-BLOCK element into Blackfriday Markdown format.
Expand Down
46 changes: 46 additions & 0 deletions test/site/content-org/all-posts.org
Original file line number Diff line number Diff line change
Expand Up @@ -2645,6 +2645,52 @@ Line 3 had no =>= char.
> ← See that this =>= on line 4 is retained even at the beginning of the line.
Line 5 has this > charcter in-between and is retained.
#+END_VERSE
* Special Blocks :special_block:
:PROPERTIES:
:EXPORT_FILE_NAME: special-blocks
:END:
** HTML5 Element Blocks
*** Block without NAME, class or id
#+BEGIN_article
This is /an article/.
#+END_article
*** Block with NAME
#+NAME: Aside A
#+BEGIN_aside
/Some/ *text* --- 1

| a | b | c |
| d | e | f |
#+END_aside
*** Block with class and id
#+ATTR_HTML: :class my-section :id section-a
#+BEGIN_section
/Some/ *text* --- 2

| g | h | i |
| j | k | l |
#+END_section
** DIV-wrapped Blocks
*** DIV without NAME, class or id
#+BEGIN_something
This is /some text/ wrapped in a =div= block with class =something=.
#+END_something
*** DIV with NAME
#+NAME: Foo A
#+BEGIN_foo
/Some/ *text* --- 3

| m | n | o |
| p | q | r |
#+END_foo
*** DIV with class and id
#+ATTR_HTML: :class my-bar :id bar-a
#+BEGIN_bar
/Some/ *text* --- 4

| s | t | u |
| v | w | x |
#+END_bar
* Org TODO keywords :todo:
** Post with a TODO heading
:PROPERTIES:
Expand Down
86 changes: 86 additions & 0 deletions test/site/content/posts/special-blocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
+++
title = "Special Blocks"
tags = ["special-block"]
draft = false
+++

## HTML5 Element Blocks {#html5-element-blocks}


### Block without NAME, class or id {#block-without-name-class-or-id}

<article>
<article></article>

This is _an article_.

</article>


### Block with NAME {#block-with-name}

<aside id="Aside A">
<aside></aside>

_Some_ **text** --- 1

| a | b | c |
|---|---|---|
| d | e | f |

</aside>


### Block with class and id {#block-with-class-and-id}

<section class="my-section" id="section-a">
<section></section>

_Some_ **text** --- 2

| g | h | i |
|---|---|---|
| j | k | l |

</section>


## DIV-wrapped Blocks {#div-wrapped-blocks}


### DIV without NAME, class or id {#div-without-name-class-or-id}

<div class="something">
<div></div>

This is _some text_ wrapped in a `div` block with class `something`.

</div>


### DIV with NAME {#div-with-name}

<div class="foo" id="Foo A">
<div></div>

_Some_ **text** --- 3

| m | n | o |
|---|---|---|
| p | q | r |

</div>


### DIV with class and id {#div-with-class-and-id}

<div class="my-bar bar" id="bar-a">
<div></div>

_Some_ **text** --- 4

| s | t | u |
|---|---|---|
| v | w | x |

</div>

0 comments on commit a2e9396

Please sign in to comment.