diff --git a/src/LinkDotNet.Blog.Web/Features/MarkdownConverter.cs b/src/LinkDotNet.Blog.Web/Features/MarkdownConverter.cs index 0a13afb1..9246f2bc 100644 --- a/src/LinkDotNet.Blog.Web/Features/MarkdownConverter.cs +++ b/src/LinkDotNet.Blog.Web/Features/MarkdownConverter.cs @@ -1,10 +1,13 @@ using System.Collections.Generic; using System.Linq; +using System.Text; using Markdig; using Markdig.Extensions.AutoIdentifiers; using Markdig.Renderers.Html; using Markdig.Syntax; +using Markdig.Syntax.Inlines; using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Primitives; namespace LinkDotNet.Blog.Web.Features; @@ -38,9 +41,30 @@ public static IReadOnlyCollection GenerateToc(string markdownContent) return document .Descendants() .Where(h => h.Inline?.FirstChild is not null) - .Select(heading => new TocItem { Level = heading.Level, Text = heading.Inline.FirstChild.ToString(), Id = heading.GetAttributes().Id }) + .Select(heading => new TocItem { Level = heading.Level, Text = InlineToString(heading.Inline), Id = heading.GetAttributes().Id }) .ToArray(); } + + private static string InlineToString(ContainerInline inline) + { + var sb = new StringBuilder(); + var current = inline.FirstChild; + while (current is not null) + { + if (current is CodeInline cd) + { + sb.Append(cd.Content); + } + else + { + sb.Append(current); + } + + current = current.NextSibling; + } + + return sb.ToString(); + } } public class TocItem diff --git a/tests/LinkDotNet.Blog.UnitTests/Web/Features/ShowBlogPost/Components/TableOfContentsTests.cs b/tests/LinkDotNet.Blog.UnitTests/Web/Features/ShowBlogPost/Components/TableOfContentsTests.cs index c13cb782..dc913700 100644 --- a/tests/LinkDotNet.Blog.UnitTests/Web/Features/ShowBlogPost/Components/TableOfContentsTests.cs +++ b/tests/LinkDotNet.Blog.UnitTests/Web/Features/ShowBlogPost/Components/TableOfContentsTests.cs @@ -52,4 +52,17 @@ public void ShouldSetAnchorLinkCorrectWhenAlreadyAnchorInUrl() links[0].GetAttribute("href").Should().Be("https://localhost#header-1"); links[1].GetAttribute("href").Should().Be("https://localhost#header-2"); } + + [Fact] + public void ShouldCreateCorrectTocWithCodeInHeadings() + { + const string content = "# This is `Header` 1"; + + var cut = Render(p => p + .Add(x => x.Content, content) + .Add(x => x.CurrentUri, "https://localhost")); + + var link = cut.Find("nav a"); + link.TextContent.Should().Be("This is Header 1"); + } }