Skip to content

Commit

Permalink
Add support for "previous" and "next" document navigation (#258)
Browse files Browse the repository at this point in the history
Introduced navigation indices for Markdown files, enabling seamless
transitions between "previous" and "next" documents. Updated views and
models to reflect these changes, improving navigation usability.


https://github.com/user-attachments/assets/dda58a4e-5684-4c18-a409-3fca5f74f782


Video inspired by @reakaleek's PR's :)
  • Loading branch information
Mpdreamz authored Jan 16, 2025
1 parent 8269091 commit d6b668f
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 12 deletions.
16 changes: 12 additions & 4 deletions src/Elastic.Markdown/IO/DocumentationSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.Collections.Frozen;
using System.IO.Abstractions;
using Elastic.Markdown.Diagnostics;
using Elastic.Markdown.IO.Configuration;
Expand Down Expand Up @@ -56,17 +57,24 @@ public DocumentationSet(BuildContext context)

LastWrite = Files.Max(f => f.SourceFile.LastWriteTimeUtc);

FlatMappedFiles = Files.ToDictionary(file => file.RelativePath, file => file);
FlatMappedFiles = Files.ToDictionary(file => file.RelativePath, file => file).ToFrozenDictionary();

var folderFiles = Files
.GroupBy(file => file.RelativeFolder)
.ToDictionary(g => g.Key, g => g.ToArray());

Tree = new DocumentationGroup(Configuration.TableOfContents, FlatMappedFiles, folderFiles)
var fileIndex = 0;
Tree = new DocumentationGroup(Configuration.TableOfContents, FlatMappedFiles, folderFiles, ref fileIndex)
{
Parent = null
};

MarkdownFiles = Files.OfType<MarkdownFile>().ToDictionary(i => i.NavigationIndex, i => i).ToFrozenDictionary();

}

public FrozenDictionary<int, MarkdownFile> MarkdownFiles { get; }

public MarkdownFile? GetMarkdownFile(IFileInfo sourceFile)
{
var relativePath = Path.GetRelativePath(SourcePath.FullName, sourceFile.FullName);
Expand Down Expand Up @@ -104,9 +112,9 @@ private DocumentationFile CreateMarkDownFile(IFileInfo file, BuildContext contex

public DocumentationGroup Tree { get; }

public List<DocumentationFile> Files { get; }
public IReadOnlyCollection<DocumentationFile> Files { get; }

public Dictionary<string, DocumentationFile> FlatMappedFiles { get; }
public FrozenDictionary<string, DocumentationFile> FlatMappedFiles { get; }

public void ClearOutputDirectory()
{
Expand Down
2 changes: 2 additions & 0 deletions src/Elastic.Markdown/IO/MarkdownFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public string? NavigationTitle
public string FileName { get; }
public string Url => $"{UrlPathPrefix}/{RelativePath.Replace(".md", ".html")}";

public int NavigationIndex { get; set; }

private bool _instructionsParsed;
private DocumentationGroup? _parent;

Expand Down
9 changes: 6 additions & 3 deletions src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ public DocumentationGroup(
IReadOnlyCollection<ITocItem> toc,
IDictionary<string, DocumentationFile> lookup,
IDictionary<string, DocumentationFile[]> folderLookup,
ref int fileIndex,
int depth = 0,
MarkdownFile? index = null
)
{
Depth = depth;
Index = ProcessTocItems(index, toc, lookup, folderLookup, depth, out var groups, out var files, out var navigationItems);
Index = ProcessTocItems(index, toc, lookup, folderLookup, depth, ref fileIndex, out var groups, out var files, out var navigationItems);

GroupsInOrder = groups;
FilesInOrder = files;
Expand All @@ -59,6 +60,7 @@ public DocumentationGroup(
IDictionary<string, DocumentationFile> lookup,
IDictionary<string, DocumentationFile[]> folderLookup,
int depth,
ref int fileIndex,
out List<DocumentationGroup> groups,
out List<MarkdownFile> files,
out List<INavigationItem> navigationItems)
Expand All @@ -75,10 +77,11 @@ public DocumentationGroup(
continue;

md.Parent = this;
md.NavigationIndex = ++fileIndex;

if (file.Children.Count > 0 && d is MarkdownFile virtualIndex)
{
var group = new DocumentationGroup(file.Children, lookup, folderLookup, depth + 1, virtualIndex)
var group = new DocumentationGroup(file.Children, lookup, folderLookup, ref fileIndex, depth + 1, virtualIndex)
{
Parent = this
};
Expand Down Expand Up @@ -108,7 +111,7 @@ public DocumentationGroup(
.ToArray();
}

var group = new DocumentationGroup(children, lookup, folderLookup, depth + 1)
var group = new DocumentationGroup(children, lookup, folderLookup, ref fileIndex, depth + 1)
{
Parent = this
};
Expand Down
3 changes: 1 addition & 2 deletions src/Elastic.Markdown/IO/State/LinkReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public record LinkReference
public static LinkReference Create(DocumentationSet set)
{
var crossLinks = set.Context.Collector.CrossLinks.ToHashSet().ToArray();
var links = set.FlatMappedFiles.Values
.OfType<MarkdownFile>()
var links = set.MarkdownFiles.Values
.Select(m => m.RelativePath).ToArray();
return new LinkReference
{
Expand Down
5 changes: 4 additions & 1 deletion src/Elastic.Markdown/Slices/HtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public async Task<string> RenderLayout(MarkdownFile markdown, Cancel ctx = defau
await DocumentationSet.Tree.Resolve(ctx);
var navigationHtml = await RenderNavigation(markdown, ctx);

var previous = DocumentationSet;
var previous = DocumentationSet.MarkdownFiles.GetValueOrDefault(markdown.NavigationIndex - 1);
var next = DocumentationSet.MarkdownFiles.GetValueOrDefault(markdown.NavigationIndex + 1);

var remote = DocumentationSet.Context.Git.RepositoryName;
var branch = DocumentationSet.Context.Git.Branch;
Expand All @@ -59,6 +60,8 @@ public async Task<string> RenderLayout(MarkdownFile markdown, Cancel ctx = defau
PageTocItems = markdown.TableOfContents.Values.ToList(),
Tree = DocumentationSet.Tree,
CurrentDocument = markdown,
PreviousDocument = previous,
NextDocument = next,
NavigationHtml = navigationHtml,
UrlPathPrefix = markdown.UrlPathPrefix,
Applies = markdown.YamlFrontMatter?.AppliesTo,
Expand Down
2 changes: 2 additions & 0 deletions src/Elastic.Markdown/Slices/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
PageTocItems = Model.PageTocItems,
Tree = Model.Tree,
CurrentDocument = Model.CurrentDocument,
Previous = Model.PreviousDocument,
Next = Model.NextDocument,
NavigationHtml = Model.NavigationHtml,
UrlPathPrefix = Model.UrlPathPrefix,
GithubEditUrl = Model.GithubEditUrl
Expand Down
19 changes: 17 additions & 2 deletions src/Elastic.Markdown/Slices/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,30 @@
<span>Back to top</span>
</button>
<div class="navigation flex print:hidden">
@if (Model.Previous != null)
{
<div class="navigation-previous">
<i class="i-lucide chevron-left"></i>
<a href="@Model.Previous.Url">
<div class="page-info">
<span>Previous</span>
<div class="title">@Model.Previous.NavigationTitle</div>
</div>
</a>
</div>
}
@if (Model.Next != null)
{
<div class="navigation-next">
<a href="elastic/index.html">
<a href="@Model.Next.Url">
<div class="page-info">
<span>Next</span>
<div class="title">Elastic content</div>
<div class="title">@Model.Next.NavigationTitle</div>
</div>
<i class="i-lucide chevron-right"></i>
</a>
</div>
}
</div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/Elastic.Markdown/Slices/_ViewModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class IndexViewModel
public required DocumentationGroup Tree { get; init; }
public required IReadOnlyCollection<PageTocItem> PageTocItems { get; init; }
public required MarkdownFile CurrentDocument { get; init; }
public required MarkdownFile? PreviousDocument { get; init; }
public required MarkdownFile? NextDocument { get; init; }
public required string NavigationHtml { get; init; }
public required string? UrlPathPrefix { get; init; }
public required string? GithubEditUrl { get; init; }
Expand All @@ -26,6 +28,8 @@ public class LayoutViewModel
public required IReadOnlyCollection<PageTocItem> PageTocItems { get; init; }
public required DocumentationGroup Tree { get; init; }
public required MarkdownFile CurrentDocument { get; init; }
public required MarkdownFile? Previous { get; init; }
public required MarkdownFile? Next { get; init; }
public required string NavigationHtml { get; set; }
public required string? UrlPathPrefix { get; set; }
public required string? GithubEditUrl { get; set; }
Expand Down

0 comments on commit d6b668f

Please sign in to comment.