fix(formats): ignore block and inline HTML comments in markdown import (#2225)

This commit is contained in:
divyanshu2074
2026-10-25 10:31:01 -04:00
committed by GitHub
parent 0d2d1776dd
commit 1b0faddfa8
+32 -2
View File
@@ -5,7 +5,7 @@
//! bottom-border paragraph), bullet and ordered lists (nested by indentation), GFM pipe tables,
//! and inlines: emphasis/strong (the CommonMark delimiter algorithm), `~~strike~~`, code spans,
//! inline links, autolinks, images (`data:` URIs become pictures, others their alt text),
//! backslash escapes, entities, `<br>` and `<a id>` anchors.
//! backslash escapes, entities, HTML comments (`<!-- ... -->`), `<br>` and `<a id>` anchors.
//!
//! Export writes the same constructs; pictures become `![alt](media-name)` placeholders.
@@ -351,6 +351,7 @@ fn interrupts(l: &str) -> bool {
|| thematic_break(t)
|| fence(t).is_some()
|| t.starts_with('>')
|| t.starts_with("<!--")
|| list_marker(t).is_some_and(|m| (!m.ordered || m.start == 1) && !is_blank(t.get(m.len..).unwrap_or("")))
}
@@ -360,7 +361,11 @@ fn flush_para(lines: &mut Vec<String>, out: &mut Vec<FBlock>, depth: usize, refs
}
let text = join_lines(lines);
lines.clear();
let p = Para { inlines: parse_inlines(&text, &Fmt::default(), depth, refs), ..Default::default() };
let inlines = parse_inlines(&text, &Fmt::default(), depth, refs);
if inlines.is_empty() {
return;
}
let p = Para { inlines, ..Default::default() };
out.push(FBlock::Para(p));
}
@@ -470,6 +475,16 @@ fn parse_blocks(lines: &[String], depth: usize, level: u8, refs: &Refs) -> Vec<F
}
continue;
}
if t.starts_with("<!--") {
flush_para(&mut para, &mut out, depth, refs);
while let Some(l) = lines.get(i) {
i += 1;
if l.contains("-->") {
break;
}
}
continue;
}
if t.starts_with('>') {
flush_para(&mut para, &mut out, depth, refs);
let mut inner: Vec<String> = Vec::new();
@@ -1016,6 +1031,12 @@ fn tokenize(s: &str, base: &Fmt, depth: usize, refs: &Refs) -> Vec<Node> {
}
}
b'<' => {
if let Some(pos) = s.get(i..).and_then(|r| r.strip_prefix("<!--")).and_then(|r| r.find("-->")) {
flush!();
i += 4 + pos + 3;
text_start = i;
continue;
}
let rest = s.get(i + 1..).unwrap_or("");
let end = within(rest, MAX_TAG).find('>');
let inner = end.and_then(|e| rest.get(..e)).unwrap_or("");
@@ -2052,4 +2073,13 @@ mod tests {
assert_eq!(p3.text(), "one item");
assert!(p3.list.unwrap().ordered);
}
#[test]
fn html_comments_are_ignored_in_blocks_and_inlines() {
let md = "<!-- block comment -->\n\nHello <!-- inline comment -->world!\n\n<!--\nmultiline\ncomment\n-->\n\nAfter comment.";
let flow = parse(md);
assert_eq!(flow.blocks.len(), 2);
let texts: Vec<String> = flow.blocks.iter().filter_map(|b| if let FBlock::Para(p) = b { Some(p.text()) } else { None }).collect();
assert_eq!(texts, ["Hello world!", "After comment."]);
}
}