|
1 | 1 | // Licensed to Elasticsearch B.V under one or more agreements. |
2 | 2 | // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. |
3 | 3 | // See the LICENSE file in the project root for more information |
| 4 | + |
4 | 5 | using Markdig.Helpers; |
5 | 6 |
|
6 | 7 | namespace Elastic.Markdown.IO; |
7 | 8 |
|
8 | 9 | public class DocumentationFolder |
9 | 10 | { |
10 | 11 | public MarkdownFile? Index { get; } |
11 | | - private MarkdownFile[] Files { get; } |
12 | | - private DocumentationFolder[] Nested { get; } |
13 | 12 |
|
14 | | - public OrderedList<MarkdownFile> FilesInOrder { get; private set; } |
15 | | - public OrderedList<DocumentationFolder> GroupsInOrder { get; private set; } |
| 13 | + public List<MarkdownFile> FilesInOrder { get; } = new(); |
| 14 | + public List<DocumentationFolder> GroupsInOrder { get; } = new(); |
| 15 | + |
| 16 | + private HashSet<MarkdownFile> OwnFiles { get; } |
| 17 | + |
16 | 18 | public int Level { get; } |
17 | | - public string? FolderName { get; } |
18 | 19 |
|
19 | | - public DocumentationFolder(Dictionary<string, MarkdownFile[]> markdownFiles, int level, string folderName) |
| 20 | + public DocumentationFolder(IReadOnlyCollection<ITocItem> toc, |
| 21 | + IDictionary<string, DocumentationFile> lookup, |
| 22 | + IDictionary<string, DocumentationFile[]> folderLookup, |
| 23 | + int level = 0, |
| 24 | + MarkdownFile? index = null) |
20 | 25 | { |
21 | 26 | Level = level; |
22 | | - FolderName = folderName; |
23 | | - |
24 | | - var files = markdownFiles |
25 | | - .Where(k => k.Key.EndsWith(".md")).SelectMany(g => g.Value) |
26 | | - .Where(file => file.ParentFolders.Count == level) |
27 | | - .ToArray(); |
28 | | - |
29 | | - |
30 | | - Files = files |
31 | | - .Where(file => file.FileName != "index.md") |
32 | | - .ToArray(); |
33 | | - |
34 | | - FilesInOrder = new OrderedList<MarkdownFile>(Files); |
35 | | - |
36 | | - Index = files.FirstOrDefault(f => f.FileName == "index.md"); |
| 27 | + Index = index; |
37 | 28 |
|
38 | | - var newLevel = level + 1; |
39 | | - var groups = new List<DocumentationFolder>(); |
40 | | - foreach (var kv in markdownFiles.Where(kv=> !kv.Key.EndsWith(".md"))) |
| 29 | + foreach (var tocItem in toc) |
41 | 30 | { |
42 | | - var folder = kv.Key; |
43 | | - var folderFiles = kv.Value |
44 | | - .Where(file => file.ParentFolders.Count > level) |
45 | | - .Where(file => file.ParentFolders[level] == folder).ToArray(); |
46 | | - var mapped = folderFiles |
47 | | - .GroupBy(file => |
48 | | - { |
49 | | - var path = file.ParentFolders.Count > newLevel ? file.ParentFolders[newLevel] : file.FileName; |
50 | | - return path; |
51 | | - }) |
52 | | - .ToDictionary(k => k.Key, v => v.ToArray()); |
53 | | - var documentationGroup = new DocumentationFolder(mapped, newLevel, folder); |
54 | | - groups.Add(documentationGroup); |
| 31 | + if (tocItem is TocFile file) |
| 32 | + { |
| 33 | + if (!lookup.TryGetValue(file.Path, out var d) || d is not MarkdownFile md) |
| 34 | + continue; |
55 | 35 |
|
| 36 | + if (file.Children.Count > 0 && d is MarkdownFile virtualIndex) |
| 37 | + { |
| 38 | + var group = new DocumentationFolder(file.Children, lookup, folderLookup, level + 1, virtualIndex); |
| 39 | + GroupsInOrder.Add(group); |
| 40 | + continue; |
| 41 | + } |
| 42 | + |
| 43 | + FilesInOrder.Add(md); |
| 44 | + if (file.Path.EndsWith("index.md") && d is MarkdownFile i) |
| 45 | + Index ??= i; |
| 46 | + } |
| 47 | + else if (tocItem is TocFolder folder) |
| 48 | + { |
| 49 | + var children = folder.Children; |
| 50 | + if (children.Count == 0 |
| 51 | + && folderLookup.TryGetValue(folder.Path, out var documentationFiles)) |
| 52 | + { |
| 53 | + children = documentationFiles |
| 54 | + .Select(d => new TocFile(d.RelativePath, true, [])) |
| 55 | + .ToArray(); |
| 56 | + } |
| 57 | + |
| 58 | + var group = new DocumentationFolder(children, lookup, folderLookup, level + 1); |
| 59 | + GroupsInOrder.Add(group); |
| 60 | + } |
56 | 61 | } |
57 | | - Nested = groups.ToArray(); |
58 | | - GroupsInOrder = new OrderedList<DocumentationFolder>(Nested); |
| 62 | + |
| 63 | + Index ??= FilesInOrder.FirstOrDefault(); |
| 64 | + if (Index != null) |
| 65 | + FilesInOrder = FilesInOrder.Except(new[] { Index }).ToList(); |
| 66 | + OwnFiles = [..FilesInOrder]; |
59 | 67 | } |
60 | 68 |
|
61 | 69 | public bool HoldsCurrent(MarkdownFile current) => |
62 | | - Index == current || Files.Contains(current) || Nested.Any(n => n.HoldsCurrent(current)); |
| 70 | + Index == current || OwnFiles.Contains(current) || GroupsInOrder.Any(n => n.HoldsCurrent(current)); |
63 | 71 |
|
64 | 72 | private bool _resolved; |
| 73 | + |
65 | 74 | public async Task Resolve(Cancel ctx = default) |
66 | 75 | { |
67 | 76 | if (_resolved) return; |
68 | 77 |
|
69 | | - await Parallel.ForEachAsync(Files, ctx, async (file, token) => await file.ParseAsync(token)); |
70 | | - await Parallel.ForEachAsync(Nested, ctx, async (group, token) => await group.Resolve(token)); |
| 78 | + await Parallel.ForEachAsync(FilesInOrder, ctx, async (file, token) => await file.ParseAsync(token)); |
| 79 | + await Parallel.ForEachAsync(GroupsInOrder, ctx, async (group, token) => await group.Resolve(token)); |
71 | 80 |
|
72 | 81 | await (Index?.ParseAsync(ctx) ?? Task.CompletedTask); |
73 | 82 |
|
74 | | - var fileList = new OrderedList<MarkdownFile>(); |
75 | | - var groupList = new OrderedList<DocumentationFolder>(); |
76 | | - |
77 | | - |
78 | | - FilesInOrder = fileList; |
79 | | - GroupsInOrder = groupList; |
80 | 83 | _resolved = true; |
81 | 84 | } |
82 | 85 | } |
0 commit comments