diff --git a/ZeroSpace/ZeroSpace.Web/Services/ZeroSpaceLinks.cs b/ZeroSpace/ZeroSpace.Web/Services/ZeroSpaceLinks.cs new file mode 100644 index 0000000..9b8c734 --- /dev/null +++ b/ZeroSpace/ZeroSpace.Web/Services/ZeroSpaceLinks.cs @@ -0,0 +1,45 @@ +using System.Text.RegularExpressions; +using ZeroSpace.Model; + +namespace ZeroSpace.Web.Services; + +public static partial class ZeroSpaceLinks +{ + private static readonly IReadOnlyDictionary SystemUrls = StarSystems.All + .ToDictionary(static system => system.Name, static system => $"/StarSystem/{system.Id}", StringComparer.OrdinalIgnoreCase); + + private static readonly IReadOnlyDictionary MasteryUrls = SystemMasteries.All + .ToDictionary(static mastery => mastery.Name, static mastery => $"/SystemMastery/{mastery.Id}", StringComparer.OrdinalIgnoreCase); + + public static string? UrlFor(string name) + { + if (SystemUrls.TryGetValue(name, out var systemUrl)) + { + return systemUrl; + } + + return MasteryUrls.TryGetValue(name, out var masteryUrl) ? masteryUrl : null; + } + + public static string ResolveWikiLinks(string markdown) + { + return WikiLinkPattern().Replace(markdown, match => + { + var name = match.Groups[1].Value.Trim(); + var url = UrlFor(name); + return url is null ? name : $"[{name}]({url})"; + }); + } + + public static string Humanize(string camelCase) + { + var spaced = CamelCasePattern().Replace(camelCase, " "); + return spaced.Length == 0 ? spaced : char.ToUpperInvariant(spaced[0]) + spaced[1..]; + } + + [GeneratedRegex(@"\[\[([^\]]+)\]\]")] + private static partial Regex WikiLinkPattern(); + + [GeneratedRegex("(?<=[a-z0-9])(?=[A-Z])")] + private static partial Regex CamelCasePattern(); +}