Add ink integration UI and media playback

This commit is contained in:
2026-05-15 21:23:46 +02:00
parent 44dc64f830
commit f2e786d5bc
89 changed files with 6561 additions and 556 deletions
+45
View File
@@ -0,0 +1,45 @@
import type { StoryTag } from '../interfaces/turn-result';
const LEGACY_TAG_ALIASES: Record<string, string> = {
audio: 'sfx',
audioloop: 'music',
separator: 'section',
};
function normalizeKey(key: string): string {
const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, '-');
return LEGACY_TAG_ALIASES[normalized] || normalized;
}
export function parseTag(raw: string): StoryTag | null {
const text = String(raw || '').trim().replace(/^#\s*/, '');
if (!text) return null;
const bracketMatch = text.match(/^([A-Za-z][\w-]*)(?:\[([^\]]*)\])?(?:\(([^)]*)\))?$/);
if (bracketMatch) {
const tag: StoryTag = { key: normalizeKey(bracketMatch[1]) };
if (typeof bracketMatch[2] !== 'undefined') tag.value = bracketMatch[2].trim();
if (typeof bracketMatch[3] !== 'undefined') tag.param = bracketMatch[3].trim();
return tag;
}
const bareMatch = text.match(/^[A-Za-z][\w-]*$/);
if (bareMatch) {
return { key: normalizeKey(text) };
}
return null;
}
export function parseTags(rawTags: unknown[] | undefined): StoryTag[] {
if (!Array.isArray(rawTags)) return [];
return rawTags
.map((raw) => parseTag(String(raw ?? '')))
.filter((tag): tag is StoryTag => Boolean(tag));
}
export function getTagValue(tags: StoryTag[], key: string): string | undefined {
const normalizedKey = normalizeKey(key);
return tags.find((tag) => tag.key === normalizedKey)?.value;
}