markdown_preview: Fix alt text causing mismatched highlighting runs (#40374)

Lukas Wirth created

Fixes ZED-277

Release Notes:

- Fixed alt text in markdown preview creating inconsistent highlighting

Change summary

crates/markdown_preview/src/markdown_parser.rs | 52 +++++++++++++++----
1 file changed, 40 insertions(+), 12 deletions(-)

Detailed changes

crates/markdown_preview/src/markdown_parser.rs 🔗

@@ -9,7 +9,9 @@ use html5ever::{ParseOpts, local_name, parse_document, tendril::TendrilSink};
 use language::LanguageRegistry;
 use markup5ever_rcdom::RcDom;
 use pulldown_cmark::{Alignment, Event, Options, Parser, Tag, TagEnd};
-use std::{cell::RefCell, collections::HashMap, ops::Range, path::PathBuf, rc::Rc, sync::Arc, vec};
+use std::{
+    cell::RefCell, collections::HashMap, mem, ops::Range, path::PathBuf, rc::Rc, sync::Arc, vec,
+};
 
 pub async fn parse_markdown(
     markdown_input: &str,
@@ -407,6 +409,9 @@ impl<'a> MarkdownParser<'a> {
                         if let Some(mut image) = image.take() {
                             if !text.is_empty() {
                                 image.set_alt_text(std::mem::take(&mut text).into());
+                                mem::take(&mut highlights);
+                                mem::take(&mut region_ranges);
+                                mem::take(&mut regions);
                             }
                             markdown_text_like.push(MarkdownParagraphChunk::Image(image));
                         }
@@ -1275,17 +1280,40 @@ mod tests {
             panic!("Expected a paragraph");
         };
         assert_eq!(
-            paragraph[0],
-            MarkdownParagraphChunk::Image(Image {
-                source_range: 0..111,
-                link: Link::Web {
-                    url: "https://blog.logrocket.com/wp-content/uploads/2024/04/exploring-zed-open-source-code-editor-rust-2.png".to_string(),
-                },
-                alt_text: Some("test".into()),
-                height: None,
-                width: None,
-            },)
-        );
+                paragraph[0],
+                MarkdownParagraphChunk::Image(Image {
+                    source_range: 0..111,
+                    link: Link::Web {
+                        url: "https://blog.logrocket.com/wp-content/uploads/2024/04/exploring-zed-open-source-code-editor-rust-2.png".to_string(),
+                    },
+                    alt_text: Some("test".into()),
+                    height: None,
+                    width: None,
+                },)
+            );
+    }
+
+    #[gpui::test]
+    async fn test_image_alt_text() {
+        let parsed = parse("[![Zed](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/zed-industries/zed/main/assets/badge/v0.json)](https://zed.dev)\n ").await;
+
+        let paragraph = if let ParsedMarkdownElement::Paragraph(text) = &parsed.children[0] {
+            text
+        } else {
+            panic!("Expected a paragraph");
+        };
+        assert_eq!(
+                    paragraph[0],
+                    MarkdownParagraphChunk::Image(Image {
+                        source_range: 0..142,
+                        link: Link::Web {
+                            url: "https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/zed-industries/zed/main/assets/badge/v0.json".to_string(),
+                        },
+                        alt_text: Some("Zed".into()),
+                        height: None,
+                        width: None,
+                    },)
+                );
     }
 
     #[gpui::test]