57 lines
1.5 KiB
JavaScript
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;
|
||
|
}
|