emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Rudolf Adamkovič" <salutis@me.com>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: Ihor Radchenko <yantar92@gmail.com>, emacs-orgmode@gnu.org
Subject: Re: [PATCH] Re: Update Org to MathJax 3
Date: Sun, 13 Nov 2022 21:52:10 +0100	[thread overview]
Message-ID: <m2r0y6inlx.fsf@me.com> (raw)
In-Reply-To: <87leof8os1.fsf@localhost>

[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]

Ihor Radchenko <yantar92@posteo.net> writes:

> I note that you did not mention in the news that MathJax 2 support is
> dropped. This is a very important thing we must highlight and ring all
> the bells about.

Fixed.  See the 8th revision of the patch attached below.  Better?

> Consider that someone has customized path option to a local copy of
> MathJax version 2. Then, things will get broken after the update!

Correct, and we spell it out in the manual, in the "... and breaking
changes" section.

Digression [no comment needed; just venting]: This confirms, again, that
we should focus on LaTeX, the strength of Org, instead of defaulting to
the unstable world of JavaScript, copying popular Markdown editors that
have to use MathJax do due to their lack of integration with LaTeX.

> However, it could be at least a good idea to warn the users who are
> trying to use MathJax 2.  Would it be possible?

As far as I know, we have no reliable way of knowing the version of
MathJax without actually reading the JavaScript file, locally and
remotely.

Rudy

[-- Attachment #2: 0001-ox-html-Update-from-MathJax-2-to-MathJax-3.patch --]
[-- Type: text/x-patch, Size: 53176 bytes --]

From b886755450e052c3584e793fe0960914b0733001 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rudolf=20Adamkovi=C4=8D?= <salutis@me.com>
Date: Fri, 7 Oct 2022 15:03:48 +0200
Subject: [PATCH] ox-html: Update from MathJax 2 to MathJax 3+

* lisp/ox-html.el (
org-html-mathjax-options,
org-html-mathjax-template,
org-html--build-mathjax-config
): Update from MathJax 2 to 3 while maintaining compatibility.  All
legacy options should continue to work, except for the 'path' option
which must now point to MathJax 3 or later.
* testing/lisp/test-ox-html.el (
ox-html/mathjax-path-none,
ox-html/mathjax-path-default,
ox-html/mathjax-path-custom,
ox-html/mathjax-path-in-buffer,
ox-html/mathjax-options-default,
ox-html/mathjax-options-custom,
ox-html/mathjax-options-in-buffer,
ox-html/mathjax-legacy-scale-default,
ox-html/mathjax-legacy-scale-custom,
ox-html/mathjax-legacy-scale-in-buffer,
ox-html/mathjax-legacy-scale-message,
ox-html/mathjax-legacy-scale-message-in-buffer,
ox-html/mathjax-legacy-scale-ignore,
ox-html/mathjax-legacy-autonumber-ams,
ox-html/mathjax-legacy-autonumber-ams-in-buffer,
ox-html/mathjax-legacy-autonumber-none,
ox-html/mathjax-legacy-autonumber-none-in-buffer,
ox-html/mathjax-legacy-autonumber-all,
ox-html/mathjax-legacy-autonumber-all-in-buffer,
ox-html/mathjax-legacy-autonumber-message,
ox-html/mathjax-legacy-autonumber-message-in-buffer,
ox-html/mathjax-legacy-font-tex,
ox-html/mathjax-legacy-font-tex-in-buffer,
ox-html/mathjax-legacy-font-stix-web,
ox-html/mathjax-legacy-font-stix-web-in-buffer,
ox-html/mathjax-legacy-font-asana-math,
ox-html/mathjax-legacy-font-asana-math-in-buffer,
ox-html/mathjax-legacy-font-neo-euler,
ox-html/mathjax-legacy-font-neo-euler-in-buffer,
ox-html/mathjax-legacy-font-gyre-pagella,
ox-html/mathjax-legacy-font-gyre-pagella-in-buffer,
ox-html/mathjax-legacy-font-gyre-termes,
ox-html/mathjax-legacy-font-gyre-termes-in-buffer,
ox-html/mathjax-legacy-font-latin-modern,
ox-html/mathjax-legacy-font-latin-modern-in-buffer,
ox-html/mathjax-legacy-line-breaks-true,
ox-html/mathjax-legacy-line-breaks-true-in-buffer,
ox-html/mathjax-legacy-line-breaks-false,
ox-html/mathjax-legacy-line-breaks-false-in-buffer,
ox-html/mathjax-legacy-line-breaks-message,
ox-html/mathjax-legacy-line-breaks-message-in-buffer): Test MathJax in
general and also the conversion of legacy options from MathJax 2 to 3.
* testing/org-test.el (org-test-capture-messages): Add a new macro
useful for testing the messages put in the echo area.
* etc/ORG-NEWS: Document MathJax 2 to 3 upgrade, highlighting the
benefits of the new version but also mentioning the fact that the user
may need to update the `path' option in `org-html-mathjax-options'.
* doc/org-manual.org (Math formatting in HTML export): Update the link
to the MathJax CDN and the example of how to use `+HTML_MATHJAX' with
MathJax 3.  Also, remove the note on MathJax extensions, as they did
not work (and do not work) as documented.

Link: https://list.orgmode.org/orgmode/m2a667n4ax.fsf@me.com/
---
 doc/org-manual.org           |  20 +-
 etc/ORG-NEWS                 |  38 ++
 lisp/ox-html.el              | 257 ++++++++---
 testing/lisp/test-ox-html.el | 818 +++++++++++++++++++++++++++++++++++
 testing/org-test.el          |  11 +
 5 files changed, 1063 insertions(+), 81 deletions(-)
 create mode 100644 testing/lisp/test-ox-html.el

diff --git a/doc/org-manual.org b/doc/org-manual.org
index dc2fc57cd..3514f84e4 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13228,24 +13228,20 @@ as-is.
 LaTeX math snippets (see [[*LaTeX fragments]]) can be displayed in two
 different ways on HTML pages.  The default is to use the
 [[https://www.mathjax.org][MathJax]], which should work out of the box
-with Org[fn:: By default Org loads MathJax from
-[[https://cdnjs.com][cdnjs.com]] as recommended by
-[[https://www.mathjax.org][MathJax]].][fn:46].  Some MathJax display
-options can be configured via ~org-html-mathjax-options~, or in the
-buffer.  For example, with the following settings,
+with Org[fn:: By default, Org loads MathJax from
+[[https://www.jsdelivr.com/][jsDelivr]], as recommended in
+[[https://docs.mathjax.org/en/latest/web/start.html][Getting Started
+with MathJax Components]].][fn:46].  Some MathJax display options can
+be configured via ~org-html-mathjax-options~, or in the buffer.  For
+example, with the following settings,
 
 #+begin_example
-,#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler
-,#+HTML_MATHJAX: cancel.js noErrors.js
+,#+HTML_MATHJAX: align: left indent: 5em tagside: left
 #+end_example
 
 #+texinfo: @noindent
 equation labels are displayed on the left margin and equations are
-five em from the left margin.  In addition, it loads the two MathJax
-extensions =cancel.js= and =noErrors.js=[fn:: See
-[[https://docs.mathjax.org/en/latest/input/tex/extensions.html#tex-and-latex-extensions][TeX
-and LaTeX extensions]] in the [[https://docs.mathjax.org][MathJax
-manual]] to learn about extensions.].
+five em from the left margin.
 
 #+vindex: org-html-mathjax-template
 See the docstring of ~org-html-mathjax-options~ for all supported
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index b542da34b..404a907c6 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -139,6 +139,44 @@ rely on the details of visibility state implementation in
 backend.  From now on, using =outline-*= functions is strongly
 discouraged when working with Org files.
 
+*** HTML export uses MathJax 3+ instead of MathJax 2
+
+Org now uses MathJax 3 by default instead of MathJax 2.  During HTML
+exports, Org automatically converts all legacy MathJax 2 options to
+the corresponding MathJax 3+ options, except for the ~path~ option in
+which now /must/ point to a file containing MathJax version 3 or
+later.  The new Org does /not/ work with the legacy MathJax 2.
+
+Further, if you need to use a non-default ~font~ or ~linebreaks~ (now
+~overflow~), then the ~path~ must point to MathJax 4 or later.
+
+See the updated ~org-html-mathjax-options~ for more details.
+
+MathJax 3, a ground-up rewrite of MathJax 2 came out in 2019.  The new
+version brings modularity, better and faster rendering, improved LaTeX
+support, and more.
+
+For more information about new features, see:
+
+https://docs.mathjax.org/en/latest/upgrading/whats-new-3.0.html
+https://docs.mathjax.org/en/latest/upgrading/whats-new-3.1.html
+https://docs.mathjax.org/en/latest/upgrading/whats-new-3.2.html
+
+MathJax 3 comes with useful extensions.  For instance, you can typeset
+calculus with the ~physics~ extension or chemistry with the ~mhchem~
+extension, like in LaTeX.
+
+Note that the Org manual does not discuss loading of MathJax
+extensions via ~+HTML_MATHJAX~ anymore.  It has never worked anyway.
+To actually load extensions, consult the official documentation:
+
+https://docs.mathjax.org/en/latest/input/tex/extensions.html
+
+Lastly, MathJax 3 changed the default JavaScript content delivery
+network (CDN) provider from CloudFlare to jsDelivr.  You can find the
+new terms of service, including the privacy policy, at
+https://www.jsdelivr.com/terms.
+
 ** New features
 *** Clock table can now produce quarterly reports
 
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index cad06aebf..443ae4ebe 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -1166,72 +1166,116 @@ See `format-time-string' for more information on its components."
 ;;;; Template :: Mathjax
 
 (defcustom org-html-mathjax-options
-  '((path "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML" )
-    (scale "100")
+  '((path "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js")
+    (scale 1.0)
     (align "center")
-    (font "TeX")
-    (linebreaks "false")
-    (autonumber "AMS")
+    (font "mathjax-modern")
+    (overflow "overflow")
+    (tags "ams")
     (indent "0em")
     (multlinewidth "85%")
     (tagindent ".8em")
     (tagside "right"))
   "Options for MathJax setup.
 
-Alist of the following elements.  All values are strings.
+Alist of the following elements.
 
-path          The path to MathJax.
+path          The path to MathJax version 3 or later.
 scale         Scaling with HTML-CSS, MathML and SVG output engines.
 align         How to align display math: left, center, or right.
-font          The font to use with HTML-CSS and SVG output.  As of MathJax 2.5
-              the following values are understood: \"TeX\", \"STIX-Web\",
-              \"Asana-Math\", \"Neo-Euler\", \"Gyre-Pagella\",
-              \"Gyre-Termes\", and \"Latin-Modern\".
+font          The font to use with HTML-CSS and SVG output.  Needs
+              MathJax version 4+.  MathJax 4 provides 11 fonts:
+              \"mathjax-modern\"   Latin-Modern font, default in MathJax 4+
+              \"mathjax-asana\"    Asana-Math font
+              \"mathjax-bonum\"    Gyre Bonum font
+              \"mathjax-dejavu\"   Gyre DejaVu font
+              \"mathjax-pagella\"  Gyre Pagella font
+              \"mathjax-schola\"   Gyre Schola font
+              \"mathjax-termes\"   Gyre Termes font
+              \"mathjax-stix2\"    STIX2 font
+              \"mathjax-fira\"     Fira and Fira-Math fonts
+              \"mathjax-euler\"    Neo Euler font that extends Latin-Modern
+              \"mathjax-tex\"      The original MathJax TeX font
+overflow      How to break displayed equations when too large. Needs
+              MathJax 4 or newer.  Supported options include
+              \"overflow\", \"scale\", \"scroll\", \"truncate\",
+              \"linebreak\", and \"elide\".
 linebreaks    Let MathJax perform automatic linebreaks.  Valid values
               are \"true\" and \"false\".
 indent        If align is not center, how far from the left/right side?  For
               example, \"1em\".
 multlinewidth The width of the multline environment.
-autonumber    How to number equations.  Valid values are \"none\",
-              \"all\" and \"AMS\".
+tags          How to number equations.  Valid values are \"none\",
+              \"all\" and \"ams\".
 tagindent     The amount tags are indented.
 tagside       Which side to show tags/labels on.  Valid values are
               \"left\" and \"right\"
 
-You can also customize this for each buffer, using something like
+You can also customize this for some buffer, using something like
 
-#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler
+#+HTML_MATHJAX: align: left indent: 5em tagside: left
 
 For further information about MathJax options, see the MathJax documentation:
 
-  https://docs.mathjax.org/"
+  https://docs.mathjax.org/
+
+To maintain compatibility with pre-9.6 Org that used MathJax 2,
+the following conversions take place.
+
+The legacy \"autonumber\" option, with the value \"AMS\",
+\"None\", or \"All\", becomes the \"tags\" option set to the
+value \"ams\", \"none\", or \"all\", respectively.
+
+Any legacy values of the \"scale\" option, specified as
+percentage strings, become converted to unit-interval numbers.
+For example, a legacy scale of \"150\" becomes a scale of 1.5.
+
+The legacy \"linebreaks\" option, with the value \"true\" or
+\"false\", becomes the \"overflow\" option set to the value
+\"linebreak\" or \"overflow\", respectively.
+
+The legacy values of the \"font\" option, namely \"TeX\",
+\"STIX-Web\", \"Asana-Math\", \"Neo-Euler\", \"Gyre-Pagella\",
+\"Gyre-Termes\", \"Latin-Modern\", become converted to the
+corresponding MathJax 4+ font names.
+
+Legacy options and values always take precedence.
+"
   :group 'org-export-html
-  :package-version '(Org . "8.3")
+  :package-version '(Org . "9.6")
   :type '(list :greedy t
 	       (list :tag "path   (the path from where to load MathJax.js)"
 		     (const :format "       " path) (string))
 	       (list :tag "scale  (scaling for the displayed math)"
-		     (const :format "       " scale) (string))
+		     (const :format "   " scale) (float))
 	       (list :tag "align  (alignment of displayed equations)"
 		     (const :format "       " align) (string))
-	       (list :tag "font (used to display math)"
-		     (const :format "            " font)
-		     (choice (const "TeX")
-			     (const "STIX-Web")
-			     (const "Asana-Math")
-			     (const "Neo-Euler")
-			     (const "Gyre-Pagella")
-			     (const "Gyre-Termes")
-			     (const "Latin-Modern")))
-	       (list :tag "linebreaks (automatic line-breaking)"
-		     (const :format "      " linebreaks)
-		     (choice (const "true")
-			     (const "false")))
-	       (list :tag "autonumber (when should equations be numbered)"
-		     (const :format "      " autonumber)
-		     (choice (const "AMS")
-			     (const "None")
-			     (const "All")))
+               (list :tag "font (used to typeset math)"
+		     (const :format "               " font)
+                     (choice (const "mathjax-modern")
+                             (const "mathjax-asana")
+                             (const "mathjax-bonum")
+                             (const "mathjax-dejavu")
+                             (const "mathjax-pagella")
+                             (const "mathjax-schola")
+                             (const "mathjax-termes")
+                             (const "mathjax-stix2")
+                             (const "mathjax-fira")
+                             (const "mathjax-euler")
+                             (const "mathjax-tex")))
+               (list :tag "overflow (how to break displayed math)"
+		     (const :format "         " overflow)
+                     (choice (const "overflow")
+                             (const "scale")
+                             (const "scroll")
+                             (const "truncate")
+                             (const "linebreak")
+                             (const "elide")))
+	       (list :tag "tags (whether equations are numbered and how)"
+		     (const :format "    " tags)
+		     (choice (const "ams")
+			     (const "none")
+			     (const "all")))
 	       (list :tag "indent (indentation with left or right alignment)"
 		     (const :format "       " indent) (string))
 	       (list :tag "multlinewidth (width to use for the multline environment)"
@@ -1244,27 +1288,38 @@ For further information about MathJax options, see the MathJax documentation:
 			     (const "right")))))
 
 (defcustom org-html-mathjax-template
-  "<script type=\"text/x-mathjax-config\">
-    MathJax.Hub.Config({
-        displayAlign: \"%ALIGN\",
-        displayIndent: \"%INDENT\",
-
-        \"HTML-CSS\": { scale: %SCALE,
-                        linebreaks: { automatic: \"%LINEBREAKS\" },
-                        webFont: \"%FONT\"
-                       },
-        SVG: {scale: %SCALE,
-              linebreaks: { automatic: \"%LINEBREAKS\" },
-              font: \"%FONT\"},
-        NativeMML: {scale: %SCALE},
-        TeX: { equationNumbers: {autoNumber: \"%AUTONUMBER\"},
-               MultLineWidth: \"%MULTLINEWIDTH\",
-               TagSide: \"%TAGSIDE\",
-               TagIndent: \"%TAGINDENT\"
-             }
-});
+  "<script>
+  window.MathJax = {
+    tex: {
+      ams: {
+        multlineWidth: '%MULTLINEWIDTH'
+      },
+      tags: '%TAGS',
+      tagSide: '%TAGSIDE',
+      tagIndent: '%TAGINDENT'
+    },
+    chtml: {
+      scale: %SCALE,
+      displayAlign: '%ALIGN',
+      displayIndent: '%INDENT'
+    },
+    svg: {
+      scale: %SCALE,
+      displayAlign: '%ALIGN',
+      displayIndent: '%INDENT'
+    },
+    output: {
+      font: '%FONT',
+      displayOverflow: '%OVERFLOW'
+    }
+  };
 </script>
-<script src=\"%PATH\"></script>"
+
+<script
+  id=\"MathJax-script\"
+  async
+  src=\"%PATH\">
+</script>"
   "The MathJax template.  See also `org-html-mathjax-options'."
   :group 'org-export-html
   :type 'string)
@@ -1945,21 +2000,85 @@ INFO is a plist used as a communication channel."
   "Insert the user setup into the mathjax template.
 INFO is a plist used as a communication channel."
   (when (and (memq (plist-get info :with-latex) '(mathjax t))
-	     (org-element-map (plist-get info :parse-tree)
-		 '(latex-fragment latex-environment) #'identity info t nil t))
+             (org-element-map (plist-get info :parse-tree)
+                 '(latex-fragment latex-environment) #'identity info t nil t))
     (let ((template (plist-get info :html-mathjax-template))
-	  (options (plist-get info :html-mathjax-options))
-	  (in-buffer (or (plist-get info :html-mathjax) "")))
+          (options (let ((options (plist-get info :html-mathjax-options)))
+                     ;; If the user customized some legacy option, set
+                     ;; the corresponding new option to nil, so that
+                     ;; the legacy user choice overrides the default.
+                     ;; Otherwise, the user did not set the legacy
+                     ;; option, in which case still set the legacy
+                     ;; option but to no value, so that the code can
+                     ;; find its in-buffer value, if set.
+                     `((,(if (plist-member options 'autonumber)
+                             'tags 'autonumber)
+                        nil)
+                       (,(if (plist-member options 'linebreaks)
+                             'overflow 'linebreaks)
+                        nil)
+                       ,@options)))
+          (in-buffer (or (plist-get info :html-mathjax) "")))
       (dolist (e options (org-element-normalize-string template))
-	(let ((name (car e))
-	      (val (nth 1 e)))
-	  (when (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
-	    (setq val
-		  (car (read-from-string (substring in-buffer (match-end 0))))))
-	  (unless (stringp val) (setq val (format "%s" val)))
-	  (while (string-match (concat "%" (upcase (symbol-name name)))
-			       template)
-	    (setq template (replace-match val t t template))))))))
+        (let ((symbol (car e))
+              (value (nth 1 e)))
+          (when (string-match (concat "\\<" (symbol-name symbol) ":")
+                              in-buffer)
+            (setq value
+                  (car (split-string (substring in-buffer
+                                                (match-end 0))))))
+          (when value
+            (pcase symbol
+              (`font
+               (when-let
+                   ((value-new
+                     (pcase value
+                       ("TeX" "mathjax-tex")
+                       ("STIX-Web" "mathjax-stix2")
+                       ("Asana-Math" "mathjax-asana")
+                       ("Neo-Euler" "mathjax-euler")
+                       ("Gyre-Pagella" "mathjax-pagella")
+                       ("Gyre-Termes" "mathjax-termes")
+                       ("Latin-Modern" "mathjax-modern"))))
+                 (setq value value-new)))
+              (`linebreaks
+               (org-display-warning
+                "Converting legacy MathJax option: linebreaks")
+               (setq symbol 'overflow
+                     value (if (string= value "true")
+                               "linebreak"
+                             "overflow")))
+              (`scale
+               (when (stringp value)
+                 (let ((value-maybe (string-to-number value)))
+                   (setq value
+                         (if (= value-maybe 0)
+                             (progn
+                               (org-display-warning
+                                (format "Non-numerical MathJax scale: %s"
+                                        value))
+                               1.0)
+                           value-maybe))))
+               (when (>= value 10)
+                 (setq value
+                       (let ((value-new (/ (float value) 100)))
+                         (org-display-warning
+                          (format "Converting legacy MathJax scale: %s to %s"
+                                  value
+                                  value-new))
+                         value-new))))
+              (`autonumber
+               (org-display-warning
+                "Converting legacy MathJax option: autonumber")
+               (setq symbol 'tags
+                     value (downcase value))))
+            (while (string-match (format "\\(%%%s\\)[^A-Z]"
+                                         (upcase (symbol-name symbol)))
+                                 template)
+              (setq template
+                    (replace-match (format "%s" value)
+                                   t
+                                   t template 1)))))))))
 
 (defun org-html-format-spec (info)
   "Return format specification for preamble and postamble.
diff --git a/testing/lisp/test-ox-html.el b/testing/lisp/test-ox-html.el
new file mode 100644
index 000000000..e1b492733
--- /dev/null
+++ b/testing/lisp/test-ox-html.el
@@ -0,0 +1,818 @@
+;;; test-ox-html.el --- Tests for ox-html.el
+
+;; Copyright (C) 2022  Rudolf Adamkovič
+
+;; Author: Rudolf Adamkovič <salutis@me.com>
+
+;; This file is part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ox-html)
+
+\f
+;;; Loading MathJax
+
+(ert-deftest ox-html/mathjax-path-none ()
+  "Test that MathJax does not load when not needed."
+  (should-not
+   (org-test-with-temp-text "No LaTeX here."
+     (let ((export-buffer "*Test HTML Export*")
+           (org-export-show-temporary-export-buffer nil))
+       (org-export-to-buffer 'html export-buffer
+         nil nil nil nil nil
+         #'html-mode)
+       (with-current-buffer export-buffer
+         (let ((case-fold-search t))
+           (search-forward "MathJax" nil t)))))))
+
+(ert-deftest ox-html/mathjax-path-default ()
+  "Test the default path from which MathJax loads."
+  (should
+   (= 1 (org-test-with-temp-text "$x$"
+          (let ((export-buffer "*Test HTML Export*")
+                (org-export-show-temporary-export-buffer nil))
+            (org-export-to-buffer 'html export-buffer
+              nil nil nil nil nil
+              #'html-mode)
+            (with-current-buffer export-buffer
+              (how-many (rx "<script
+  id=\"MathJax-script\"
+  async
+  src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js\">
+</script>"))))))))
+
+(ert-deftest ox-html/mathjax-path-custom ()
+  "Test a customized path from which MathJax loads."
+  (should
+   (= 1 (org-test-with-temp-text "$x$"
+          (let ((export-buffer "*Test HTML Export*")
+                (org-export-show-temporary-export-buffer nil)
+                (org-html-mathjax-options
+                 '((path "./mathjax/es5/tex-mml-chtml.js"))))
+            (org-export-to-buffer 'html export-buffer
+              nil nil nil nil nil
+              #'html-mode)
+            (with-current-buffer export-buffer
+              (how-many (rx "<script
+  id=\"MathJax-script\"
+  async
+  src=\"./mathjax/es5/tex-mml-chtml.js\">
+</script>"))))))))
+
+(ert-deftest ox-html/mathjax-path-in-buffer ()
+  "Test a in-buffer customized path from which MathJax loads."
+  (should
+   (= 1 (org-test-with-temp-text "
+#+HTML_MATHJAX: path: ./mathjax/es5/tex-mml-chtml.js
+$x$"
+          (let ((export-buffer "*Test HTML Export*")
+                (org-export-show-temporary-export-buffer nil))
+            (org-export-to-buffer 'html export-buffer
+              nil nil nil nil nil
+              #'html-mode)
+            (with-current-buffer export-buffer
+              (how-many (rx "<script
+  id=\"MathJax-script\"
+  async
+  src=\"./mathjax/es5/tex-mml-chtml.js\">
+</script>"))))))))
+
+\f
+;;; Configuring MathJax with options
+
+(ert-deftest ox-html/mathjax-options-default ()
+  "Test the default MathJax options."
+  (should
+   (= 1 (org-test-with-temp-text "$x$"
+          (let ((export-buffer "*Test HTML Export*")
+                (org-export-show-temporary-export-buffer nil))
+            (org-export-to-buffer 'html export-buffer
+              nil nil nil nil nil
+              #'html-mode)
+            (with-current-buffer export-buffer
+              (how-many (rx "<script>
+  window.MathJax = {
+    tex: {
+      ams: {
+        multlineWidth: '85%'
+      },
+      tags: 'ams',
+      tagSide: 'right',
+      tagIndent: '.8em'
+    },
+    chtml: {
+      scale: 1.0,
+      displayAlign: 'center',
+      displayIndent: '0em'
+    },
+    svg: {
+      scale: 1.0,
+      displayAlign: 'center',
+      displayIndent: '0em'
+    },
+    output: {
+      font: 'mathjax-modern',
+      displayOverflow: 'overflow'
+    }
+  };
+</script>"))))))))
+
+(ert-deftest ox-html/mathjax-options-custom ()
+  "Test customized MathJax options."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               '((path "<unused>")      ; tested elsewhere
+                 (scale 0.5)
+                 (align "right")
+                 (font "mathjax-euler")
+                 (overflow "scale")
+                 (tags "all")
+                 (indent "1em")
+                 (multlinewidth "100%")
+                 (tagindent "2em")
+                 (tagside "left"))))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx "<script>
+  window.MathJax = {
+    tex: {
+      ams: {
+        multlineWidth: '100%'
+      },
+      tags: 'all',
+      tagSide: 'left',
+      tagIndent: '2em'
+    },
+    chtml: {
+      scale: 0.5,
+      displayAlign: 'right',
+      displayIndent: '1em'
+    },
+    svg: {
+      scale: 0.5,
+      displayAlign: 'right',
+      displayIndent: '1em'
+    },
+    output: {
+      font: 'mathjax-euler',
+      displayOverflow: 'scale'
+    }
+  };
+</script>"))))))))
+
+(ert-deftest ox-html/mathjax-options-in-buffer ()
+  "Test in-buffer customized MathJax options."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: scale: 0.5
+#+HTML_MATHJAX: align: right
+#+HTML_MATHJAX: font: mathjax-euler
+#+HTML_MATHJAX: overflow: scale
+#+HTML_MATHJAX: tags: all
+#+HTML_MATHJAX: indent: 1em
+#+HTML_MATHJAX: multlinewidth: 100%
+#+HTML_MATHJAX: tagindent: 2em
+#+HTML_MATHJAX: tagside: left"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx "<script>
+  window.MathJax = {
+    tex: {
+      ams: {
+        multlineWidth: '100%'
+      },
+      tags: 'all',
+      tagSide: 'left',
+      tagIndent: '2em'
+    },
+    chtml: {
+      scale: 0.5,
+      displayAlign: 'right',
+      displayIndent: '1em'
+    },
+    svg: {
+      scale: 0.5,
+      displayAlign: 'right',
+      displayIndent: '1em'
+    },
+    output: {
+      font: 'mathjax-euler',
+      displayOverflow: 'scale'
+    }
+  };
+</script>"))))))))
+
+\f
+;;; Converting legacy MathJax scales
+
+;; Define a legacy scale as any scale given as a percentage string,
+;; such as "150", instead of a unit-interval float, such as 1.5.
+
+(ert-deftest ox-html/mathjax-legacy-scale-default ()
+  "Test the legacy scale conversion with the old default value."
+  (should
+   (= 2
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(scale "100") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "scale: 1.0" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-custom ()
+  "Test the legacy scale conversion with a non-default value."
+  (should
+   (= 2
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(scale "10") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "scale: 0.1" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-in-buffer ()
+  "Test the legacy scale conversion with an in-buffer value."
+  (should
+   (= 2
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: scale: 10"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "scale: 0.1" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-message ()
+  "Test the legacy scale conversion message."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Converting legacy MathJax scale: 20 to 0.2"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil)
+                 (org-html-mathjax-options
+                  (cons '(scale "20") org-html-mathjax-options)))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-message-in-buffer ()
+  "Test the legacy scale conversion message for an in-buffer value."
+  (should
+   (seq-count
+    (lambda (message)
+      (string= "Converting legacy MathJax scale: 20 to 0.2"
+               message))
+    (org-test-capture-warnings
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: scale: 20"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-ignore ()
+  "Test the legacy scale conversion ignores small values."
+  (should
+   (= 2
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options '((scale "9"))))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "scale: 9" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-invalid ()
+  "Test the legacy scale conversion with an invalid value."
+  (should
+   (= 2
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(scale "xxx") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "scale: 1.0" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-scale-invalid-message ()
+  "Test the invalid legacy scale conversion message."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Non-numerical MathJax scale: xxx"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil)
+                 (org-html-mathjax-options
+                  (cons '(scale "xxx") org-html-mathjax-options)))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+\f
+;;; Converting legacy MathJax auto-numbering
+
+;; NOTE: AMS stands for American Mathematical Society.
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-ams ()
+  "Test legacy auto-numbering, when AMS."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(autonumber "AMS") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'ams'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-ams-in-buffer ()
+  "Test legacy auto-numbering, when AMS in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: autonumber: AMS"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'ams'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-none ()
+  "Test legacy auto-numbering, when disabled."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(autonumber "None") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'none'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-none-in-buffer ()
+  "Test legacy auto-numbering, when disabled in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: autonumber: None"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'none'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-all ()
+  "Test legacy auto-numbering, when enabled."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(autonumber "All") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'all'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-all-in-buffer ()
+  "Test legacy auto-numbering, when enabled in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: autonumber: All"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "tags: 'all'" (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-message ()
+  "Test legacy auto-numbering conversion message."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Converting legacy MathJax option: autonumber"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil)
+                 (org-html-mathjax-options
+                  (cons '(autonumber "AMS") org-html-mathjax-options)))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+(ert-deftest ox-html/mathjax-legacy-autonumber-message-in-buffer ()
+  "Test legacy auto-numbering conversion message."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Converting legacy MathJax option: autonumber"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: autonumber: AMS"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+\f
+;;; Converting legacy MathJax fonts
+
+(ert-deftest ox-html/mathjax-legacy-font-tex ()
+  "Test legacy font, when TeX."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "TeX") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-tex'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-tex-in-buffer ()
+  "Test legacy font, when TeX in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: TeX"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-tex'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-stix-web ()
+  "Test legacy font, when STIX-Web."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "STIX-Web") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-stix2'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-stix-web-in-buffer ()
+  "Test legacy font, when STIX-Web in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: STIX-Web"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-stix2'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-asana-math ()
+  "Test legacy font, when Asana-Math."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "Asana-Math") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-asana'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-asana-math-in-buffer ()
+  "Test legacy font, when Asana-Math in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: Asana-Math"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-asana'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-neo-euler ()
+  "Test legacy font, when Neo-Euler."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "Neo-Euler") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-euler'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-neo-euler-in-buffer ()
+  "Test legacy font, when Neo-Euler in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: Neo-Euler"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-euler'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-gyre-pagella ()
+  "Test legacy font, when Gyre-Pagella."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "Gyre-Pagella") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-pagella'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-gyre-pagella-in-buffer ()
+  "Test legacy font, when Gyre-Pagella in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: Gyre-Pagella"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-pagella'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-gyre-termes ()
+  "Test legacy font, when Gyre-Termes."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "Gyre-Termes") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-termes'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-gyre-termes-in-buffer ()
+  "Test legacy font, when Gyre-Termes in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: Gyre-Termes"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-termes'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-latin-modern ()
+  "Test legacy font, when Latin-Modern."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(font "Latin-Modern") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-modern'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-font-latin-modern-in-buffer ()
+  "Test legacy font, when Latin-Modern in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: font: Latin-Modern"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "font: 'mathjax-modern'"
+                               (or "," "\n"))))))))))
+
+\f
+;;; Converting legacy MathJax line breaks
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-true ()
+  "Test legacy line breaks, when true."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (append '((linebreaks "true")
+                         (overflow "overflow"))
+                       org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "displayOverflow: 'linebreak'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-true-in-buffer ()
+  "Test legacy line breaks, when true in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: linebreaks: true"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(overflow "overflow") org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "displayOverflow: 'linebreak'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-false ()
+  "Test legacy line breaks, when false."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (append '((linebreaks "false")
+                         (overflow "linebreak"))
+                       org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "displayOverflow: 'overflow'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-false-in-buffer ()
+  "Test legacy line breaks, when true in-buffer."
+  (should
+   (= 1
+      (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: linebreaks: false"
+        (let ((export-buffer "*Test HTML Export*")
+              (org-export-show-temporary-export-buffer nil)
+              (org-html-mathjax-options
+               (cons '(overflow "linebreak")
+                     org-html-mathjax-options)))
+          (org-export-to-buffer 'html export-buffer
+            nil nil nil nil nil
+            #'html-mode)
+          (with-current-buffer export-buffer
+            (how-many (rx (seq "displayOverflow: 'overflow'"
+                               (or "," "\n"))))))))))
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-message ()
+  "Test the legacy line breaks conversion message."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Converting legacy MathJax option: linebreaks"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil)
+                 (org-html-mathjax-options (cons '(linebreaks "true")
+                                                 org-html-mathjax-options)))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+(ert-deftest ox-html/mathjax-legacy-line-breaks-message-in-buffer ()
+  "Test the legacy scale conversion message for an in-buffer value."
+  (should
+   (= 1
+      (seq-count
+       (lambda (message)
+         (string= "Converting legacy MathJax option: linebreaks"
+                  message))
+       (org-test-capture-warnings
+         (org-test-with-temp-text "$x$
+#+HTML_MATHJAX: linebreaks: true"
+           (let ((export-buffer "*Test HTML Export*")
+                 (org-export-show-temporary-export-buffer nil))
+             (org-export-to-buffer 'html export-buffer
+               nil nil nil nil nil
+               #'html-mode))))))))
+
+(provide 'test-ox-html)
+;;; test-ox-html.el ends here
diff --git a/testing/org-test.el b/testing/org-test.el
index 9f7bab9ea..880d9e845 100644
--- a/testing/org-test.el
+++ b/testing/org-test.el
@@ -33,6 +33,7 @@
 
 (require 'org)
 (require 'org-id)
+(require 'org-macs)
 
 ;;; Ob constants
 
@@ -531,6 +532,16 @@ TIME can be a non-nil Lisp time value, or a string specifying a date and time."
 				    (or a ,at) (or b ,at)))))
 	 ,@body))))
 
+(defmacro org-test-capture-warnings (&rest body)
+  "Capture all warnings passed to `org-display-warning' within BODY."
+  (declare (indent 0) (debug t))
+  `(let ((messages (list)))
+     (cl-letf (((symbol-function 'org-display-warning)
+                (lambda (message)
+                  (setq messages (cons message messages)))))
+       ,@body)
+     (nreverse messages)))
+
 (provide 'org-test)
 
 ;;; org-test.el ends here
-- 
2.38.1


[-- Attachment #3: Type: text/plain, Size: 329 bytes --]

-- 
"Programming reliably -- must be an activity of an undeniably
mathematical nature […] You see, mathematics is about thinking, and
doing mathematics is always trying to think as well as possible."
-- Edsger W. Dijkstra, 1981

Rudolf Adamkovič <salutis@me.com> [he/him]
Studenohorská 25
84103 Bratislava
Slovakia

  reply	other threads:[~2022-11-13 20:53 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-07 13:36 Update Org to MathJax 3 Rudolf Adamkovič
2022-10-08  7:20 ` Ihor Radchenko
2022-10-08 21:32   ` Rudolf Adamkovič
2022-11-05  0:20     ` [PATCH] " Rudolf Adamkovič
2022-11-05 12:01       ` Ihor Radchenko
2022-11-05 16:56         ` Rudolf Adamkovič
2022-11-05 22:44           ` Rudolf Adamkovič
2022-11-06  3:52             ` Ihor Radchenko
2022-11-06 23:49               ` Rudolf Adamkovič
2022-11-07  3:02                 ` Ihor Radchenko
2022-11-07 20:56                   ` Rudolf Adamkovič
2022-11-08  5:20                     ` Ihor Radchenko
2022-11-08 23:37                       ` Rudolf Adamkovič
2022-11-09  0:05                         ` Rudolf Adamkovič
2022-11-09  5:40                           ` Ihor Radchenko
2022-11-09 23:01                             ` Rudolf Adamkovič
2022-11-10  2:34                               ` Ihor Radchenko
2022-11-11 12:50                                 ` Rudolf Adamkovič
2022-11-13  4:24                                   ` Ihor Radchenko
2022-11-13 20:52                                     ` Rudolf Adamkovič [this message]
2022-11-14  4:33                                       ` Ihor Radchenko
2022-11-19 13:10                                         ` Bastien Guerry
2022-11-21  2:51                                           ` Ihor Radchenko
2022-11-22 20:56                                             ` Rudolf Adamkovič
2022-11-23 11:11                                               ` Ihor Radchenko
2022-11-23 23:08                                                 ` Rudolf Adamkovič
2022-11-09  2:49                         ` Ihor Radchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2r0y6inlx.fsf@me.com \
    --to=salutis@me.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=yantar92@gmail.com \
    --cc=yantar92@posteo.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).