feat: add support for stat sheet SVG rendering

Introduces the ability to discover and render `*.sheet.svg` files.
These files can contain `<text>` elements with `${key}` templates
that reactively update based on the current journal stats.

- Add `StatSheet` type and CLI scanning logic
- Implement `SheetView` for rendering SVGs with live bindings
- Add `parseSheet` utility to extract template patterns from SVG
- Update file indexer to include `.svg` files
This commit is contained in:
2026-07-09 12:04:25 +08:00
parent 4f3b03d082
commit 30d1c5dc1b
9 changed files with 478 additions and 127 deletions
+3 -1
View File
@@ -22,7 +22,7 @@ import {
resolveBlockAs,
parseSparkTableCsv,
} from "./block-scanner.js";
import type { SparkTableCompletion } from "./types.js";
import type { SparkTableCompletion, StatSheet } from "./types.js";
// Re-export shared pieces for convenience
export {
@@ -41,6 +41,7 @@ export interface ProcessedBlocks {
stats: StatDef[];
statTemplates: StatTemplate[];
sparkTables: SparkTableCompletion[];
statSheets: StatSheet[];
}
export interface BlockResult {
@@ -81,6 +82,7 @@ export function processBlocks(
stats: [],
statTemplates: [],
sparkTables: [],
statSheets: [],
};
const stripped = content.replace(
+2
View File
@@ -14,6 +14,7 @@ export type {
SparkTableCompletion,
StatDef,
StatTemplate,
StatSheet,
} from "./types.js";
/**
@@ -33,5 +34,6 @@ export function scanCompletions(
sparkTables: blocks.sparkTables,
stats: blocks.stats,
statTemplates: blocks.statTemplates,
statSheets: blocks.statSheets,
};
}
+13
View File
@@ -6,6 +6,18 @@ import type { StatDef, StatTemplate } from "./stat-parser.js";
export type { StatDef, StatTemplate };
/** A stat sheet discovered from a *.sheet.svg file */
export interface StatSheet {
/** Unique id — filename sans .sheet.svg */
id: string;
/** Display label — from <title> or derived from filename */
label: string;
/** Raw SVG content */
svg: string;
/** Source file path for attribution */
source: string;
}
/** A single dice expression found in a markdown file */
export interface DiceCompletion {
/** Display text shown in the dropdown */
@@ -46,6 +58,7 @@ export interface CompletionsPayload {
sparkTables: SparkTableCompletion[];
stats: StatDef[];
statTemplates: StatTemplate[];
statSheets: StatSheet[];
}
/**