From 46246edb9c33fbb3493b164f7af5bf3cb23c8004 Mon Sep 17 00:00:00 2001 From: Orson Peters Date: Mon, 16 Jan 2023 22:03:40 +0100 Subject: [PATCH] Made backslash escape starting delimiters. --- contrib/auto-render/splitAtDelimiters.js | 11 ++++++++++- contrib/auto-render/test/auto-render-spec.js | 18 ++++++++++++++++++ docs/autorender.md | 6 ++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/contrib/auto-render/splitAtDelimiters.js b/contrib/auto-render/splitAtDelimiters.js index 21b59030a5..1411ebbf50 100644 --- a/contrib/auto-render/splitAtDelimiters.js +++ b/contrib/auto-render/splitAtDelimiters.js @@ -46,15 +46,24 @@ const splitAtDelimiters = function(text, delimiters) { if (index === -1) { break; } + + const escaped = index > 0 && text[index - 1] === "\\"; if (index > 0) { data.push({ type: "text", - data: text.slice(0, index), + data: text.slice(0, index - (escaped ? 1 : 0)), }); text = text.slice(index); // now text starts with delimiter } // ... so this always succeeds: const i = delimiters.findIndex((delim) => text.startsWith(delim.left)); + + if (escaped) { + data[data.length - 1].data += text.slice(0, delimiters[i].left.length); + text = text.slice(delimiters[i].left.length); + continue; + } + index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length); if (index === -1) { break; diff --git a/contrib/auto-render/test/auto-render-spec.js b/contrib/auto-render/test/auto-render-spec.js index accb326195..c51fcc1b87 100644 --- a/contrib/auto-render/test/auto-render-spec.js +++ b/contrib/auto-render/test/auto-render-spec.js @@ -305,6 +305,24 @@ describe("A delimiter splitter", function() { rawData: "$$boo$$", display: true}, ]); }); + + it("correctly escapes start symbols", function() { + expect(splitAtDelimiters("test \\$40 for $foobar$$$bla$$\\$$boo", + [ + {left:"$$", right:"$$", display:true}, + {left:"$", right:"$", display:false}, + ])).toEqual( + [ + {type: "text", data: "test $"}, + {type: "text", data: "40 for "}, + {type: "math", data: "foobar", + rawData: "$foobar$", display: false}, + {type: "math", data: "bla", + rawData: "$$bla$$", display: true}, + {type: "text", data: "$$"}, + {type: "text", data: "boo"}, + ]); + }); }); describe("Pre-process callback", function() { diff --git a/docs/autorender.md b/docs/autorender.md index 00b1a9a7bf..78ea412057 100644 --- a/docs/autorender.md +++ b/docs/autorender.md @@ -115,6 +115,12 @@ in addition to five auto-render-specific keys: ] ``` + Note that if a left delimiter is preceded by a backslash (`\`), the backslash + is stripped and the delimiter is ignored (math mode is not entered). So `\$40 + is greater than \$30` gets transformed to `$40 is greater than $30`, if `$` is + configured to be a left delimiter. If it is not, the backslashes are left + untouched. + - `ignoredTags`: This is a list of DOM node types to ignore when recursing through. The default value is `["script", "noscript", "style", "textarea", "pre", "code", "option"]`.