Skip to content

Commit 894408a

Browse files
committed
Correct processing of backtick code block on blockquote (fix Issue#2969)
This patch makes the filter "backtick_code_block" to remove '>' characters at the head of each line. How many '>' characters should be removed? It is decided by the number of '>' characters at the first line. This patch works well even if there are too few '>' characters at the head of a line. (Simply removes all '>' characters less than or equal to the number of '>' characters at the first lines.)
1 parent 79bdc95 commit 894408a

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

lib/plugins/filter/before_post_render/backtick_code_block.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const stripIndent = require('strip-indent');
44
const { highlight } = require('hexo-util');
55

6-
const rBacktick = /(\s*)(`{3,}|~{3,}) *(.*) *\n([\s\S]+?)\s*\2(\n+|$)/g;
6+
const rBacktick = /^((?:\s*>){0,3}\s*)(`{3,}|~{3,}) *(.*) *\n([\s\S]+?)\s*\2(\n+|$)/gm;
77
const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/;
88
const rLangCaption = /([^\s]+)\s*(.+)?/;
99

@@ -50,6 +50,14 @@ function backtickCodeBlock(data) {
5050
}
5151
}
5252

53+
const endOfStart = start.split('\n').pop();
54+
if (endOfStart && endOfStart.includes('>')) {
55+
const depth = endOfStart.split('>').length - 1;
56+
const regexp = new RegExp(`^(\\s*>){0,${depth}}\\s`, 'mg');
57+
const paddingOnEnd = ' '; // complement uncaptured whitespaces at last line
58+
content = (content + paddingOnEnd).replace(regexp, '').replace(/\n$/, '');
59+
}
60+
5361
content = highlight(stripIndent(content), options)
5462
.replace(/{/g, '{')
5563
.replace(/}/g, '}');

test/scripts/hexo/post.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,4 +739,67 @@ describe('Post', () => {
739739
].join('\n'));
740740
});
741741
});
742+
743+
// test for Issue #2969
744+
it('render() - backtick cocde block in blockquote', () => {
745+
const code = 'alert("Hello world")';
746+
const highlighted = util.highlight(code);
747+
const quotedContent = [
748+
'This is a code-block',
749+
'',
750+
'```',
751+
code,
752+
'```'
753+
];
754+
755+
const content = [
756+
'Hello',
757+
'',
758+
...quotedContent.map(s => '> ' + s)
759+
].join('\n');
760+
761+
return post.render(null, {
762+
content,
763+
engine: 'markdown'
764+
}).then(data => {
765+
data.content.trim().should.eql([
766+
'<p>Hello</p>',
767+
'<blockquote>',
768+
'<p>This is a code-block</p>',
769+
highlighted + '</blockquote>'
770+
].join('\n'));
771+
});
772+
});
773+
774+
// test derived from Issue #2969
775+
it('render() - "lang=dos" backtick cocde block in blockquote', () => {
776+
const code = '> dir';
777+
const highlighted = util.highlight(code);
778+
const quotedContent = [
779+
'This is a code-block',
780+
'',
781+
'```',
782+
code,
783+
'```'
784+
];
785+
786+
const content = [
787+
'Hello',
788+
'',
789+
...quotedContent.map(s => '> ' + s)
790+
].join('\n');
791+
792+
return post.render(null, {
793+
content,
794+
engine: 'markdown'
795+
}).then(data => {
796+
data.content.trim().should.eql([
797+
'<p>Hello</p>',
798+
'<blockquote>',
799+
'<p>This is a code-block</p>',
800+
highlighted + '</blockquote>'
801+
].join('\n'));
802+
});
803+
});
804+
742805
});

0 commit comments

Comments
 (0)