Vibed deck viewer
This commit is contained in:
+155
-2
@@ -30,7 +30,7 @@ foreach (var file in mdFiles)
|
||||
if (endIndex < 0)
|
||||
continue;
|
||||
|
||||
var frontmatter = content[3..endIndex].Trim();
|
||||
var frontmatter = content[3..endIndex].Trim().Replace("\r\n", "\n").Replace("\r", "\n");
|
||||
var yaml = ParseYaml(frontmatter);
|
||||
|
||||
var name = Path.GetFileNameWithoutExtension(file);
|
||||
@@ -117,6 +117,75 @@ writer.WriteLine(" ];");
|
||||
writer.WriteLine("}");
|
||||
|
||||
Console.WriteLine($"Generated {cards.Count} cards in {generatedFile}");
|
||||
|
||||
// ── Decks ──
|
||||
var decksDir = Path.Combine(docsDir, "Decks");
|
||||
var deckFiles = Directory.Exists(decksDir) ? Directory.GetFiles(decksDir, "*.md") : [];
|
||||
var decks = new List<DeckData>();
|
||||
|
||||
foreach (var file in deckFiles)
|
||||
{
|
||||
var content = Encoding.UTF8.GetString(File.ReadAllBytes(file));
|
||||
if (!content.StartsWith("---")) continue;
|
||||
var endIndex = content.IndexOf("---", 3, StringComparison.Ordinal);
|
||||
if (endIndex < 0) continue;
|
||||
|
||||
var frontmatter = content[3..endIndex].Trim().Replace("\r\n", "\n").Replace("\r", "\n");
|
||||
var yaml = ParseYaml(frontmatter);
|
||||
|
||||
var name = Path.GetFileNameWithoutExtension(file);
|
||||
var isVisible = yaml.GetValueOrDefault("isVisible") == "true";
|
||||
|
||||
var deck = new DeckData
|
||||
{
|
||||
Name = name,
|
||||
Cards = ParseList(yaml, "cards").Select(s => StripWikiLink(s) ?? "").Where(s => s != "").ToList(),
|
||||
Keycards = ParseList(yaml, "keycards").Select(s => StripWikiLink(s) ?? "").Where(s => s != "").ToList(),
|
||||
Divers = ParseList(yaml, "divers").Select(s => StripWikiLink(s) ?? "").Where(s => s != "").ToList(),
|
||||
Description = StripWikiLinks(NullIfNa(yaml.GetValueOrDefault("description")))?.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n\n", "\n").Replace("\n\n", "\n"),
|
||||
Factions = ParseList(yaml, "factions").Select(s => StripWikiLink(s) ?? "").Where(s => s != "").ToList(),
|
||||
IsVisible = isVisible,
|
||||
};
|
||||
|
||||
decks.Add(deck);
|
||||
}
|
||||
|
||||
Console.WriteLine($"Parsed {decks.Count} deck files");
|
||||
|
||||
// Generate Decks.g.cs
|
||||
var deckGeneratedFile = Path.Combine(repoRoot, "Chrono", "Web", "Generated", "Decks.g.cs");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(deckGeneratedFile)!);
|
||||
using var deckWriter = new StreamWriter(deckGeneratedFile, false, Encoding.UTF8);
|
||||
deckWriter.WriteLine("// <auto-generated/>");
|
||||
deckWriter.WriteLine("#nullable enable");
|
||||
deckWriter.WriteLine();
|
||||
deckWriter.WriteLine("namespace Chrono.Model;");
|
||||
deckWriter.WriteLine();
|
||||
deckWriter.WriteLine("public static class DeckDatabase");
|
||||
deckWriter.WriteLine("{");
|
||||
deckWriter.WriteLine(" public static readonly System.Collections.Generic.List<DeckData> Decks =");
|
||||
deckWriter.WriteLine(" [");
|
||||
|
||||
for (var i = 0; i < decks.Count; i++)
|
||||
{
|
||||
var d = decks[i];
|
||||
deckWriter.WriteLine(" new()");
|
||||
deckWriter.WriteLine(" {");
|
||||
WriteProp(deckWriter, "Name", d.Name, 3);
|
||||
WriteListProp(deckWriter, "Cards", d.Cards, 3);
|
||||
WriteListProp(deckWriter, "Keycards", d.Keycards, 3);
|
||||
WriteListProp(deckWriter, "Divers", d.Divers, 3);
|
||||
WriteStrProp(deckWriter, "Description", d.Description, 3);
|
||||
WriteListProp(deckWriter, "Factions", d.Factions, 3);
|
||||
deckWriter.WriteLine($" IsVisible = {(d.IsVisible ? "true" : "false")},");
|
||||
var comma = i < decks.Count - 1 ? "," : "";
|
||||
deckWriter.WriteLine($" }}{comma}");
|
||||
}
|
||||
|
||||
deckWriter.WriteLine(" ];");
|
||||
deckWriter.WriteLine("}");
|
||||
|
||||
Console.WriteLine($"Generated {decks.Count} decks in {deckGeneratedFile}");
|
||||
return 0;
|
||||
|
||||
// --- Helpers ---
|
||||
@@ -181,10 +250,48 @@ static Dictionary<string, string> ParseYaml(string yaml)
|
||||
var lines = yaml.Split('\n');
|
||||
string? currentKey = null;
|
||||
var listBuffer = new List<string>();
|
||||
var inBlockScalar = false;
|
||||
string? blockScalarKey = null;
|
||||
var blockScalarLines = new List<string>();
|
||||
string? quoteKey = null;
|
||||
var quoteLines = new List<string>();
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var trimmed = line.Trim();
|
||||
|
||||
if (inBlockScalar)
|
||||
{
|
||||
if (line.Length == 0 || line[0] == ' ' || line[0] == '\t')
|
||||
{
|
||||
blockScalarLines.Add(trimmed);
|
||||
continue;
|
||||
}
|
||||
if (blockScalarKey != null)
|
||||
dict[blockScalarKey] = string.Join("\n", blockScalarLines);
|
||||
inBlockScalar = false;
|
||||
blockScalarKey = null;
|
||||
blockScalarLines.Clear();
|
||||
}
|
||||
|
||||
if (quoteKey != null)
|
||||
{
|
||||
if (line.Length == 0 || line[0] == ' ' || line[0] == '\t')
|
||||
{
|
||||
quoteLines.Add(trimmed);
|
||||
if (trimmed.EndsWith("\""))
|
||||
{
|
||||
dict[quoteKey] = string.Join("\n", quoteLines.Select(UnescapeYaml)).TrimEnd('"');
|
||||
quoteKey = null;
|
||||
quoteLines.Clear();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dict[quoteKey] = string.Join("\n", quoteLines.Select(UnescapeYaml));
|
||||
quoteKey = null;
|
||||
quoteLines.Clear();
|
||||
}
|
||||
|
||||
if (trimmed.Length == 0) continue;
|
||||
|
||||
if (trimmed.StartsWith("- "))
|
||||
@@ -205,16 +312,62 @@ static Dictionary<string, string> ParseYaml(string yaml)
|
||||
currentKey = trimmed[..colonIndex].Trim();
|
||||
var value = trimmed[(colonIndex + 1)..].Trim();
|
||||
|
||||
if (value.Length == 0) continue;
|
||||
if (value is "|" or "|-")
|
||||
{
|
||||
inBlockScalar = true;
|
||||
blockScalarKey = currentKey;
|
||||
blockScalarLines.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.StartsWith("\"") && !value.EndsWith("\""))
|
||||
{
|
||||
quoteKey = currentKey;
|
||||
quoteLines.Clear();
|
||||
quoteLines.Add(value.TrimStart('"'));
|
||||
continue;
|
||||
}
|
||||
|
||||
dict[currentKey] = value;
|
||||
}
|
||||
|
||||
if (listBuffer.Count > 0 && currentKey != null)
|
||||
dict[currentKey] = string.Join("\n", listBuffer);
|
||||
|
||||
if (inBlockScalar && blockScalarKey != null)
|
||||
dict[blockScalarKey] = string.Join("\n", blockScalarLines);
|
||||
|
||||
if (quoteKey != null)
|
||||
dict[quoteKey] = string.Join("\n", quoteLines.Select(UnescapeYaml));
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
static string UnescapeYaml(string s)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (var i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (s[i] == '\\' && i + 1 < s.Length)
|
||||
{
|
||||
switch (s[i + 1])
|
||||
{
|
||||
case 'r': sb.Append('\r'); i++; break;
|
||||
case 'n': sb.Append('\n'); i++; break;
|
||||
case 't': sb.Append('\t'); i++; break;
|
||||
case '\\': sb.Append('\\'); i++; break;
|
||||
case '"': sb.Append('"'); i++; break;
|
||||
default: sb.Append(s[i]); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(s[i]);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
static void WriteProp(StreamWriter w, string name, string value, int indent)
|
||||
{
|
||||
w.WriteLine($"{new string(' ', indent * 4)}{name} = {ToLiteral(value)},");
|
||||
|
||||
Reference in New Issue
Block a user