mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-22 13:52:54 +00:00
+121
@@ -0,0 +1,121 @@
|
||||
import HTMLRenderer from './html_renderer';
|
||||
|
||||
class TokenTree {
|
||||
constructor() {
|
||||
this.rootNode = { children: [] };
|
||||
this.stack = [this.rootNode];
|
||||
}
|
||||
|
||||
get top() {
|
||||
return this.stack[this.stack.length - 1];
|
||||
}
|
||||
|
||||
get root() { return this.rootNode; }
|
||||
|
||||
add(node) {
|
||||
this.top.children.push(node);
|
||||
}
|
||||
|
||||
openNode(kind) {
|
||||
const node = { kind, children: [] };
|
||||
this.add(node);
|
||||
this.stack.push(node);
|
||||
}
|
||||
|
||||
closeNode() {
|
||||
if (this.stack.length > 1) {
|
||||
return this.stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
closeAllNodes() {
|
||||
while (this.closeNode());
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return JSON.stringify(this.rootNode, null, 4);
|
||||
}
|
||||
|
||||
walk(builder) {
|
||||
return this.constructor._walk(builder, this.rootNode);
|
||||
}
|
||||
|
||||
static _walk(builder, node) {
|
||||
if (typeof node === "string") {
|
||||
builder.addText(node);
|
||||
} else if (node.children) {
|
||||
builder.openNode(node);
|
||||
node.children.forEach((child) => this._walk(builder, child));
|
||||
builder.closeNode(node);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
static _collapse(node) {
|
||||
if (!node.children) {
|
||||
return;
|
||||
}
|
||||
if (node.children.every(el => typeof el === "string")) {
|
||||
node.text = node.children.join("");
|
||||
delete node.children;
|
||||
} else {
|
||||
node.children.forEach((child) => {
|
||||
if (typeof child === "string") return;
|
||||
TokenTree._collapse(child);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Currently this is all private API, but this is the minimal API necessary
|
||||
that an Emitter must implement to fully support the parser.
|
||||
|
||||
Minimal interface:
|
||||
|
||||
- addKeyword(text, kind)
|
||||
- addText(text)
|
||||
- addSublanguage(emitter, subLanguageName)
|
||||
- finalize()
|
||||
- openNode(kind)
|
||||
- closeNode()
|
||||
- closeAllNodes()
|
||||
- toHTML()
|
||||
|
||||
*/
|
||||
export default class TokenTreeEmitter extends TokenTree {
|
||||
constructor(options) {
|
||||
super();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
addKeyword(text, kind) {
|
||||
if (text === "") { return; }
|
||||
|
||||
this.openNode(kind);
|
||||
this.addText(text);
|
||||
this.closeNode();
|
||||
}
|
||||
|
||||
addText(text) {
|
||||
if (text === "") { return; }
|
||||
|
||||
this.add(text);
|
||||
}
|
||||
|
||||
addSublanguage(emitter, name) {
|
||||
const node = emitter.root;
|
||||
node.kind = name;
|
||||
node.sublanguage = true;
|
||||
this.add(node);
|
||||
}
|
||||
|
||||
toHTML() {
|
||||
const renderer = new HTMLRenderer(this, this.options);
|
||||
return renderer.value();
|
||||
}
|
||||
|
||||
finalize() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user