POLYTONE — the AI-native programming language

Guide

The toolbox: paths, cli, markdown

Since Sprints 372–374 the parts every command-line tool and site generator needs are in the standard library.

toc.pt
import cli
import markdown
import paths
import texts

fn level(line: Text) -> Int:
    mut n = 0
    for c in line.chars():
        if c != "#":
            return n
        n = n + 1
    return n

fn main() -> Int:
    let spec = cli.spec("toc", "Prints a table of contents").option("depth", "d", "3", "deepest level").positional("file", "the Markdown file")
    match cli.parse(spec, args()):
        case Err(e):
            eprint(e)
            return 2
        case Ok(opts):
            let depth = opts.value("depth").to_int().unwrap_or(3)
            let page = paths.with_extension(paths.name(opts.value("file")), "html")
            let doc = "# Notes\n\n## Install\n\n### From source\n\n## First steps"
            for line in doc.split("\n"):
                let n = level(line)
                if n >= 2 and n <= depth:
                    let title = line.slice(n + 1, line.len())
                    print("{texts.repeat("  ", n - 2)}- [{title}]({page}#{markdown.slug(title)})")
            return 0

cli declares what a program accepts in one chained expression — flag, option with a fallback, positional — and parse(spec, args()) answers with every value by name: --depth 3, --depth=3, -d 3 and -d3 all work, -h prints cli.usage(spec), and a mistake is an Err naming what was expected (missing argument <file> — usage: toc [options] <file>), here exit 2. paths works on text only — join, name, parent, stem, extension, with_extension, normalize, relative — so the same code runs in tests and in the browser. markdown.to_html renders the everyday Markdown subset with every character escaped and script links inert; title and slug give a page its name and its anchors. examples/site/ builds a whole site from the three.