1
0
silverbullet/common/tree.ts

88 lines
2.3 KiB
TypeScript
Raw Normal View History

import { SyntaxNode } from "@lezer/common";
2022-04-03 16:12:16 +00:00
import wikiMarkdownLang from "../webapp/parser";
export type MarkdownTree = {
2022-04-04 09:51:41 +00:00
type?: string; // undefined === text node
2022-04-04 13:25:07 +00:00
from?: number;
to?: number;
2022-04-04 09:51:41 +00:00
text?: string;
children?: MarkdownTree[];
2022-04-03 16:12:16 +00:00
};
2022-04-09 12:28:41 +00:00
function treeToAST(text: string, n: SyntaxNode, offset = 0): MarkdownTree {
2022-04-04 09:51:41 +00:00
let children: MarkdownTree[] = [];
let nodeText: string | undefined;
let child = n.firstChild;
while (child) {
children.push(treeToAST(text, child));
child = child.nextSibling;
}
2022-04-03 16:12:16 +00:00
2022-04-04 09:51:41 +00:00
if (children.length === 0) {
children = [
{
2022-04-09 12:28:41 +00:00
from: n.from + offset,
to: n.to + offset,
2022-04-04 09:51:41 +00:00
text: text.substring(n.from, n.to),
},
];
} else {
let newChildren: MarkdownTree[] | string = [];
let index = n.from;
for (let child of children) {
let s = text.substring(index, child.from);
if (s) {
newChildren.push({
2022-04-09 12:28:41 +00:00
from: index + offset,
to: child.from! + offset,
2022-04-04 09:51:41 +00:00
text: s,
});
}
newChildren.push(child);
2022-04-04 13:25:07 +00:00
index = child.to!;
2022-04-03 16:12:16 +00:00
}
2022-04-04 09:51:41 +00:00
let s = text.substring(index, n.to);
if (s) {
2022-04-09 12:28:41 +00:00
newChildren.push({ from: index + offset, to: n.to + offset, text: s });
2022-04-03 16:12:16 +00:00
}
2022-04-04 09:51:41 +00:00
children = newChildren;
}
2022-04-03 16:12:16 +00:00
2022-04-04 09:51:41 +00:00
let result: MarkdownTree = {
type: n.name,
2022-04-09 12:28:41 +00:00
from: n.from + offset,
to: n.to + offset,
2022-04-04 09:51:41 +00:00
};
if (children.length > 0) {
result.children = children;
}
if (nodeText) {
result.text = nodeText;
}
return result;
2022-04-03 16:12:16 +00:00
}
export function parse(text: string): MarkdownTree {
2022-04-09 12:28:41 +00:00
let tree = treeToAST(text, wikiMarkdownLang.parser.parse(text).topNode);
// replaceNodesMatching(tree, (n): MarkdownTree | undefined | null => {
// if (n.type === "FencedCode") {
// let infoN = findNodeMatching(n, (n) => n.type === "CodeInfo");
// let language = infoN!.children![0].text;
// let textN = findNodeMatching(n, (n) => n.type === "CodeText");
// let text = textN!.children![0].text!;
//
// console.log(language, text);
// switch (language) {
// case "yaml":
// let parsed = StreamLanguage.define(yaml).parser.parse(text);
// let subTree = treeToAST(text, parsed.topNode, n.from);
// // console.log(JSON.stringify(subTree, null, 2));
// subTree.type = "yaml";
// return subTree;
// }
// }
// return;
// });
return tree;
2022-04-03 16:12:16 +00:00
}