From 398f3a6cdeea478eaa0e75ca1251d06c00874d9b Mon Sep 17 00:00:00 2001
From: Kaushal Modi
Date: Sat, 27 Jan 2018 01:58:44 -0500
Subject: [PATCH] Export "description" special block content to front-matter
Fixes https://github.com/kaushalmodi/ox-hugo/issues/118
---
ox-hugo.el | 72 ++++++++++++++++---
test/site/content-org/all-posts.org | 62 ++++++++++++++--
...ption-multi-line-org-special-block-toml.md | 11 +++
...ption-multi-line-org-special-block-yaml.md | 13 ++++
...tion-single-line-org-special-block-toml.md | 8 +++
...tion-single-line-org-special-block-yaml.md | 8 +++
.../content/posts/post-description-quotes.md | 1 +
.../bare_min/layouts/_default/single.html | 5 ++
8 files changed, 163 insertions(+), 17 deletions(-)
create mode 100644 test/site/content/posts/description-multi-line-org-special-block-toml.md
create mode 100644 test/site/content/posts/description-multi-line-org-special-block-yaml.md
create mode 100644 test/site/content/posts/description-single-line-org-special-block-toml.md
create mode 100644 test/site/content/posts/description-single-line-org-special-block-yaml.md
diff --git a/ox-hugo.el b/ox-hugo.el
index fe6e28e..76aeedc 100644
--- a/ox-hugo.el
+++ b/ox-hugo.el
@@ -110,6 +110,11 @@ helps set the bundle path correctly for such cases (where
EXPORT_HUGO_BUNDLE and EXPORT_FILE_NAME are set in the same
subtree).")
+(defvar org-hugo--description nil
+ "Variable to store the current post's description.
+This variable is updated by the `org-hugo-special-block'
+function.")
+
(defvar org-hugo-allow-export-after-save t
"Enable flag for `org-hugo-export-wim-to-md-after-save'.
When nil, the above function will not export the Org file to
@@ -637,7 +642,8 @@ newer."
(keyword . org-hugo-keyword)
(link . org-hugo-link)
(paragraph . org-hugo-paragraph)
- (src-block . org-hugo-src-block))
+ (src-block . org-hugo-src-block)
+ (special-block . org-hugo-special-block))
:filters-alist '((:filter-body . org-hugo-body-filter))
;;;; options-alist
;; KEY KEYWORD OPTION DEFAULT BEHAVIOR
@@ -811,7 +817,8 @@ This function is called in the very end of
`org-hugo-publish-to-md'.
This is an internal function."
- (advice-remove 'org-babel-exp-code #'org-hugo--org-babel-exp-code))
+ (advice-remove 'org-babel-exp-code #'org-hugo--org-babel-exp-code)
+ (setq org-hugo--description nil))
(defun org-hugo--get-headline-number (headline info &optional toc)
"Return htmlized section number for the HEADLINE.
@@ -1924,6 +1931,24 @@ channel."
(setq ret (org-blackfriday--div-wrap-maybe src-block ret))
ret))
+;;;; Special Block
+(defun org-hugo-special-block (special-block contents _info)
+ "Transcode a SPECIAL-BLOCK element from Org to Hugo-compatible Markdown.
+CONTENTS holds the contents of the block.
+
+This function saves the content of \"description\" special block
+to the global variable `org-hugo--description'.
+
+For all other special blocks, processing is passed on to
+`org-blackfriday-special-block'."
+ (let ((block-type (org-element-property :type special-block)))
+ (cond
+ ((string= block-type "description")
+ (setq org-hugo--description (org-trim contents))
+ nil)
+ (t
+ (org-blackfriday-special-block special-block contents nil)))))
+
;;; Filter Functions
@@ -1973,8 +1998,11 @@ INFO is a plist holding export options."
(format "%s%s%s" fm body org-hugo-footer)))
;;;;; Hugo Front Matter
-(defun org-hugo--quote-string (val &optional prefer-no-quotes)
- "Wrap VAL with double quotes if it is a string.
+(defun org-hugo--quote-string (val &optional prefer-no-quotes format)
+ "Wrap VAL with appropriate quotes if it is a string.
+
+If VAL contains newlines, format it according to TOML or YAML
+FORMAT to preserve them.
VAL is returned as-it-is under the following cases:
- It is not a string (or nil).
@@ -1982,13 +2010,14 @@ VAL is returned as-it-is under the following cases:
- It is a string and it's value is \"true\" or \"false\".
- It is a string representing a date.
-If PREFER-NO-QUOTES is non-nil, return the VAL as-it-is if it's a
-string with just alphanumeric characters."
+If optional argument PREFER-NO-QUOTES is non-nil, return the VAL
+as-it-is if it's a string with just alphanumeric characters.
+
+Optional argument FORMAT can be \"toml\" or \"yaml\"."
(cond
((or (null val) ;nil
(not (stringp val)) ;could be a number, like menu weight
- (and (stringp val)
- (> (safe-length val) 0)
+ (and (org-string-nw-p val)
(string= (substring val 0 1) "\"") ;First char is literally a "
(string= (substring val -1) "\"")) ;Last char is literally a "
(string= "true" val)
@@ -2005,6 +2034,26 @@ string with just alphanumeric characters."
((and prefer-no-quotes
(string-match-p "\\`[a-zA-Z0-9]+\\'" val))
val)
+ ((and (org-string-nw-p val)
+ (string-match-p "\n" val))
+ (if (and (stringp format)
+ (string= format "yaml"))
+ (progn
+ ;; https://yaml-multiline.info/
+ ;;
+ ;; | |foo : >
+ ;; |abc | abc
+ ;; | >>> |
+ ;; |def |
+ ;; | | def
+ ;;
+ (setq val (replace-regexp-in-string "^" " " val)) ;Indent by 2 spaces
+ ;; In Org, a single blank line is used to start a new
+ ;; paragraph. In the YAML multi-line string, that needs to
+ ;; be 2 blank lines.
+ (setq val (replace-regexp-in-string "\n \n" "\n\n\n" val))
+ (format ">\n%s" val))
+ (format "\"\"\"%s\"\"\"" val))) ;Triple-quote
(t
(concat "\"" (replace-regexp-in-string "\"" "\\\\\"" val) "\""))))
@@ -2262,6 +2311,9 @@ INFO is a plist used as a communication channel."
(mapcar #'org-trim author-list-1))))))
(creator (and (plist-get info :with-creator)
(plist-get info :creator)))
+ (description (or org-hugo--description
+ (org-string-nw-p
+ (org-export-data (plist-get info :description) info))))
(aliases-raw (let ((aliases-raw-1
(org-string-nw-p
(org-export-data (plist-get info :hugo-aliases) info))))
@@ -2353,7 +2405,7 @@ INFO is a plist used as a communication channel."
;; variables will be ordered.
(title . ,(org-hugo--sanitize-title info))
(author . ,author-list)
- (description . ,(org-export-data (plist-get info :description) info))
+ (description . ,description)
(date . ,(org-hugo--format-date :date info))
(publishDate . ,(org-hugo--format-date :hugo-publishdate info))
(expiryDate . ,(org-hugo--format-date :hugo-expirydate info))
@@ -2596,7 +2648,7 @@ are \"toml\" and \"yaml\"."
(listp value)
(org-hugo--get-yaml-toml-list-string value))
(t
- (org-hugo--quote-string value)))))))))))
+ (org-hugo--quote-string value nil format)))))))))))
(concat sep front-matter bf-string menu-string res-string sep)))
(defun org-hugo--selective-property-inheritance ()
diff --git a/test/site/content-org/all-posts.org b/test/site/content-org/all-posts.org
index 96c67a0..fa8f72f 100644
--- a/test/site/content-org/all-posts.org
+++ b/test/site/content-org/all-posts.org
@@ -375,13 +375,6 @@ happen in post titles ({{{hugoissue(4175)}}}).
:END:
- All the Org markup characters are removed.
- The "markup characters" not doing actual markup are retained.
-* Description meta-data with "quoted text"
-:PROPERTIES:
-:EXPORT_FILE_NAME: post-description-quotes
-:EXPORT_DESCRIPTION: Some description with "quoted text"
-:EXPORT_DATE: 2017-07-24
-:END:
-Testing a post with double quotes in the description.
* Excluded post :noexport:
:PROPERTIES:
:EXPORT_FILE_NAME: excluded-post
@@ -3763,6 +3756,61 @@ comma-separated.
:EXPORT_KEYWORDS: abc
:EXPORT_KEYWORDS+: def
:END:
+** Description :description:
+*** Description meta-data with "quoted text"
+:PROPERTIES:
+:EXPORT_FILE_NAME: post-description-quotes
+:EXPORT_DESCRIPTION: Some description with "quoted text"
+:EXPORT_DATE: 2017-07-24
+:END:
+Testing a post with double quotes in the description.
+*** Description set using Org Special Block :special_block:
+**** TOML :toml:
+:PROPERTIES:
+:EXPORT_HUGO_FRONT_MATTER_FORMAT: toml
+:END:
+***** Single-line description set using Org Special Block (TOML) :single_line:
+:PROPERTIES:
+:EXPORT_FILE_NAME: description-single-line-org-special-block-toml
+:END:
+#+begin_description
+Short description
+#+end_description
+Post content.
+***** Multi-line description set using Org Special Block (TOML) :multi_line:
+:PROPERTIES:
+:EXPORT_FILE_NAME: description-multi-line-org-special-block-toml
+:END:
+#+begin_description
+Short description
+of this post
+
+*line* -- /italics/ --- +strikethrough+
+#+end_description
+Post content.
+**** YAML :yaml:
+:PROPERTIES:
+:EXPORT_HUGO_FRONT_MATTER_FORMAT: yaml
+:END:
+***** Single-line description set using Org Special Block (YAML) :single_line:
+:PROPERTIES:
+:EXPORT_FILE_NAME: description-single-line-org-special-block-yaml
+:END:
+#+begin_description
+Short description
+#+end_description
+Post content.
+***** Multi-line description set using Org Special Block (YAML) :multi_line:
+:PROPERTIES:
+:EXPORT_FILE_NAME: description-multi-line-org-special-block-yaml
+:END:
+#+begin_description
+Short description
+of this post
+
+*line* -- /italics/ --- +strikethrough+
+#+end_description
+Post content.
** Replace front-matter keys :keys:replace:
*** Replace only "linkTitle" key :linktitle:
:PROPERTIES:
diff --git a/test/site/content/posts/description-multi-line-org-special-block-toml.md b/test/site/content/posts/description-multi-line-org-special-block-toml.md
new file mode 100644
index 0000000..f66ab88
--- /dev/null
+++ b/test/site/content/posts/description-multi-line-org-special-block-toml.md
@@ -0,0 +1,11 @@
++++
+title = "Multi-line description set using Org Special Block (TOML)"
+description = """Short description
+of this post
+
+**line** -- _italics_ --- ~~strikethrough~~"""
+tags = ["front-matter", "description", "special-block", "toml", "multi-line"]
+draft = false
++++
+
+Post content.
diff --git a/test/site/content/posts/description-multi-line-org-special-block-yaml.md b/test/site/content/posts/description-multi-line-org-special-block-yaml.md
new file mode 100644
index 0000000..dab57a7
--- /dev/null
+++ b/test/site/content/posts/description-multi-line-org-special-block-yaml.md
@@ -0,0 +1,13 @@
+---
+title : "Multi-line description set using Org Special Block (YAML)"
+description : >
+ Short description
+ of this post
+
+
+ **line** -- _italics_ --- ~~strikethrough~~
+tags : ["front-matter", "description", "special-block", "yaml", "multi-line"]
+draft : false
+---
+
+Post content.
diff --git a/test/site/content/posts/description-single-line-org-special-block-toml.md b/test/site/content/posts/description-single-line-org-special-block-toml.md
new file mode 100644
index 0000000..468789e
--- /dev/null
+++ b/test/site/content/posts/description-single-line-org-special-block-toml.md
@@ -0,0 +1,8 @@
++++
+title = "Single-line description set using Org Special Block (TOML)"
+description = "Short description"
+tags = ["front-matter", "description", "special-block", "toml", "single-line"]
+draft = false
++++
+
+Post content.
diff --git a/test/site/content/posts/description-single-line-org-special-block-yaml.md b/test/site/content/posts/description-single-line-org-special-block-yaml.md
new file mode 100644
index 0000000..d5a6504
--- /dev/null
+++ b/test/site/content/posts/description-single-line-org-special-block-yaml.md
@@ -0,0 +1,8 @@
+---
+title : "Single-line description set using Org Special Block (YAML)"
+description : "Short description"
+tags : ["front-matter", "description", "special-block", "yaml", "single-line"]
+draft : false
+---
+
+Post content.
diff --git a/test/site/content/posts/post-description-quotes.md b/test/site/content/posts/post-description-quotes.md
index 099b5ac..45dae4c 100644
--- a/test/site/content/posts/post-description-quotes.md
+++ b/test/site/content/posts/post-description-quotes.md
@@ -2,6 +2,7 @@
title = "Description meta-data with \"quoted text\""
description = "Some description with \"quoted text\""
date = 2017-07-24
+tags = ["front-matter", "description"]
draft = false
+++
diff --git a/test/site/themes/bare_min/layouts/_default/single.html b/test/site/themes/bare_min/layouts/_default/single.html
index 9d11cd9..da93d4d 100644
--- a/test/site/themes/bare_min/layouts/_default/single.html
+++ b/test/site/themes/bare_min/layouts/_default/single.html
@@ -42,6 +42,11 @@
{{ end }}
+ {{ with .Description }}
+
+ {{ . | markdownify }}
+
+ {{ end }}
{{ .Content }}
{{ with .Resources }}