Interpolate text blocks in html helpers

This commit is contained in:
Tangent Wantwight 2023-11-20 22:54:56 -05:00
parent 44fe2165d2
commit fa11099850
4 changed files with 37 additions and 7 deletions

View file

@ -153,7 +153,7 @@ function triggerEvent(handlerPos: number) {
const script = parse(theCard.code);
if (script[0]) {
runNoctl(vm, script[1], (word) => {});
runNoctl(vm, script[1]);
} else {
console.debug(script[1]);
}

View file

@ -1,13 +1,29 @@
import { AsHtml, Concat, ProcResult, TextPiece } from "../words";
import { getOptRaw } from "./options";
import { TemplateBlock } from '../parser';
import { evaluateWord } from '../vm';
import { AsHtml, Concat, ProcResult, TextPiece } from '../words';
import { CardVm } from './card';
import { getOptRaw } from './options';
const htmlBlockCmd =
(tag: string) =>
({}, argv: TextPiece[]): ProcResult =>
getOptRaw(argv, { $min: 1 }, (_opts, words) => {
(vm: CardVm, argv: TextPiece[]): ProcResult =>
getOptRaw(argv, { $min: 1, raw: 0 }, ({ raw }, words) => {
function interpolate(word: TextPiece) {
if ("text" in word && !raw) {
const [tmplMatch] = TemplateBlock.match(word.text, 0);
if (tmplMatch) {
const result = evaluateWord(vm, tmplMatch[0]);
return AsHtml(result);
} else {
return AsHtml(word);
}
} else {
return AsHtml(word);
}
}
return (
words
.map((word) => ({ html: `<${tag}>${AsHtml(word)}</${tag}>` }))
.map((word) => ({ html: `<${tag}>${interpolate(word)}</${tag}>` }))
.reduce(Concat, null) ?? { html: "" }
);
});

View file

@ -54,6 +54,20 @@ const QuotedWord = Sequence(
Regex(/"/y).expects('"')
).map(([, pieces], pos) => SimplifyWord(pieces, pos));
export const TemplateBlock = Sequence(
AtLeast(
0,
Choose<InterpolatedPiece>(
BackslashEscape,
Bracket,
Regex(/[^\\\[]+/y)
.expects("CHAR")
.map(([text]) => ({ text }))
)
),
End()
).map(([pieces], pos) => SimplifyWord(pieces, pos));
const Brace: Pattern<string> = Sequence(
Regex(/\{/y).expects("{"),
AtLeast(

View file

@ -30,7 +30,7 @@ export type Vm<Context = {}> = {
output: string;
} & Context;
function evaluateWord<Context>(
export function evaluateWord<Context>(
state: Vm<Context>,
word: Word | InterpolatedPiece
): TextPiece | ErrorResult {