tell markdown parser to ignore properly-formatted math tags
This commit is contained in:
parent
bdd332c8b5
commit
f0c4473107
1 changed files with 41 additions and 10 deletions
|
@ -23,19 +23,47 @@ const ALLOWED_HTML_TAGS = ['sub', 'sup', 'del', 'u'];
|
||||||
// These types of node are definitely text
|
// These types of node are definitely text
|
||||||
const TEXT_NODES = ['text', 'softbreak', 'linebreak', 'paragraph', 'document'];
|
const TEXT_NODES = ['text', 'softbreak', 'linebreak', 'paragraph', 'document'];
|
||||||
|
|
||||||
function is_math_node(node) {
|
// prevent renderer from interpreting contents of AST node
|
||||||
return node != null &&
|
function freeze_node(walker, node) {
|
||||||
node.literal != null &&
|
const newNode = new commonmark.Node('custom_inline', node.sourcepos);
|
||||||
node.literal.match(/^<((div|span) data-mx-maths="[^"]*"|\/(div|span))>$/) != null;
|
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('^(<code>|</code>|[^<>]*)$')) {
|
||||||
|
freeze_node(walker, node);
|
||||||
|
// leave when span or div is closed
|
||||||
|
} else if (node.literal == '</span>' || node.literal == '</div>') {
|
||||||
|
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) {
|
function is_allowed_html_tag(node) {
|
||||||
if (SettingsStore.getValue("feature_latex_maths") &&
|
|
||||||
(is_math_node(node) ||
|
|
||||||
(node.literal.match(/^<\/?code>$/) && is_math_node(node.parent)))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regex won't work for tags with attrs, but we only
|
// Regex won't work for tags with attrs, but we only
|
||||||
// allow <del> anyway.
|
// allow <del> anyway.
|
||||||
const matches = /^<\/?(.*)>$/.exec(node.literal);
|
const matches = /^<\/?(.*)>$/.exec(node.literal);
|
||||||
|
@ -173,6 +201,9 @@ export default class Markdown {
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// prevent strange behaviour when mixing latex math and markdown
|
||||||
|
freeze_math(this.parsed);
|
||||||
|
|
||||||
return renderer.render(this.parsed);
|
return renderer.render(this.parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue