UNPKG

@atomist/rug

Version:

TypeScript model for Atomist Rugs, see http://docs.atomist.com/

127 lines (126 loc) 4.4 kB
"use strict"; /** * Helper functions for working with TreeNodes in simple * cases where we don't need a path expression. */ Object.defineProperty(exports, "__esModule", { value: true }); function hasTag(n, t) { return n.nodeTags().indexOf(t) > -1; } exports.hasTag = hasTag; function findPathFromAncestor(n, nodeTest) { var parent = n.parent(); // Makes checking for parent function later easy if (parent == null) { // We couldn't resolve the path return null; } else if (nodeTest(parent)) { // console.log(`Gotcha: Parent is ${parent}`) // TODO what if it's not unique - need position, but then parent.children may reinitialize. // Not if a mutable container, admittedly return "/" + n.nodeName(); } else if (parent.parent()) { return findPathFromAncestor(parent, nodeTest) + ("/" + n.nodeName()); } else { return null; } } exports.findPathFromAncestor = findPathFromAncestor; function findPathFromAncestorWithTag(n, tag) { var r = findPathFromAncestor(n, function (node) { return node.nodeTags().contains(tag); }); return r; } exports.findPathFromAncestorWithTag = findPathFromAncestorWithTag; /** * Return an ancestor meeting the given criteria * or null if it cannot be found */ function findAncestor(n, nodeTest) { var parent = n.parent(); // Makes checking for parent function later easy if (parent == null) { return null; } else if (nodeTest(parent)) { // console.log(`Gotcha: Parent is ${parent}`) return parent; } else if (parent.parent()) { return findAncestor(parent, nodeTest); } else { return null; } } exports.findAncestor = findAncestor; /** * Find an ancestor with a given tag */ function findAncestorWithTag(n, tag) { var r = findAncestor(n, function (node) { return node.nodeTags().indexOf(tag) !== -1; }); return r; } exports.findAncestorWithTag = findAncestorWithTag; function nodeAndTagsStringifier(tn) { if (tn.children().length === 0) { return tn.nodeName() + ":[" + tn.value() + "]"; } return tn.nodeName() + ":[" + tn.nodeTags().join(", ") + "]"; } exports.nodeAndTagsStringifier = nodeAndTagsStringifier; function nodeAndValueStringifier(tn, maxLen) { if (maxLen === void 0) { maxLen = 30; } if (tn.children().length === 0 || tn.value().length < maxLen) { return tn.nodeName() + ":[" + tn.value() + "]"; } return tn.nodeName() + ":len=" + tn.value().length; } exports.nodeAndValueStringifier = nodeAndValueStringifier; function stringifyInternal(tn, nodeStringifier) { var shorterString = nodeStringifier(tn); var lines = [shorterString].concat( // oh for flatMap... exports.flatten(tn.children() .filter(function (k) { return k.value().length > 0; }) .map(function (k) { return stringifyInternal(k, nodeStringifier); }))); return lines.filter(function (l) { return l.length > 0; }).map(function (l) { return " " + l; }); } // TODO move to a utility module exports.flatten = function (arr) { return arr.reduce(function (acc, val) { return acc.concat(Array.isArray(val) ? exports.flatten(val) : val); }, []); }; /** * Pretty string dump */ function stringify(tn, nodeStringifier) { if (nodeStringifier === void 0) { nodeStringifier = nodeAndValueStringifier; } return stringifyInternal(tn, nodeStringifier).join("\n"); } exports.stringify = stringify; /** * Use as replacer argument in JSON.stringify. * Essentially a curried functionality, allowing us to pass in a stringifier */ function nodeReplacer(nodeStringifier) { if (nodeStringifier === void 0) { nodeStringifier = nodeAndValueStringifier; } return function (key, value) { if (value.nodeTags && value.value && value.children) { // TextTreeNode return { __kind__: "TextTreeNode", name: value.nodeName(), tags: value.nodeTags().join(","), structure: nodeStringifier(value), }; } else if (value.nodeTags) { return { __kind__: "GraphNode", name: value.nodeName(), tags: value.nodeTags().join(","), toString: value + "", }; } return value; }; } exports.nodeReplacer = nodeReplacer;