diff --git a/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift b/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift index 06bd9e1c..ae2b20dd 100644 --- a/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift +++ b/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift @@ -13,4 +13,10 @@ public protocol InlineImageProvider { /// - url: The URL of the image to display. /// - label: The accessibility label associated with the image. func image(with url: URL, label: String) async throws -> Image + + func placeholder() -> Text? +} + +extension InlineImageProvider { + public func placeholder() -> Text? { nil } } diff --git a/Sources/MarkdownUI/Renderer/TextInlineRenderer.swift b/Sources/MarkdownUI/Renderer/TextInlineRenderer.swift index e3f86673..791390ff 100644 --- a/Sources/MarkdownUI/Renderer/TextInlineRenderer.swift +++ b/Sources/MarkdownUI/Renderer/TextInlineRenderer.swift @@ -6,14 +6,16 @@ extension Sequence where Element == InlineNode { textStyles: InlineTextStyles, images: [String: Image], softBreakMode: SoftBreak.Mode, - attributes: AttributeContainer + attributes: AttributeContainer, + placeholderImage: Text? ) -> Text { var renderer = TextInlineRenderer( baseURL: baseURL, textStyles: textStyles, images: images, softBreakMode: softBreakMode, - attributes: attributes + attributes: attributes, + placeholderImage: placeholderImage ) renderer.render(self) return renderer.result @@ -28,6 +30,7 @@ private struct TextInlineRenderer { private let images: [String: Image] private let softBreakMode: SoftBreak.Mode private let attributes: AttributeContainer + private let placeholderImage: Text? private var shouldSkipNextWhitespace = false init( @@ -35,13 +38,15 @@ private struct TextInlineRenderer { textStyles: InlineTextStyles, images: [String: Image], softBreakMode: SoftBreak.Mode, - attributes: AttributeContainer + attributes: AttributeContainer, + placeholderImage: Text? ) { self.baseURL = baseURL self.textStyles = textStyles self.images = images self.softBreakMode = softBreakMode self.attributes = attributes + self.placeholderImage = placeholderImage } mutating func render(_ inlines: S) where S.Element == InlineNode { @@ -103,6 +108,8 @@ private struct TextInlineRenderer { private mutating func renderImage(_ source: String) { if let image = self.images[source] { self.result = self.result + Text(image) + } else if let placeholderImage { + self.result = self.result + placeholderImage } } diff --git a/Sources/MarkdownUI/Views/Inlines/InlineText.swift b/Sources/MarkdownUI/Views/Inlines/InlineText.swift index 9da39404..269f4494 100644 --- a/Sources/MarkdownUI/Views/Inlines/InlineText.swift +++ b/Sources/MarkdownUI/Views/Inlines/InlineText.swift @@ -28,7 +28,8 @@ struct InlineText: View { ), images: self.inlineImages, softBreakMode: self.softBreakMode, - attributes: attributes + attributes: attributes, + placeholderImage: self.inlineImageProvider.placeholder() ) } .task(id: self.inlines) {