mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-11-02 21:14:27 +00:00
Fix regex for code block end detection in wikiparser (#9739)
* Fix regex for code block end detection in wikiparser * Anchor the codeblock end fence to its own line Close an empty code block without consuming the tiddler, while a fence only counts when it stands alone on its line. * Match the end fence with (^|\r?\n) so the empty block case closes at the line start and a code line ending in ``` stays inside the block * Add test-codeblock-parser.js covering empty blocks with language and CRLF, delimiter newline handling, mid-line fences and a missing fence
This commit is contained in:
1 parent
855dc2fbb9
commit
97e27d0dad
3 files changed
+83
-1
No files matched your search
@@ -25,7 +25,7 @@ exports.init = function(parser) {
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
var reEnd = /(\r?\n```$)/mg;
|
||||
var reEnd = /(^|\r?\n)```$/mg;
|
||||
var languageStart = this.parser.pos + 3,
|
||||
languageEnd = languageStart + this.match[1].length;
|
||||
// Move past the match
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*\
|
||||
title: test-codeblock-parser.js
|
||||
type: application/javascript
|
||||
tags: [[$:/tags/test-spec]]
|
||||
|
||||
Tests the codeblock wikitext rule (#9047): an empty code block must parse
|
||||
cleanly, and a closing fence only counts when it stands alone on its line.
|
||||
|
||||
\*/
|
||||
"use strict";
|
||||
|
||||
describe("codeblock parser tests (#9047)", function() {
|
||||
|
||||
var wiki = new $tw.Wiki();
|
||||
|
||||
function parse(text) {
|
||||
return wiki.parseText("text/vnd.tiddlywiki",text).tree;
|
||||
}
|
||||
|
||||
it("parses an empty code block with a language", function() {
|
||||
// Browser console: $tw.wiki.parseText("text/vnd.tiddlywiki","```bash\n```").tree
|
||||
// Expected: one codeblock node, code "", language "bash".
|
||||
var tree = parse("```bash\n```");
|
||||
expect(tree.length).toBe(1);
|
||||
expect(tree[0].type).toBe("codeblock");
|
||||
expect(tree[0].attributes.code.value).toBe("");
|
||||
expect(tree[0].attributes.language.value).toBe("bash");
|
||||
});
|
||||
|
||||
it("handles CRLF line endings around both fences", function() {
|
||||
// Browser console: $tw.wiki.parseText("text/vnd.tiddlywiki","```bash\r\nfoo\r\n```").tree
|
||||
// Expected: one codeblock node with code "foo"; neither the CRLF after the
|
||||
// opening fence nor the one before the closing fence is part of the code.
|
||||
var tree = parse("```bash\r\nfoo\r\n```");
|
||||
expect(tree.length).toBe(1);
|
||||
expect(tree[0].type).toBe("codeblock");
|
||||
expect(tree[0].attributes.code.value).toBe("foo");
|
||||
});
|
||||
|
||||
it("keeps the content of a block and drops the delimiting newlines", function() {
|
||||
// Browser console: $tw.wiki.parseText("text/vnd.tiddlywiki","```\nfoo\n```").tree
|
||||
// Expected: one codeblock node with code "foo"; the newlines around the
|
||||
// delimiter lines are not part of the code.
|
||||
var tree = parse("```\nfoo\n```");
|
||||
expect(tree.length).toBe(1);
|
||||
expect(tree[0].type).toBe("codeblock");
|
||||
expect(tree[0].attributes.code.value).toBe("foo");
|
||||
});
|
||||
|
||||
it("only closes the block when the fence stands alone on its line", function() {
|
||||
// A content line ending in ``` is code, not a closing fence, e.g. nested
|
||||
// markdown fences or template literals quoted inside a code block.
|
||||
// Browser console: $tw.wiki.parseText("text/vnd.tiddlywiki","```\nabc```\ndef\n```").tree
|
||||
// Expected: one codeblock containing "abc```\ndef"; nothing leaks out as wikitext.
|
||||
var tree = parse("```\nabc```\ndef\n```");
|
||||
expect(tree.length).toBe(1);
|
||||
expect(tree[0].type).toBe("codeblock");
|
||||
expect(tree[0].attributes.code.value).toBe("abc```\ndef");
|
||||
});
|
||||
|
||||
it("swallows the rest of the tiddler when no closing fence exists", function() {
|
||||
// Browser console: $tw.wiki.parseText("text/vnd.tiddlywiki","```bash\nfoo").tree
|
||||
// Expected: one codeblock node with code "foo", extending to the end of the text.
|
||||
var tree = parse("```bash\nfoo");
|
||||
expect(tree.length).toBe(1);
|
||||
expect(tree[0].type).toBe("codeblock");
|
||||
expect(tree[0].attributes.code.value).toBe("foo");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
change-category: hackability
|
||||
change-type: bugfix
|
||||
created: 20260711181412000
|
||||
description: Empty code blocks parse cleanly; a closing fence only counts alone on its line
|
||||
github-contributors: pmario
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9739
|
||||
release: 5.5.0
|
||||
tags: $:/tags/ChangeNote
|
||||
title: $:/changenotes/5.5.0/#9739
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
* An empty code block such as ```` ```bash ```` directly followed by the closing fence parses as an empty codeblock instead of swallowing the rest of the tiddler (fixes [[Issue #9047|https://github.com/TiddlyWiki/TiddlyWiki5/issues/9047]])
|
||||
* A closing fence only ends the block when it stands alone on its line, so code lines ending in three backticks stay inside the block
|
||||
Reference in new issue
Block a user