diff --git a/ET/Console/Program.cs b/ET/Console/Program.cs index 48cc2d0..fa4a099 100644 --- a/ET/Console/Program.cs +++ b/ET/Console/Program.cs @@ -1,10 +1,12 @@ -using System.Text.RegularExpressions; +using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; +using System.Text.RegularExpressions; var exeDir = AppContext.BaseDirectory; var solutionDir = FindContainingDir(exeDir, "ET.sln") - ?? throw new InvalidOperationException("Cannot find ET.sln"); + ?? throw new InvalidOperationException("Cannot find ET.sln"); var srcDir = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Notes")); var dstDir = Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs", "notes")); @@ -18,13 +20,17 @@ if (!Directory.Exists(srcDir)) return 1; } -SyncNotes(srcDir, dstDir); +var entries = SyncNotes(srcDir, dstDir); +CopyOverview(solutionDir, dstDir, entries); +CopyImages(solutionDir, Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs"))); +var indexJson = BuildIndex(entries); +File.WriteAllText(Path.Combine(Path.GetDirectoryName(dstDir)!, "notes-index.json"), indexJson); GenerateMap(srcDir, Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs"))); Console.WriteLine("Done."); return 0; -static void SyncNotes(string srcDir, string dstDir) +static List SyncNotes(string srcDir, string dstDir) { Directory.CreateDirectory(dstDir); @@ -38,16 +44,33 @@ static void SyncNotes(string srcDir, string dstDir) var name = Path.GetFileNameWithoutExtension(file); var slug = Slugify(name); - File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), overwrite: true); + File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), true); string? category = null; + string? cost = null; + string? gearCategory = null; + string? effect = null; + string? location = null; var content = File.ReadAllText(file); var fmMatch = Regex.Match(content, @"^---\s*\n(.*?)\n---", RegexOptions.Singleline); if (fmMatch.Success) { - var catMatch = Regex.Match(fmMatch.Groups[1].Value, @"(?m)^category:\s*(.+)$"); + var fm = fmMatch.Groups[1].Value; + var catMatch = Regex.Match(fm, @"(?m)^category:\s*(.+)$", RegexOptions.IgnoreCase); if (catMatch.Success) category = catMatch.Groups[1].Value.Trim().Trim('"'); + var costMatch = Regex.Match(fm, @"(?m)^cost:\s*(.+)$", RegexOptions.IgnoreCase); + if (costMatch.Success) + cost = costMatch.Groups[1].Value.Trim().Trim('"'); + var gcMatch = Regex.Match(fm, @"(?m)^gear category:\s*(.+)$", RegexOptions.IgnoreCase); + if (gcMatch.Success) + gearCategory = gcMatch.Groups[1].Value.Trim().Trim('"'); + var effMatch = Regex.Match(fm, @"(?m)^effect:\s*(.+)$", RegexOptions.IgnoreCase); + if (effMatch.Success) + effect = effMatch.Groups[1].Value.Trim().Trim('"'); + var locMatch = Regex.Match(fm, @"(?m)^location:\s*(.+)$", RegexOptions.IgnoreCase); + if (locMatch.Success) + location = locMatch.Groups[1].Value.Trim().Trim('"'); } var entry = new Dictionary @@ -57,18 +80,61 @@ static void SyncNotes(string srcDir, string dstDir) }; if (category != null) entry["category"] = category; + if (cost != null) + entry["cost"] = cost; + if (gearCategory != null) + entry["gearCategory"] = gearCategory; + if (effect != null) + entry["effect"] = effect; + if (location != null) + entry["location"] = location; entries.Add(entry); } - var index = new Dictionary { ["notes"] = entries }; - var json = JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true }); - - var indexPath = Path.Combine(Path.GetDirectoryName(dstDir)!, "notes-index.json"); - File.WriteAllText(indexPath, json); - Console.WriteLine($"Copied {entries.Count} notes."); - Console.WriteLine($"Index written to: {indexPath}"); + return entries; +} + +static void CopyOverview(string solutionDir, string dstDir, List entries) +{ + var srcOverview = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Overview.md")); + if (!File.Exists(srcOverview)) return; + + var slug = "overview"; + File.Copy(srcOverview, Path.Combine(dstDir, $"{slug}.md"), true); + + entries.Add(new Dictionary + { + ["slug"] = slug, + ["title"] = "Overview", + ["category"] = "Overview" + }); + + Console.WriteLine("Copied Overview.md."); +} + +static void CopyImages(string solutionDir, string dstDir) +{ + var srcImgs = Path.GetFullPath(Path.Combine(solutionDir, "..", "docs", "Images")); + if (!Directory.Exists(srcImgs)) return; + + var dstImgs = Path.Combine(dstDir, "images"); + Directory.CreateDirectory(dstImgs); + + foreach (var file in Directory.EnumerateFiles(srcImgs)) + { + var name = Path.GetFileName(file); + File.Copy(file, Path.Combine(dstImgs, name), true); + } + + Console.WriteLine($"Copied images from {srcImgs}."); +} + +static string BuildIndex(List entries) +{ + var index = new Dictionary { ["notes"] = entries }; + return JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true }); } static void GenerateMap(string srcDir, string dstDir) @@ -79,7 +145,7 @@ static void GenerateMap(string srcDir, string dstDir) ["Forest"] = "#2e7d32", ["Mountain"] = "#78909c", ["Water"] = "#42a5f5", - ["Wasteland"] = "#8d6e63", + ["Wasteland"] = "#8d6e63" }; var regionFiles = Directory.EnumerateFiles(srcDir, "*.md") @@ -130,19 +196,19 @@ static void GenerateMap(string srcDir, string dstDir) var srcMapImage = Path.GetFullPath(Path.Combine(srcDir, "..", "Images", "Map.png")); var dstMapImage = Path.Combine(dstDir, "Map.png"); if (File.Exists(srcMapImage)) - File.Copy(srcMapImage, dstMapImage, overwrite: true); + File.Copy(srcMapImage, dstMapImage, true); var nameLookup = regions.ToDictionary(r => r.Name); var pad = 60; var maxX = (regions.Count > 0 ? regions.Max(r => r.X) : 0) + pad * 2; var maxY = (regions.Count > 0 ? regions.Max(r => r.Y) : 0) + pad * 2; - var svg = new System.Text.StringBuilder(); + var svg = new StringBuilder(); svg.AppendLine(""); svg.AppendLine(""""""); - svg.AppendLine($""""""); + svg.AppendLine(""""""); foreach (var (terrain, color) in terrainColors) { svg.AppendLine($""""""); @@ -150,17 +216,18 @@ static void GenerateMap(string srcDir, string dstDir) svg.AppendLine($""""""); svg.AppendLine(""); } + svg.AppendLine(""); foreach (var region in regions) + foreach (var conn in region.Connections) { - foreach (var conn in region.Connections) - { - if (!nameLookup.TryGetValue(conn, out var target) || string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) >= 0) - continue; + if (!nameLookup.TryGetValue(conn, out var target) || + string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) >= 0) + continue; - svg.AppendLine($""""""); - } + svg.AppendLine( + $""""""); } foreach (var region in regions) @@ -171,17 +238,20 @@ static void GenerateMap(string srcDir, string dstDir) svg.AppendLine($""""""); svg.AppendLine($""""""); - svg.AppendLine($""""""); + svg.AppendLine( + $""""""); var labelX = cx + 24; - svg.AppendLine($""""""); - svg.Append(System.Text.Encodings.Web.HtmlEncoder.Default.Encode(region.Name)); + svg.AppendLine( + $""""""); + svg.Append(HtmlEncoder.Default.Encode(region.Name)); svg.AppendLine(""); foreach (var lm in region.Landmarks) { - svg.AppendLine($""""""); - svg.Append(System.Text.Encodings.Web.HtmlEncoder.Default.Encode($"\u2605 {lm}")); + svg.AppendLine( + $""""""); + svg.Append(HtmlEncoder.Default.Encode($"\u2605 {lm}")); svg.AppendLine(""); } @@ -231,10 +301,11 @@ static string? FindContainingDir(string startDir, string markerFile) return dir.FullName; dir = dir.Parent; } + return null; } -class RegionData +internal class RegionData { public string Name { get; set; } = ""; public string Slug { get; set; } = ""; @@ -243,5 +314,4 @@ class RegionData public int Y { get; set; } public List Connections { get; set; } = new(); public List Landmarks { get; set; } = new(); -} - +} \ No newline at end of file diff --git a/ET/Web/App.razor b/ET/Web/App.razor index 3e84bca..735b1ff 100644 --- a/ET/Web/App.razor +++ b/ET/Web/App.razor @@ -1,4 +1,5 @@ - +@using Web.Pages + diff --git a/ET/Web/Layout/MainLayout.razor b/ET/Web/Layout/MainLayout.razor index fdc3d5d..29a0f6f 100644 --- a/ET/Web/Layout/MainLayout.razor +++ b/ET/Web/Layout/MainLayout.razor @@ -5,7 +5,9 @@
- @Body + + @Body +
\ No newline at end of file diff --git a/ET/Web/Layout/MainLayout.razor.css b/ET/Web/Layout/MainLayout.razor.css index ecf25e5..96750bb 100644 --- a/ET/Web/Layout/MainLayout.razor.css +++ b/ET/Web/Layout/MainLayout.razor.css @@ -9,7 +9,8 @@ main { } .sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); + background-color: var(--bg-sidebar); + border-right: 1px solid var(--border-color); } .top-row { @@ -21,20 +22,20 @@ main { align-items: center; } - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } +.top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; +} - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } +.top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; +} - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } +.top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; +} @media (max-width: 640.98px) { .top-row { diff --git a/ET/Web/Layout/NavMenu.razor b/ET/Web/Layout/NavMenu.razor index 6525fc7..c8fbce2 100644 --- a/ET/Web/Layout/NavMenu.razor +++ b/ET/Web/Layout/NavMenu.razor @@ -1,8 +1,10 @@ -@inject Web.Services.DocsService DocsService +@inject DocsService DocsService