Re: ox-html Incorrectly (?) Puts HTML Into the `` Tag</span></a></span> </h1> <p class="darkgray font13"> <span class="sender pipe"><a href="/search?l=emacs-orgmode@gnu.org&q=from:%22Jacob+S.+Gordon%22" rel="nofollow"><span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Jacob S. Gordon</span></span></a></span> <span class="date"><a href="/search?l=emacs-orgmode@gnu.org&q=date:20251226" rel="nofollow">Fri, 26 Dec 2025 19:02:54 -0800</a></span> </p> </div> <div itemprop="articleBody" class="msgBody"> <!--X-Body-of-Message--> <pre>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:</pre><pre> 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. <a rel="nofollow" href="https://useplaintext.email/#etiquette">https://useplaintext.email/#etiquette</a></pre><pre>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: <a rel="nofollow" href="https://list.orgmode.org/87bla649i3....@nicolasgoaziou.fr/">https://list.orgmode.org/87bla649i3....@nicolasgoaziou.fr/</a> 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 "&lrm;")) 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. <a rel="nofollow" href="https://useplaintext.email/#etiquette">https://useplaintext.email/#etiquette</a> </pre> </div> <div class="msgButtons margintopdouble"> <ul class="overflow"> <li class="msgButtonItems"><a class="button buttonleft " accesskey="p" href="msg168036.html">Previous message</a></li> <li class="msgButtonItems textaligncenter"><a class="button" accesskey="c" href="thrd10.html#168054">View by thread</a></li> <li class="msgButtonItems textaligncenter"><a class="button" accesskey="i" href="maillist.html#168054">View by date</a></li> <li class="msgButtonItems textalignright"><a class="button buttonright " accesskey="n" href="msg165709.html">Next message</a></li> </ul> </div> <a name="tslice"></a> <div class="tSliceList margintopdouble"> <ul class="icons monospace"> <li class="icons-email"><span class="subject"><a href="msg165708.html">Re: ox-html Incorrectly (?) Puts HTML Into the `<title&...</a></span> <span class="sender italic">Jacob S. Gordon</span></li> <li><ul> <li class="icons-email"><span class="subject"><a href="msg165737.html">Re: ox-html Incorrectly (?) Puts HTML Into the `<t...</a></span> <span class="sender italic">Ihor Radchenko</span></li> <li><ul> <li class="icons-email"><span class="subject"><a href="msg168011.html">Re: ox-html Incorrectly (?) Puts HTML Into the `&...</a></span> <span class="sender italic">Ihor Radchenko</span></li> <li><ul> <li class="icons-email"><span class="subject"><a href="msg168036.html">Re: ox-html Incorrectly (?) Puts HTML Into th...</a></span> <span class="sender italic">Jacob S. Gordon</span></li> </ul></li> <li class="icons-email tSliceCur"><span class="subject">Re: ox-html Incorrectly (?) Puts HTML Into the `&...</span> <span class="sender italic">Jacob S. Gordon</span></li> </ul> </ul> </ul> </div> <div class="overflow msgActions margintopdouble"> <div class="msgReply" > <h2> Reply via email to </h2> <form method="POST" action="/mailto.php"> <input type="hidden" name="subject" value="Re: ox-html Incorrectly (?) Puts HTML Into the `<title>` Tag"> <input type="hidden" name="msgid" value="bbdb4b9e-0f6a-4e97-8f89-ae9e77701e56@gmail.com"> <input type="hidden" name="relpath" value="emacs-orgmode@gnu.org/msg168054.html"> <input type="submit" value=" Jacob S. Gordon "> </form> </div> </div> </div> <div class="aside" role="complementary"> <div class="logo"> <a href="/"><img src="/logo.png" width=247 height=88 alt="The Mail Archive"></a> </div> <form class="overflow" action="/search" method="get"> <input type="hidden" name="l" value="emacs-orgmode@gnu.org"> <label class="hidden" for="q">Search the site</label> <input class="submittext" type="text" id="q" name="q" placeholder="Search emacs-orgmode"> <input class="submitbutton" name="submit" type="image" src="/submit.png" alt="Submit"> </form> <div class="nav margintop" id="nav" role="navigation"> <ul class="icons font16"> <li class="icons-home"><a href="/">The Mail Archive home</a></li> <li class="icons-list"><a href="/emacs-orgmode@gnu.org/">emacs-orgmode - all messages</a></li> <li class="icons-about"><a href="/emacs-orgmode@gnu.org/info.html">emacs-orgmode - about the list</a></li> <li class="icons-expand"><a href="/search?l=emacs-orgmode@gnu.org&q=subject:%22Re%5C%3A+ox%5C-html+Incorrectly+%5C%28%5C%3F%5C%29+Puts+HTML+Into+the+%60%3Ctitle%3E%60+Tag%22&o=newest&f=1" title="e" id="e">Expand</a></li> <li class="icons-prev"><a href="msg168036.html" title="p">Previous message</a></li> <li class="icons-next"><a href="msg165709.html" title="n">Next message</a></li> </ul> </div> <div class="listlogo margintopdouble"> </div> <div class="margintopdouble"> </div> </div> </div> <div class="footer" role="contentinfo"> <ul> <li><a href="/">The Mail Archive home</a></li> <li><a href="/faq.html#newlist">Add your mailing list</a></li> <li><a href="/faq.html">FAQ</a></li> <li><a href="/faq.html#support">Support</a></li> <li><a href="/faq.html#privacy">Privacy</a></li> <li class="darkgray">bbdb4b9e-0f6a-4e97-8f89-ae9e77701e56@gmail.com</li> </ul> </div> </body> </html> <script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'9b59b5f1bc471b67',t:'MTc2NzAxNTY0MQ=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>