Files
ttrpg-tools/src/components/doc-data.ts
T
hypercross 99dd49b077 refactor: simplify DocDialog and move documentation to markdown body
Simplify the `DocDialog` component by removing hardcoded property
tables and syntax blocks. Instead, rely on the raw markdown body
provided in the `DocEntry` to render documentation content. This
shifts the responsibility of formatting (syntax, props, etc.) from
the component to the individual markdown files, allowing for more
flexible and detailed documentation.
2026-07-13 15:29:08 +08:00

80 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import yaml from "js-yaml";
export interface DocEntry {
tag: string;
icon: string;
title: string;
/** Full markdown body (everything after frontmatter ---) */
body: string;
}
/** Splits frontmatter and markdown body from a raw .md string. */
function parseFrontmatter(raw: string): Record<string, unknown> | null {
const normalized = raw.replace(/\r\n/g, "\n");
const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
if (!match) return null;
try {
return yaml.load(match[1]) as Record<string, unknown>;
} catch {
return null;
}
}
function getBody(raw: string): string {
const normalized = raw.replace(/\r\n/g, "\n");
const match = normalized.match(/^---\n[\s\S]*?\n---\n?([\s\S]*)$/);
return (match ? match[1] : raw).trim();
}
function parseEntry(raw: string): DocEntry | null {
const fm = parseFrontmatter(raw);
if (!fm) return null;
return {
tag: fm.tag as string,
icon: fm.icon as string,
title: fm.title as string,
body: getBody(raw),
};
}
// Static imports each .md file is asset/source so imports are strings.
// Add a new import here when creating a new doc entry.
import mdDiceRaw from "../doc-entries/md-dice.md";
import mdTableRaw from "../doc-entries/md-table.md";
import mdLinkRaw from "../doc-entries/md-link.md";
import mdPinsRaw from "../doc-entries/md-pins.md";
import mdFontRaw from "../doc-entries/md-font.md";
import mdBgRaw from "../doc-entries/md-bg.md";
import mdBorderRaw from "../doc-entries/md-border.md";
import mdEmbedRaw from "../doc-entries/md-embed.md";
import mdDeckRaw from "../doc-entries/md-deck.md";
import mdYarnRaw from "../doc-entries/md-yarn-spinner.md";
import mdCommanderRaw from "../doc-entries/md-commander.md";
const rawDocuments: string[] = [
mdDiceRaw,
mdTableRaw,
mdLinkRaw,
mdPinsRaw,
mdFontRaw,
mdBgRaw,
mdBorderRaw,
mdEmbedRaw,
mdDeckRaw,
mdYarnRaw,
mdCommanderRaw,
];
let _entries: DocEntry[] | null = null;
function loadDocEntries(): DocEntry[] {
if (_entries) return _entries;
_entries = rawDocuments.map(parseEntry).filter(Boolean) as DocEntry[];
_entries.sort((a, b) => a.tag.localeCompare(b.tag));
return _entries;
}
export const docEntries = loadDocEntries();