Skip to content

Commit 54343a2

Browse files
Mpdreamzreakaleek
andauthored
Fix parent breadcrumbs in assembler build (#1113)
* stage * fix tests and breadcrumb when primary_nav: false * fix precalculated crosslink path on windows * Update src/Elastic.Markdown/Slices/Layout/_Breadcrumbs.cshtml Co-authored-by: Jan Calanog <[email protected]> --------- Co-authored-by: Jan Calanog <[email protected]>
1 parent a74045c commit 54343a2

File tree

15 files changed

+250
-127
lines changed

15 files changed

+250
-127
lines changed

src/Elastic.Markdown/IO/Configuration/ConfigurationFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Project is not null
5757
&& Project.Equals("Elastic documentation", StringComparison.OrdinalIgnoreCase);
5858

5959
public ConfigurationFile(BuildContext context)
60-
: base(context.ConfigurationPath, context.DocumentationSourceDirectory)
60+
: base(context.ConfigurationPath, context.DocumentationSourceDirectory, context.Git.RepositoryName)
6161
{
6262
_context = context;
6363
ScopeDirectory = context.ConfigurationPath.Directory!;

src/Elastic.Markdown/IO/DocumentationFile.cs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,37 @@
88

99
namespace Elastic.Markdown.IO;
1010

11-
public abstract record DocumentationFile(IFileInfo SourceFile, IDirectoryInfo RootPath)
11+
public abstract record DocumentationFile
1212
{
13-
public string RelativePath { get; } = Path.GetRelativePath(RootPath.FullName, SourceFile.FullName);
14-
public string RelativeFolder { get; } = Path.GetRelativePath(RootPath.FullName, SourceFile.Directory!.FullName);
13+
protected DocumentationFile(IFileInfo sourceFile, IDirectoryInfo rootPath, string repository)
14+
{
15+
SourceFile = sourceFile;
16+
RelativePath = Path.GetRelativePath(rootPath.FullName, SourceFile.FullName);
17+
RelativeFolder = Path.GetRelativePath(rootPath.FullName, SourceFile.Directory!.FullName);
18+
CrossLink = $"{repository}://{RelativePath.Replace('\\', '/')}";
19+
}
20+
21+
public string RelativePath { get; }
22+
public string RelativeFolder { get; }
23+
public string CrossLink { get; }
1524

1625
/// Allows documentation files of non markdown origins to advertise as their markdown equivalent in links.json
1726
public virtual string LinkReferenceRelativePath => RelativePath;
1827

28+
public IFileInfo SourceFile { get; }
1929
}
2030

21-
public record ImageFile(IFileInfo SourceFile, IDirectoryInfo RootPath, string MimeType = "image/png")
22-
: DocumentationFile(SourceFile, RootPath);
31+
public record ImageFile(IFileInfo SourceFile, IDirectoryInfo RootPath, string Repository, string MimeType = "image/png")
32+
: DocumentationFile(SourceFile, RootPath, Repository);
2333

24-
public record StaticFile(IFileInfo SourceFile, IDirectoryInfo RootPath)
25-
: DocumentationFile(SourceFile, RootPath);
34+
public record StaticFile(IFileInfo SourceFile, IDirectoryInfo RootPath, string Repository)
35+
: DocumentationFile(SourceFile, RootPath, Repository);
2636

27-
public record ExcludedFile(IFileInfo SourceFile, IDirectoryInfo RootPath)
28-
: DocumentationFile(SourceFile, RootPath);
37+
public record ExcludedFile(IFileInfo SourceFile, IDirectoryInfo RootPath, string Repository)
38+
: DocumentationFile(SourceFile, RootPath, Repository);
2939

30-
public record SnippetFile(IFileInfo SourceFile, IDirectoryInfo RootPath)
31-
: DocumentationFile(SourceFile, RootPath)
40+
public record SnippetFile(IFileInfo SourceFile, IDirectoryInfo RootPath, string Repository)
41+
: DocumentationFile(SourceFile, RootPath, Repository)
3242
{
3343
private SnippetAnchors? Anchors { get; set; }
3444
private bool _parsed;

src/Elastic.Markdown/IO/DocumentationSet.cs

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,46 @@ public interface INavigationLookups
2626

2727
public interface IPositionalNavigation
2828
{
29+
FrozenDictionary<string, INavigationItem> MarkdownNavigationLookup { get; }
30+
2931
MarkdownFile? GetPrevious(MarkdownFile current);
3032
MarkdownFile? GetNext(MarkdownFile current);
33+
34+
INavigationItem[] GetParents(INavigationItem current)
35+
{
36+
var parents = new List<INavigationItem>();
37+
var parent = current.Parent;
38+
do
39+
{
40+
if (parent is null)
41+
continue;
42+
parents.Add(parent);
43+
parent = parent.Parent;
44+
} while (parent != null);
45+
46+
return [.. parents];
47+
}
48+
MarkdownFile[] GetParentMarkdownFiles(INavigationItem current)
49+
{
50+
var parents = new List<MarkdownFile>();
51+
var navigationParents = GetParents(current);
52+
foreach (var parent in navigationParents)
53+
{
54+
if (parent is FileNavigationItem f)
55+
parents.Add(f.File);
56+
if (parent is GroupNavigationItem { Group.Index: not null } g)
57+
parents.Add(g.Group.Index);
58+
if (parent is DocumentationGroup { Index: not null } dg)
59+
parents.Add(dg.Index);
60+
}
61+
return [.. parents];
62+
}
63+
MarkdownFile[] GetParentMarkdownFiles(MarkdownFile file)
64+
{
65+
if (MarkdownNavigationLookup.TryGetValue(file.CrossLink, out var navigationItem))
66+
return GetParentMarkdownFiles(navigationItem);
67+
return [];
68+
}
3169
}
3270

3371
public record NavigationLookups : INavigationLookups
@@ -71,6 +109,8 @@ public class DocumentationSet : INavigationLookups, IPositionalNavigation
71109

72110
IReadOnlyCollection<IDocsBuilderExtension> INavigationLookups.EnabledExtensions => Configuration.EnabledExtensions;
73111

112+
public FrozenDictionary<string, INavigationItem> MarkdownNavigationLookup { get; }
113+
74114
// FrozenDictionary<Uri, TableOfContentsReference>? indexedTableOfContents = null
75115
public DocumentationSet(
76116
BuildContext build,
@@ -137,9 +177,32 @@ public DocumentationSet(
137177

138178
MarkdownFiles = markdownFiles.Where(f => f.NavigationIndex > -1).ToDictionary(i => i.NavigationIndex, i => i).ToFrozenDictionary();
139179

180+
MarkdownNavigationLookup = Tree.NavigationItems
181+
.SelectMany(Pairs)
182+
.ToDictionary(kv => kv.Item1, kv => kv.Item2)
183+
.ToFrozenDictionary();
184+
140185
ValidateRedirectsExists();
141186
}
142187

188+
public static (string, INavigationItem)[] Pairs(INavigationItem item)
189+
{
190+
if (item is FileNavigationItem f)
191+
return [(f.File.CrossLink, item)];
192+
if (item is GroupNavigationItem g)
193+
{
194+
var index = new List<(string, INavigationItem)>();
195+
if (g.Group.Index is not null)
196+
index.Add((g.Group.Index.CrossLink, g));
197+
198+
return index.Concat(g.Group.NavigationItems.SelectMany(Pairs).ToArray())
199+
.DistinctBy(kv => kv.Item1)
200+
.ToArray();
201+
}
202+
203+
return [];
204+
}
205+
143206
private DocumentationFile[] ScanDocumentationFiles(BuildContext build, IDirectoryInfo sourceDirectory) =>
144207
[.. build.ReadFileSystem.Directory
145208
.EnumerateFiles(sourceDirectory.FullName, "*.*", SearchOption.AllDirectories)
@@ -150,11 +213,11 @@ [.. build.ReadFileSystem.Directory
150213
.Where(f => !Path.GetRelativePath(sourceDirectory.FullName, f.FullName).StartsWith('.'))
151214
.Select<IFileInfo, DocumentationFile>(file => file.Extension switch
152215
{
153-
".jpg" => new ImageFile(file, SourceDirectory, "image/jpeg"),
154-
".jpeg" => new ImageFile(file, SourceDirectory, "image/jpeg"),
155-
".gif" => new ImageFile(file, SourceDirectory, "image/gif"),
156-
".svg" => new ImageFile(file, SourceDirectory, "image/svg+xml"),
157-
".png" => new ImageFile(file, SourceDirectory),
216+
".jpg" => new ImageFile(file, SourceDirectory, build.Git.RepositoryName, "image/jpeg"),
217+
".jpeg" => new ImageFile(file, SourceDirectory, build.Git.RepositoryName, "image/jpeg"),
218+
".gif" => new ImageFile(file, SourceDirectory, build.Git.RepositoryName, "image/gif"),
219+
".svg" => new ImageFile(file, SourceDirectory, build.Git.RepositoryName, "image/svg+xml"),
220+
".png" => new ImageFile(file, SourceDirectory, build.Git.RepositoryName),
158221
".md" => CreateMarkDownFile(file, build),
159222
_ => DefaultFileHandling(file, sourceDirectory)
160223
})];
@@ -167,7 +230,7 @@ private DocumentationFile DefaultFileHandling(IFileInfo file, IDirectoryInfo sou
167230
if (documentationFile is not null)
168231
return documentationFile;
169232
}
170-
return new ExcludedFile(file, sourceDirectory);
233+
return new ExcludedFile(file, sourceDirectory, Build.Git.RepositoryName);
171234
}
172235

173236
private void ValidateRedirectsExists()
@@ -265,15 +328,15 @@ private DocumentationFile CreateMarkDownFile(IFileInfo file, BuildContext contex
265328
{
266329
var relativePath = Path.GetRelativePath(SourceDirectory.FullName, file.FullName);
267330
if (Configuration.Exclude.Any(g => g.IsMatch(relativePath)))
268-
return new ExcludedFile(file, SourceDirectory);
331+
return new ExcludedFile(file, SourceDirectory, context.Git.RepositoryName);
269332

270333
if (relativePath.Contains("_snippets"))
271-
return new SnippetFile(file, SourceDirectory);
334+
return new SnippetFile(file, SourceDirectory, context.Git.RepositoryName);
272335

273336
// we ignore files in folders that start with an underscore
274337
var folder = Path.GetDirectoryName(relativePath);
275338
if (folder is not null && (folder.Contains($"{Path.DirectorySeparatorChar}_", StringComparison.Ordinal) || folder.StartsWith('_')))
276-
return new ExcludedFile(file, SourceDirectory);
339+
return new ExcludedFile(file, SourceDirectory, context.Git.RepositoryName);
277340

278341
if (Configuration.Files.Contains(relativePath))
279342
return ExtensionOrDefaultMarkdown();
@@ -282,7 +345,7 @@ private DocumentationFile CreateMarkDownFile(IFileInfo file, BuildContext contex
282345
return ExtensionOrDefaultMarkdown();
283346

284347
context.EmitError(Configuration.SourceFile, $"Not linked in toc: {relativePath}");
285-
return new ExcludedFile(file, SourceDirectory);
348+
return new ExcludedFile(file, SourceDirectory, context.Git.RepositoryName);
286349

287350
MarkdownFile ExtensionOrDefaultMarkdown()
288351
{

src/Elastic.Markdown/IO/MarkdownFile.cs

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public MarkdownFile(
3737
BuildContext build,
3838
DocumentationSet set
3939
)
40-
: base(sourceFile, rootPath)
40+
: base(sourceFile, rootPath, build.Git.RepositoryName)
4141
{
4242
FileName = sourceFile.Name;
4343
FilePath = sourceFile.FullName;
@@ -52,26 +52,21 @@ DocumentationSet set
5252
//may be updated by DocumentationGroup.ProcessTocItems
5353
//todo refactor mutability of MarkdownFile as a whole
5454
ScopeDirectory = build.Configuration.ScopeDirectory;
55+
5556
NavigationRoot = set.Tree;
5657
NavigationSource = set.Source;
5758
}
5859

5960
public IDirectoryInfo ScopeDirectory { get; set; }
6061

61-
public INavigation NavigationRoot { get; set; }
62+
public INavigationGroup NavigationRoot { get; set; }
6263

6364
public Uri NavigationSource { get; set; }
6465

6566
public string Id { get; } = Guid.NewGuid().ToString("N")[..8];
6667

6768
private DiagnosticsCollector Collector { get; }
6869

69-
public DocumentationGroup? Parent
70-
{
71-
get => FileName == "index.md" ? _parent?.Parent : _parent;
72-
set => _parent = value;
73-
}
74-
7570
public bool Hidden { get; internal set; }
7671
public string? UrlPathPrefix { get; }
7772
protected MarkdownParser MarkdownParser { get; }
@@ -135,8 +130,7 @@ public string Url
135130
_url = DefaultUrlPath;
136131
return _url;
137132
}
138-
var path = RelativePath;
139-
var crossLink = new Uri($"{_set.Build.Git.RepositoryName}://{path}");
133+
var crossLink = new Uri(CrossLink);
140134
var uri = _set.LinkResolver.UriResolver.Resolve(crossLink, DefaultUrlPathSuffix);
141135
_url = uri.AbsolutePath;
142136
return _url;
@@ -146,26 +140,9 @@ public string Url
146140

147141
public int NavigationIndex { get; set; } = -1;
148142

149-
public string? GroupId { get; set; }
150-
151143
private bool _instructionsParsed;
152-
private DocumentationGroup? _parent;
153144
private string? _title;
154145

155-
public MarkdownFile[] YieldParents()
156-
{
157-
var parents = new List<MarkdownFile>();
158-
var parent = Parent;
159-
do
160-
{
161-
if (parent is { Index: not null } && parent.Index != this)
162-
parents.Add(parent.Index);
163-
parent = parent?.Parent;
164-
} while (parent != null);
165-
166-
return [.. parents];
167-
}
168-
169146
/// this get set by documentationset when validating redirects
170147
/// because we need to minimally parse to see the anchors anchor validation is deferred.
171148
public IReadOnlyDictionary<string, string?>? AnchorRemapping { get; set; }
@@ -367,5 +344,4 @@ public string CreateHtml(MarkdownDocument document)
367344
_ = document.Remove(h1);
368345
return document.ToHtml(MarkdownParser.Pipeline);
369346
}
370-
371347
}

0 commit comments

Comments
 (0)