Skip to content

Commit

Permalink
Support HTML_CONTAINER and HTML_CONTAINER_CLASS
Browse files Browse the repository at this point in the history
Fixes #271.
  • Loading branch information
kaushalmodi committed Jan 10, 2022
1 parent 497d588 commit 4ea2bd3
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 16 deletions.
20 changes: 20 additions & 0 deletions doc/ox-hugo-manual.org
Original file line number Diff line number Diff line change
Expand Up @@ -3837,6 +3837,26 @@ This links to the {{{relref(Org Special Blocks,org-special-blocks)}}} page.
will also render to:

This links to the {{{relref(Org Special Blocks,org-special-blocks)}}} page.
*** HTML Containers
:PROPERTIES:
:EXPORT_FILE_NAME: html-containers
:END:
#+begin_description
Support ~HTML_CONTAINER~ and ~HTML_CONTAINER_CLASS~ similar to the way
~ox-html~ does, but also supporting property inheritance.
#+end_description
The ~HTML_CONTAINER~ and ~HTML_CONTAINER_CLASS~ properties can be
added to any of the subtrees with the ~EXPORT_~ prefix.

If a sub-tree has the property ~EXPORT_HTML_CONTAINER: section~, that
sub-tree is exported as a heading surrounding with ~<section>~ and
~</section>~. By default, that ~section~ tag has the class
"outline-NUM" where /NUM/ is the level of that heading in that post.

Additionally, if it has the property ~EXPORT_HTML_CONTAINER_CLASS:
foo~, the "foo" class gets added to that container tag as well.

{{{test-search(container)}}}
** Meta
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "7.meta"
Expand Down
80 changes: 64 additions & 16 deletions ox-hugo.el
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,16 @@ block."
:type '(repeat string))
;;;###autoload (put 'org-hugo-special-block-raw-content-types 'safe-local-variable (lambda (x) (stringp x)))

(defcustom org-hugo-container-element ""
"HTML element to use for wrapping top level sections.
Can be set with the in-buffer HTML_CONTAINER property.
When set to \"\", the top level sections are not wrapped in any
HTML element."
:group 'org-export-hugo
:type 'string)
;;;###autoload (put 'org-hugo-container-element 'safe-local-variable 'stringp)



;;; Define Back-End
Expand Down Expand Up @@ -819,6 +829,8 @@ block."
(:hugo-paired-shortcodes "HUGO_PAIRED_SHORTCODES" nil org-hugo-paired-shortcodes space)
(:hugo-pandoc-citations "HUGO_PANDOC_CITATIONS" nil nil)
(:bibliography "BIBLIOGRAPHY" nil nil newline) ;Used in ox-hugo-pandoc-cite
(:html-container "HTML_CONTAINER" nil org-hugo-container-element)
(:html-container-class "HTML_CONTAINER_CLASS" nil "")

;; Front-matter variables
;; https://gohugo.io/content-management/front-matter/#front-matter-variables
Expand Down Expand Up @@ -1881,10 +1893,44 @@ a communication channel."
(org-hugo--get-anchor heading info)))
(heading-title (org-hugo--heading-title style level loffset title
todo-fmtd anchor numbers))
(wrap-element (org-hugo--container heading info))
(content-str (or (org-string-nw-p contents) "")))
(format "%s%s" heading-title content-str)))))))
(if wrap-element
(let* ((container-class (or (org-element-property :HTML_CONTAINER_CLASS heading)
(org-element-property :EXPORT_HTML_CONTAINER_CLASS heading)
(plist-get info :html-container-class)))
(container-class-str (when (org-string-nw-p container-class)
(concat " " container-class))))
(format (concat "<%s class=\"outline-%d%s\">\n"
"%s%s\n"
"</%s>")
wrap-element level container-class-str
heading-title content-str
wrap-element))
(format "%s%s" heading-title content-str))))))))

;;;;; Heading Helpers
(defun org-hugo--container (heading info)
"Get the HTML container element for HEADING.
INFO is a plist used as a communication channel.
If a heading has `:HTML_CONTAINER:' or `:EXPORT_HTML_CONTAINER:'
property, that is used for the container element.
Else if the `:html-container' property is a non-empty string:
- For the top level headings, wrapping is done using that property.
- For second and lower level headings, wrapping is done using
the HTML <div> tags.
Else, no HTML element is wrapped around the HEADING."
(or (org-element-property :HTML_CONTAINER heading) ;property of the immediate heading
(org-element-property :EXPORT_HTML_CONTAINER heading) ;property of the immediate heading
(and (org-string-nw-p (plist-get info :html-container)) ;inherited :html-container: property if any
(if (= 1 (org-export-get-relative-level heading info))
(plist-get info :html-container)
"div"))))

;;;###autoload
(defun org-hugo-slug (str)
"Convert string STR to a `slug' and return that string.
Expand Down Expand Up @@ -3903,6 +3949,8 @@ are \"toml\" and \"yaml\"."
"HUGO_BASE_DIR"
"HUGO_GOLDMARK"
"HUGO_CODE_FENCE"
"HTML_CONTAINER"
"HTML_CONTAINER_CLASS"
"HUGO_MENU"
"HUGO_CUSTOM_FRONT_MATTER"
"HUGO_DRAFT"
Expand Down Expand Up @@ -4232,7 +4280,7 @@ links."
(org-export-get-environment 'hugo)))
(local-variables (buffer-local-variables))
(bound-variables (org-export--list-bound-variables))
vars)
vars)
(with-current-buffer buffer
(let ((inhibit-modification-hooks t)
(org-mode-hook nil)
Expand All @@ -4243,20 +4291,20 @@ links."
;; through BIND keywords.
(dolist (entry local-variables vars)
(when (consp entry)
(let ((var (car entry))
(val (cdr entry)))
(and (not (memq var org-export-ignored-local-variables))
(or (memq var
'(default-directory
buffer-file-name
buffer-file-coding-system))
(assq var bound-variables)
(string-match "^\\(org-\\|orgtbl-\\)"
(symbol-name var)))
;; Skip unreadable values, as they cannot be
;; sent to external process.
(or (not val) (ignore-errors (read (format "%S" val))))
(push (set (make-local-variable var) val) vars)))))
(let ((var (car entry))
(val (cdr entry)))
(and (not (memq var org-export-ignored-local-variables))
(or (memq var
'(default-directory
buffer-file-name
buffer-file-coding-system))
(assq var bound-variables)
(string-match "^\\(org-\\|orgtbl-\\)"
(symbol-name var)))
;; Skip unreadable values, as they cannot be
;; sent to external process.
(or (not val) (ignore-errors (read (format "%S" val))))
(push (set (make-local-variable var) val) vars)))))

;; Process all link elements in the AST.
(org-element-map ast 'link
Expand Down
40 changes: 40 additions & 0 deletions test/site/content-org/all-posts.org
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,46 @@ in Markdown.
Above title would render to ~Version 0.1 <span
class="timestamp-wrapper"><span class="timestamp">&lt;2017-10-11
Wed&gt;</span></span>~ in Markdown.
** HTML Container :container:html:
:PROPERTIES:
:EXPORT_HTML_CONTAINER: section
:END:
*** HTML Container with class
:PROPERTIES:
:EXPORT_FILE_NAME: html-container-with-class
:EXPORT_HTML_CONTAINER_CLASS: foo
:END:
**** Top level heading 1
This heading is wrapped in a ~section~ tag with classes ~outline-1~
and ~foo~.
***** Sub-heading 1.1
This heading is wrapped in a ~div~ tag with classes ~outline-2~ and
~foo~.
**** Top level heading 2
:PROPERTIES:
:EXPORT_HTML_CONTAINER_CLASS: bar
:END:
This heading is wrapped in a ~section~ tag with classes ~outline-2~ and
~bar~.
***** Sub-heading 2.1
:PROPERTIES:
:EXPORT_HTML_CONTAINER_CLASS: zoo
:END:
This heading is wrapped in a ~div~ tag with classes ~outline-2~ and
~zoo~.
**** Top level heading 3
:PROPERTIES:
:EXPORT_HTML_CONTAINER: aside
:END:
This heading is wrapped in an ~aside~ tag with classes ~outline-1~ and
~foo~.
***** Sub-heading 3.1
:PROPERTIES:
:EXPORT_HTML_CONTAINER: blockquote
:EXPORT_HTML_CONTAINER_CLASS: baz
:END:
This heading is wrapped in a ~blockquote~ tag with classes ~outline-2~
and ~baz~.
* Title in Front Matter :title:
** Awesome title with "quoted text"
:PROPERTIES:
Expand Down
59 changes: 59 additions & 0 deletions test/site/content/posts/html-container-with-class.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
+++
title = "HTML Container with class"
tags = ["headings", "container", "html"]
draft = false
+++

<section class="outline-1 foo">

## Top level heading 1 {#top-level-heading-1}

This heading is wrapped in a `section` tag with classes `outline-1`
and `foo`.

<div class="outline-2 foo">

### Sub-heading 1.1 {#sub-heading-1-dot-1}

This heading is wrapped in a `div` tag with classes `outline-2` and
`foo`.

</div>

</section>

<section class="outline-1 bar">

## Top level heading 2 {#top-level-heading-2}

This heading is wrapped in a `section` tag with classes `outline-2` and
`bar`.

<div class="outline-2 zoo">

### Sub-heading 2.1 {#sub-heading-2-dot-1}

This heading is wrapped in a `div` tag with classes `outline-2` and
`zoo`.

</div>

</section>

<aside class="outline-1 foo">

## Top level heading 3 {#top-level-heading-3}

This heading is wrapped in an `aside` tag with classes `outline-1` and
`foo`.

<blockquote class="outline-2 baz">

### Sub-heading 3.1 {#sub-heading-3-dot-1}

This heading is wrapped in a `blockquote` tag with classes `outline-2`
and `baz`.

</blockquote>

</aside>

0 comments on commit 4ea2bd3

Please sign in to comment.