<p align="center">
<img src="assets/logo.svg" alt="rusty-rich logo" width="600"/>
</p>
<p align="center">
<strong>Rich text and beautiful formatting for the terminal โ a Rust port of Python's <a href="https://github.com/Textualize/rich">Rich</a> library.</strong>
</p>
<p align="center">
<a href="https://crates.io/crates/rusty-rich"><img src="https://img.shields.io/crates/v/rusty-rich?color=F74C00" alt="crates.io"></a>
<a href="https://docs.rs/rusty-rich"><img src="https://img.shields.io/docsrs/rusty-rich?color=F74C00" alt="docs.rs"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
<a href="#"><img src="https://img.shields.io/badge/tests-197%20passed-brightgreen" alt="tests"></a>
</p>
---
## โจ Features
- ๐จ **Style** โ foreground/background colors, bold, italic, underline, dim, blink, reverse, strikethrough, overline, conceal, frame, encircle, links
- ๐ **Console markup** โ `[bold red]text[/bold red]` BBCode-like inline styling
- ๐ฏ **256 named colors** โ full ANSI 256-color palette with aliases, hex, RGB, auto-downgrade
- ๐ญ **170+ theme styles** โ repr, json, markdown, logging, traceback, rule, bar, progress, table, tree, syntax, prompt categories
- ๐ **Table** โ tabular data with headers, footers, colspan/rowspan, column alignment, sections, 17 box styles
- ๐ฒ **Tree** โ hierarchical tree rendering with Unicode guides
- ๐ฆ **Panel** โ bordered containers with titles, subtitles
- โ **Rule** โ horizontal dividers with optional titles
- ๐ **Padding & Align** โ CSS-style padding and alignment helpers
- ๐ **Columns** โ side-by-side layout
- ๐๏ธ **Layout** โ recursive split-pane layout with ratio sizing
- โณ **Progress** โ multi-task progress bars with 11 column types, file tracking, `track()` iterator
- ๐ **Spinner** โ 55 animated spinners with case-insensitive name lookup
- ๐ **Status** โ spinner + message with in-place update
- ๐ **Live** โ auto-updating displays with alt-screen, transient mode, stdout/stderr redirect via `LiveWriter`
- ๐ **Syntax highlighting** โ powered by syntect (100+ languages)
- ๐ **Markdown** โ headings, code blocks, lists, blockquotes, links, **tables**
- ๐ **JSON** โ pretty-printed, syntax-highlighted JSON
- ๐ **Logging** โ Rich-formatted log records via the `log` crate
- ๐ผ๏ธ **Box drawing** โ 17 box styles (rounded, square, heavy, double, ASCII, etc.)
- ๐ฅ๏ธ **Screen / Alt-screen** โ full-screen terminal applications with `ScreenContext`
- โจ๏ธ **Prompts** โ `Prompt`, `IntPrompt`, `FloatPrompt`, `Confirm`, `Select<T>`, password mode
- ๐ด **Traceback** โ rich exception rendering with locals, source code, frame suppression, panic hook
- ๐ค **HTML & SVG export** โ capture console output for the web
- ๐งฉ **Segment utilities** โ simplify, split_lines, strip_styles, strip_links, align, divide, set_shape, filter_control
## ๐ฆ Installation
```toml
[dependencies]
rusty-rich = "0.2"
```
## ๐ Quick Start
```rust
use rusty_rich::{
Console, Panel, Table, Column, Rule, Tree,
Style, Color, AlignMethod, Padding,
};
fn main() {
let mut console = Console::new();
// Print with markup
console.print_str("[bold green]Hello, [red]World![/red][/bold green]");
// Create a panel with a title
let panel = Panel::new("Hello inside a rounded box!")
.title("My Panel")
.border_style(Style::new().color(Color::parse("cyan").unwrap()));
console.println(&panel);
// Create a table
let mut table = Table::new();
table.add_column(Column::new("Name").justify(AlignMethod::Left));
table.add_column(Column::new("Age").justify(AlignMethod::Right));
table.add_row_str("Alice", "30");
table.add_row_str("Bob", "25");
console.println(&table);
// Create a tree
let mut tree = Tree::new("Root");
tree.add("Child 1").add("Grandchild");
tree.add("Child 2");
console.println(&tree);
// Draw a rule
console.rule("Section Break", None, None, None);
}
```
## ๐ฏ Colors (256 names)
```rust
use rusty_rich::{Color, Style};
// Named colors โ 256 ANSI palette
let red = Color::parse("red").unwrap();
let hot_pink = Color::parse("hot_pink").unwrap();
let steel_blue = Color::parse("steel_blue").unwrap();
let grey53 = Color::parse("grey53").unwrap();
// Hex / RGB
let orange = Color::from_hex("#FF6600").unwrap();
let custom = Color::from_rgb(100, 200, 50);
// TrueColor โ 8-bit โ Standard auto-downgrade
let style = Style::new()
.color(Color::parse("#FF6600").unwrap())
.bgcolor(Color::parse("#1E1E2E").unwrap())
.bold(true)
.italic(true);
```
## ๐ Table with Colspan & Rowspan
```rust
use rusty_rich::{Table, Column, Cell};
let mut table = Table::new().title("User Report");
table.add_column(Column::new("Name"));
table.add_column(Column::new("Details").colspan(2)); // spans 2 columns
table.add_column(Column::new("Role")); // skipped by colspan above
let row = vec![
Cell::new("Alice"),
Cell::new("Engineer").colspan(2),
];
table.add_row(row);
```
## โณ Progress Bars
```rust
use rusty_rich::Progress;
use std::thread;
use std::time::Duration;
let mut progress = Progress::new();
let task_id = progress.add_task("Downloading...", Some(100.0));
for i in 0..=100 {
progress.update(task_id, i as f64);
print!("\r{}", progress.render(80));
thread::sleep(Duration::from_millis(20));
}
println!();
// Or use the `track()` convenience with an iterator
let items: Vec<_> = (0..100).collect();
let tracker = progress.track(items, "Processing", None);
for item in tracker {
// process item โ progress auto-advances
}
```
## ๐ Markdown (with tables)
```rust
use rusty_rich::render_markdown;
use rusty_rich::Console;
let md = render_markdown("
# Hello
| Alice | 30 |
| Bob | 25 |
- list item 1
- list item 2
");
let console = Console::new();
console.println(&md);
```
## โจ๏ธ Interactive Prompts
```rust
use rusty_rich::{Prompt, Confirm, IntPrompt, Select};
// String input
let name = Prompt::ask_with("Enter your name").unwrap();
// Password input (masked with *)
let password = Prompt::new("Password").password(true).ask().unwrap();
// Confirmation with default
let ok = Confirm::ask_with("Continue?", true).unwrap();
// Integer with validation
let age = IntPrompt::ask_with("Enter age").unwrap();
// Pick from numbered choices
let choice = Select::new("Pick a color")
.choice("Red", "red")
.choice("Green", "green")
.choice("Blue", "blue")
.ask()
.unwrap();
```
## ๐ Live Display with Writer
```rust
use rusty_rich::{Console, Live, LiveWriter, Panel};
use std::io::Write;
use std::thread;
use std::time::Duration;
let mut live = Live::new(Panel::new("Starting...").title("Status"));
let mut writer = live.create_writer();
live.start().unwrap();
for i in 0..=100 {
// Redirect writes through the live display
writeln!(writer, "Processing item {}...", i).unwrap();
live.update(Panel::new(format!("Progress: {}%", i)).title("Status")).unwrap();
thread::sleep(Duration::from_millis(50));
}
live.stop().unwrap();
```
## ๐ด Rich Tracebacks
```rust
use rusty_rich::traceback;
// Install a global panic hook for rich tracebacks
traceback::install();
// Or render manually
let tb = Traceback::from_exception("MyError", "something went wrong", frames)
.show_locals(true)
.max_frames(5)
.suppress(vec!["std::".into(), "core::".into()]);
```
## ๐ฅ๏ธ Full-Screen Apps
```rust
use rusty_rich::{Console, Screen, Live, Panel};
use std::thread;
use std::time::Duration;
let mut console = Console::new();
let mut screen = console.screen(); // enters alternate screen
screen.enter();
let mut live = Live::new(Panel::new("Loading...").title("Status"));
live.start().unwrap();
for i in 0..=100 {
live.update(Panel::new(format!("Progress: {}%", i)).title("Status")).unwrap();
thread::sleep(Duration::from_millis(50));
}
live.stop().unwrap();
screen.exit(); // restores terminal
```
## ๐จ Box Styles (17 built-in)
| `BOX_ROUNDED` | โญโโฎ โ โ โฐโโฏ |
| `BOX_SQUARE` | โโโ โ โ โโโ |
| `BOX_HEAVY` | โโโ โ โ โโโ |
| `BOX_DOUBLE` | โโโ โ โ โโโ |
| `BOX_DOUBLE_EDGE` | โโโ โ โ โโโ |
| `BOX_HEAVY_EDGE` | โโโ โ โ โโโ |
| `BOX_HEAVY_HEAD` | โโโ โ โ โโโ |
| `BOX_SIMPLE` | borderless with separators |
| `BOX_SIMPLE_HEAVY` | borderless with heavy separators |
| `BOX_MINIMAL` | minimal horizontal rules |
| `BOX_ASCII` | `+--+` ASCII-safe |
| `BOX_ASCII2` | `+--+` alternate ASCII |
| `BOX_MARKDOWN` | pipe-style markdown tables |
| โฆ and 4 more |
## ๐งฉ Segment Utilities
```rust
use rusty_rich::segment::{self, Segment, Segments};
let segs: Segments = vec![
Segment::styled("Hello ", Style::new().bold(true)),
Segment::styled("World", Style::new().bold(true)),
].into();
// Combine adjacent same-styled segments
let simplified = segs.simplify(); // โ one "Hello World" segment
// Split into lines
let lines = segment::split_lines(&segs.segments);
// Strip all styling
let plain = segment::strip_styles(&segs.segments); // โ "Hello World"
// Align vertically
let aligned = segment::align_middle(&lines, 80, 10, None);
```
## ๐ Module Map
```
src/
โโโ lib.rs # Crate root + re-exports
โโโ console.rs # Central rendering engine
โโโ screen.rs # Full-screen / alt-screen / ScreenContext
โโโ color.rs # TrueColor / 256 / Standard (256 names)
โโโ style.rs # 13 attributes + hyperlinks + metadata
โโโ theme.rs # 170+ named styles + stack
โโโ segment.rs # Segment + 9 utility functions
โโโ text.rs # Text with Span styling
โโโ cells.rs # Unicode cell width utilities
โโโ measure.rs # Width measurement protocol
โโโ align.rs # Horizontal + vertical alignment
โโโ ratio.rs # Proportional space distribution
โโโ markup.rs # BBCode-like markup parser
โโโ highlighter.rs # Regex/Repr highlighters
โ
โโโ panel.rs # Bordered container
โโโ table.rs # Tabular data + colspan/rowspan
โโโ tree.rs # Hierarchical tree
โโโ rule.rs # Horizontal divider
โโโ padding.rs # CSS-style padding
โโโ columns.rs # Side-by-side layout
โโโ layout.rs # Split-pane layout
โโโ box_drawing.rs # 17 box/border styles
โ
โโโ progress.rs # Multi-task progress + track()
โโโ progress_columns.rs # 11 progress column types
โโโ spinner.rs # 55 animated spinners
โโโ status.rs # Spinner + message
โโโ live.rs # Auto-updating display + LiveWriter
โ
โโโ syntax.rs # Syntax highlighting (syntect)
โโโ markdown.rs # Markdown rendering + table support
โโโ json.rs # Pretty-printed JSON
โโโ logging.rs # log crate integration
โโโ prompt.rs # 5 interactive prompt types
โโโ traceback.rs # Rich exception tracebacks
โโโ export.rs # HTML / SVG / text export
```
## ๐ฌ Compared to Python Rich
| Console + markup | โ
| โ
|
| Text / Span / Style | โ
| โ
|
| 256 named colors | โ
| โ
|
| Table (colspan/rowspan) | โ
| โ
|
| Panel / Rule / Tree | โ
| โ
|
| Layout / Columns | โ
| โ
|
| Progress (11 column types) | โ
| โ
|
| Live / Status | โ
| โ
|
| Syntax highlighting | โ
| โ
|
| Markdown (incl. tables) | โ
| โ
|
| JSON / Logging | โ
| โ
|
| Traceback (locals, suppress) | โ
| โ
|
| Screen / Alt-screen | โ
| โ
|
| Prompts (5 types) | โ
| โ
|
| 55+ Spinners | 80+ | 55 |
| 17 Box styles | 20 | 17 |
| HTML / SVG export | โ
| โ
|
| Segment utilities | โ
| โ
|
| LiveWriter / redirect | โ
| โ
|
| 170+ Theme styles | 170+ | 170+ |
| Pretty / Inspect | โ
| โ |
| Emoji / ANSI decoder | โ
| โ |
| Jupyter support | โ
| โ |
| **Overall parity** | | **~72%** |
## ๐งช Testing
```bash
cargo test # 197 unit tests
cargo test --test battle_test # Integration / battle tests
```
## ๐ License
MIT โ See [LICENSE](LICENSE) for details.
---
<p align="center">
<sub>Inspired by <a href="https://github.com/Textualize/rich">Textualize/rich</a> โ the Python library that makes terminal output beautiful.</sub>
</p>