silphius/app/dialogue.js
2024-07-13 03:02:55 -05:00

57 lines
1.5 KiB
JavaScript

import mdx from 'remark-mdx';
import parse from 'remark-parse';
import {unified} from 'unified';
import {visitParents as visit} from 'unist-util-visit-parents';
const parser = unified().use(parse).use(mdx);
function computeParams(ancestors) {
const params = {};
for (let i = ancestors.length - 1; i >= 0; --i) {
const {dialogue} = ancestors[i];
if (dialogue) {
if (!(dialogue.name in params)) {
params[dialogue.name] = dialogue.params;
}
}
}
return params;
}
export function parseLetters(source) {
const tree = parser.parse(source);
tree.dialogue = {
name: 'rate',
params: {frequency: 0.05, length: 0},
};
const letters = [];
visit(tree, (node, ancestors) => {
switch (node.type) {
case 'mdxJsxFlowElement':
case 'mdxJsxTextElement': {
node.dialogue = {name: node.name, params: {length: 0}};
for (const {name, value: {value}} of node.attributes) {
node.dialogue.params[name] = value;
}
break;
}
case 'text': {
const params = computeParams(ancestors);
const split = node.value.split('');
for (let i = 0; i < split.length; ++i) {
const indices = {};
for (const name in params) {
indices[name] = i + params[name].length;
}
letters.push({character: split[i], indices, params});
}
for (const name in params) {
params[name].length += split.length;
}
break;
}
}
});
return letters;
}