Skip to content

Commit 738a3f3

Browse files
Using MathJax when KaTeX fails
1 parent c1be2e4 commit 738a3f3

File tree

6 files changed

+206
-73
lines changed

6 files changed

+206
-73
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Place the following line in the `<head>` section of your document:
99
<script type="text/javascript" src="https://codeassign.github.io/markjax/dist/markjax.min.js"></script>
1010
```
1111

12-
Now you can write simple HTML which users `markjax`:
12+
Now you can write simple HTML which uses `markjax`:
1313
```html
1414
<html>
1515
<head>
@@ -20,7 +20,7 @@ Now you can write simple HTML which users `markjax`:
2020
<div id="output"></div>
2121

2222
<script>
23-
document.getElementById("output").innerHTML = markjax("# Hello\n$\LaTeX$");
23+
markjax("# Hello\n$\LaTeX$", document.getElementById("output"));
2424
</script>
2525
</body>
2626
</html>

dist/markjax.js

+66-22
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
11
/**
2-
* markjax v1.0.5
2+
* markjax v1.1.0
33
* Copyright CodeAssign
44
* @link http://markjax.codeassign.com/
55
* @license Apache-2.0
66
*/
77
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markjax = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
88
(function () {
9-
var katex = document.createElement("link");
10-
katex.rel = "stylesheet";
11-
katex.href = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css";
12-
document.getElementsByTagName("head")[0].appendChild(katex);
13-
14-
var highlight = document.createElement("link");
15-
highlight.rel = "stylesheet";
16-
highlight.href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css";
17-
document.getElementsByTagName("head")[0].appendChild(highlight);
9+
var head = document.getElementsByTagName("head")[0];
10+
11+
var mathjaxConfig = document.createElement("script");
12+
mathjaxConfig.type = "text/x-mathjax-config";
13+
mathjaxConfig[(window.opera ? "innerHTML" : "text")] =
14+
"MathJax.Hub.Config({" +
15+
" showProcessingMessages: false," +
16+
" messageStyle: \"none\"," +
17+
" skipStartupTypeset: false," +
18+
" tex2jax: {" +
19+
" inlineMath: [['$','$']]," +
20+
" displayMath: [['$$', '$$']]," +
21+
" ignoreClass: \".*\"," +
22+
" processClass: \"mathjax\"" +
23+
" }," +
24+
" TeX: {" +
25+
" equationNumbers: {" +
26+
" autoNumber: \"AMS\"" +
27+
" }" +
28+
" }" +
29+
"});";
30+
head.appendChild(mathjaxConfig);
31+
32+
var mathjax = document.createElement("script");
33+
mathjax.type = "text/javascript";
34+
mathjax.src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
35+
head.appendChild(mathjax);
36+
37+
var katex = document.createElement("link");
38+
katex.rel = "stylesheet";
39+
katex.href = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css";
40+
head.appendChild(katex);
41+
42+
var highlight = document.createElement("link");
43+
highlight.rel = "stylesheet";
44+
highlight.href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css";
45+
head.appendChild(highlight);
1846
})();
1947

2048
var marked = require("marked");
2149
var katex = require("katex");
22-
var highlight = require("highlight.js")
50+
var highlight = require("highlight.js");
51+
var memoMath = {};
2352

2453
function EscapeTex(text) {
2554
var re = /(`+)(\s*)([\s\S]*?[^`])(\s*)(\1)(?!`)/g;
@@ -157,6 +186,10 @@ function splitWithDelimiters(text, delimiters) {
157186
return data;
158187
}
159188

189+
function remember(key, element) {
190+
memoMath[key] = element.innerHTML;
191+
}
192+
160193
function renderMathInText(text, delimiters) {
161194
var data = splitWithDelimiters(text, delimiters);
162195

@@ -176,15 +209,26 @@ function renderMathInText(text, delimiters) {
176209
if (!(e instanceof katex.ParseError)) {
177210
throw e;
178211
}
179-
console.error(
180-
"KaTeX auto-render: Failed to parse `" + data[i].data +
181-
"` with ",
182-
e
183-
);
184-
fragment.appendChild(document.createTextNode(data[i].rawData));
185-
continue;
212+
213+
span.innerHTML = data[i].rawData;
214+
span.classList.add("mathjax");
215+
216+
var style = data[i].display ? "$$" : "$";
217+
var trimmedData = data[i].data.trim();
218+
if (trimmedData[trimmedData.length - 1] === '\\') {
219+
trimmedData += " ";
220+
}
221+
var rawData = style + trimmedData + style;
222+
223+
if (memoMath[rawData] === undefined) {
224+
MathJax.Hub.Queue(["Typeset", MathJax.Hub, span]);
225+
MathJax.Hub.Queue([remember, rawData, span]);
226+
} else {
227+
span.innerHTML = memoMath[rawData];
228+
}
229+
} finally {
230+
fragment.appendChild(span);
186231
}
187-
fragment.appendChild(span);
188232
}
189233
}
190234

@@ -225,7 +269,7 @@ function renderMathInElement(elem) {
225269
renderElem(elem, defaultOptions.delimiters, defaultOptions.ignoredTags);
226270
}
227271

228-
function markjax(text, markedOptions = {}) {
272+
function markjax(text, element, markedOptions = {}) {
229273
if (markedOptions["breaks"] === undefined) {
230274
markedOptions["breaks"] = true;
231275
}
@@ -259,8 +303,8 @@ function markjax(text, markedOptions = {}) {
259303
}
260304
}
261305

262-
renderMathInElement(node);
263-
return node.innerHTML;
306+
element.innerHTML = node.innerHTML;
307+
renderMathInElement(element);
264308
}
265309

266310
module.exports = markjax;

dist/markjax.min.js

+67-23
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,60 @@
11
/**
2-
* markjax v1.0.5
2+
* markjax v1.1.0
33
* Copyright CodeAssign
44
* @link http://markjax.codeassign.com/
55
* @license Apache-2.0
66
*/
77
/**
8-
* markjax v1.0.5
8+
* markjax v1.1.0
99
* Copyright CodeAssign
1010
* @link http://markjax.codeassign.com/
1111
* @license Apache-2.0
1212
*/
1313
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markjax = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
1414
(function () {
15-
var katex = document.createElement("link");
16-
katex.rel = "stylesheet";
17-
katex.href = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css";
18-
document.getElementsByTagName("head")[0].appendChild(katex);
19-
20-
var highlight = document.createElement("link");
21-
highlight.rel = "stylesheet";
22-
highlight.href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css";
23-
document.getElementsByTagName("head")[0].appendChild(highlight);
15+
var head = document.getElementsByTagName("head")[0];
16+
17+
var mathjaxConfig = document.createElement("script");
18+
mathjaxConfig.type = "text/x-mathjax-config";
19+
mathjaxConfig[(window.opera ? "innerHTML" : "text")] =
20+
"MathJax.Hub.Config({" +
21+
" showProcessingMessages: false," +
22+
" messageStyle: \"none\"," +
23+
" skipStartupTypeset: false," +
24+
" tex2jax: {" +
25+
" inlineMath: [['$','$']]," +
26+
" displayMath: [['$$', '$$']]," +
27+
" ignoreClass: \".*\"," +
28+
" processClass: \"mathjax\"" +
29+
" }," +
30+
" TeX: {" +
31+
" equationNumbers: {" +
32+
" autoNumber: \"AMS\"" +
33+
" }" +
34+
" }" +
35+
"});";
36+
head.appendChild(mathjaxConfig);
37+
38+
var mathjax = document.createElement("script");
39+
mathjax.type = "text/javascript";
40+
mathjax.src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
41+
head.appendChild(mathjax);
42+
43+
var katex = document.createElement("link");
44+
katex.rel = "stylesheet";
45+
katex.href = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css";
46+
head.appendChild(katex);
47+
48+
var highlight = document.createElement("link");
49+
highlight.rel = "stylesheet";
50+
highlight.href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css";
51+
head.appendChild(highlight);
2452
})();
2553

2654
var marked = require("marked");
2755
var katex = require("katex");
28-
var highlight = require("highlight.js")
56+
var highlight = require("highlight.js");
57+
var memoMath = {};
2958

3059
function EscapeTex(text) {
3160
var re = /(`+)(\s*)([\s\S]*?[^`])(\s*)(\1)(?!`)/g;
@@ -163,6 +192,10 @@ function splitWithDelimiters(text, delimiters) {
163192
return data;
164193
}
165194

195+
function remember(key, element) {
196+
memoMath[key] = element.innerHTML;
197+
}
198+
166199
function renderMathInText(text, delimiters) {
167200
var data = splitWithDelimiters(text, delimiters);
168201

@@ -182,15 +215,26 @@ function renderMathInText(text, delimiters) {
182215
if (!(e instanceof katex.ParseError)) {
183216
throw e;
184217
}
185-
console.error(
186-
"KaTeX auto-render: Failed to parse `" + data[i].data +
187-
"` with ",
188-
e
189-
);
190-
fragment.appendChild(document.createTextNode(data[i].rawData));
191-
continue;
218+
219+
span.innerHTML = data[i].rawData;
220+
span.classList.add("mathjax");
221+
222+
var style = data[i].display ? "$$" : "$";
223+
var trimmedData = data[i].data.trim();
224+
if (trimmedData[trimmedData.length - 1] === '\\') {
225+
trimmedData += " ";
226+
}
227+
var rawData = style + trimmedData + style;
228+
229+
if (memoMath[rawData] === undefined) {
230+
MathJax.Hub.Queue(["Typeset", MathJax.Hub, span]);
231+
MathJax.Hub.Queue([remember, rawData, span]);
232+
} else {
233+
span.innerHTML = memoMath[rawData];
234+
}
235+
} finally {
236+
fragment.appendChild(span);
192237
}
193-
fragment.appendChild(span);
194238
}
195239
}
196240

@@ -231,7 +275,7 @@ function renderMathInElement(elem) {
231275
renderElem(elem, defaultOptions.delimiters, defaultOptions.ignoredTags);
232276
}
233277

234-
function markjax(text, markedOptions = {}) {
278+
function markjax(text, element, markedOptions = {}) {
235279
if (markedOptions["breaks"] === undefined) {
236280
markedOptions["breaks"] = true;
237281
}
@@ -265,8 +309,8 @@ function markjax(text, markedOptions = {}) {
265309
}
266310
}
267311

268-
renderMathInElement(node);
269-
return node.innerHTML;
312+
element.innerHTML = node.innerHTML;
313+
renderMathInElement(element);
270314
}
271315

272316
module.exports = markjax;

index.html

+5-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
<textarea class="col-xs-12 col-sm-6 col-md-6 col-lg-6" id="input" onkeyup="render()">
2323
# MarkJax
2424

25-
Markdown + LaTeX parser made by [CodeAssign](https://codeassign.com).
25+
Markdown + $\LaTeX$ parser made by [CodeAssign](https://codeassign.com).
2626

27-
It converts Markdown + LaTeX text, such as this one, and produces HTML.
27+
It converts Markdown + $\LaTeX$ text, such as this one, and produces HTML.
2828

29-
It uses [marked](https://github.com/chjj/marked) as Markdown parser and [katex](https://khan.github.io/KaTeX/) as LaTeX parser.
29+
It uses [marked](https://github.com/chjj/marked) as Markdown parser and [katex](https://khan.github.io/KaTeX/)
30+
and [MathJax](https://www.mathjax.org/) as $\LaTeX$ parsers.
3031

3132
It is available on [GitHub](https://github.com/codeassign/markjax).
3233

@@ -41,7 +42,7 @@
4142
function render() {
4243
var textarea = document.getElementById("input");
4344
var preview = document.getElementById("output");
44-
preview.innerHTML = markjax(textarea.value);
45+
markjax(textarea.value, preview);
4546
}
4647
render();
4748
</script>

0 commit comments

Comments
 (0)