Crate prettypretty

Source
Expand description

§Pretty 🌸 Pretty

Prettypretty brings 2020s color science to 1970 terminals. This version of the API documentation covers both Rust and Python interfaces. You can find a version without Python integration, with the pyffi feature disabled, on Docs.rs. The user guide provides a comprehensive overview and several deep dives covering both languages. There also are the type stubs and API documentation for Python as well as the shared source repository, Rust crate, and Python package.

§1. Overview

Prettypretty’s main abstractions are:

  • Color implements high-resolution colors by combining a ColorSpace with three Float coordinates. Its methods expose much of prettypretty’s functionality, including conversion between color spaces, interpolation between colors, calculation of perceptual contrast, as well as gamut testing, clipping, and mapping.
  • The termco module offers a choice of terminal-specific color formats AnsiColor, EmbeddedRgb, GrayGradient, EightBitColor, Rgb, as well as the wrapper Colorant.
  • The style module defines terminal Styles as a text FormatUpdate combined with foreground and background Colorants. It also defines Layer to distinguish between the two colors and Fidelity to represent a terminal’s styling capabilities.
  • Translator implements translation between color formats. To ensure high quality results, its preferred algorithms leverage the perceptually uniform Oklab/Oklch color space. For conversion to the 16 ANSI colors, it also reqires the terminal’s current color Theme.
  • The optional gamut and spectrum submodules enable the traversal of color space gamuts and the human visual gamut, respectively. The plot.py and viz3d.py scripts leverage the additional functionality for generating helpful color visualizations.

§2. One-Two-Three: Styles!

Prettypretty’s three-step workflow for awesome terminal styles works like this.

§i. Assemble Your Styles

First, assemble your application’s styles by modifying the empty Style::default().

// 1. Assemble application styles
let chic = Style::default()
    .bold()
    .underlined()
    .with_foreground(Rgb::new(215, 40, 39));

Style::with_foreground and Style::with_background accept any of prettypretty’s color representations, i.e., AnsiColor, EmbeddedRgb, GrayGradient, EightBitColor, Rgb or high-resolution Color.

§ii. Adjust Your Styles

Second, determine the terminal’s current color theme with Theme::query and its color support with Fidelity::from_environment.

// 2a. Determine terminal's color support and theme
let options = Options::with_log();
let (has_tty, theme) = match Connection::with_options(options) {
    Ok(tty) => (true, Theme::query(&tty)?),
    Err(_) => (false, VGA_COLORS),
};
let fidelity = Fidelity::from_environment(has_tty);

Use the theme to instantiate a Translator, which specializes in complex color conversions and then adjust your application’s styles to the current color theme and fidelity. Style::cap puts a cap on styles with the help of Translator::cap, which takes care of colors.

// 2b. Actually adjust styles
let translator = Translator::new(OkVersion::Revised, theme);
let effective_chic = &chic.cap(fidelity, &translator);

§iii. Apply Your Styles

Third, to apply a style, just write its display. To undo the style again, just write the negation’s display.

// 3. Apply and revert styles
println!("{}Wow!{}", effective_chic, -effective_chic);

And the terminal exclaims: wow! 🎉

§3. Optional Features

Prettypretty supports four feature flags:

  • f64 selects the eponymous type as floating point type Float and u64 as Bits instead of f32 as Float and u32 as Bits. This feature is enabled by default.
  • tty controls Theme::query and its implementation with the prettytty terminal crate. This feature is enabled by default.
  • gamut controls support for tracing the boundaries of color spaces (mod gamut, ColorSpace::gamut) and the human visual gamut (mod spectrum). This feature is disabled by default.
  • pyffi controls prettypretty’s Python integration through PyO3. This feature is disabled by default.

Prettypretty’s Python extension module is built with Maturin, PyO3’s dedicated build tool. Since Python packages typically come with “batteries included,” the gamut feature is also enabled when building the Python extension module. However, the tty feature is disabled, and prettypretty’s Python package includes its own terminal abstraction.

Throughout the API documentation, items that are only available in Rust are decorated with Rust only!. Items that are only available in Python are decorated with Python only!. Similarly, items only available with the tty feature are decorated with TTY only! and items only available with the gamut feature are decorated with Gamut only!.

§4. Acknowledgements

Implementing prettypretty’s color support was a breeze. In part, that was because I had been toying with different approaches to terminal styling for a while and knew what I wanted to build. In part, that was because I benefitted from Lea Verou’s and Chris Lilley’s work on the Color.js library and CSS Color 4 specification. Prettypretty directly reuses Color.js’ formulae for conversion between color spaces and implements several CSS Color 4 algorithms. Thank you! 🌸

Modules§

  • Utility module with prettypretty’s errors.
  • Optional module implementing the traversal of RGB gamut boundaries with ColorSpace::gamut.
  • Optional module implementing the traversal of the human visual gamut.
  • Terminal-specific text fromatting and styles.
  • Terminal color representations.
  • Utility module implementing terminal color themes.

Macros§

  • Test macro for asserting the equality of floating point numbers.
  • Test macro for asserting the equality of colors.
  • Create a new sRGB color from 24-bit integer coordinates.

Structs§

Enums§

Functions§

  • Determine whether the two floats are close enough to be considered equal. Python only!

Type Aliases§