0.0.0-alpha.2 ā€¢ Published 1 month ago

@suin/printree v0.0.0-alpha.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

printree

A flexible TypeScript library for rendering tree structures as ASCII art.

Installation

npm install @suin/printree

Features

  • šŸŒ³ Render any tree structure as ASCII art
  • šŸŽØ Fully customizable node formatting
  • šŸ·ļø Support for labeled nodes
  • šŸ“Š Optional node indices and children count
  • šŸ“ Perfect for directory trees, JSON AST, and more
  • šŸ’Ŗ Written in TypeScript with full type safety

Usage

Basic Example

import { format, type Options } from "@suin/printree";

// Define your tree node types
type Node = Parent | Leaf;
type Parent = { kind: string; children: Node[] };
type Leaf = { kind: string; value: string };

// Configure how to format your tree
const options: Options<Node> = {
  getChildren(node) {
    return "children" in node ? node.children : undefined;
  },
  formatNode(node) {
    let text = node.kind;
    if ("value" in node) {
      text += `: ${JSON.stringify(node.value)}`;
    }
    return text;
  },
};

// Create your tree
const tree: Node = {
  kind: "root",
  children: [
    {
      kind: "node",
      children: [
        { kind: "leaf", value: "Hello" },
        { kind: "leaf", value: "World!" },
      ],
    },
  ],
};

// Format it!
console.log(format(tree, options));

Output:

root
ā””ā”€ node
   ā”œā”€ leaf: "Hello"
   ā””ā”€ leaf: "World!"

Directory Tree Example

type Entry = Directory | File;
type Directory = { type: "directory"; name: string; children: Entry[] };
type File = { type: "file"; name: string };

const options: Options<Entry> = {
  getChildren(node) {
    return node.type === "directory" ? node.children : undefined;
  },
  formatNode(node) {
    return node.name;
  },
};

const tree: Entry = {
  type: "directory",
  name: "project",
  children: [
    {
      type: "directory",
      name: "src",
      children: [
        { type: "file", name: "index.ts" },
        { type: "file", name: "utils.ts" },
      ],
    },
    { type: "file", name: "README.md" },
  ],
};

console.log(format(tree, options));

Output:

project
ā”œā”€ src
ā”‚  ā”œā”€ index.ts
ā”‚  ā””ā”€ utils.ts
ā””ā”€ README.md

Advanced Features

Node Indices

const options: Options<Node> = {
  // ...
  formatNode(node, { index }) {
    return index !== undefined ? `${index} ${node.name}` : node.name;
  },
};

Output:

root
ā”œā”€ 0 node
ā”‚  ā”œā”€ 0 leaf
ā”‚  ā””ā”€ 1 leaf
ā””ā”€ 1 node

Children Count

const options: Options<Node> = {
  // ...
  formatNode(node, { children }) {
    return children ? `${node.name}[${children.length}]` : node.name;
  },
};

Output:

root[2]
ā”œā”€ node[2]
ā”‚  ā”œā”€ leaf
ā”‚  ā””ā”€ leaf
ā””ā”€ node[0]

Labeled Nodes

const options: Options<Node> = {
  // ...
  formatNode(node, { label }) {
    return label ? `${label}: ${node.name}` : node.name;
  },
};

Output:

root
ā”œā”€ key1: value1
ā””ā”€ key2: value2

API

format<T>(tree: T | ReadonlyArray<T>, options: Options<T>): string

Formats a tree structure or array of nodes into an ASCII tree representation.

Options

interface Options<T> {
  // Get children of a node (return undefined for leaf nodes)
  getChildren(node: T): ReadonlyArray<T> | ReadonlyArray<LabeledNode<T>> | undefined;
  
  // Format a node into a string
  formatNode(node: T, opts: {
    readonly label?: string;
    readonly children?: ReadonlyArray<T> | ReadonlyArray<LabeledNode<T>>;
    readonly index?: number;
  }): string;
}

License

MIT

Author

suin