80 lines
3.2 KiB
Markdown
80 lines
3.2 KiB
Markdown
# printer
|
|
|
|
## Purpose
|
|
|
|
Stdout / stderr renderers used by the `suaveplan-font-compress` bin. Owns
|
|
the help screen, banner, per-file progress lines (success / skip / error),
|
|
and the end-of-run summary block. Every renderer writes through an injected
|
|
`NodeJS.WritableStream` so a host (test harness, CI dashboard, web preview)
|
|
can capture the output without monkey-patching the global `process.stdout`.
|
|
Lives in its own module so the entry can stay under the AGENTS.md §3 file
|
|
size budget while keeping the operator-visible output independently
|
|
inspectable and unit-testable.
|
|
|
|
## Features
|
|
|
|
- `HELP_TEXT` — the full `--help` screen, including every flag in the spec
|
|
delta plus the exit-code table.
|
|
- `printBanner` — one-shot summary printed before any per-file work,
|
|
showing input, output, format, and force state.
|
|
- `printSuccessLine` — `✓` line with the family name and either the
|
|
compressed byte count (`--format=json`) or the compression ratio
|
|
(`--format=btf`).
|
|
- `printSkipLine` — `⏭` line when an output already exists and `--force`
|
|
was not set.
|
|
- `printErrorLine` — `✗` line written to stderr with the file basename and
|
|
the failure message.
|
|
- `printSummary` — block with total / converted / errors / original size /
|
|
compressed size / ratio / savings, terminated by the output path.
|
|
|
|
## Usage: Basic
|
|
|
|
```ts
|
|
import { HELP_TEXT, printBanner, printSummary } from "./printer.js";
|
|
|
|
process.stdout.write(HELP_TEXT);
|
|
printBanner(process.stdout, "/fonts", "/out", "btf", false);
|
|
printSummary(process.stdout, summary, "/out");
|
|
```
|
|
|
|
## Usage: Advanced
|
|
|
|
```ts
|
|
import { Writable } from "node:stream";
|
|
import { printSummary } from "./printer.js";
|
|
|
|
const chunks: string[] = [];
|
|
const captured = new Writable({
|
|
write(chunk, _enc, cb) {
|
|
chunks.push(chunk.toString("utf8"));
|
|
cb();
|
|
},
|
|
});
|
|
printSummary(captured, summary, "/out");
|
|
// chunks.join("") now holds the rendered block — assert in tests / pipe
|
|
// to a CI dashboard webhook.
|
|
```
|
|
|
|
## API Reference
|
|
|
|
| Name | Signature | Notes |
|
|
|---|---|---|
|
|
| `HELP_TEXT` | `string` | Pre-rendered help screen (ANSI tones included). |
|
|
| `printBanner` | `(stdout, inputPath, outputPath, format, force) => void` | Writes the run-start block. |
|
|
| `printSuccessLine` | `(stdout, font, originalBytes, compressedBytes, format) => void` | Emits `✓` line; format choice changes the tail. |
|
|
| `printSkipLine` | `(stdout, file) => void` | Emits `⏭` for already-existing outputs. |
|
|
| `printErrorLine` | `(stderr, file, message) => void` | Emits `✗` to stderr. |
|
|
| `printSummary` | `(stdout, summary, outputRoot) => void` | Emits the end-of-run block. |
|
|
| `RunSummary` | record | `{ totalFiles, successCount, errorCount, totalOriginalSize, totalCompressedSize }`. |
|
|
|
|
## Implementation Notes
|
|
|
|
ANSI tones come from `format-utils.ts` so the palette is single-sourced.
|
|
Every line is composed by `Array#join("\n")` rather than template literals
|
|
with leading newlines — the test harness can split on `\n` and assert on
|
|
exact strings without worrying about stray indentation. The summary block
|
|
always renders the savings percentage even when no bytes were processed
|
|
(`formatSavings` falls back to `"0.0%"` for non-positive inputs) so the
|
|
output shape stays stable when an operator runs the bin against an empty
|
|
directory.
|