1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! Terminal-specific text fromatting and styles.
//!
//!
//! # I. Overview
//!
//! **`Style`**: This module supports styling terminal appearance with ANSI SGR
//! escape sequences through [`Style`], which combine an optional
//! [`FormatUpdate`] for text formatting with an optional foreground
//! [`Colorant`](crate::termco::Colorant) and an optional background
//! [`Colorant`](crate::termco::Colorant).
//!
//! **`Fidelity`** and **`Layer`**: It also defines [`Layer`] to distinguish between
//! foreground and background colors as well as [`Fidelity`] to capture a
//! terminal's level of color support.
//!
//! **Text Formatting**: This module represents a style's text formatting as a
//! [`FormatUpdate`], which contains a disabling [`Format`] and an enabling
//! [`Format`], each comprising zero or more [`Attribute`]s. All three types
//! support addition, negation, and subtraction to compose attributes into
//! formats and to update the terminal's appearance. However, most applications
//! won't need to interact with these types, since they can configure styles'
//! text formatting with [`Style::bold`], [`Style::thin`], [`Style::italic`],
//! and so on.
//!
//!
//! # II. The One-Two-Three of Styles
//!
//! Using prettypretty's styles requires three steps:
//!
//! 1. **Assemble a style** by modifying the empty [`Style::default`].
//! 2. **Adjust the style** to the terminal's fidelity level with
//! [`Style::cap`], which can translate even high-resolution colors to ANSI
//! colors.
//! 3. **Apply the style** by writing it to the terminal and restore default
//! appearance again by writing its negation.
//!
//! The examples cover the same three steps.
//!
//!
//! # III. Examples
//!
//! ## 1. Fluently Assemble Style
//!
//! Fluently assemble a style for bold, underlined red text:
//! ```
//! # use prettypretty::style::{Attribute, FormatUpdate, Style};
//! # use prettypretty::termco::{Colorant, Rgb};
//! let style = Style::default()
//! .bold()
//! .with_foreground(Rgb::new(215, 40, 39))
//! .underlined();
//!
//! assert_eq!(
//! style.format(),
//! FormatUpdate::from(Attribute::Bold + Attribute::Underlined)
//! );
//! assert_eq!(
//! style.foreground(),
//! Some(Colorant::Rgb(Rgb::new(215, 40, 39))).as_ref()
//! );
//! assert_eq!(style.background(), None);
//! ```
//! <div class=color-swatch>
//! <div style="background-color: rgb(215 40 39);"></div>
//! </div>
//! <br>
//!
//! As demonstrated above, the order of method invocations does not matter when
//! assembling styles. If you set a color more than once, the most recent
//! invocation wins.
//!
//!
//! ## 2. Adjust Style to Terminal and User Preferences
//!
//! Prepare the style from the previous example for use in a terminal that
//! supports only ANSI colors:
//! ```
//! # use prettypretty::{OkVersion, Translator};
//! # use prettypretty::style::{Fidelity, Style};
//! # use prettypretty::termco::{AnsiColor, Colorant, Rgb};
//! # use prettypretty::theme::VGA_COLORS;
//! # let style = Style::default()
//! # .bold()
//! # .with_foreground(Rgb::new(215, 40, 39))
//! # .underlined();
//! let translator = Translator::new(
//! OkVersion::Revised, VGA_COLORS.clone());
//!
//! let style = style.cap(Fidelity::Ansi, &translator);
//!
//! assert_eq!(
//! style.foreground(),
//! Some(Colorant::Ansi(AnsiColor::Red)).as_ref()
//! );
//! ```
//! <div class=color-swatch>
//! <div style="background-color: rgb(170 0 0);"></div>
//! </div>
//! <br>
//!
//!
//! ## 3. Apply Style to Text
//!
//! Apply the adjusted style from the previous example to `Wow!`, while also
//! restoring terminal appearance again:
//! ```
//! # use prettypretty::{OkVersion, Translator};
//! # use prettypretty::style::{Fidelity, Style};
//! # use prettypretty::termco::{AnsiColor, Colorant, Rgb};
//! # use prettypretty::theme::VGA_COLORS;
//! # let style = Style::default()
//! # .bold()
//! # .with_foreground(Rgb::new(215, 40, 39))
//! # .underlined();
//! # let translator = Translator::new(
//! # OkVersion::Revised, VGA_COLORS.clone());
//! # let style = style.cap(Fidelity::Ansi, &translator);
//! let s = format!("{}Wow!{}", style, -&style);
//!
//! assert_eq!(s, "\x1b[1;4;31mWow!\x1b[22;24;39m");
//! ```
//! The terminal is impressed and exclaims:
//! <img style="display: inline-block; vertical-align: top"
//! src="https://raw.githubusercontent.com/apparebit/prettypretty/main/docs/figures/wow.png"
//! alt="wow!" width="44">
//!
//! <hr>
pub use ;
pub use ;
pub use Style;