Skip to content

blackwell-systems/prettychars

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

19 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

prettychars

Crates.io Documentation License: MIT OR Apache-2.0

Unicode text styling and named glyph lookup with zero runtime overhead.

Features

  • 24 Text Styles: Transform text into mathematical bold, circled, fullwidth, and more
  • 531 Named Glyphs: Look up Unicode symbols by intuitive names like arrow.right or star.filled
  • Zero Runtime Cost: Uses compile-time perfect hash functions for O(1) lookups
  • VS15 Handling: Automatically applies variation selectors for consistent text rendering
  • No Dependencies: Minimal footprint (except PHF for static data generation)

Quick Start

Add to your Cargo.toml:

[dependencies]
prettychars = "0.1"

Text Styling

use prettychars::{style, Style};

// Mathematical styles
let bold = style("Hello", Style::MathBold);           // ๐‡๐ž๐ฅ๐ฅ๐จ
let italic = style("World", Style::Italic);           // ๐‘Š๐‘œ๐‘Ÿ๐‘™๐‘‘
let mono = style("Code", Style::Monospace);           // ๐™ฒ๐š˜๐š๐šŽ

// Enclosed styles
let circled = style("RUST", Style::Circled);          // โ“‡โ“Šโ“ˆโ“‰
let squared = style("WARN", Style::Squared);          // ๐Ÿ…†๐Ÿ„ฐ๐Ÿ…๐Ÿ„ฝ

// Typography
let fancy = style("Script", Style::Script);           // ๐’ฎ๐’ธ๐“‡๐’พ๐“…๐“‰
let gothic = style("Fraktur", Style::Fraktur);        // ๐”‰๐”ฏ๐”ž๐”จ๐”ฑ๐”ฒ๐”ฏ

// Technical
let wide = style("Full", Style::Fullwidth);           // ๏ผฆ๏ฝ•๏ฝŒ๏ฝŒ
let small = style("CAPS", Style::SmallCaps);          // แด„แด€แด˜๊œฑ

Named Glyphs

use prettychars::glyph;

// Arrows
println!("{}", glyph("arrow.right").unwrap());        // โ†’
println!("{}", glyph("arrow.double-left").unwrap());  // โ‡

// Box drawing
println!("{}", glyph("box.light.tl").unwrap());       // โ”Œ
println!("{}", glyph("box.heavy.cross").unwrap());    // โ•‹

// Symbols
println!("{}", glyph("check.mark").unwrap());         // โœ“
println!("{}", glyph("star.filled").unwrap());        // โ˜…
println!("{}", glyph("heart").unwrap());              // โ™ฅ

// Math
println!("{}", glyph("math.infinity").unwrap());      // โˆž
println!("{}", glyph("math.sum").unwrap());           // โˆ‘

// Currency
println!("{}", glyph("currency.euro").unwrap());      // โ‚ฌ
println!("{}", glyph("currency.bitcoin").unwrap());   // โ‚ฟ

Discovery

use prettychars::{glyph_names, style_names};

// Find all arrow glyphs
for name in glyph_names().filter(|n| n.starts_with("arrow.")) {
    println!("{}: {}", name, glyph(name).unwrap());
}

// List all available styles
for style in style_names() {
    println!("{:?}", style);
}

Chaining Operations

Combine multiple prettychars operations for rich terminal interfaces:

use prettychars::{glyph, style, Style};

// Progress bars with mixed elements
let progress = format!(
    "{} [{}{}] {}% {}", 
    glyph("arrow.right").unwrap(),
    glyph("block.full").unwrap().repeat(7),
    glyph("block.left.4").unwrap(),
    75,
    glyph("check.mark").unwrap()
);

// Status indicators with styled text
let status = format!("{} {}", 
    glyph("misc.warning").unwrap(),
    style("HIGH CPU", Style::MathBold)
);

// Complex UI elements
let title = format!("{} {} {}", 
    glyph("star").unwrap(),
    style("DASHBOARD", Style::SmallCaps),
    glyph("star").unwrap()
);

See examples/chaining.rs for complete patterns.

Available Styles

Mathematical

  • MathBold - Bold (๐€๐๐‚๐š๐›๐œ๐ŸŽ๐Ÿ๐Ÿ)
  • Italic - Italic (๐ด๐ต๐ถ๐‘Ž๐‘๐‘)
  • BoldItalic - Bold italic (๐‘จ๐‘ฉ๐‘ช๐’‚๐’ƒ๐’„)
  • DoubleStruck - Blackboard bold (๐”ธ๐”นโ„‚๐•’๐•“๐•”๐Ÿ˜๐Ÿ™๐Ÿš)

Enclosed

  • Circled - Circled letters (โ’ถโ’ทโ’ธโ’ถโ’ทโ’ธ)
  • CircledNegative - Negative circled (๐Ÿ…๐Ÿ…‘๐Ÿ…’)
  • Squared - Squared letters (๐Ÿ„ฐ๐Ÿ„ฑ๐Ÿ„ฒ)
  • SquaredNegative - Negative squared (๐Ÿ…ฐ๐Ÿ…ฑ๐Ÿ…ฒ)
  • Parenthesized - Parenthesized (โ’œโ’โ’ž)

Typography

  • Fraktur - Gothic/Blackletter (๐”„๐”…๐”†๐”ž๐”Ÿ๐” )
  • FrakturBold - Bold Fraktur (๐•ฌ๐•ญ๐•ฎ๐–†๐–‡๐–ˆ)
  • Script - Calligraphic (๐’œโ„ฌ๐’ž๐’ถ๐’ท๐’ธ)
  • ScriptBold - Bold script (๐“๐“‘๐“’๐“ช๐“ซ๐“ฌ)
  • SmallCaps - Small capitals (แด€ส™แด„)

Technical

  • Monospace - Fixed-width (๐™ฐ๐™ฑ๐™ฒ๐šŠ๐š‹๐šŒ๐Ÿถ๐Ÿท๐Ÿธ)
  • Fullwidth - East Asian fullwidth (๏ผก๏ผข๏ผฃ๏ฝ๏ฝ‚๏ฝƒ๏ผ๏ผ‘๏ผ’)
  • SansSerif - Sans-serif (๐– ๐–ก๐–ข๐–บ๐–ป๐–ผ๐Ÿข๐Ÿฃ๐Ÿค)
  • SansSerifBold - Bold sans-serif (๐—”๐—•๐—–๐—ฎ๐—ฏ๐—ฐ๐Ÿฌ๐Ÿญ๐Ÿฎ)
  • SansSerifItalic - Italic sans-serif (๐˜ˆ๐˜‰๐˜Š๐˜ข๐˜ฃ๐˜ค)
  • SansSerifBoldItalic - Bold italic sans-serif (๐˜ผ๐˜ฝ๐˜พ๐™–๐™—๐™˜)

Effects

  • Superscript - Raised (แดฌแดฎแถœโฐยนยฒ)
  • Subscript - Lowered (โ‚โ‚‘โ‚’โ‚€โ‚โ‚‚)
  • Strikethrough - Struck through (AฬถBฬถCฬถ)
  • Inverted - Upside down (ษqษ”)

Glyph Categories

The 531 named glyphs are organized into categories:

  • Arrows: Directional arrows, double arrows, dashed arrows
  • Box Drawing: Light, heavy, double, and rounded box components
  • Blocks: Full, partial, and shaded blocks for graphics
  • Shapes: Circles, squares, triangles, diamonds (filled and empty)
  • Check Marks: Checkboxes, check marks, X marks
  • Numbers: Circled, parenthesized, period-suffixed, roman numerals
  • Stars: Various star styles and sizes
  • Card Suits: Spades, hearts, diamonds, clubs
  • Dice: Six-sided die faces
  • Music: Notes, sharps, flats, naturals
  • Math: Operators, relations, set theory, logic symbols
  • Greek: Complete lowercase and uppercase Greek alphabet
  • Superscripts/Subscripts: Numbers and operators
  • Fractions: Common fractions like ยฝ, โ…“, ยผ
  • Currency: Dollar, euro, pound, bitcoin, and more
  • Miscellaneous: Symbols, emoji, weather, hazards, tools
  • Keyboard: Mac modifier keys (โŒ˜, โŒฅ, โŒƒ, โ‡ง)
  • Chess: White and black pieces

Design Principles

Zero Runtime Cost

All glyph lookups use PHF (Perfect Hash Function) to generate compile-time hash maps. This means:

  • O(1) lookup time for all 531 glyphs
  • No runtime hash computation
  • No memory allocation
  • Minimal binary size impact

VS15 Transparency

All glyphs have VS15 (U+FE0E, Variation Selector-15) applied automatically. VS15 requests text-style rendering rather than emoji-style rendering, ensuring consistent appearance across platforms. This is completely transparent to callers.

Stable Name Registry

The glyph name registry is append-only. Names are never removed or changed once published, ensuring your code won't break with updates. New glyphs may be added in minor version releases.

Use Cases

  • Terminal UIs: Rich text formatting, progress bars, box drawing
  • Logging: Styled log levels, status indicators, symbols
  • Documentation: Mathematical notation, special symbols
  • CLI Tools: Fancy output, Unicode art, tables
  • Text Processing: Transform text for social media, messaging

Performance

Benchmarking on a modern CPU shows:

  • Glyph lookup: ~2ns per lookup (faster than a HashMap)
  • Text styling: ~15ns per character
  • Zero allocations for lookups (except result String for styling)

The entire compiled PHF map for 531 glyphs adds approximately 8KB to your binary.

Compatibility

  • Rust Version: Requires Rust 1.70 or newer
  • Edition: 2021
  • no_std: Not currently supported (uses std::fmt for errors)

Examples

Progress Bar

use prettychars::glyph;

fn draw_progress(percent: u8) {
    let filled = glyph("block.full").unwrap();
    let empty = glyph("block.empty").unwrap();
    let bar_width = 20;
    let filled_count = (percent as usize * bar_width) / 100;
    
    print!("[");
    for i in 0..bar_width {
        print!("{}", if i < filled_count { filled } else { empty });
    }
    println!("] {}%", percent);
}

draw_progress(65); // [โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘] 65%

Styled CLI Output

use prettychars::{style, glyph, Style};

fn log_message(level: &str, msg: &str) {
    let (symbol, styled_level) = match level {
        "error" => (glyph("check.x.heavy").unwrap(), 
                    style("ERROR", Style::MathBold)),
        "warn" => (glyph("misc.warning").unwrap(), 
                   style("WARN", Style::Squared)),
        "info" => (glyph("check.mark").unwrap(), 
                   style("INFO", Style::Circled)),
        _ => ("?", level.to_string()),
    };
    
    println!("{} {} {}", symbol, styled_level, msg);
}

Unicode Table

use prettychars::glyph;

fn draw_table() {
    let tl = glyph("box.heavy.tl").unwrap();
    let tr = glyph("box.heavy.tr").unwrap();
    let bl = glyph("box.heavy.bl").unwrap();
    let br = glyph("box.heavy.br").unwrap();
    let h = glyph("box.heavy.h").unwrap();
    let v = glyph("box.heavy.v").unwrap();
    
    println!("{}{:โ”€<20}{}", tl, "", tr);
    println!("{} {:18} {}", v, "Table Content", v);
    println!("{}{:โ”€<20}{}", bl, "", br);
}

Terminal Examples

Run these examples to see prettychars in action:

Chess Board (cargo run --example chessboard)

  • Renders a complete 8x8 chess board with pieces in starting position
  • Uses double-line box drawing (โ•”โ•โ•โ•โ•—) for the grid structure
  • Shows checkerboard pattern with Unicode shade characters
  • Displays all 12 chess pieces: โ™”โ™•โ™–โ™—โ™˜โ™™ (white) and โ™šโ™›โ™œโ™โ™žโ™Ÿ (black)
  • Includes algebraic notation (a-h columns, 1-8 rows)

System Dashboard (cargo run --example dashboard)

  • Creates a monitoring interface with multiple sections
  • Progress bars using 8-level gradient blocks (โ–โ–‚โ–ƒโ–„โ–…โ–†โ–‡โ–ˆ)
  • Service status indicators with checkmarks (โœ”) and crosses (โœ˜)
  • Sparkline charts for network traffic visualization
  • Warning alerts with appropriate symbols (โš )
  • Professional layout using heavy box drawing characters

Both examples demonstrate:

  • Zero runtime overhead through PHF lookups
  • Rich terminal UIs using only Unicode characters
  • Proper alignment and spacing in terminal environments

Note: GitHub's markdown renderer cannot properly display Unicode box-drawing alignment. The examples render perfectly in actual terminals. See TERMINAL_COMPATIBILITY.md for terminal-specific guidance.

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

When suggesting new glyphs, please ensure they:

  • Have a clear, intuitive name following the existing naming scheme
  • Are widely supported across platforms
  • Fill a genuine use case

Acknowledgments

Extracted from the mdfx project by Blackwell Systems, this crate provides the Unicode styling and glyph functionality as a standalone library.

About

Unicode text styling and named glyph lookup with zero runtime overhead.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages