Please find v1 of a patch attached. All emphasis markers are stripped
except for strike-through, as that could change the meaning or create
ambiguous text. Everything else is not transcoded, including:
1. inline source blocks
2. radio targets & links
3. math
4. sub/superscripts
I think 1 and 2 would be reasonable to support, i.e. replacing links
with a description, falling back to the URI. The others I don’t think
can be handled in an unopinionated, backend-independent way.
What do people think?
Thanks,
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette
From 1575aede70d4586eb652976c7f7b587482b52191 Mon Sep 17 00:00:00 2001
From: "Jacob S. Gordon" <jacob.as.gor...@gmail.com>
Date: Fri, 26 Dec 2025 20:04:29 -0500
Subject: [PATCH v1] ox-html: Add option to strip markup from HTML title
metadata
Emphasis such as *bold* in the document title will make it into the
title tag when exported to HTML. Add an option
'org-html-strip-title-metadata-markup', which when non-nil forces most
emphasis markers to be removed from this tag.
* lisp/ox.el (org-export-strip-markup-backend,
org-export-strip-markup): Add backend and function to transcode
emphasis markup to plain text.
* lisp/ox-html.el (org-html-strip-title-metadata-markup,
org-export-define-backend): Add option to strip markup from the title
metadata tag.
(org-html--build-meta-info): Strip markup from the tag when the option
is set.
* testing/lisp/test-ox-html.el (ox-html/test-strip-title-tag-markup):
Add test.
Link: https://list.orgmode.org/87bla649i3....@nicolasgoaziou.fr/
Co-authored-by: Nicolas Goaziou <m...@nicolasgoaziou.fr>
---
lisp/ox-html.el | 17 +++++++++++++++--
lisp/ox.el | 26 ++++++++++++++++++++++++++
testing/lisp/test-ox-html.el | 19 +++++++++++++++++++
3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index fa0c021af..fab9d94df 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -157,6 +157,8 @@ (org-export-define-backend 'html
(:html-preamble-format nil nil org-html-preamble-format)
(:html-prefer-user-labels nil nil org-html-prefer-user-labels)
(:html-self-link-headlines nil "html-self-link-headlines" org-html-self-link-headlines)
+ (:html-strip-title-metadata-markup
+ nil nil org-html-strip-title-metadata-markup)
(:html-table-align-individual-fields
nil nil org-html-table-align-individual-fields)
(:html-table-caption-above nil nil org-html-table-caption-above)
@@ -743,6 +745,14 @@ (defcustom org-html-self-link-headlines nil
:type 'boolean
:safe #'booleanp)
+(defcustom org-html-strip-title-metadata-markup nil
+ "When non-nil, remove markup from the title metadata using
+`org-export-strip-emphasis-backend'."
+ :group 'org-export-html
+ :package-version '(Org . "9.8")
+ :type 'boolean
+ :safe #'booleanp)
+
(defcustom org-html-prefer-user-labels nil
"When non-nil use user-defined names and ID over internal ones.
@@ -1994,8 +2004,11 @@ (defun org-html--build-meta-entry
(defun org-html--build-meta-info (info)
"Return meta tags for exported document.
INFO is a plist used as a communication channel."
- (let* ((title (org-html-plain-text
- (org-element-interpret-data (plist-get info :title)) info))
+ (let* ((title
+ (if (plist-get info :html-strip-title-metadata-markup)
+ (org-export-strip-markup (plist-get info :title) info)
+ (org-html-plain-text
+ (org-element-interpret-data (plist-get info :title)) info)))
;; Set title to an invisible character instead of leaving it
;; empty, which is invalid.
(title (if (org-string-nw-p title) title "‎"))
diff --git a/lisp/ox.el b/lisp/ox.el
index fe5157aed..a7a7fbc9a 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -6696,6 +6696,32 @@ (defun org-export-translate (s encoding info)
(plist-get translations :default)
s)))
+;;;; For Stripping Markup
+;;
+;; `org-export-strip-markup' transcodes some Org elements to plain
+;; text without markup.
+
+(defconst org-export-strip-markup-backend
+ (org-export-create-backend :transcoders
+ '((bold . (lambda (_ c _) c))
+ (italic . (lambda (_ c _) c))
+ (underline . (lambda (_ c _) c))
+ (strike-through . (lambda (_ c _)
+ (format "+%s+" c)))
+ (code . (lambda (c _ _)
+ (org-element-property :value c)))
+ (verbatim . (lambda (v _ _)
+ (org-element-property :value v)))))
+ "Export backend that strips Org emphasis markup from text.
+All markers are removed except for strike-through, as that could change
+the meaning or create ambiguous text. Other objects are not transcoded.")
+
+(defun org-export-strip-markup (data info)
+ "Export DATA to text without emphasis markup using
+`org-export-strip-markup-backend'."
+ (org-export-data-with-backend data
+ org-export-strip-markup-backend
+ info))
;;; Asynchronous Export
diff --git a/testing/lisp/test-ox-html.el b/testing/lisp/test-ox-html.el
index 5a8e7df3c..4ad9c09d5 100644
--- a/testing/lisp/test-ox-html.el
+++ b/testing/lisp/test-ox-html.el
@@ -1106,5 +1106,24 @@ (ert-deftest org-html/test-toc-text ()
(expected "\n<ul>\n<li>\n<ul>\n<li>1\n<ul>\n<li>1.1</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>2</li>\n</ul>\n"))
(should (string= (org-html--toc-text toc-entries nil) expected))))
+;;; Stripping markup from the <title> tag
+
+(ert-deftest ox-html/test-strip-title-tag-markup ()
+ "When `org-html-strip-title-metadata-markup' is non-nil, ensure the
+`<title'> tag is striped of emphasis markers."
+ (dolist (case '(("*b* /i/ ~c~ =v= _u_ +s+" . "b i c v u +s+")
+ ("*/bi/* +~sc~+ _+us+_" . "bi +sc+ +us+")))
+ (let ((export-buffer "*Test HTML Export*")
+ (org-export-show-temporary-export-buffer nil)
+ (org-html-strip-title-metadata-markup t)
+ (title (car case))
+ (expected (cdr case)))
+ (org-test-with-temp-text (format "#+TITLE: %s" title)
+ (org-export-to-buffer 'html export-buffer nil nil nil nil nil)
+ (with-current-buffer export-buffer
+ (should (= 1 (how-many
+ (format "<title>%s</title>"
+ (regexp-quote expected))))))))))
+
(provide 'test-ox-html)
;;; test-ox-html.el ends here
base-commit: ded231f7010ef1f1f4fc6e4815558a28e1689488
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette