Add ink integration UI and media playback
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user