Custom spans in Org mode
Org mode's HTML export lets you use #+BEGIN_...
and #+END_...
blocks for custom <div>
classes, but what about custom <span>
classes? There are some ways to do it, but they all move the text out
of the normal document flow, which makes reading the source difficult.
Instead, you can use org-add-link-type, usually a way to register
custom link schemes. Org links are inline and quite readable, and
there is a notion of a link that isn't clickable, so it's not too
much semantic abuse.
(defun jw/html-escape-attribute (value)
"Entity-escape VALUE and wrap it in quotes."
;; http://www.w3.org/TR/2009/WD-html5-20090212/serializing-html-fragments.html
;;
;; "Escaping a string... consists of replacing any occurrences of
;; the "&" character by the string "&", any occurrences of the
;; U+00A0 NO-BREAK SPACE character by the string " ", and, if
;; the algorithm was invoked in the attribute mode, any occurrences
;; of the """ character by the string """..."
(let* ((value (replace-regexp-in-string "&" "&" value))
(value (replace-regexp-in-string "\u00a0" " " value))
(value (replace-regexp-in-string "\"" """ value)))
value))
(eval-after-load "org"
'(org-add-link-type
"span" #'ignore ; not an 'openable' link
#'(lambda (class desc format)
(pcase format
(`html (format "<span class=\"%s\">%s</span>"
(jw/html-escape-attribute class)
(or desc "")))
(_ (or desc ""))))))
Now you can type links such as:
Check out this [[span:special][text block]].
Which generates HTML output like:
<p>Check out this <span class="special">text block</span>.</p>