ttrpg-tools/src/components/journal-doc-data.ts

67 lines
1.8 KiB
TypeScript

import yaml from "js-yaml";
export interface JournalDocEntry {
tag: string;
icon: string;
title: string;
description: string;
syntax: string;
props: { name: string; type: string; default?: string; desc: string }[];
body: 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;
}
function parseEntry(raw: string): JournalDocEntry | 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,
description: fm.description as string,
syntax: fm.syntax as string,
props: (fm.props as JournalDocEntry["props"]) ?? [],
body: getBody(raw),
};
}
import journalGmRaw from "../doc-entries/journal-gm.md";
import journalPlayerRaw from "../doc-entries/journal-player.md";
import journalSetRaw from "../doc-entries/journal-set.md";
import journalRollRaw from "../doc-entries/journal-roll.md";
import journalLinkRaw from "../doc-entries/journal-link.md";
const rawDocuments: string[] = [
journalGmRaw,
journalPlayerRaw,
journalSetRaw,
journalRollRaw,
journalLinkRaw,
];
let _entries: JournalDocEntry[] | null = null;
function loadJournalDocEntries(): JournalDocEntry[] {
if (_entries) return _entries;
_entries = rawDocuments.map(parseEntry).filter(Boolean) as JournalDocEntry[];
return _entries;
}
export const journalDocEntries = loadJournalDocEntries();