Skip to content

Commit a20e310

Browse files
committed
feat: Decouple greentext handling from blockquote parsing
1 parent 15c22fa commit a20e310

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

src/parser/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,11 @@ where
432432
fn parse_block_quote_prefix(&mut self, line: &str) -> bool {
433433
let bytes = line.as_bytes();
434434
let indent = self.indent;
435-
if indent <= 3 && bytes.get(self.first_nonspace) == Some(&b'>') && !self.is_greentext(line)
436-
{
435+
436+
// When already inside a blockquote, always treat `>` as a blockquote marker,
437+
// even if it's a lone `>` (which represents a blank line in the blockquote).
438+
// This allows multi-paragraph blockquotes without requiring a space after `>`.
439+
if indent <= 3 && bytes.get(self.first_nonspace) == Some(&b'>') {
437440
self.advance_offset(line, indent + 1, true);
438441

439442
if byte_matches(bytes, self.offset, strings::is_space_or_tab) {

src/tests/greentext.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn separate_quotes_on_line_end() {
1919
html_opts!(
2020
[extension.greentext],
2121
"> 1\n>\n> 2",
22-
"<blockquote>\n<p>1</p>\n</blockquote>\n<p>&gt;</p>\n<blockquote>\n<p>2</p>\n</blockquote>\n"
22+
"<blockquote>\n<p>1</p>\n<p>2</p>\n</blockquote>\n"
2323
);
2424
}
2525

@@ -40,3 +40,73 @@ fn unnest_quotes_on_line_end_commonmark() {
4040
"<blockquote>\n<p>1</p>\n<blockquote>\n<p>2</p>\n</blockquote>\n<p>1</p>\n</blockquote>\n"
4141
);
4242
}
43+
44+
#[test]
45+
fn greentext_disabled_blockquote() {
46+
assert_ast_match!(
47+
[],
48+
"> First line.\n> The second sentence in the first line.\n>\n> Second line.",
49+
(document (1:1-4:14) [
50+
(block_quote (1:1-4:14) [
51+
(paragraph (1:3-2:40) [
52+
(text (1:3-1:13) "First line.")
53+
(softbreak (1:14-1:14))
54+
(text (2:3-2:40) "The second sentence in the first line.")
55+
])
56+
(paragraph (4:3-4:14) [
57+
(text (4:3-4:14) "Second line.")
58+
])
59+
])
60+
])
61+
);
62+
}
63+
64+
#[test]
65+
fn greentext_enabled_blockquote() {
66+
assert_ast_match!(
67+
[extension.greentext],
68+
"> First line.\n> The second sentence in the first line.\n>\n> Second line.",
69+
(document (1:1-4:14) [
70+
(block_quote (1:1-4:14) [
71+
(paragraph (1:3-2:40) [
72+
(text (1:3-1:13) "First line.")
73+
(softbreak (1:14-1:14))
74+
(text (2:3-2:40) "The second sentence in the first line.")
75+
])
76+
(paragraph (4:3-4:14) [
77+
(text (4:3-4:14) "Second line.")
78+
])
79+
])
80+
])
81+
);
82+
}
83+
84+
#[test]
85+
fn greentext_disabled_blockquote_alerts() {
86+
html_opts!(
87+
[extension.alerts],
88+
"> [!Note]\n> This is the first line.\n>\n> Second line.",
89+
concat!(
90+
"<div class=\"markdown-alert markdown-alert-note\">\n",
91+
"<p class=\"markdown-alert-title\">Note</p>\n",
92+
"<p>This is the first line.</p>\n",
93+
"<p>Second line.</p>\n",
94+
"</div>\n",
95+
),
96+
);
97+
}
98+
99+
#[test]
100+
fn greentext_enabled_blockquote_alerts() {
101+
html_opts!(
102+
[extension.greentext, extension.alerts],
103+
"> [!Note]\n> This is the first line.\n>\n> Second line.",
104+
concat!(
105+
"<div class=\"markdown-alert markdown-alert-note\">\n",
106+
"<p class=\"markdown-alert-title\">Note</p>\n",
107+
"<p>This is the first line.</p>\n",
108+
"<p>Second line.</p>\n",
109+
"</div>\n",
110+
),
111+
);
112+
}

0 commit comments

Comments
 (0)