Skip to content

Commit

Permalink
feat: set toc name from title (#9475)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufeih authored Nov 25, 2023
1 parent c6c6c35 commit 73482d1
Show file tree
Hide file tree
Showing 31 changed files with 114 additions and 82 deletions.
14 changes: 5 additions & 9 deletions docs/docs/table-of-contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,15 @@ To add a TOC, create a file named `toc.yml`. Here's the structure for a simple Y
items:
- name: Tutorial
items:
- name: Introduction
href: tutorial.md
- name: Step 1
href: step-1.md
- name: Step 2
href: step-2.md
- name: Step 3
href: step-3.md
- href: tutorial.md
- href: step-1.md
- href: step-2.md
- href: step-3.md
```
The YAML document is a tree of TOC nodes, each of which has these properties:
- `name`: The display name for the TOC node.
- `name`: An optional display name for the TOC node. When not specified, uses the `title` metadata or the first Heading 1 element from the referenced article as the display name.
- `href`: The path the TOC node leads to. Optional because a node can exist just to parent other nodes.
- `items`: If a node has children, they're listed in the items array.
- `uid`: The uid of the article. Can be used instead of `href`.
Expand Down
12 changes: 4 additions & 8 deletions samples/seed/articles/toc.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
pdfFileName: seed.pdf
pdfCoverPage: pdf/cover.html
items:
- name: Getting Started
href: docfx_getting_started.md
- href: docfx_getting_started.md
- name: Engineering Docs
expanded: true
items:
- name: Section 1
- name: Engineering Guidelines
href: engineering_guidelines.md
- name: CSharp Coding Standards
href: csharp_coding_standards.md
- name: Markdown
href: markdown.md
- href: engineering_guidelines.md
- href: csharp_coding_standards.md
- href: markdown.md
- name: Microsoft Docs
href: https://docs.microsoft.com/en-us/
51 changes: 48 additions & 3 deletions src/Docfx.Build/ManifestProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Concurrent;

using Docfx.Common;
using Docfx.DataContracts.Common;
using Docfx.Plugins;

namespace Docfx.Build.Engine;
Expand Down Expand Up @@ -33,6 +34,8 @@ public ManifestProcessor(List<ManifestItemWithContext> manifestWithContext, Docu

public void Process()
{
UpdateTocName();

UpdateContext();

// Afterwards, m.Item.Model.Content is always IDictionary
Expand All @@ -53,8 +56,6 @@ public void Process()
}
}

#region Private

private void UpdateContext()
{
_context.ResolveExternalXRefSpec();
Expand Down Expand Up @@ -181,5 +182,49 @@ private List<ManifestItem> ProcessTemplate()
return _templateProcessor.Process(_manifestWithContext.Select(s => s.Item).ToList(), _context.ApplyTemplateSettings, _globalMetadata);
}

#endregion
private void UpdateTocName()
{
var titles = (
from item in _manifestWithContext
let title = GetTitle(item)
where !string.IsNullOrEmpty(title)
group title
by item.FileModel.Key).ToDictionary(g => g.Key, g => g.First());

foreach (var item in _manifestWithContext)
{
if (item.FileModel.Content is not TocItemViewModel toc)
continue;

UpdateTocNameCore(toc.Items);
}

void UpdateTocNameCore(List<TocItemViewModel> items)
{
if (items is null)
return;

foreach (var node in items)
{
if (string.IsNullOrEmpty(node.Name))
{
if (node.Href is not null && titles.TryGetValue(UriUtility.GetPath(node.Href), out var title))
node.Name = title;
else
Logger.LogWarning(
$"TOC item ({node}) with empty name found. Missing a name?",
code: WarningCodes.Build.EmptyTocItemName);
}

UpdateTocNameCore(node.Items);
}
}

string GetTitle(ManifestItemWithContext item)
{
return item.FileModel.Content is Dictionary<string, object> dict &&
dict.TryGetValue("title", out var title) &&
title is string result ? result : null;
}
}
}
8 changes: 0 additions & 8 deletions src/Docfx.Build/TableOfContents/TocResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,6 @@ private TocItemInfo ResolveItemCore(TocItemInfo wrapper, Stack<FileAndType> stac
// validate href
ValidateHref(item);

// validate if name is missing
if (!isRoot && string.IsNullOrEmpty(item.Name) && string.IsNullOrEmpty(item.TopicUid))
{
Logger.LogWarning(
$"TOC item ({item}) with empty name found. Missing a name?",
code: WarningCodes.Build.EmptyTocItemName);
}

// TocHref supports 2 forms: absolute path and local toc file.
// When TocHref is set, using TocHref as Href in output, and using Href as Homepage in output
var tocHrefType = Utility.GetHrefType(item.TocHref);
Expand Down
7 changes: 5 additions & 2 deletions templates/modern/src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ export function loc(id: string, args?: { [key: string]: string }): string {
/**
* Add <wbr> into long word.
*/
export function breakWord(text: string): string[] {
export function breakWord(text?: string): string[] {
if (!text) {
return []
}
const regex = /([a-z0-9])([A-Z]+[a-z])|([a-zA-Z0-9][.,/<>_])/g
const result = []
let start = 0
Expand All @@ -55,7 +58,7 @@ export function breakWord(text: string): string[] {
/**
* Add <wbr> into long word.
*/
export function breakWordLit(text: string): TemplateResult {
export function breakWordLit(text?: string): TemplateResult {
const result = []
breakWord(text).forEach(word => {
if (result.length > 0) {
Expand Down
2 changes: 1 addition & 1 deletion templates/modern/src/toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { classMap } from 'lit-html/directives/class-map.js'
import { breakWordLit, meta, isExternalHref, loc, isSameURL } from './helper'

export type TocNode = {
name: string
name?: string
href?: string
expanded?: boolean
items?: TocNode[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
{
"Number": 2,
"Text": "Table of ContentsGetting Started3Engineering DocsSection 1Engineering Guidelines5CSharp Coding Standards8Markdown15Microsoft Docs",
"Text": "Table of ContentsGetting Started with docfx3Engineering DocsSection 1Engineering Guidelines5C# Coding Standards8Markdown15Microsoft Docs",
"Links": [
{
"Uri": "https://docs.microsoft.com/en-us/"
Expand Down Expand Up @@ -278,7 +278,7 @@
],
"Bookmarks": [
{
"Title": "Getting Started",
"Title": "Getting Started with docfx",
"Children": [],
"Destination": {
"PageNumber": 3,
Expand Down Expand Up @@ -314,7 +314,7 @@
}
},
{
"Title": "CSharp Coding Standards",
"Title": "C# Coding Standards",
"Children": [],
"Destination": {
"PageNumber": 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"order": 100.0,
"items": [
{
"name": "Getting Started",
"name": "Getting Started with docfx",
"href": "docfx_getting_started.html",
"topicHref": "docfx_getting_started.html",
"tocHref": null,
Expand Down Expand Up @@ -31,7 +31,7 @@
"leaf": true
},
{
"name": "CSharp Coding Standards",
"name": "C# Coding Standards",
"href": "csharp_coding_standards.html",
"topicHref": "csharp_coding_standards.html",
"tocHref": null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"content": "{\"order\":100,\"items\":[{\"name\":\"Getting Started\",\"href\":\"docfx_getting_started.html\",\"topicHref\":\"docfx_getting_started.html\"},{\"name\":\"Engineering Docs\",\"items\":[{\"name\":\"Section 1\"},{\"name\":\"Engineering Guidelines\",\"href\":\"engineering_guidelines.html\",\"topicHref\":\"engineering_guidelines.html\"},{\"name\":\"CSharp Coding Standards\",\"href\":\"csharp_coding_standards.html\",\"topicHref\":\"csharp_coding_standards.html\"}],\"expanded\":true},{\"name\":\"Markdown\",\"href\":\"markdown.html\",\"topicHref\":\"markdown.html\"},{\"name\":\"Microsoft Docs\",\"href\":\"https://docs.microsoft.com/en-us/\",\"topicHref\":\"https://docs.microsoft.com/en-us/\"}],\"pdfFileName\":\"seed.pdf\",\"pdfCoverPage\":\"pdf/cover.html\",\"pdf\":true,\"pdfTocPage\":true}"
"content": "{\"order\":100,\"items\":[{\"name\":\"Getting Started with docfx\",\"href\":\"docfx_getting_started.html\",\"topicHref\":\"docfx_getting_started.html\"},{\"name\":\"Engineering Docs\",\"items\":[{\"name\":\"Section 1\"},{\"name\":\"Engineering Guidelines\",\"href\":\"engineering_guidelines.html\",\"topicHref\":\"engineering_guidelines.html\"},{\"name\":\"C# Coding Standards\",\"href\":\"csharp_coding_standards.html\",\"topicHref\":\"csharp_coding_standards.html\"}],\"expanded\":true},{\"name\":\"Markdown\",\"href\":\"markdown.html\",\"topicHref\":\"markdown.html\"},{\"name\":\"Microsoft Docs\",\"href\":\"https://docs.microsoft.com/en-us/\",\"topicHref\":\"https://docs.microsoft.com/en-us/\"}],\"pdfFileName\":\"seed.pdf\",\"pdfCoverPage\":\"pdf/cover.html\",\"pdf\":true,\"pdfTocPage\":true}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"order": 100,
"items": [
{
"name": "Getting Started",
"name": "Getting Started with docfx",
"href": "docfx_getting_started.html",
"topicHref": "docfx_getting_started.html"
},
Expand All @@ -18,7 +18,7 @@
"topicHref": "engineering_guidelines.html"
},
{
"name": "CSharp Coding Standards",
"name": "C# Coding Standards",
"href": "csharp_coding_standards.html",
"topicHref": "csharp_coding_standards.html"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"includedFrom": "~/articles/toc.yml",
"items": [
{
"name": "Getting Started",
"name": "Getting Started with docfx",
"href": "../articles/docfx_getting_started.html",
"topicHref": "../articles/docfx_getting_started.html",
"tocHref": null,
Expand Down Expand Up @@ -35,7 +35,7 @@
"leaf": true
},
{
"name": "CSharp Coding Standards",
"name": "C# Coding Standards",
"href": "../articles/csharp_coding_standards.html",
"topicHref": "../articles/csharp_coding_standards.html",
"tocHref": null,
Expand Down
Loading

0 comments on commit 73482d1

Please sign in to comment.