markdown: Ignore html comments (#28318)

Fernando Tagawa created

Closes #28300

| Before | After |
| ------ | ----- |
|
![Screenshot_20250408_073355](https://github.com/user-attachments/assets/50dcb56d-bc70-4329-94cb-5b848f265c97)
|
![Screenshot_20250408_073322](https://github.com/user-attachments/assets/ba5c519a-bb34-4724-9c14-3278c6c09afd)
|

Release Notes:

- N/A

Change summary

crates/markdown/src/markdown.rs | 32 +++++++++++++++++++++++++++++++-
crates/markdown/src/parser.rs   | 22 ++++++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)

Detailed changes

crates/markdown/src/markdown.rs 🔗

@@ -1050,7 +1050,18 @@ impl Element for MarkdownElement {
                     builder.pop_text_style();
                 }
                 MarkdownEvent::Html => {
-                    builder.push_text(&parsed_markdown.source[range.clone()], range.clone());
+                    let html = &parsed_markdown.source[range.clone()];
+                    if html.starts_with("<!--") {
+                        builder.html_comment = true;
+                    }
+                    if html.trim_end().ends_with("-->") {
+                        builder.html_comment = false;
+                        continue;
+                    }
+                    if builder.html_comment {
+                        continue;
+                    }
+                    builder.push_text(html, range.clone());
                 }
                 MarkdownEvent::InlineHtml => {
                     builder.push_text(&parsed_markdown.source[range.clone()], range.clone());
@@ -1267,6 +1278,7 @@ struct MarkdownElementBuilder {
     pending_line: PendingLine,
     rendered_links: Vec<RenderedLink>,
     current_source_index: usize,
+    html_comment: bool,
     base_text_style: TextStyle,
     text_style_stack: Vec<TextStyleRefinement>,
     code_block_stack: Vec<Option<Arc<Language>>>,
@@ -1294,6 +1306,7 @@ impl MarkdownElementBuilder {
             pending_line: PendingLine::default(),
             rendered_links: Vec::new(),
             current_source_index: 0,
+            html_comment: false,
             base_text_style,
             text_style_stack: Vec::new(),
             code_block_stack: Vec::new(),
@@ -1707,6 +1720,23 @@ mod tests {
             &render_markdown("\"hey\"", cx),
             vec![vec![(0, 0), (3, 1), (4, 2), (5, 3), (6, 4), (9, 5)]],
         );
+
+        // HTML Comments are ignored
+        assert_mappings(
+            &render_markdown(
+                "<!--\nrdoc-file=string.c\n- str.intern   -> symbol\n- str.to_sym   -> symbol\n-->\nReturns",
+                cx,
+            ),
+            vec![vec![
+                (0, 78),
+                (1, 79),
+                (2, 80),
+                (3, 81),
+                (4, 82),
+                (5, 83),
+                (6, 84),
+            ]],
+        );
     }
 
     fn render_markdown(markdown: &str, cx: &mut TestAppContext) -> RenderedText {

crates/markdown/src/parser.rs 🔗

@@ -537,6 +537,28 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_html_comments() {
+        assert_eq!(
+            parse_markdown("  <!--\nrdoc-file=string.c\n-->\nReturns"),
+            (
+                vec![
+                    (2..30, Start(HtmlBlock)),
+                    (2..2, SubstitutedText("  ".into())),
+                    (2..7, Html),
+                    (7..26, Html),
+                    (26..30, Html),
+                    (2..30, End(MarkdownTagEnd::HtmlBlock)),
+                    (30..37, Start(Paragraph)),
+                    (30..37, Text),
+                    (30..37, End(MarkdownTagEnd::Paragraph))
+                ],
+                HashSet::new(),
+                HashSet::new()
+            )
+        )
+    }
+
     #[test]
     fn test_plain_urls_and_escaped_text() {
         assert_eq!(