From 6bf1b872074d064ed3460b28d772a199bcf6d149 Mon Sep 17 00:00:00 2001 From: 6d486f49 Date: Wed, 10 Jun 2026 21:35:28 -0400 Subject: [PATCH] ... --- ET/Web/Models/NoteInfo.cs | 2 + ET/Web/Pages/DocViewer.razor | 8 +- ET/Web/Pages/Docs.razor | 8 +- ET/Web/Services/DocsService.cs | 13 ++ ET/Web/SyncDocs.ps1 | 13 +- ET/Web/wwwroot/css/app.css | 17 ++- ET/Web/wwwroot/docs/notes-index.json | 210 ++++++++++++++++----------- 7 files changed, 183 insertions(+), 88 deletions(-) diff --git a/ET/Web/Models/NoteInfo.cs b/ET/Web/Models/NoteInfo.cs index 5bddc7f..d9c5558 100644 --- a/ET/Web/Models/NoteInfo.cs +++ b/ET/Web/Models/NoteInfo.cs @@ -4,6 +4,7 @@ public class NoteInfo { public string Slug { get; set; } = ""; public string Title { get; set; } = ""; + public string? Category { get; set; } } public class NotesIndex @@ -15,6 +16,7 @@ public class NoteDocument { public string Slug { get; set; } = ""; public string Title { get; set; } = ""; + public string? Category { get; set; } public string FrontmatterHtml { get; set; } = ""; public string HtmlContent { get; set; } = ""; } diff --git a/ET/Web/Pages/DocViewer.razor b/ET/Web/Pages/DocViewer.razor index 1c2f364..c18289b 100644 --- a/ET/Web/Pages/DocViewer.razor +++ b/ET/Web/Pages/DocViewer.razor @@ -15,7 +15,13 @@ else if (doc == null) } else { -

@doc.Title

+

+ @doc.Title + @if (!string.IsNullOrEmpty(doc.Category)) + { + @doc.Category + } +

@if (!string.IsNullOrEmpty(doc.FrontmatterHtml)) { diff --git a/ET/Web/Pages/Docs.razor b/ET/Web/Pages/Docs.razor index 59dda5c..a4133fc 100644 --- a/ET/Web/Pages/Docs.razor +++ b/ET/Web/Pages/Docs.razor @@ -15,7 +15,13 @@ else @foreach (var note in notes.OrderBy(n => n.Title)) { -

@note.Title

+

+ @note.Title + @if (!string.IsNullOrEmpty(note.Category)) + { + @note.Category + } +

} diff --git a/ET/Web/Services/DocsService.cs b/ET/Web/Services/DocsService.cs index 5bd1a4d..535efd0 100644 --- a/ET/Web/Services/DocsService.cs +++ b/ET/Web/Services/DocsService.cs @@ -82,6 +82,19 @@ public class DocsService if (frontmatterLines.Count > 0) { + foreach (var line in frontmatterLines) + { + var colonIdx = line.IndexOf(':'); + if (colonIdx > 0) + { + var key = line[..colonIdx].Trim(); + if (string.Equals(key, "category", StringComparison.OrdinalIgnoreCase)) + { + doc.Category = line[(colonIdx + 1)..].Trim().Trim('"'); + } + } + } + var fmHtml = new System.Text.StringBuilder(); fmHtml.Append(""); foreach (var line in frontmatterLines) diff --git a/ET/Web/SyncDocs.ps1 b/ET/Web/SyncDocs.ps1 index 89a7baf..580f59e 100644 --- a/ET/Web/SyncDocs.ps1 +++ b/ET/Web/SyncDocs.ps1 @@ -16,7 +16,18 @@ Get-ChildItem -Path $src -Filter "*.md" | ForEach-Object { Copy-Item $_.FullName (Join-Path $dst "$slug.md") - $entries += @{ slug = $slug; title = $base } + $category = $null + $content = Get-Content $_.FullName -Raw + if ($content -match '(?s)^---\s*\n(.*?)\n---') { + $frontmatter = $Matches[1] + if ($frontmatter -match '(?m)^category:\s*(.+)$') { + $category = $Matches[1].Trim().Trim('"') + } + } + + $entry = @{ slug = $slug; title = $base } + if ($category) { $entry.category = $category } + $entries += $entry } $indexPath = "$PSScriptRoot\wwwroot\docs\notes-index.json" diff --git a/ET/Web/wwwroot/css/app.css b/ET/Web/wwwroot/css/app.css index 1f93b02..3353d89 100644 --- a/ET/Web/wwwroot/css/app.css +++ b/ET/Web/wwwroot/css/app.css @@ -198,4 +198,19 @@ table.frontmatter td.fm-key { .markdown-body th { background: #f8f9fa; } .markdown-body code { background: #f0f0f0; padding: 0.15rem 0.3rem; border-radius: 3px; font-size: 0.9em; } .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; } \ No newline at end of file +.markdown-body blockquote { border-left: 3px solid #dee2e6; padding-left: 1rem; color: #6c757d; margin: 0.75rem 0; } + +.category-badge { + display: inline-block; + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + padding: 0.2em 0.6em; + border-radius: 4px; + vertical-align: middle; + margin-left: 0.5rem; + background: #e8f4fd; + color: #1b6ec2; + border: 1px solid #b8daff; +} \ No newline at end of file diff --git a/ET/Web/wwwroot/docs/notes-index.json b/ET/Web/wwwroot/docs/notes-index.json index 58c9e87..2fe084d 100644 --- a/ET/Web/wwwroot/docs/notes-index.json +++ b/ET/Web/wwwroot/docs/notes-index.json @@ -1,24 +1,27 @@ { "notes": [ { - "slug": "artificer", - "title": "Artificer" + "title": "Artificer", + "category": "Role", + "slug": "artificer" }, { "slug": "awareness", "title": "Awareness" }, { - "slug": "cache-map", - "title": "Cache Map" + "title": "Cache Map", + "category": "Gear", + "slug": "cache-map" }, { "slug": "card-library", "title": "Card Library" }, { - "slug": "concoliator", - "title": "Concoliator" + "title": "Concoliator", + "category": "Role", + "slug": "concoliator" }, { "slug": "contents", @@ -41,12 +44,14 @@ "title": "Dirt Roads" }, { - "slug": "dolewood-canoe", - "title": "Dolewood Canoe" + "title": "Dolewood Canoe", + "category": "Gear", + "slug": "dolewood-canoe" }, { - "slug": "e03", - "title": "E.03" + "title": "E.03", + "category": "Event", + "slug": "e03" }, { "slug": "ecology", @@ -73,80 +78,95 @@ "title": "Explore Phase" }, { - "slug": "explorer", - "title": "Explorer" + "title": "Explorer", + "category": "Role", + "slug": "explorer" }, { - "slug": "ferinodex", - "title": "Ferinodex" + "title": "Ferinodex", + "category": "Gear", + "slug": "ferinodex" }, { "slug": "flora-meeples", "title": "Flora Meeples" }, { - "slug": "forest-1", - "title": "Forest 1" + "title": "Forest 1", + "category": "Region", + "slug": "forest-1" }, { - "slug": "forest-2", - "title": "Forest 2" + "title": "Forest 2", + "category": "Region", + "slug": "forest-2" }, { - "slug": "forest-3", - "title": "Forest 3" + "title": "Forest 3", + "category": "Region", + "slug": "forest-3" }, { - "slug": "forest-4", - "title": "Forest 4" + "title": "Forest 4", + "category": "Region", + "slug": "forest-4" }, { - "slug": "forest-5", - "title": "Forest 5" + "title": "Forest 5", + "category": "Region", + "slug": "forest-5" }, { "slug": "forest", "title": "Forest" }, { - "slug": "gauzeblade", - "title": "Gauzeblade" + "title": "Gauzeblade", + "category": "Gear", + "slug": "gauzeblade" }, { "slug": "gear-cards", "title": "Gear Cards" }, { - "slug": "grass-1", - "title": "Grass 1" + "title": "Grass 1", + "category": "Region", + "slug": "grass-1" }, { - "slug": "grass-2", - "title": "Grass 2" + "title": "Grass 2", + "category": "Region", + "slug": "grass-2" }, { - "slug": "grass-3", - "title": "Grass 3" + "title": "Grass 3", + "category": "Region", + "slug": "grass-3" }, { - "slug": "grass-4", - "title": "Grass 4" + "title": "Grass 4", + "category": "Region", + "slug": "grass-4" }, { - "slug": "grass-5", - "title": "Grass 5" + "title": "Grass 5", + "category": "Region", + "slug": "grass-5" }, { "slug": "grasslands", "title": "Grasslands" }, { - "slug": "guide", - "title": "Guide" + "title": "Guide", + "category": "Role", + "slug": "guide" }, { - "slug": "hidden-trail-map", - "title": "Hidden Trail Map" + "title": "Hidden Trail Map", + "category": "Gear", + "slug": "hidden-trail-map" }, { "slug": "injury-cards", @@ -165,44 +185,52 @@ "title": "Market" }, { - "slug": "mountain-1", - "title": "Mountain 1" + "title": "Mountain 1", + "category": "Region", + "slug": "mountain-1" }, { - "slug": "mountain-2", - "title": "Mountain 2" + "title": "Mountain 2", + "category": "Region", + "slug": "mountain-2" }, { - "slug": "mountain-3", - "title": "Mountain 3" + "title": "Mountain 3", + "category": "Region", + "slug": "mountain-3" }, { - "slug": "mountain-4", - "title": "Mountain 4" + "title": "Mountain 4", + "category": "Region", + "slug": "mountain-4" }, { - "slug": "mountain-5", - "title": "Mountain 5" + "title": "Mountain 5", + "category": "Region", + "slug": "mountain-5" }, { "slug": "mountain", "title": "Mountain" }, { - "slug": "paratrepsis-whistle", - "title": "Paratrepsis Whistle" + "title": "Paratrepsis Whistle", + "category": "Gear", + "slug": "paratrepsis-whistle" }, { "slug": "paved-roads", "title": "Paved Roads" }, { - "slug": "perfect-day-1", - "title": "Perfect Day 1" + "title": "Perfect Day 1", + "category": "Event", + "slug": "perfect-day-1" }, { - "slug": "phonoscopic-headset", - "title": "Phonoscopic Headset" + "title": "Phonoscopic Headset", + "category": "Gear", + "slug": "phonoscopic-headset" }, { "slug": "player-boards", @@ -257,20 +285,23 @@ "title": "Round" }, { - "slug": "ruins-map", - "title": "Ruins Map" + "title": "Ruins Map", + "category": "Gear", + "slug": "ruins-map" }, { "slug": "scout", "title": "Scout" }, { - "slug": "shaper", - "title": "Shaper" + "title": "Shaper", + "category": "Role", + "slug": "shaper" }, { - "slug": "shepard", - "title": "Shepard" + "title": "Shepard", + "category": "Role", + "slug": "shepard" }, { "slug": "story", @@ -281,32 +312,37 @@ "title": "Supply" }, { - "slug": "terrain-2", - "title": "Terrain 2" + "title": "Terrain 2", + "category": "Terrain", + "slug": "terrain-2" }, { - "slug": "terrain-3", - "title": "Terrain 3" + "title": "Terrain 3", + "category": "Terrain", + "slug": "terrain-3" }, { "slug": "terrain-cards", "title": "Terrain Cards" }, { - "slug": "terrain", - "title": "Terrain" + "title": "Terrain", + "category": "Terrain", + "slug": "terrain" }, { - "slug": "totem-of-the-irix", - "title": "Totem of the Irix" + "title": "Totem of the Irix", + "category": "Gear", + "slug": "totem-of-the-irix" }, { "slug": "trade", "title": "Trade" }, { - "slug": "trader", - "title": "Trader" + "title": "Trader", + "category": "Role", + "slug": "trader" }, { "slug": "trail-markers", @@ -333,32 +369,38 @@ "title": "Victory Condition" }, { - "slug": "wasteland-1", - "title": "Wasteland 1" + "title": "Wasteland 1", + "category": "Region", + "slug": "wasteland-1" }, { "slug": "wasteland", "title": "Wasteland" }, { - "slug": "water-1", - "title": "Water 1" + "title": "Water 1", + "category": "Region", + "slug": "water-1" }, { - "slug": "water-2", - "title": "Water 2" + "title": "Water 2", + "category": "Region", + "slug": "water-2" }, { - "slug": "water-3", - "title": "Water 3" + "title": "Water 3", + "category": "Region", + "slug": "water-3" }, { - "slug": "water-4", - "title": "Water 4" + "title": "Water 4", + "category": "Region", + "slug": "water-4" }, { - "slug": "water-5", - "title": "Water 5" + "title": "Water 5", + "category": "Region", + "slug": "water-5" }, { "slug": "weather",