From 7291c3565f82273aca169769e0523e653ab9276b Mon Sep 17 00:00:00 2001 From: 6d486f49 Date: Wed, 10 Jun 2026 22:11:00 -0400 Subject: [PATCH] ... --- ET/Console/Program.cs | 209 +++++++++++++++--- ET/Web/Pages/Home.razor | 12 +- ET/Web/wwwroot/css/app.css | 15 ++ ET/Web/wwwroot/docs/map.svg | 154 +++++++++++++ docs/.obsidian/workspace.json | 8 +- ...e a map of regions and how they connect.md | 9 + docs/_Tasks.base | 5 +- 7 files changed, 370 insertions(+), 42 deletions(-) create mode 100644 ET/Web/wwwroot/docs/map.svg create mode 100644 docs/Tasks/Generate a map of regions and how they connect.md diff --git a/ET/Console/Program.cs b/ET/Console/Program.cs index 8962163..59fa2c2 100644 --- a/ET/Console/Program.cs +++ b/ET/Console/Program.cs @@ -1,4 +1,5 @@ using System.Text.RegularExpressions; +using System.Text.Json; var exeDir = AppContext.BaseDirectory; @@ -17,53 +18,185 @@ if (!Directory.Exists(srcDir)) return 1; } -Directory.CreateDirectory(dstDir); +SyncNotes(srcDir, dstDir); +GenerateMap(srcDir, Path.GetFullPath(Path.Combine(solutionDir, "Web", "wwwroot", "docs"))); -foreach (var file in Directory.GetFiles(dstDir)) - File.Delete(file); +Console.WriteLine("Done."); +return 0; -var entries = new List(); - -foreach (var file in Directory.EnumerateFiles(srcDir, "*.md")) +static void SyncNotes(string srcDir, string dstDir) { - var name = Path.GetFileNameWithoutExtension(file); - var slug = Slugify(name); + Directory.CreateDirectory(dstDir); - File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), overwrite: true); + foreach (var file in Directory.GetFiles(dstDir)) + File.Delete(file); - string? category = null; - var content = File.ReadAllText(file); - var fmMatch = Regex.Match(content, @"^---\s*\n(.*?)\n---", RegexOptions.Singleline); - if (fmMatch.Success) + var entries = new List(); + + foreach (var file in Directory.EnumerateFiles(srcDir, "*.md")) { - var catMatch = Regex.Match(fmMatch.Groups[1].Value, @"(?m)^category:\s*(.+)$"); - if (catMatch.Success) - category = catMatch.Groups[1].Value.Trim().Trim('"'); + var name = Path.GetFileNameWithoutExtension(file); + var slug = Slugify(name); + + File.Copy(file, Path.Combine(dstDir, $"{slug}.md"), overwrite: true); + + string? category = 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*(.+)$"); + if (catMatch.Success) + category = catMatch.Groups[1].Value.Trim().Trim('"'); + } + + var entry = new Dictionary + { + ["slug"] = slug, + ["title"] = name + }; + if (category != null) + entry["category"] = category; + + entries.Add(entry); } - var entry = new Dictionary - { - ["slug"] = slug, - ["title"] = name - }; - if (category != null) - entry["category"] = category; + var index = new Dictionary { ["notes"] = entries }; + var json = JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true }); - entries.Add(entry); + 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}"); } -var index = new Dictionary { ["notes"] = entries }; -var json = System.Text.Json.JsonSerializer.Serialize(index, new System.Text.Json.JsonSerializerOptions +static void GenerateMap(string srcDir, string dstDir) { - WriteIndented = true -}); + var terrainColors = new Dictionary + { + ["Grass"] = "#4caf50", + ["Forest"] = "#2e7d32", + ["Mountain"] = "#78909c", + ["Water"] = "#42a5f5", + ["Wasteland"] = "#8d6e63", + }; -var indexPath = Path.Combine(Path.GetDirectoryName(dstDir)!, "notes-index.json"); -File.WriteAllText(indexPath, json); + var regionFiles = Directory.EnumerateFiles(srcDir, "*.md") + .Select(f => (File: f, Content: File.ReadAllText(f))) + .Where(t => Regex.IsMatch(t.Content, @"(?m)^category:\s*Region$")) + .ToList(); -Console.WriteLine($"Copied {entries.Count} notes."); -Console.WriteLine($"Index written to: {indexPath}"); -return 0; + var regions = new List(); + + foreach (var (file, content) in regionFiles) + { + var fmMatch = Regex.Match(content, @"^---\s*\n(.*?)\n---", RegexOptions.Singleline); + if (!fmMatch.Success) continue; + + var fm = fmMatch.Groups[1].Value; + var name = Path.GetFileNameWithoutExtension(file); + + var xMatch = Regex.Match(fm, @"(?m)^X:\s*(\d+)"); + var yMatch = Regex.Match(fm, @"(?m)^Y:\s*(\d+)"); + if (!xMatch.Success || !yMatch.Success) continue; + + var connMatches = Regex.Matches(fm, @"\[\[([^\]]+)\]\]"); + var conns = connMatches.Select(m => m.Groups[1].Value).ToList(); + + var landmarks = new List(); + var lmSection = Regex.Match(fm, @"Landmarks:\s*\n((?:\s*-\s*""\[\[([^\]]+)\]\]""\s*\n?)*)"); + if (lmSection.Success) + { + var lmEntries = Regex.Matches(lmSection.Groups[1].Value, @"\[\[([^\]]+)\]\]"); + landmarks.AddRange(lmEntries.Select(m => m.Groups[1].Value)); + } + + var terrain = name.Split(' ')[0]; + + regions.Add(new RegionData + { + Name = name, + Terrain = terrain, + X = int.Parse(xMatch.Groups[1].Value), + Y = int.Parse(yMatch.Groups[1].Value), + Connections = conns, + Landmarks = landmarks + }); + } + + var nameLookup = regions.ToDictionary(r => r.Name); + + var pad = 60; + var maxX = regions.Max(r => r.X) + pad * 2; + var maxY = regions.Max(r => r.Y) + pad * 2; + + var svg = new System.Text.StringBuilder(); + svg.AppendLine($""); + + svg.AppendLine($""""""); + + svg.AppendLine($""""""); + foreach (var (terrain, color) in terrainColors) + { + svg.AppendLine($""""""); + svg.AppendLine($""""""); + svg.AppendLine($""""""); + svg.AppendLine(""); + } + svg.AppendLine(""); + + foreach (var region in regions) + { + foreach (var conn in region.Connections) + { + if (!nameLookup.TryGetValue(conn, out var target) || string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) >= 0) + continue; + + svg.AppendLine($""""""); + } + } + + foreach (var region in regions) + { + var cx = region.X + pad; + var cy = region.Y + pad; + var color = terrainColors.GetValueOrDefault(region.Terrain, "#888"); + + svg.AppendLine($""""""); + svg.AppendLine($""""""); + + var labelX = cx + 24; + svg.AppendLine($""""""); + svg.Append(System.Text.Encodings.Web.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(""); + } + } + + var legendX = maxX - 160; + var legendY = 20; + svg.AppendLine($""""""); + svg.AppendLine($"""Legend"""); + var ly = legendY + 32; + foreach (var (terrain, color) in terrainColors) + { + svg.AppendLine($""""""); + svg.AppendLine($"""{terrain}"""); + ly += 22; + } + + svg.AppendLine(""); + + var mapPath = Path.Combine(dstDir, "map.svg"); + File.WriteAllText(mapPath, svg.ToString()); + Console.WriteLine($"Map written to: {mapPath} ({regions.Count} regions)"); +} static string Slugify(string name) { @@ -90,3 +223,13 @@ static string? FindContainingDir(string startDir, string markerFile) return null; } +class RegionData +{ + public string Name { get; set; } = ""; + public string Terrain { get; set; } = ""; + public int X { get; set; } + public int Y { get; set; } + public List Connections { get; set; } = new(); + public List Landmarks { get; set; } = new(); +} + diff --git a/ET/Web/Pages/Home.razor b/ET/Web/Pages/Home.razor index dfcdf75..1ddabb4 100644 --- a/ET/Web/Pages/Home.razor +++ b/ET/Web/Pages/Home.razor @@ -1,7 +1,13 @@ @page "/" -Home +Earthborne Trailblazer -

Hello, world!

+

Earthborne Trailblazer

-Welcome to your new app. \ No newline at end of file +
+ +
+ +

+ Browse documentation → +

\ No newline at end of file diff --git a/ET/Web/wwwroot/css/app.css b/ET/Web/wwwroot/css/app.css index 3353d89..1a052fa 100644 --- a/ET/Web/wwwroot/css/app.css +++ b/ET/Web/wwwroot/css/app.css @@ -200,6 +200,21 @@ table.frontmatter td.fm-key { .markdown-body pre code { background: none; padding: 0; } .markdown-body blockquote { border-left: 3px solid #dee2e6; padding-left: 1rem; color: #6c757d; margin: 0.75rem 0; } +.map-container { + max-width: 100%; + margin: 1.5rem 0; + border: 1px solid #dee2e6; + border-radius: 8px; + overflow: hidden; + background: #1a1a2e; +} + +.map-svg { + width: 100%; + height: auto; + display: block; +} + .category-badge { display: inline-block; font-size: 0.7rem; diff --git a/ET/Web/wwwroot/docs/map.svg b/ET/Web/wwwroot/docs/map.svg new file mode 100644 index 0000000..dc4cdf1 --- /dev/null +++ b/ET/Web/wwwroot/docs/map.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Forest 1 + + + +Forest 2 + + + +Forest 3 + + + +Forest 4 + + + +Forest 5 + + + +Grass 1 + +★ Lone Tree Station + + + +Grass 2 + +★ Spire + + + +Grass 3 + + + +Grass 4 + + + +Grass 5 + + + +Mountain 1 + + + +Mountain 2 + + + +Mountain 3 + + + +Mountain 4 + + + +Mountain 5 + + + +Wasteland 1 + + + +Water 1 + +★ Research Station + + + +Water 2 + +★ White Sky + + + +Water 3 + + + +Water 4 + + + +Water 5 + +Legend + +Grass + +Forest + +Mountain + +Water + +Wasteland + diff --git a/docs/.obsidian/workspace.json b/docs/.obsidian/workspace.json index 758440d..1bf7d90 100644 --- a/docs/.obsidian/workspace.json +++ b/docs/.obsidian/workspace.json @@ -117,12 +117,12 @@ "state": { "type": "markdown", "state": { - "file": "Tasks/Generate a map of regions and how they connect.md", + "file": "Tasks/Generate a csharp script to do what you did.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "Generate a map of regions and how they connect" + "title": "Generate a csharp script to do what you did" } } ], @@ -290,12 +290,13 @@ }, "active": "a4f3f788b08f3cf9", "lastOpenFiles": [ + "Tasks/Generate a Markdown Website.md", "_Tasks.base", + "Tasks/Generate a csharp script to do what you did.md", "Tasks/Generate a map of regions and how they connect.md", "Bases/_Roles.base", "_Overview.md", "Bases/Regions.base", - "Tasks/Generate a Markdown Website.md", "Untitled 2.md", "Tasks", "Notes/Artificer.md", @@ -333,7 +334,6 @@ "Notes/Mountain 5.md", "Notes/Mountain 4.md", "Notes/Mountain 3.md", - "Notes/Mountain 2.md", "Bases" ] } \ No newline at end of file diff --git a/docs/Tasks/Generate a map of regions and how they connect.md b/docs/Tasks/Generate a map of regions and how they connect.md new file mode 100644 index 0000000..cbab785 --- /dev/null +++ b/docs/Tasks/Generate a map of regions and how they connect.md @@ -0,0 +1,9 @@ +--- +category: Task +status: Done +--- +Create me an image that will represent a map that a player can travel all. + +Area's a player can travel to are called regions. Find the region data by checking the markdown files with the category of region in their front matter. + +The connection frontmatter are how the region connects. Make the regions circles, and draw lines between regions on where they connect. Use the X and Y frontmatter to determine the placement of the regions. \ No newline at end of file diff --git a/docs/_Tasks.base b/docs/_Tasks.base index 5f639d6..70448bd 100644 --- a/docs/_Tasks.base +++ b/docs/_Tasks.base @@ -135,10 +135,11 @@ views: cardOrders: file.file: {} note.status: - Working On: - - Map.md + Working On: [] Done: - Tasks/Generate a Markdown Website.md + - Generate a csharp script to do what you did.md + - Tasks/Generate a map of regions and how they connect.md Uncategorized: [] columnColors: file.file: {}