π¨ wrap-ansi
A high-performance, Unicode-aware Rust library for intelligently wrapping text while preserving ANSI escape sequences, colors, styles, and hyperlinks.
This library is a faithful Rust port of the popular JavaScript wrap-ansi library, designed for terminal applications, CLI tools, and any software that needs to display formatted text in constrained widths.
β¨ Key Features
| Feature | Description |
|---|---|
| π¨ ANSI-Aware Wrapping | Preserves colors, styles, and formatting across line breaks |
| π Hyperlink Support | Maintains clickable OSC 8 hyperlinks when wrapping |
| π Unicode Ready | Correctly handles CJK characters, emojis, and combining marks |
| β‘ High Performance | Optimized algorithms with pre-compiled regex patterns |
| π οΈ Flexible Options | Hard/soft wrapping, trimming, word boundaries control |
| π Memory Safe | Built-in protection against DoS attacks with input size limits |
| π Rich API | Fluent builder pattern and comprehensive error handling |
π Quick Start
Add this to your Cargo.toml:
[]
= "0.1.0"
Basic Text Wrapping
use wrap_ansi;
let text = "The quick brown fox jumps over the lazy dog";
let wrapped = wrap_ansi;
println!;
// Output:
// The quick brown fox
// jumps over the lazy
// dog
ANSI Colors & Styles
use wrap_ansi;
// Colors are preserved across line breaks!
let colored = "\u{001B}[31mThis is red text that will be wrapped properly\u{001B}[39m";
let wrapped = wrap_ansi;
println!;
// Each line will have proper color codes: \u{001B}[31m...\u{001B}[39m
Advanced Configuration
use ;
// Using the builder pattern for clean configuration
let options = builder
.hard_wrap // Break long words
.trim_whitespace // Preserve whitespace
.word_wrap // Respect word boundaries
.build;
let text = "supercalifragilisticexpialidocious word";
let wrapped = wrap_ansi;
println!;
// Output:
// supercalif
// ragilistic
// expialidoc
// ious word
π API Reference
Core Functions
wrap_ansi(string, columns, options) -> String
The main wrapping function that handles text with ANSI escape sequences.
Parameters:
string: &str- Input text (may contain ANSI escape sequences)columns: usize- Target column width for wrappingoptions: Option<WrapOptions>- Optional configuration (uses defaults ifNone)
Returns: Wrapped text with preserved ANSI sequences
wrap_ansi_checked(string, columns, options) -> Result<String, WrapError>
Safe version with comprehensive error handling and input validation.
Parameters: Same as wrap_ansi
Returns:
Ok(String)- Successfully wrapped textErr(WrapError)- Detailed error information
Errors:
InvalidColumnWidth(usize)- Column width must be > 0InputTooLarge(usize, usize)- Input exceeds 10MB limit
Configuration Options
WrapOptions
Fine-grained control over wrapping behavior:
WrapOptionsBuilder
Fluent builder interface for creating options:
let options = builder
.hard_wrap
.trim_whitespace
.word_wrap
.build;
Builder Methods:
.hard_wrap(bool)- Configure hard wrapping behavior.trim_whitespace(bool)- Configure whitespace trimming.word_wrap(bool)- Configure word boundary respect.build()- Build the finalWrapOptions
π― Use Cases
Perfect for:
- CLI Applications: Format help text, error messages, and output
- Terminal UIs: Create responsive layouts that adapt to terminal width
- Documentation Tools: Generate formatted text with preserved styling
- Log Processing: Wrap log entries while maintaining color coding
- Code Formatters: Handle syntax-highlighted code with proper wrapping
π Advanced Features
Wrapping Modes
| Mode | Behavior | Use Case |
|---|---|---|
| Soft Wrap (default) | Long words move to next line intact | Natural text flow |
| Hard Wrap | Long words break at column boundary | Strict width constraints |
| Character Wrap | Break anywhere, ignore word boundaries | Monospace layouts |
ANSI Sequence Support
β
Foreground Colors: Standard (30-37) and bright (90-97)
β
Background Colors: Standard (40-47) and bright (100-107)
β
Text Styles: Bold, italic, underline, strikethrough
β
Color Resets: Proper handling of reset sequences (39, 49)
β
Hyperlinks: OSC 8 sequences for clickable terminal links
β
Custom SGR: Support for any Select Graphic Rendition codes
Unicode & Internationalization
use ;
// CJK characters are properly counted as 2 columns
let chinese = "δ½ ε₯½δΈηοΌθΏζ―δΈδΈͺζ΅θ―";
let wrapped = wrap_ansi;
// Emojis and combining characters work correctly
let emoji = "Hello π World π with emojis";
let options = builder.hard_wrap.build;
let wrapped = wrap_ansi;
π§ Error Handling
For applications requiring robust error handling:
use ;
let text = "Hello, world!";
match wrap_ansi_checked
π Performance
- Zero-copy operations where possible
- Pre-compiled regex patterns for ANSI sequence parsing
- Efficient string operations with capacity pre-allocation
- DoS protection with configurable input size limits (10MB default)
- Minimal allocations through careful memory management
π€ Compatibility
- Rust Edition: 2024
- MSRV: 1.70.0
- Platforms: All platforms supported by Rust
- Terminal Compatibility: Works with all ANSI-compatible terminals
π Examples
Check out the examples directory for comprehensive usage examples:
The example demonstrates:
- Builder pattern usage
- Error handling patterns
- ANSI color preservation
- Hyperlink support
- Unicode text handling
- Complex ANSI sequences
π Dependencies
ansi-escape-sequences- ANSI sequence detection and strippingregex- Pattern matching for ANSI sequencesstring-width- Unicode-aware string width calculationthiserror- Error handling derive macros
π License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
π Acknowledgments
This library is inspired by and aims to be compatible with the JavaScript wrap-ansi library by Sindre Sorhus and the Chalk team.