diff --git a/js/mathjax_startup.js b/js/mathjax_startup.js
new file mode 100644
index 0000000000..8ec535db20
--- /dev/null
+++ b/js/mathjax_startup.js
@@ -0,0 +1,132 @@
+/***************************************************************
+ * Implements startup of MathJax v4
+ ***************************************************************/
+
+// Base config options. Will be supplemented by optional parts later
+let mathJaxOpts = {
+ "tex": {
+ "inlineMath": [
+ [
+ "\\(",
+ "\\)"
+ ]
+ ],
+ "tags": "none",
+ "tagSide": "right",
+ "tagIndent": ".8em",
+ "packages": {
+ "[+]": [
+ "amscd",
+ "color",
+ "knowl"
+ ]
+ }
+ },
+ "options": {
+ "ignoreHtmlClass": "tex2jax_ignore|ignore-math",
+ "processHtmlClass": "process-math",
+ },
+ "chtml": {
+ "scale": 0.98,
+ "mtextInheritFont": true
+ },
+ "loader": {
+ "load": [
+ "input/asciimath",
+ "[tex]/amscd",
+ "[tex]/color",
+ ]
+ }
+};
+
+
+export function startMathJax(opts) {
+ if(opts.hasWebworkReps || opts.hasSage) {
+ mathJaxOpts['renderActions'] = {
+ "findScript": [
+ 10,
+ function (doc) {
+ document.querySelectorAll('script[type^="math/tex"]').forEach(function (node) {
+ var display = !!node.type.match(/; *mode=display/);
+ var math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
+ var text = document.createTextNode('');
+ node.parentNode.replaceChild(text, node);
+ math.start = { node: text, delim: '', n: 0 };
+ math.end = { node: text, delim: '', n: 0 };
+ doc.math.push(math);
+ });
+ },
+ ""
+ ]
+ }
+ }
+
+ if(opts.isReact) {
+ mathJaxOpts['startup'] = {
+ typeset: false,
+ }
+ } else {
+ mathJaxOpts['startup'] = {
+ ready() {
+ const { Configuration } = MathJax._.input.tex.Configuration;
+ const configuration = Configuration.create("knowl", {
+ handler: {
+ macro: ["knowl"]
+ }
+ });
+
+ const NodeUtil = MathJax._.input.tex.NodeUtil.default;
+
+ function GetArgumentMML(parser, name) {
+ const arg = parser.ParseArg(name);
+ if (!NodeUtil.isInferred(arg)) {
+ return arg;
+ }
+ const children = NodeUtil.getChildren(arg);
+ if (children.length === 1) {
+ return children[0];
+ }
+ const mrow = parser.create("node", "mrow");
+ NodeUtil.copyChildren(arg, mrow);
+ NodeUtil.copyAttributes(arg, mrow);
+ return mrow;
+ };
+
+ const CommandMap = MathJax._.input.tex.TokenMap.CommandMap;
+ new CommandMap(
+ "knowl",
+ {
+ knowl(parser, name) {
+ const url = parser.GetArgument(name);
+ const arg = GetArgumentMML(parser, name);
+ const mrow = parser.create("node", "mrow", [arg], { tabindex: '0', "data-knowl": url });
+ parser.Push(mrow);
+ }
+ }
+ );
+
+ MathJax.startup.defaultReady();
+ },
+ pageReady() {
+ return MathJax.startup.defaultPageReady().then(rsMathReady);
+ },
+ }
+ }
+
+ if(opts.htmlPresentation) {
+ mathJaxOpts['options']['menuOptions'] = {
+ "settings": {
+ "zoom": "Click",
+ "zscale": "300%"
+ }
+ }
+ }
+
+ // Apply the options
+ window.MathJax = mathJaxOpts;
+
+ // Lets Runestone know that MathJax is ready
+ const runestoneMathReady = new Promise((resolve) => window.rsMathReady = resolve);
+ window.runestoneMathReady = runestoneMathReady;
+}
+
diff --git a/js/mathjaxknowl3.js b/js/mathjaxknowl3.js
deleted file mode 100644
index 4b4ecac0af..0000000000
--- a/js/mathjaxknowl3.js
+++ /dev/null
@@ -1,48 +0,0 @@
-
- const { Configuration } = MathJax._.input.tex.Configuration;
- const { CommandMap } = MathJax._.input.tex.SymbolMap;
- const NodeUtil = MathJax._.input.tex.NodeUtil.default;
-
- var GetArgumentMML = function (parser, name) {
- var arg = parser.ParseArg(name);
- if (!NodeUtil.isInferred(arg)) {
- return arg;
- }
- var children = NodeUtil.getChildren(arg);
- if (children.length === 1) {
- return children[0];
- }
- var mrow = parser.create("node", "mrow");
- NodeUtil.copyChildren(arg, mrow);
- NodeUtil.copyAttributes(arg, mrow);
- return mrow;
- };
-
- let mathjaxKnowl = {};
- /**
- * Implements \knowl{url}{math}
- * @param {TexParser} parser The calling parser.
- * @param {string} name The TeX string
- */
- mathjaxKnowl.Knowl = function (parser, name) {
- var url = parser.GetArgument(name);
- var arg = GetArgumentMML(parser, name);
- var mrow = parser.create("node", "mrow", [arg], {
- tabindex: '0',
- "data-knowl": url
- });
- parser.Push(mrow);
- };
-
- new CommandMap(
- "knowl",
- {
- knowl: ["Knowl"]
- },
- mathjaxKnowl
- );
- const configuration = Configuration.create("knowl", {
- handler: {
- macro: ["knowl"]
- }
- });
diff --git a/xsl/pretext-common.xsl b/xsl/pretext-common.xsl
index 010852e573..1d03821bfd 100644
--- a/xsl/pretext-common.xsl
+++ b/xsl/pretext-common.xsl
@@ -411,12 +411,6 @@ $inline-solution-back|$divisional-solution-back|$worksheet-solution-back|$readin
-
-
-
-
-
-
diff --git a/xsl/pretext-html.xsl b/xsl/pretext-html.xsl
index de8ab29a56..92e53e9510 100644
--- a/xsl/pretext-html.xsl
+++ b/xsl/pretext-html.xsl
@@ -13163,152 +13163,32 @@ TODO:
-
-
-
- var runestoneMathReady = new Promise((resolve) => window.rsMathReady = resolve);
- window.MathJax =
-
-
-
-
-
- ;
-
-
-
-
-
-
-
-
- text/javascript
-
-
+
+
+
+
diff --git a/xsl/pretext-runestone.xsl b/xsl/pretext-runestone.xsl
index 389371356f..8b2e68477d 100644
--- a/xsl/pretext-runestone.xsl
+++ b/xsl/pretext-runestone.xsl
@@ -225,7 +225,7 @@ along with PreTeXt. If not, see .
*** Runestone Services ***
-