diff --git a/src/Elastic.Markdown/Helpers/IdExtensions.cs b/src/Elastic.Markdown/Helpers/IdExtensions.cs new file mode 100644 index 000000000..1dda142ca --- /dev/null +++ b/src/Elastic.Markdown/Helpers/IdExtensions.cs @@ -0,0 +1,13 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// 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.Security.Cryptography; +using System.Text; + +namespace Elastic.Markdown.Helpers; + +public static class ShortId +{ + public static string Create(params string[] components) => Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(string.Join("", components))))[..8]; +} diff --git a/src/Elastic.Markdown/IO/MarkdownFile.cs b/src/Elastic.Markdown/IO/MarkdownFile.cs index 3c533824e..ecf034ca4 100644 --- a/src/Elastic.Markdown/IO/MarkdownFile.cs +++ b/src/Elastic.Markdown/IO/MarkdownFile.cs @@ -4,6 +4,8 @@ using System.IO.Abstractions; using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; using Elastic.Documentation.Diagnostics; using Elastic.Documentation.Navigation; using Elastic.Markdown.Diagnostics; @@ -51,6 +53,7 @@ DocumentationSet set _configurationFile = build.Configuration.SourceFile; _globalSubstitutions = build.Configuration.Substitutions; _set = set; + Id = ShortId.Create(FilePath); //may be updated by DocumentationGroup.ProcessTocItems //todo refactor mutability of MarkdownFile as a whole ScopeDirectory = build.Configuration.ScopeDirectory; @@ -65,7 +68,7 @@ DocumentationSet set public Uri NavigationSource { get; set; } - public string Id { get; } = Guid.NewGuid().ToString("N")[..8]; + public string Id { get; } private IDiagnosticsCollector Collector { get; } diff --git a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs index 1c31bcf8c..d9c9ccea5 100644 --- a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs +++ b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs @@ -4,8 +4,11 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; +using System.Text; using Elastic.Documentation; using Elastic.Documentation.Configuration.TableOfContents; +using Elastic.Markdown.Helpers; namespace Elastic.Markdown.IO.Navigation; @@ -125,7 +128,7 @@ public class DocumentationGroup : INavigationGroup { private readonly TableOfContentsTreeCollector _treeCollector; - public string Id { get; } = Guid.NewGuid().ToString("N")[..8]; + public string Id { get; } public string NavigationRootId => NavigationRoot.Id; @@ -196,7 +199,7 @@ protected DocumentationGroup( GroupsInOrder = groups; FilesInOrder = files; NavigationItems = navigationItems; - + Id = ShortId.Create(NavigationSource.ToString(), FolderName); if (Index is not null) FilesInOrder = [.. FilesInOrder.Except([Index])]; } diff --git a/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs b/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs index f9b8ed0b6..7a73c8997 100644 --- a/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs +++ b/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs @@ -1,7 +1,10 @@ // Licensed to Elasticsearch B.V under one or more agreements. // 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.Security.Cryptography; using System.Text; +using Elastic.Markdown.Helpers; using Elastic.Markdown.Myst.Settings; namespace Elastic.Markdown.Slices.Directives; @@ -56,7 +59,13 @@ public class ImageViewModel public required string? Target { get; init; } public required string? Width { get; init; } public required string? ImageUrl { get; init; } - public string UniqueImageId { get; } = Guid.NewGuid().ToString("N")[..8]; + + private string? _uniqueImageId; + + public string UniqueImageId => + _uniqueImageId ??= string.IsNullOrEmpty(ImageUrl) + ? Guid.NewGuid().ToString("N")[..8] // fallback to a random ID if ImageUrl is null or empty + : ShortId.Create(ImageUrl); public required string? Screenshot { get; init; } public string Style diff --git a/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml b/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml index 43b34754b..b4288a441 100644 --- a/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml +++ b/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml @@ -2,9 +2,7 @@