Skip to content

Commit

Permalink
feat: gen TOC name for folder ref or include (dotnet#9481)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufeih authored and p-kostov committed Jun 28, 2024
1 parent 2eb1fdc commit 95b34c5
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/Docfx.Build/TableOfContents/BuildTocDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BuildTocDocument : BaseDocumentBuildStep
/// </summary>
public override IEnumerable<FileModel> Prebuild(ImmutableList<FileModel> models, IHostService host)
{
return TocHelper.ResolveToc(models, host);
return TocHelper.ResolveToc(models);
}

public override void Build(FileModel model, IHostService host)
Expand Down
2 changes: 1 addition & 1 deletion src/Docfx.Build/TableOfContents/TocHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static class TocHelper
YamlDeserializerWithFallback.Create<TocViewModel>()
.WithFallback<TocItemViewModel>();

public static List<FileModel> ResolveToc(ImmutableList<FileModel> models, IHostService host)
public static List<FileModel> ResolveToc(ImmutableList<FileModel> models)
{
var tocCache = new Dictionary<string, TocItemInfo>(FilePathComparer.OSPlatformSensitiveStringComparer);
var nonReferencedTocModels = new List<FileModel>();
Expand Down
17 changes: 17 additions & 0 deletions src/Docfx.Build/TableOfContents/TocResolver.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Web;
using Docfx.Common;
using Docfx.DataContracts.Common;
using Docfx.Plugins;
Expand Down Expand Up @@ -197,6 +198,11 @@ select ResolveItem(new TocItemInfo(file, i), stack, false) into r
item.Href = item.TopicHref;
}

if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.TocHref))
{
item.Name = GetTocItemName(item.TocHref);
}

if (item.Items != null)
{
for (int i = 0; i < item.Items.Count; i++)
Expand All @@ -209,6 +215,11 @@ select ResolveItem(new TocItemInfo(file, i), stack, false) into r
case HrefType.MarkdownTocFile:
case HrefType.YamlTocFile:
{
if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Href))
{
item.Name = GetTocItemName(item.Href);
}

item.IncludedFrom = item.Href;

var href = (RelativePath)item.Href;
Expand All @@ -220,6 +231,7 @@ select ResolveItem(new TocItemInfo(file, i), stack, false) into r
// For referenced toc, content from referenced toc is expanded as the items of current toc item,
// Href is reset to the homepage of current toc item
item.Href = item.TopicHref;

var referencedTocClone = referencedToc?.Items?.Clone();

// For [reference](a/toc.md), and toc.md contains not-exist.md, the included not-exist.md should be resolved to a/not-exist.md
Expand Down Expand Up @@ -390,4 +402,9 @@ private static void ValidateHref(TocItemViewModel item)
item.Href = UriUtility.GetPath(item.Href);
}
}

private static string GetTocItemName(string href)
{
return HttpUtility.UrlDecode(href.TrimEnd("toc.yml").TrimEnd('/', '\\').Replace('-', ' ').Replace('_', ' '));
}
}
33 changes: 30 additions & 3 deletions test/Docfx.Tests.Common/TestBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json;
using Xunit;

namespace Docfx.Tests.Common;
Expand Down Expand Up @@ -51,8 +52,6 @@ private static string GetFolder()
return folder;
}

#region IO related

protected static string CreateFile(string fileName, string[] lines, string baseFolder)
{
ArgumentNullException.ThrowIfNull(lines);
Expand Down Expand Up @@ -111,7 +110,35 @@ protected static string CreateDirectory(string dir, string baseFolder)
return subDirectory;
}

#endregion
public static void AssertJsonEquivalent(string expected, string actual)
{
AssertJsonEquivalent(
JsonDocument.Parse(expected, new() { AllowTrailingCommas = true }).RootElement,
JsonDocument.Parse(actual, new() { AllowTrailingCommas = true }).RootElement);
}

public static void AssertJsonEquivalent(JsonElement expected, JsonElement actual)
{
Assert.Equal(expected.ValueKind, actual.ValueKind);

switch (expected.ValueKind)
{
case JsonValueKind.Object:
foreach (var property in expected.EnumerateObject())
AssertJsonEquivalent(property.Value, actual.GetProperty(property.Name));
break;

case JsonValueKind.Array:
for (var i = 0; i < expected.GetArrayLength(); i++)
AssertJsonEquivalent(expected[i], actual[i]);
break;

default:
Assert.Equal(expected.GetRawText(), actual.GetRawText());
break;
}
}


public virtual void Dispose()
{
Expand Down
54 changes: 53 additions & 1 deletion test/docfx.Tests/DocsetBuildTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,23 @@ private static async Task<Dictionary<string, Func<string>>> Build(Dictionary<str
Directory.CreateDirectory(testDirectory);
foreach (var (path, content) in files)
{
File.WriteAllText(Path.Combine(testDirectory, path), content);
var filePath = Path.GetFullPath(Path.Combine(testDirectory, path));
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, content);
}

if (!files.ContainsKey("docfx.json"))
{
File.WriteAllText($"{testDirectory}/docfx.json",
"""
{
"build": {
"content": [{ "files": [ "**/*.md", "**/*.yml" ] }],
"template": ["default", "modern"],
"dest": "_site"
}
}
""");
}

await Docset.Build($"{testDirectory}/docfx.json");
Expand Down Expand Up @@ -242,4 +258,40 @@ public static async Task Build_With_RedirectUri_Files()
var urls = XDocument.Parse(sitemapXml).Root.Elements();
Assert.True(!urls.Any());
}

[Fact]
public static async Task Build_Toc_Gen_Name()
{
var outputs = await Build(new()
{
["toc.yml"] =
"""
- href: from-h1.md
- href: from-title.md
- href: folder-ref/sub-folder/
- href: nested-toc%3F/toc.yml
""",
["from-h1.md"] = "# H1",
["from-title.md"] =
"""
---
title: Title
---
""",
["folder-ref/sub-folder/toc.yml"] = "- name: Folder Ref",
["nested-toc%3F/toc.yml"] = "- name: Nested TOC",
});

AssertJsonEquivalent(
"""
{
"items": [
{ "name": "H1", "href": "from-h1.html" },
{ "name": "Title", "href": "from-title.html" },
{ "name": "folder ref/sub folder" },
{ "name": "nested toc?" },
]
}
""", outputs["toc.json"]());
}
}

0 comments on commit 95b34c5

Please sign in to comment.