Refactor latex replace code

This commit is contained in:
Sven Mäder 2021-04-01 12:09:51 +02:00
parent ac1f9b4247
commit 73130cad02

View file

@ -47,60 +47,61 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} =
const orig = md; const orig = md;
if (SettingsStore.getValue("feature_latex_maths")) { if (SettingsStore.getValue("feature_latex_maths")) {
// detect math with tex delimiters, inline: $...$, display $$...$$ const patternNames = ['tex', 'latex'];
// preferably use negative lookbehinds, not supported in all major browsers: const patternTypes = ['display', 'inline'];
// const displayPattern = "^(?<!\\\\)\\$\\$(?![ \\t])(([^$]|\\\\\\$)+?)\\$\\$$"; const patternDefaults = {
// const inlinePattern = "(?:^|\\s)(?<!\\\\)\\$(?!\\s)(([^$]|\\\\\\$)+?)(?<!\\\\|\\s)\\$"; "tex": {
// detect math with tex delimiters, inline: $...$, display $$...$$
// preferably use negative lookbehinds, not supported in all major browsers:
// const displayPattern = "^(?<!\\\\)\\$\\$(?![ \\t])(([^$]|\\\\\\$)+?)\\$\\$$";
// const inlinePattern = "(?:^|\\s)(?<!\\\\)\\$(?!\\s)(([^$]|\\\\\\$)+?)(?<!\\\\|\\s)\\$";
// conditions for display math detection $$...$$: // conditions for display math detection $$...$$:
// - pattern starts at beginning of line or is not prefixed with backslash or dollar // - pattern starts at beginning of line or is not prefixed with backslash or dollar
// - left delimiter ($$) is not escaped by backslash // - left delimiter ($$) is not escaped by backslash
const displayPatternAlternative = (SdkConfig.get()['latex_maths_delims'] || "display": "(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$",
{})['display_pattern_alternative'] ||
"(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$";
// conditions for inline math detection $...$: // conditions for inline math detection $...$:
// - pattern starts at beginning of line, follows whitespace character or punctuation // - pattern starts at beginning of line, follows whitespace character or punctuation
// - pattern is on a single line // - pattern is on a single line
// - left and right delimiters ($) are not escaped by backslashes // - left and right delimiters ($) are not escaped by backslashes
// - left delimiter is not followed by whitespace character // - left delimiter is not followed by whitespace character
// - right delimiter is not prefixed with whitespace character // - right delimiter is not prefixed with whitespace character
const inlinePatternAlternative = (SdkConfig.get()['latex_maths_delims'] || "inline":
{})['inline_pattern_alternative'] || "(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$",
"(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$"; },
"latex": {
// detect math with latex delimiters, inline: \(...\), display \[...\]
md = md.replace(RegExp(displayPatternAlternative, "gm"), function(m, p1, p2) { // conditions for display math detection \[...\]:
const p2e = AllHtmlEntities.encode(p2); // - pattern starts at beginning of line or is not prefixed with backslash
return `${p1}<div data-mx-maths="${p2e}">\n\n</div>\n\n`; // - pattern is not empty
}); "display": "(^|[^\\\\])\\\\\\[(?!\\\\\\])(.*?)\\\\\\]",
md = md.replace(RegExp(inlinePatternAlternative, "gm"), function(m, p1, p2) { // conditions for inline math detection \(...\):
const p2e = AllHtmlEntities.encode(p2); // - pattern starts at beginning of line or is not prefixed with backslash
return `${p1}<span data-mx-maths="${p2e}"></span>`; // - pattern is not empty
}); "inline": "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)",
},
};
// detect math with latex delimiters, inline: \(...\), display \[...\] patternNames.forEach(function(patternName) {
patternTypes.forEach(function(patternType) {
// get the regex replace pattern from config or use the default
const pattern = (SdkConfig.get()["latex_maths_delims"] ||
{})[patternType + "_pattern_" + patternName] ||
patternDefaults[patternName][patternType];
// conditions for display math detection \[...\]: md = md.replace(RegExp(pattern, "gms"), function(m, p1, p2) {
// - pattern starts at beginning of line or is not prefixed with backslash const p2e = AllHtmlEntities.encode(p2);
// - pattern is not empty switch (patternType) {
const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || case "display":
"(^|[^\\\\])\\\\\\[(?!\\\\\\])(.*?)\\\\\\]"; return `${p1}<div data-mx-maths="${p2e}">\n\n</div>\n\n`;
case "inline":
// conditions for inline math detection \(...\): return `${p1}<span data-mx-maths="${p2e}"></span>`;
// - pattern starts at beginning of line or is not prefixed with backslash }
// - pattern is not empty });
const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || });
"(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)";
md = md.replace(RegExp(displayPattern, "gms"), function(m, p1, p2) {
const p2e = AllHtmlEntities.encode(p2);
return `${p1}<div data-mx-maths="${p2e}">\n\n</div>\n\n`;
});
md = md.replace(RegExp(inlinePattern, "gms"), function(m, p1, p2) {
const p2e = AllHtmlEntities.encode(p2);
return `${p1}<span data-mx-maths="${p2e}"></span>`;
}); });
// make sure div tags always start on a new line, otherwise it will confuse // make sure div tags always start on a new line, otherwise it will confuse