1
0
silverbullet/common/markdown_parser/parse_tree.ts
Zef Hemel aaebea5e54
Major directive refactor (#195)
Fixes #188 #144 #76: major refactor of directive parsing, rendering, styling
2022-12-14 20:04:20 +01:00

65 lines
1.5 KiB
TypeScript

import type { ParseTree } from "$sb/lib/tree.ts";
import type { Language, SyntaxNode } from "../deps.ts";
export function lezerToParseTree(
text: string,
n: SyntaxNode,
offset = 0,
): ParseTree {
let children: ParseTree[] = [];
let nodeText: string | undefined;
let child = n.firstChild;
while (child) {
children.push(lezerToParseTree(text, child));
child = child.nextSibling;
}
if (children.length === 0) {
children = [
{
from: n.from + offset,
to: n.to + offset,
text: text.substring(n.from, n.to),
},
];
} else {
const newChildren: ParseTree[] = [];
let index = n.from;
for (const child of children) {
const s = text.substring(index, child.from);
if (s) {
newChildren.push({
from: index + offset,
to: child.from! + offset,
text: s,
});
}
newChildren.push(child);
index = child.to!;
}
const s = text.substring(index, n.to);
if (s) {
newChildren.push({ from: index + offset, to: n.to + offset, text: s });
}
children = newChildren;
}
const result: ParseTree = {
type: n.name,
from: n.from + offset,
to: n.to + offset,
};
if (children.length > 0) {
result.children = children;
}
if (nodeText) {
result.text = nodeText;
}
return result;
}
export function parse(language: Language, text: string): ParseTree {
const tree = lezerToParseTree(text, language.parser.parse(text).topNode);
return tree;
}