diff --git a/src/Markdown.js b/src/Markdown.js
index 2e6f391818..dc4d442aff 100644
--- a/src/Markdown.js
+++ b/src/Markdown.js
@@ -22,47 +22,12 @@ const ALLOWED_HTML_TAGS = ['sub', 'sup', 'del', 'u'];
// These types of node are definitely text
const TEXT_NODES = ['text', 'softbreak', 'linebreak', 'paragraph', 'document'];
-// prevent renderer from interpreting contents of AST node
-function freeze_node(walker, node) {
- const newNode = new commonmark.Node('custom_inline', node.sourcepos);
- newNode.onEnter = node.literal;
- node.insertAfter(newNode);
- node.unlink();
- walker.resumeAt(newNode.next, true);
-}
-
-// prevent renderer from interpreting contents of latex math tags
-function freeze_math(parsed) {
- const walker = parsed.walker();
- let ev;
- let inMath = false;
- while ( (ev = walker.next()) ) {
- const node = ev.node;
- if (ev.entering) {
- if (!inMath) {
- // entering a math tag
- if (node.literal != null && node.literal.match('^<(div|span) data-mx-maths="[^"]*">$') != null) {
- inMath = true;
- freeze_node(walker, node);
- }
- } else {
- // math tags should only contain a single code block, with URL-escaped latex as fallback output
- if (node.literal != null && node.literal.match('^(|
|[^<>]*)$')) {
- freeze_node(walker, node);
- // leave when span or div is closed
- } else if (node.literal == '' || node.literal == '') {
- inMath = false;
- freeze_node(walker, node);
- // this case only happens if we have improperly formatted math tags, so bail
- } else {
- inMath = false;
- }
- }
- }
- }
-}
-
function is_allowed_html_tag(node) {
+ if (node.literal != null &&
+ node.literal.match('^<((div|span) data-mx-maths="[^"]*"|\/(div|span))>$') != null) {
+ return true;
+ }
+
// Regex won't work for tags with attrs, but we only
// allow anyway.
const matches = /^<\/?(.*)>$/.exec(node.literal);
@@ -70,6 +35,7 @@ function is_allowed_html_tag(node) {
const tag = matches[1];
return ALLOWED_HTML_TAGS.indexOf(tag) > -1;
}
+
return false;
}
@@ -199,9 +165,6 @@ export default class Markdown {
*/
};
- // prevent strange behaviour when mixing latex math and markdown
- freeze_math(this.parsed);
-
return renderer.render(this.parsed);
}
diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts
index 9f24cd5eb2..88fd1c90fc 100644
--- a/src/editor/serialize.ts
+++ b/src/editor/serialize.ts
@@ -21,6 +21,7 @@ import EditorModel from "./model";
import { AllHtmlEntities } from 'html-entities';
import SettingsStore from '../settings/SettingsStore';
import SdkConfig from '../SdkConfig';
+import cheerio from 'cheerio';
export function mdSerialize(model: EditorModel) {
return model.parts.reduce((html, part) => {
@@ -51,18 +52,29 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} =
md = md.replace(RegExp(displayPattern, "gm"), function(m, p1) {
const p1e = AllHtmlEntities.encode(p1);
- return `${p1e}
`;
+ return ``;
});
md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1) {
const p1e = AllHtmlEntities.encode(p1);
- return `${p1e}
`;
+ return ``;
});
}
const parser = new Markdown(md);
if (!parser.isPlainText() || forceHTML) {
- return parser.toHTML();
+ // feed Markdown output to HTML parser
+ const phtml = cheerio.load(parser.toHTML(),
+ { _useHtmlParser2: true, decodeEntities: false })
+
+ // add fallback output for latex math, which should not be interpreted as markdown
+ phtml('div, span').each(function() {
+ const tex = phtml(this).attr('data-mx-maths')
+ if (tex) {
+ phtml(this).html(`${tex}
`)
+ }
+ });
+ return phtml.html();
}
// ensure removal of escape backslashes in non-Markdown messages
if (md.indexOf("\\") > -1) {