gilt 2.0.0

Fast, beautiful terminal formatting for Rust — styles, tables, trees, syntax highlighting, progress bars, markdown.
Documentation
# gilt

**Rich terminal output for Rust** — a port of Python's [rich](https://github.com/Textualize/rich) library.

[![CI](https://github.com/khalidelborai/gilt/actions/workflows/ci.yml/badge.svg)](https://github.com/khalidelborai/gilt/actions)
[![Crates.io](https://img.shields.io/crates/v/gilt.svg)](https://crates.io/crates/gilt)
[![Documentation](https://docs.rs/gilt/badge.svg)](https://docs.rs/gilt)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![MSRV](https://img.shields.io/badge/MSRV-1.82.0-blue)](https://blog.rust-lang.org/2024/10/17/Rust-1.82.0.html)

![gilt styles demo](assets/demos/styles.svg)

## What gilt is — and is not

gilt is a **retained-print / inline-output** library that emits scrolling
styled ANSI output (styles, tables, trees, syntax, markdown, progress bars, live
displays) that drops straight into any CLI. You `print` renderables and they
scroll by just like normal terminal output.

**gilt is NOT a full-screen TUI framework.** It does not own the alternate
screen, does not run an event loop, and does not need `crossterm` for basic
output. Reach for [ratatui](https://crates.io/crates/ratatui) when you need a
full-screen interactive app. Use gilt for CLI output, log styling, CI reports,
build dashboards, and streaming output.

## Quick start

```toml
[dependencies]
gilt = "1.10"
```

```rust
use gilt::console::Console;

fn main() {
    let mut console = Console::default();
    console.print_text("Hello, [bold magenta]gilt[/bold magenta]!");
}
```

**Upgrading from 0.13.x?** See [MIGRATION_v1.md](MIGRATION_v1.md) — most code
becomes shorter (`Style::parse`, ergonomic `Text::styled`, `Status::run`,
`Live::from_renderable`, `Padding::wrap`, …).

## Visual gallery

**Table** — Unicode box-drawing tables with titles, styled headers, and columns:

![gilt table demo](assets/demos/table.svg)

**Tree** — hierarchical structures with configurable guide characters:

![gilt tree demo](assets/demos/tree.svg)

**Markdown** — heading, bold, italic, inline code, fenced code blocks, lists:

![gilt markdown demo](assets/demos/markdown.svg)

**Progress** — multi-bar progress with description, bar, count, and ETA:

![gilt progress demo](assets/demos/progress.svg)

> SVGs are generated by `cargo run --example gen_readme_demos --all-features`
> and committed so they render on GitHub and docs.rs without a server.

## gilt-cli — rich output without Rust

Install the binary to use gilt from shell scripts, Makefiles, and CI:

```sh
cargo install gilt-cli
```

```sh
gilt print '[bold]hello[/] from gilt'
gilt style --fg red --bold 'Error message'
gilt table < data.csv
echo '# Title' | gilt markdown
cat src/main.rs | gilt syntax --lang rust
printf 'Root\n  child1\n  child2\n' | gilt tree
gilt rule 'Deploy complete'
gilt completions bash >> ~/.bash_completion
```

See [`crates/gilt-cli/`](crates/gilt-cli/README.md) for the full subcommand
reference.

## Features

### Core widgets

`Text` · `Table` · `Panel` · `Tree` · `Columns` · `Layout` · `Padding` · `Align` · `Group`

### Terminal features

`Syntax` (150+ languages) · `Markdown` · `Json` · `Progress` (multi-bar with ETA, speed, spinner) · `Live` (in-place updates) · `Status`

### Rust-native extensions

`Gradient` · `Sparkline` · `Canvas` (Braille drawing) · `Diff` (unified + side-by-side) · `Figlet` · `CsvTable` · `Stylize` trait (`"hi".bold().red()`) · iterator `.progress()` · `Inspect` (any Debug value) · environment detection (`NO_COLOR`, `FORCE_COLOR`, `CLICOLOR`) · WCAG 2.1 contrast checking · extended underlines (curly, dotted, dashed, double) · bidirectional `anstyle` interop

### Derive macros (feature-gated)

```rust
use gilt::derives::{Table, Panel, Tree, Columns, Rule, Inspect, Renderable};
```

Auto-generate widget conversions from struct definitions. See [`crates/gilt-derive/README.md`](crates/gilt-derive/README.md).

### Optional integrations

`miette` · `eyre` · `tracing` · `anstyle`

## Why gilt over alternatives?

| | gilt | rich (Python) | ratatui | Spectre.Console (.NET) |
|---|---|---|---|---|
| Language | Rust | Python | Rust | C# |
| Full-screen TUI | no | no | **yes** | no |
| Inline scrolling output | **yes** | **yes** | no | **yes** |
| Compile-time `text!` macro | **yes** | no | no | no |
| WASM-safe | **yes** | no | no | no |
| Derive macros | **yes** | no | no | partial |
| Inline images (Kitty/Sixel/halfblock) | **yes** | partial | no | no |
| Asciinema export | **yes** | no | no | no |
| Dep-light (library) | **yes** | no | no | no |

gilt is the natural choice when you want *rich*-style inline output in a Rust
CLI or library, especially if WASM portability, dep minimisation, or
compile-time macros matter to you.

## Documentation

| Resource | Where |
|----------|-------|
| API docs | [docs.rs/gilt]https://docs.rs/gilt |
| Release notes | [CHANGELOG.md]CHANGELOG.md |
| **v1.0 migration guide** | [MIGRATION_v1.md]MIGRATION_v1.md |
| Live & streaming guide | [docs/live-and-streaming.md]docs/live-and-streaming.md |
| Derive macros | [crates/gilt-derive/]crates/gilt-derive/README.md · [docs.rs/gilt-derive]https://docs.rs/gilt-derive |
| Examples | [`examples/`]examples/ — run any with `cargo run --example <name>` |
| Feature flags & deps | [docs.rs/crate/gilt/latest/features]https://docs.rs/crate/gilt/latest/features |

## Examples

```bash
cargo run --example showcase --all-features   # full feature tour
cargo run --example table                     # core widget demos
cargo run --example progress
cargo run --example markdown
cargo run --example derive_table --features derive
cargo run --example gen_readme_demos --all-features   # regenerate README SVGs
```

## WebAssembly

gilt compiles for `wasm32-unknown-unknown` with `--no-default-features` — no
`libc`, `crossterm`, or terminal-syscall dependencies. Build with the
browser-safe feature set (the default-on `terminal-size` and `interactive`
features are native-only and excluded here):

```toml
gilt = { version = "1.10", default-features = false, features = ["json", "markdown", "syntax"] }
```

The intended browser path is record-mode + export — always set the width
explicitly since there is no terminal to query:

```rust
let mut console = Console::builder().width(80).record(true).build();
console.print(&my_widget);
let ansi = console.export_text(false, true);    // pipe into xterm.js
let html = console.export_html(None, false, true);  // inject into the DOM
```

See [`examples/wasm_export.rs`](examples/wasm_export.rs).

## Unicode handling

gilt computes visible cell width via [`unicode-width`](https://docs.rs/unicode-width)
and iterates by extended grapheme cluster (UAX #29) via
[`unicode-segmentation`](https://docs.rs/unicode-segmentation) where
correctness matters.

**Supported (correct visible width and intact iteration):**

- ASCII, Latin-1, Latin Extended
- CJK fullwidth (Chinese, Japanese, Korean) — 2 cells
- Single-codepoint emoji — 2 cells
- ZWJ family clusters (`👨‍👩‍👧`) — single 2-cell unit, never split mid-cluster
- Flag emoji (`🇺🇸` = 2 regional-indicator codepoints) — single 2-cell unit
- Variation selector sequences (`❤️` = `` + VS-16) — emoji-presentation width
- Combining mark sequences (`café` as `cafe + ́`) — 0-width combining stays with its base

**Not supported (out of scope, deferred):**

- Bidi text direction (Arabic, Hebrew RTL). `Columns::right_to_left` reverses column order, not character bidi.
- NFC/NFD normalisation — input is used as-is.
- Vertical text layout (Mongolian, classical Chinese).

Truncation and cropping (`Console::truncate`, `Text::truncate`,
`Text::right_crop`, anything routing through `set_cell_size`) snap to
grapheme-cluster boundaries — a 3-cell crop of `"👨‍👩‍👧 family"` will
not leave a dangling ZWJ joiner.

## Performance

`cargo bench` runs the criterion suite (~80 benchmarks). See [CHANGELOG.md](CHANGELOG.md) for v0.10.x → v0.11.0 perf wins (T8 lock-free Live `+21,000×`, table render `-46%`, etc.).

## Minimum Supported Rust Version

**1.82.0** (for `std::sync::LazyLock`).

## License

MIT — see [LICENSE](LICENSE).