@@ -26,8 +26,46 @@ public interface INavigationLookups
26
26
27
27
public interface IPositionalNavigation
28
28
{
29
+ FrozenDictionary < string , INavigationItem > MarkdownNavigationLookup { get ; }
30
+
29
31
MarkdownFile ? GetPrevious ( MarkdownFile current ) ;
30
32
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
+ }
31
69
}
32
70
33
71
public record NavigationLookups : INavigationLookups
@@ -71,6 +109,8 @@ public class DocumentationSet : INavigationLookups, IPositionalNavigation
71
109
72
110
IReadOnlyCollection < IDocsBuilderExtension > INavigationLookups . EnabledExtensions => Configuration . EnabledExtensions ;
73
111
112
+ public FrozenDictionary < string , INavigationItem > MarkdownNavigationLookup { get ; }
113
+
74
114
// FrozenDictionary<Uri, TableOfContentsReference>? indexedTableOfContents = null
75
115
public DocumentationSet (
76
116
BuildContext build ,
@@ -137,9 +177,32 @@ public DocumentationSet(
137
177
138
178
MarkdownFiles = markdownFiles . Where ( f => f . NavigationIndex > - 1 ) . ToDictionary ( i => i . NavigationIndex , i => i ) . ToFrozenDictionary ( ) ;
139
179
180
+ MarkdownNavigationLookup = Tree . NavigationItems
181
+ . SelectMany ( Pairs )
182
+ . ToDictionary ( kv => kv . Item1 , kv => kv . Item2 )
183
+ . ToFrozenDictionary ( ) ;
184
+
140
185
ValidateRedirectsExists ( ) ;
141
186
}
142
187
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
+
143
206
private DocumentationFile [ ] ScanDocumentationFiles ( BuildContext build , IDirectoryInfo sourceDirectory ) =>
144
207
[ .. build . ReadFileSystem . Directory
145
208
. EnumerateFiles ( sourceDirectory . FullName , "*.*" , SearchOption . AllDirectories )
@@ -150,11 +213,11 @@ [.. build.ReadFileSystem.Directory
150
213
. Where ( f => ! Path . GetRelativePath ( sourceDirectory . FullName , f . FullName ) . StartsWith ( '.' ) )
151
214
. Select < IFileInfo , DocumentationFile > ( file => file . Extension switch
152
215
{
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 ) ,
158
221
".md" => CreateMarkDownFile ( file , build ) ,
159
222
_ => DefaultFileHandling ( file , sourceDirectory )
160
223
} ) ] ;
@@ -167,7 +230,7 @@ private DocumentationFile DefaultFileHandling(IFileInfo file, IDirectoryInfo sou
167
230
if ( documentationFile is not null )
168
231
return documentationFile ;
169
232
}
170
- return new ExcludedFile ( file , sourceDirectory ) ;
233
+ return new ExcludedFile ( file , sourceDirectory , Build . Git . RepositoryName ) ;
171
234
}
172
235
173
236
private void ValidateRedirectsExists ( )
@@ -265,15 +328,15 @@ private DocumentationFile CreateMarkDownFile(IFileInfo file, BuildContext contex
265
328
{
266
329
var relativePath = Path . GetRelativePath ( SourceDirectory . FullName , file . FullName ) ;
267
330
if ( Configuration . Exclude . Any ( g => g . IsMatch ( relativePath ) ) )
268
- return new ExcludedFile ( file , SourceDirectory ) ;
331
+ return new ExcludedFile ( file , SourceDirectory , context . Git . RepositoryName ) ;
269
332
270
333
if ( relativePath . Contains ( "_snippets" ) )
271
- return new SnippetFile ( file , SourceDirectory ) ;
334
+ return new SnippetFile ( file , SourceDirectory , context . Git . RepositoryName ) ;
272
335
273
336
// we ignore files in folders that start with an underscore
274
337
var folder = Path . GetDirectoryName ( relativePath ) ;
275
338
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 ) ;
277
340
278
341
if ( Configuration . Files . Contains ( relativePath ) )
279
342
return ExtensionOrDefaultMarkdown ( ) ;
@@ -282,7 +345,7 @@ private DocumentationFile CreateMarkDownFile(IFileInfo file, BuildContext contex
282
345
return ExtensionOrDefaultMarkdown ( ) ;
283
346
284
347
context . EmitError ( Configuration . SourceFile , $ "Not linked in toc: { relativePath } ") ;
285
- return new ExcludedFile ( file , SourceDirectory ) ;
348
+ return new ExcludedFile ( file , SourceDirectory , context . Git . RepositoryName ) ;
286
349
287
350
MarkdownFile ExtensionOrDefaultMarkdown ( )
288
351
{
0 commit comments