FIX: support [code] in blockquotes (#26182)

> [code]
> line1
> line2
> [/code]

would render as

| line1
| > line2

instead of the correct

| line1
| line2

That was due to the `bbcode-block` code using a `slice` to get the content of a block and not taking into account it being nested in a quote block for example.

The fix was to get the content using the `getLines` utils method.

Context: https://meta.discourse.org/t/markdown-bbcode-code-quote-bug/299047
This commit is contained in:
Régis Hanol 2024-03-14 19:31:22 +01:00 committed by GitHub
parent 679a773411
commit 5213bba672
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 27 deletions

View File

@ -1,9 +1,8 @@
let isWhiteSpace; let isWhiteSpace;
function trailingSpaceOnly(src, start, max) { function trailingSpaceOnly(src, start, max) {
let i; for (let i = start; i < max; i++) {
for (i = start; i < max; i++) { const code = src.charCodeAt(i);
let code = src.charCodeAt(i);
if (code === 0x0a) { if (code === 0x0a) {
return true; return true;
} }
@ -35,10 +34,7 @@ export function parseBBCodeTag(src, start, max, multiline) {
} }
for (i = start + 1; i < max; i++) { for (i = start + 1; i < max; i++) {
let letter = src[i]; if (!/[a-z]/i.test(src[i])) {
if (
!((letter >= "a" && letter <= "z") || (letter >= "A" && letter <= "Z"))
) {
break; break;
} }
} }
@ -63,9 +59,7 @@ export function parseBBCodeTag(src, start, max, multiline) {
} }
for (; i < max; i++) { for (; i < max; i++) {
let letter = src[i]; if (src[i] === "]") {
if (letter === "]") {
closed = true; closed = true;
break; break;
} }
@ -90,9 +84,7 @@ export function parseBBCodeTag(src, start, max, multiline) {
val = match[1] || match[5]; val = match[1] || match[5];
if (val) { if (val) {
val = val.trim(); attrs[key] = val.trim().replace(/^["'“”](.*)["'“”]$/, "$1");
val = val.replace(/^["'“”](.*)["'“”]$/, "$1");
attrs[key] = val;
} }
} }
} }
@ -227,7 +219,6 @@ function applyBBCode(state, startLine, endLine, silent, md) {
nextLine = startLine; nextLine = startLine;
// We might have a single inline bbcode // We might have a single inline bbcode
let closeTag = findInlineCloseTag(state, info, start + info.length, max); let closeTag = findInlineCloseTag(state, info, start + info.length, max);
if (!closeTag) { if (!closeTag) {
@ -256,10 +247,7 @@ function applyBBCode(state, startLine, endLine, silent, md) {
if (startLine === nextLine) { if (startLine === nextLine) {
content = state.src.slice(start + info.length, closeTag.start); content = state.src.slice(start + info.length, closeTag.start);
} else { } else {
content = state.src.slice( content = state.getLines(startLine + 1, nextLine, 0, false);
state.bMarks[startLine + 1],
state.eMarks[nextLine - 1]
);
} }
if (!rule.replace.call(this, state, info, content)) { if (!rule.replace.call(this, state, info, content)) {
@ -343,30 +331,27 @@ function applyBBCode(state, startLine, endLine, silent, md) {
export function setup(helper) { export function setup(helper) {
helper.registerPlugin((md) => { helper.registerPlugin((md) => {
const ruler = md.block.bbcode.ruler; isWhiteSpace = md.utils.isWhiteSpace;
ruler.push("excerpt", { md.block.bbcode.ruler.push("excerpt", {
tag: "excerpt", tag: "excerpt",
wrap: "div.excerpt", wrap: "div.excerpt",
}); });
ruler.push("code", { md.block.bbcode.ruler.push("code", {
tag: "code", tag: "code",
replace(state, tagInfo, content) { replace(state, tagInfo, content) {
let token; let token = state.push("fence", "code", 0);
token = state.push("fence", "code", 0);
token.content = content; token.content = content;
return true; return true;
}, },
}); });
isWhiteSpace = md.utils.isWhiteSpace;
md.block.ruler.after( md.block.ruler.after(
"fence", "fence",
"bbcode", "bbcode",
(state, startLine, endLine, silent) => { (state, startLine, endLine, silent) =>
return applyBBCode(state, startLine, endLine, silent, md); applyBBCode(state, startLine, endLine, silent, md),
},
{ alt: ["paragraph", "reference", "blockquote", "list"] } { alt: ["paragraph", "reference", "blockquote", "list"] }
); );
}); });

View File

@ -1212,6 +1212,11 @@ eviltrout</p>
'<pre><code class="lang-auto"> s</code></pre>', '<pre><code class="lang-auto"> s</code></pre>',
"it doesn't trim leading whitespace" "it doesn't trim leading whitespace"
); );
assert.cooked(
"> [code]\n> line 1\n> line 2\n> line 3\n> [/code]",
'<blockquote>\n<pre><code class="lang-auto">line 1\nline 2\nline 3</code></pre>\n</blockquote>',
"supports quoting a whole [code] block"
);
}); });
test("tags with arguments", function (assert) { test("tags with arguments", function (assert) {