Skip to content

Instantly share code, notes, and snippets.

@gushogg-blake
Last active September 7, 2021 09:32
Show Gist options
  • Save gushogg-blake/0da06259ee2a2802cf619ca3fe03f9fe to your computer and use it in GitHub Desktop.
Save gushogg-blake/0da06259ee2a2802cf619ca3fe03f9fe to your computer and use it in GitHub Desktop.
let Parser = require("tree-sitter");
let HTML = require("tree-sitter-html");
let parser = new Parser();
parser.setLanguage(HTML);
let code = dedent(`
<!doctype html>
<html>
<body>
<script>
</script>
</body>
</html>
`);
let tree = parser.parse(code);
console.log("cursor: " + [...generateNodes_cursor(tree.rootNode)].map(n => n.type).join(" "));
console.log("pointers: " + [...generateNodes_pointers(tree.rootNode)].map(n => n.type).join(" "));
function *generateNodes_cursor(node) {
let cursor = node.walk();
while (true) {
let node = cursor.currentNode;
yield node;
if (!advanceCursor(cursor)) {
break;
}
}
}
function *generateNodes_pointers(node) {
while (true) {
yield node;
node = next(node);
if (!node) {
break;
}
}
}
function advanceCursor(cursor) {
if (cursor.gotoFirstChild()) {
return true;
}
if (cursor.gotoNextSibling()) {
return true;
}
while (cursor.gotoParent()) {
if (cursor.gotoNextSibling()) {
return true;
}
}
return false;
}
function next(node) {
if (node.firstChild) {
return node.firstChild;
}
if (node.nextSibling) {
return node.nextSibling;
}
while (node = node.parent) {
if (node.nextSibling) {
return node.nextSibling;
}
}
return null;
}
function dedent(str) {
str = str.substr(1);
let minIndent = str.split("\n").reduce(function(min, line) {
return Math.min(min, line.match(/^\t*/)[0].length);
}, Infinity) + 1;
let re = new RegExp("^\t{" + minIndent + "}", "gm");
str = str.replace(re, "");
// final indent (up to closing `) is one less so doesn't match above
str = str.replace(/\n\s+$/, "\n");
return str;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment