diff --git a/modules/docs/src/Volo.Docs.Web/TableOfContents/TocGeneratorService.cs b/modules/docs/src/Volo.Docs.Web/TableOfContents/TocGeneratorService.cs index d53bb0f91b..668147820b 100644 --- a/modules/docs/src/Volo.Docs.Web/TableOfContents/TocGeneratorService.cs +++ b/modules/docs/src/Volo.Docs.Web/TableOfContents/TocGeneratorService.cs @@ -11,6 +11,7 @@ namespace Volo.Docs.TableOfContents; public class TocGeneratorService : ITocGeneratorService, ITransientDependency { private readonly HashSet _generatedIds = []; + public record Heading(int Level, string Text, string Id); public (string TocHtml, string ProcessedContent) GenerateTocAndProcessHeadings(string content) { @@ -20,7 +21,7 @@ public class TocGeneratorService : ITocGeneratorService, ITransientDependency } _generatedIds.Clear(); - var tocHeadings = new List<(int Level, string Text, string Id)>(); + var tocHeadings = new List(); var doc = new HtmlDocument(); doc.LoadHtml(content); @@ -50,7 +51,7 @@ public class TocGeneratorService : ITocGeneratorService, ITransientDependency var level = int.Parse(node.Name.Substring(1)); if (level == 2 || level == 3) { - tocHeadings.Add((level, node.InnerText.Trim(), id)); + tocHeadings.Add(new Heading(level, node.InnerText.Trim(), id)); } } } @@ -91,13 +92,16 @@ public class TocGeneratorService : ITocGeneratorService, ITransientDependency return finalId; } - private static string BuildTocHtml(List<(int Level, string Text, string Id)> headings) + private static string BuildTocHtml(List headings) { if (headings == null || headings.Count == 0) { return string.Empty; } + const int H2Level = 2; + const int H3Level = 3; + var tocBuilder = new StringBuilder(); tocBuilder.Append("
    "); @@ -107,47 +111,47 @@ public class TocGeneratorService : ITocGeneratorService, ITransientDependency foreach (var (index, heading) in headings.Select((h, i) => (i, h))) { var isLastItem = index == headings.Count - 1; - var nextHeading = isLastItem ? default : headings[index + 1]; - var hasChildren = nextHeading.Level == 3 && heading.Level == 2; + var nextHeading = isLastItem ? null : headings[index + 1]; + + var hasChildren = nextHeading?.Level == H3Level && heading.Level == H2Level; if (heading.Level < currentLevel) { tocBuilder.Append("
"); } - else if (!isFirstH2 && heading.Level == 2 && currentLevel == 2) + else if (heading.Level == currentLevel && heading.Level == H2Level && !isFirstH2) { tocBuilder.Append(""); } - if (heading.Level == 2) + if (heading.Level == H2Level) { var liClass = hasChildren ? "nav-item toc-item-has-children" : "nav-item"; tocBuilder.Append($"
  • {heading.Text}"); isFirstH2 = false; } - else if (heading.Level == 3) + else if (heading.Level == H3Level) { - if (currentLevel != 3) + if (currentLevel < H3Level) { tocBuilder.Append("
      "); } - tocBuilder.Append($"
    • {heading.Text}
    • "); } currentLevel = heading.Level; } - if (currentLevel == 3) + if (currentLevel == H3Level) { - tocBuilder.Append("
  • "); + tocBuilder.Append(""); } - else if (currentLevel == 2 && !isFirstH2) + else if (currentLevel == H2Level) { tocBuilder.Append(""); } - tocBuilder.Append(""); + tocBuilder.Append(""); return tocBuilder.ToString(); }