UNPKG

p5-analysis

Version:

API to find, create, and analyze p5.js sketch files.

105 lines (104 loc) 3.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.printTree = exports.dedentSymbol = exports.indentSymbol = void 0; exports.indentSymbol = Symbol('indent'); exports.dedentSymbol = Symbol('dedent'); async function printTree(iter, tabWidth = 4) { const prefixStack = []; const branchString = '├' + '─'.repeat(Math.max(0, tabWidth - 2)) + ' '; let prefix = ''; for await (const { item, index, isFirst, isLast } of addTreeProperties(iter)) { if (isFirst && index > 0) { prefixStack.push(prefix); prefix = prefix.replace(/├/g, '│').replace(/─/g, ' ') + branchString; } if (isLast) { prefix = prefix.replace('├', '└'); } console.log(prefix + item); if (isLast) { prefix = prefixStack.pop(); } } } exports.printTree = printTree; /** Remove indent and unindent symbols; yield record that annotate the input items with * additional properties: * * - index: the item's position in the sequence * - isFirst: the item is the first in a group, or the entire sequence * - isLast: the item is the last in a group, or the entire sequence * * Input: *[1, indentSymbol, 2, 3, unindentSymbol, 4, indentSymbol, 5, 6, unindentSymbol, 7, 8] * Output: *[ * {item: 1, index: 0, isFirst: true, isLast: false}, * {item: 2, index: 1, isFirst: true, isLast: false}, * {item: 3, index: 2, isFirst: false, isLast: true}, * {item: 4, index: 3, isFirst: false, isLast: false}, * {item: 5, index: 4, isFirst: true, isLast: false}, * {item: 6, index: 5, isFirst: false, isLast: true}, * {item: 7, index: 6, isFirst: false, isLast: false}, * {item: 8, index: 7, isFirst: false, isLast: true}] */ async function* addTreeProperties(iter) { let index = 0; for await (const [prev, item, next] of asyncIterateWindows(dropEmptyGroups(iter), 3)) { switch (item) { case exports.indentSymbol: case exports.dedentSymbol: break; default: if (item !== undefined) { const isFirst = !prev || prev === exports.indentSymbol; // the first item is not isFirst const isLast = !next || next === exports.dedentSymbol; // the last item is isLast yield { item, isFirst, isLast, index: index++ }; } } } } /** Recursively remove *[indentSymbol, unindentSymbol] pairs from the iterable. * * Input: *[1, indentSymbol, unindentSymbol, 2, 3, indentSymbol, 4, 5, 6, unindentSymbol, 7, 8] * Output: *[1, 2, 3, indentSymbol, 4, 5, 6, unindentSymbol, 7, 8] */ async function* dropEmptyGroups(iter) { let indentation = 0; for await (const item of iter) { switch (item) { case exports.indentSymbol: indentation++; break; case exports.dedentSymbol: if (indentation > 0) { indentation--; } else { yield item; } break; default: while (indentation > 0) { indentation--; yield exports.indentSymbol; } yield item; } } } /** Input: *[1, 2, 3] * Output: *[[,,1], [,1,2], [1,2,3], [2,3,], [3,,]] * (modulo technicalities about missing vs. undefined Array elements) */ async function* asyncIterateWindows(iter, width) { const window = new Array(width); for await (const x of iter) { window.shift(); window.push(x); yield window; } for (let i = 0; i < width - 1; i++) { window.shift(); window.push(undefined); yield window; } }