From 182fa711259a15e0adf1dd3ffed00338ab62874c Mon Sep 17 00:00:00 2001 From: shainaraskas Date: Tue, 3 Nov 2026 17:12:21 -0500 Subject: [PATCH] Use the Markdown title for inline image title attributes The inline image renderer wrote the title attribute from the alt text and never read the Markdown title, so an explicit title was always dropped. Use the Markdown title when provided and fall back to the alt text. Fixes #3045 Co-Authored-By: Claude Sonnet 5.5 --- docs/syntax/images.md | 4 ++-- .../Myst/Renderers/HtmxLinkInlineRenderer.cs | 12 +++++++++--- tests/Elastic.Authoring.Tests/Inline/InlineImages.cs | 8 ++++---- .../Elastic.Markdown.Tests/Inline/InlineImageTest.cs | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/syntax/images.md b/docs/syntax/images.md index 63f765436c..7185f5d10e 100644 --- a/docs/syntax/images.md +++ b/docs/syntax/images.md @@ -93,7 +93,7 @@ Titles are optional making this the minimal syntax required: ![Elasticsearch](/syntax/images/observability.png) ``` -For inline images, the alt text always overrides any title specified in the Markdown. This ensures consistent accessibility where both the `alt` and `title` attributes contain the same descriptive text. +For inline images, the Markdown title is used as the `title` attribute, and the alt text is used as the `alt` attribute. If you don't specify a title, the alt text is used for both attributes. ```markdown ![Elasticsearch](/syntax/images/observability.png "Different title") @@ -110,7 +110,7 @@ Image sizing is specified through the title argument. You can specify just the s ![alt](img.png "=W") ``` -In this case, the alt text will be used as both the `alt` and `title` attributes, and the size parameters will be applied. +In this case, the alt text is used as both the `alt` and `title` attributes, and the size parameters are applied. `W` and `H` can be either an absolute number in pixels or a number followed by `%` to indicate relative sizing. diff --git a/src/Elastic.Markdown/Myst/Renderers/HtmxLinkInlineRenderer.cs b/src/Elastic.Markdown/Myst/Renderers/HtmxLinkInlineRenderer.cs index 73473dcade..b655630857 100644 --- a/src/Elastic.Markdown/Myst/Renderers/HtmxLinkInlineRenderer.cs +++ b/src/Elastic.Markdown/Myst/Renderers/HtmxLinkInlineRenderer.cs @@ -71,7 +71,7 @@ protected override void Write(HtmlRenderer renderer, LinkInline link) } else if (link.IsImage) { - // Handle inline images with ALT override logic + // Handle inline images WriteImage(renderer, link); } else @@ -95,8 +95,14 @@ private static void WriteImage(HtmlRenderer renderer, LinkInline link) // Write any additional attributes (like width/height from styling instructions) _ = renderer.WriteAttributes(link); - // Always use alt text as title for accessibility consistency - if (link.FirstChild != null) + // Use the Markdown title when provided, otherwise fall back to the alt text + if (!string.IsNullOrEmpty(link.Title)) + { + _ = renderer.Write(" title=\""); + _ = renderer.WriteEscape(link.Title); + _ = renderer.Write('"'); + } + else if (link.FirstChild != null) { _ = renderer.Write(" title=\""); renderer.WriteChildren(link); diff --git a/tests/Elastic.Authoring.Tests/Inline/InlineImages.cs b/tests/Elastic.Authoring.Tests/Inline/InlineImages.cs index 0d6274def9..d3bf274b09 100644 --- a/tests/Elastic.Authoring.Tests/Inline/InlineImages.cs +++ b/tests/Elastic.Authoring.Tests/Inline/InlineImages.cs @@ -44,7 +44,7 @@ public class SupplyingATitle : MarkdownTest public async Task ValidateHtml() => await Docs.ConvertsToHtml( """ -

Elasticsearch

+

Elasticsearch

""" ); } @@ -58,7 +58,7 @@ public class SupplyingATitleWithWidthAndHeight : MarkdownTest [Test, DisplayName("validate HTML: does not include width and height in title")] public async Task ValidateHtml() => await Docs.ConvertsToHtml(""" -

o

+

o

"""); } @@ -71,7 +71,7 @@ public class SupplyingATitleWithWidthAndHeightInPercentage : MarkdownTest [Test, DisplayName("validate HTML: does not include width and height in title")] public async Task ValidateHtml() => await Docs.ConvertsToHtml(""" -

o

+

o

"""); } @@ -84,6 +84,6 @@ public class SupplyingATitleWithWidthOnly : MarkdownTest [Test, DisplayName("validate HTML: sets height to width if not supplied")] public async Task ValidateHtml() => await Docs.ConvertsToHtml(""" -

o

+

o

"""); } diff --git a/tests/Elastic.Markdown.Tests/Inline/InlineImageTest.cs b/tests/Elastic.Markdown.Tests/Inline/InlineImageTest.cs index 6bc36625e1..9226294334 100644 --- a/tests/Elastic.Markdown.Tests/Inline/InlineImageTest.cs +++ b/tests/Elastic.Markdown.Tests/Inline/InlineImageTest.cs @@ -89,7 +89,7 @@ public void GeneratesAttributesInHtml() => ); } -// Test image sizing with title and sizing — explicit title in markdown is ignored; alt text is always used as title +// Test image sizing with title and sizing — explicit title in markdown is used as the title; alt text stays as alt [InheritsTests] public class InlineImageWithTitleAndSizingTest() : InlineTest( """ @@ -104,7 +104,7 @@ public class InlineImageWithTitleAndSizingTest() : InlineTest( public void GeneratesAttributesInHtml() => // language=html Html.ShouldContainHtml( - """

Elasticsearch

""" + """

Elasticsearch

""" ); }