markdown: Add support for HTML block quotes (#39755)

This PR adds support for HTML block quotes, that also allows you to have
nested variant of it.

<img width="1441" height="804" alt="Screenshot 2025-10-08 at 10 25 57"
src="https://github.com/user-attachments/assets/4e1da766-fb54-4e87-8654-1ea14330bc97"
/>

Code example used in screenshot:

```html
<blockquote>
    <p>
        Words can be like X-rays, if you use them properly—they’ll go through
        anything. You read and you’re pierced.
    </p>
    <blockquote>
        <p>
            lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.
        </p>
    </blockquote>
</blockquote>
```

Release Notes:

- Markdown: Added support for `HTML` block quotes
This commit is contained in:
Remco Smits 2025-10-08 11:33:42 +02:00 committed by GitHub
parent bbf4bfad6f
commit 4152942a8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -880,6 +880,10 @@ impl<'a> MarkdownParser<'a> {
contents: paragraph,
}));
}
} else if local_name!("blockquote") == name.local {
if let Some(blockquote) = self.extract_html_blockquote(node, source_range) {
elements.push(ParsedMarkdownElement::BlockQuote(blockquote));
}
} else if local_name!("table") == name.local {
if let Some(table) = self.extract_html_table(node, source_range) {
elements.push(ParsedMarkdownElement::Table(table));
@ -1002,6 +1006,24 @@ impl<'a> MarkdownParser<'a> {
Some(image)
}
fn extract_html_blockquote(
&self,
node: &Rc<markup5ever_rcdom::Node>,
source_range: Range<usize>,
) -> Option<ParsedMarkdownBlockQuote> {
let mut children = Vec::new();
self.consume_children(source_range.clone(), node, &mut children);
if children.is_empty() {
None
} else {
Some(ParsedMarkdownBlockQuote {
children,
source_range,
})
}
}
fn extract_html_table(
&self,
node: &Rc<markup5ever_rcdom::Node>,
@ -1410,6 +1432,61 @@ mod tests {
);
}
#[gpui::test]
async fn test_html_block_quote() {
let parsed = parse(
"<blockquote>
<p>some description</p>
</blockquote>",
)
.await;
assert_eq!(
ParsedMarkdown {
children: vec![block_quote(
vec![ParsedMarkdownElement::Paragraph(text(
"some description",
0..76
))],
0..76,
)]
},
parsed
);
}
#[gpui::test]
async fn test_html_nested_block_quote() {
let parsed = parse(
"<blockquote>
<p>some description</p>
<blockquote>
<p>second description</p>
</blockquote>
</blockquote>",
)
.await;
assert_eq!(
ParsedMarkdown {
children: vec![block_quote(
vec![
ParsedMarkdownElement::Paragraph(text("some description", 0..173)),
block_quote(
vec![ParsedMarkdownElement::Paragraph(text(
"second description",
0..173
))],
0..173,
)
],
0..173,
)]
},
parsed
);
}
#[gpui::test]
async fn test_html_table() {
let parsed = parse(