Skip to content

Commit

Permalink
Allow quoted strings with spaces in Org keywords
Browse files Browse the repository at this point in the history
Org keywords: #+HUGO_TAGS, #+HUGO_CATEGORIES, #+KEYWORDS

or

Org properties: :EXPORT_HUGO_TAGS:, :EXPORT_HUGO_CATEGORIES:, :EXPORT_KEYWORDS:

    !! This is a breaking change !!

Earlier, strings with spaces in those keywords had to be written as
abc__def. Now strings with spaces need to be written as "abc def"
instead, which is more intuitive.

This *does not* change the abc__def style required in Org
tags (e.g. :abc__def:), because Org tags cannot contain spaces. Note
that the same applies to the #+FILETAGS keyword too! In the
abc__def.
  • Loading branch information
kaushalmodi committed Jan 25, 2018
1 parent b9f108b commit 319435d
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 55 deletions.
54 changes: 28 additions & 26 deletions doc/ox-hugo-manual.org
Original file line number Diff line number Diff line change
Expand Up @@ -1038,35 +1038,37 @@ export flow. So =#+FILETAGS= will have no effect in this flow.

- To set tags, use =#+HUGO_TAGS=.
- To set categories, use =#+HUGO_CATEGORIES=.
**** Hyphens in tags (and categories)
Hyphens are not allowed in Org tags. So =ox-hugo= converts *single
underscores* to hyphens if =org-hugo-prefer-hyphen-in-tags= is set to
non-nil (default). So an Org tag *abc_def* will be exported as /tag/
*"abc-def"*. Similarly an Org tag *@abc_def* will be exported as
/category/ *"abc-def"*.
**** Hyphens and Spaces in Org tags (and categories)
Hyphens and spaces are not allowed in Org tags (=* Heading :TAG:=).

So =ox-hugo= converts:
- *single underscores* to hyphens if =org-hugo-prefer-hyphen-in-tags=
is set to non-nil (default).
- *double underscores* to spaces if =org-hugo-allow-spaces-in-tags= is
set to non-nil (default).

So an Org tag *abc_def* will be exported as /tag/ *"abc-def"*, and
*abc__def* will be exported as /tag/ *"abc def"*.

The same applies to Org tags with prefix =@= which will be exported as
/categories/. So *@abc_def* will be exported as /category/
*"abc-def"*, and *@abc__def* as /category/ *"abc def"*.

To export a tag or category with an underscore, use 3 consecutive
underscores. So an Org tag *abc___def* will be exported as /tag/
*"abc_def"*. If you rather prefer to always export single underscores
as underscores, set =org-hugo-prefer-hyphen-in-tags= to nil.

This variable does not affect the tags set via =#+HUGO_TAGS= keyword
or the =EXPORT_HUGO_TAGS= property, because Org keywords and
properties allow using the hyphen character. So underscores and
hyphens in tags (or categories in =#+HUGO_CATEGORIES= /
=EXPORT_HUGO_CATEGORIES=) remain untransformed on export.
**** Spaces in tags (and categories)
Spaces are not allowed in Org tags. So =ox-hugo= converts *double
underscores* to spaces if =org-hugo-allow-spaces-in-tags= is set to
non-nil (default). So an Org tag *abc__def* will be exported as /tag/
*"abc def"*. Similarly an Org tag *@abc__def* will be exported as
/category/ *"abc def"*.

This variable *also affects* the tags set via =#+HUGO_TAGS= keyword or
the =EXPORT_HUGO_TAGS= property, because it is not possible to
distinguish in Org keywords and properties whether the space is part
of the tag or used to separate two tags. The same applies to
categories set via =#+HUGO_CATEGORIES= / =EXPORT_HUGO_CATEGORIES=.
*"abc_def"* (and the same for categories). If you rather prefer to
always export /single underscores/ as underscores, set
=org-hugo-prefer-hyphen-in-tags= to nil.

- NOTE :: These two variables *also affect* the tags set via
=#+FILETAGS= keyword (which is used only in subtree-based
exported Org files).

These variables do not affect the tags set via keywords =#+HUGO_TAGS=,
=#+HUGO_CATEGORIES= or =#+KEYWORDS= (or their respective subtree
property forms), because Org keywords and properties allow using the
hyphen and space (/in "double-quoted strings"/) characters. So the
underscores in these keywords remain untransformed on export.
**** Examples
- [[https://raw.githubusercontent.com/kaushalmodi/ox-hugo/master/test/site/content-org/tags-and-categories.org][Org source]]
- Exported Markdown -- [[https://raw.githubusercontent.com/kaushalmodi/ox-hugo/master/test/site/content/posts/inheriting-tags.md][=inheriting-tags.md=]], [[https://raw.githubusercontent.com/kaushalmodi/ox-hugo/master/test/site/content/posts/overriding-tags.md][=overriding-tags.md=]]
Expand Down
50 changes: 26 additions & 24 deletions ox-hugo.el
Original file line number Diff line number Diff line change
Expand Up @@ -2001,8 +2001,8 @@ string with just alphanumeric characters."
(defun org-hugo--parse-property-arguments (str)
"Return an alist converted from a string STR of Hugo property value.
If STR is of type \":KEY VALUE\", the returned value is ((KEY
. VALUE)).
STR is of type \":KEY1 VALUE1 :KEY2 VALUE2 ..\". Given that, the
returned value is ((KEY1 . VALUE1) (KEY2 . VALUE2) ..).
Example: Input STR \":foo bar :baz 1 :zoo \\\"two words\\\"\" would
convert to ((foo . \"bar\") (baz . 1) (zoo . \"two words\"))."
Expand Down Expand Up @@ -2185,39 +2185,44 @@ Example: :some__tag: -> \"some tag\"."
(setq ret (cl-remove-if-not #'org-string-nw-p ret))
ret))

(defun org-hugo--delim-str-to-list (delim-str info &optional no-prefer-hyphen)
(defun org-hugo--delim-str-to-list (delim-str)
"Function to transform DELIM-STR string to a list.
1. Trim leading/trailing spaces from DELIM-STR, replace spaces
with `org-hugo--internal-list-separator'.
2. Convert that string to a list using
`org-hugo--internal-list-separator' as the separator.
3. Pass that to `org-hugo--transform-org-tags' that does some string
transformation. See that function for more info.
3. Break up each element of that list into further string elements.
Space within quoted string is retained. This is done using
`org-hugo--parse-quoted-string'. If a string element if of
type \"VALUE1 \\\"QUOTED VALUE2\\\" ..\", that is converted to
\(\"VALUE1\" \"QUOTED VALUE2\" ..).
4. Return the transformed list.
Example: \"two__words hyphenated_word\" -> (\"two words\" \"hyphenated-word\").
Note that when NO-PREFER-HYPHEN is non-nil, replacement of
underscores in DELIM-STR with hyphens as shown in the above
example will not happen.
Example: \"one\n\\\"two words\\\" three\nfour\" -> (\"one\" \"two words\" \"three\" \"four\").
This function can be applied to any string that uses
`org-hugo--internal-list-separator' as delimiter, for example,
parsing the tags, categories and keywords meta-data.
INFO is a plist used as a communication channel.
Return nil if DELIM-STR is not a string."
(when (stringp delim-str)
(let* ((delim-str (org-trim delim-str))
(delim-str (replace-regexp-in-string
" +" org-hugo--internal-list-separator
delim-str))
(str-list (split-string delim-str org-hugo--internal-list-separator))
(str-list (org-hugo--transform-org-tags
str-list info no-prefer-hyphen)))
str-list)))
ret)
(dolist (str str-list)
(let* ((format-str ":dummy '(%s)") ;The :dummy key is later discarded
(alist (org-babel-parse-header-arguments (format format-str str)))
(lst (cdr (car alist)))
(str-list2 (mapcar (lambda (elem)
(cond
((symbolp elem)
(symbol-name elem))
(t
elem)))
lst)))
(setq ret (append ret str-list2))))
ret)))

(defun org-hugo--category-p (tag)
"Return non-nil if TAG begins with \"@\".
Expand Down Expand Up @@ -2284,8 +2289,7 @@ INFO is a plist used as a communication channel."
(tags (or
;; Look for tags set using #+HUGO_TAGS keyword, or
;; EXPORT_HUGO_TAGS property if available.
(org-hugo--delim-str-to-list
(plist-get info :hugo-tags) info :no-prefer-hyphen)
(org-hugo--delim-str-to-list (plist-get info :hugo-tags))
;; Else use Org tags (the ones set in headlines
;; and/or inherited) if any.
(let* ((tags-list (cl-remove-if #'org-hugo--category-p all-t-and-c))
Expand All @@ -2296,8 +2300,7 @@ INFO is a plist used as a communication channel."
;; Look for categories set using
;; #+HUGO_CATEGORIES keyword, or
;; EXPORT_HUGO_CATEGORIES property if available.
(org-hugo--delim-str-to-list
(plist-get info :hugo-categories) info :no-prefer-hyphen)
(org-hugo--delim-str-to-list (plist-get info :hugo-categories))
;; Else use categories set using Org tags with
;; "@" prefix (the ones set in headlines and/or
;; inherited) if any.
Expand All @@ -2309,8 +2312,7 @@ INFO is a plist used as a communication channel."
categories-list)))
;; (message "dbg: categories: categories-list = %s" categories-list)
categories-list)))
(keywords (org-hugo--delim-str-to-list
(plist-get info :keywords) info :no-prefer-hyphen))
(keywords (org-hugo--delim-str-to-list (plist-get info :keywords)))
(weight (let* ((wt (plist-get info :hugo-weight))
(auto-calc (and (stringp wt)
(string= wt "auto")
Expand Down
2 changes: 1 addition & 1 deletion test/site/content-org/all-posts.org
Original file line number Diff line number Diff line change
Expand Up @@ -3735,7 +3735,7 @@ comma-separated.
*** Multiple keywords in front-matter
:PROPERTIES:
:EXPORT_FILE_NAME: multiple-keywords-in-front-matter
:EXPORT_KEYWORDS: abc def hyphenated-keyword underscored_keyword two__words these__are__four__words
:EXPORT_KEYWORDS: abc def hyphenated-keyword underscored_keyword "two words" "these are four words"
:END:
*** Keywords set using multiple properties
:PROPERTIES:
Expand Down
4 changes: 2 additions & 2 deletions test/site/content-org/keyword-collection.org
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# https://ox-hugo.scripter.co/doc/tags-and-categories/#file-based-export

# Tags
#+HUGO_TAGS: mega__front-matter
#+HUGO_TAGS: "mega front-matter"
#+HUGO_TAGS: keys
#+HUGO_TAGS: collection concatenation merging

Expand Down Expand Up @@ -54,7 +54,7 @@

# Keywords
#+KEYWORDS: keyword1 keyword2
#+KEYWORDS: three__word__keywords3
#+KEYWORDS: "three word keywords3"

# Outputs
#+HUGO_OUTPUTS: html
Expand Down
3 changes: 2 additions & 1 deletion test/site/content-org/tags-and-categories.org
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#+FILETAGS: alpha beta
#+FILETAGS: hyphened-tag
#+FILETAGS: tag__with__lot__of__words

# Categories
#+FILETAGS: @cat1
Expand Down Expand Up @@ -37,7 +38,7 @@ added as Org tags to headlines as well as =#+FILETAGS=.
:PROPERTIES:
:EXPORT_HUGO_TAGS: overriding
:EXPORT_HUGO_TAGS+: underscore_is_retained hyphenated-works
:EXPORT_HUGO_CATEGORIES: cat3 3__word__cat
:EXPORT_HUGO_CATEGORIES: cat3 "3 word cat"
:EXPORT_FILE_NAME: overriding-tags
:END:
By using =EXPORT_HUGO_TAGS= in the property drawer, Org tags in the
Expand Down
2 changes: 1 addition & 1 deletion test/site/content/posts/inheriting-tags.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
+++
title = "Inheriting tags"
tags = ["hyphened-tag", "alpha", "beta", "super", "gamma", "delta", "two words"]
tags = ["tag with lot of words", "hyphened-tag", "alpha", "beta", "super", "gamma", "delta", "two words"]
categories = ["cat1", "cat2"]
draft = false
+++
Expand Down

0 comments on commit 319435d

Please sign in to comment.