add fallback output in code block AFTER markdown processing
parent
38d1aac978
commit
cc713aff72
|
@ -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('^(<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) {
|
||||
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 <del> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 `<div data-mx-maths="${p1e}"><code>${p1e}</code></div>`;
|
||||
return `<div data-mx-maths="${p1e}"></div>`;
|
||||
});
|
||||
|
||||
md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1) {
|
||||
const p1e = AllHtmlEntities.encode(p1);
|
||||
return `<span data-mx-maths="${p1e}"><code>${p1e}</code></span>`;
|
||||
return `<span data-mx-maths="${p1e}"></span>`;
|
||||
});
|
||||
}
|
||||
|
||||
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(`<code>${tex}</code>`)
|
||||
}
|
||||
});
|
||||
return phtml.html();
|
||||
}
|
||||
// ensure removal of escape backslashes in non-Markdown messages
|
||||
if (md.indexOf("\\") > -1) {
|
||||
|
|
Loading…
Reference in New Issue