flower_pot/
lib.rs

1
2#![warn(missing_docs)]
3
4//! Constants and simple functions for invoking ANSI control codes used for text-styling in terminals (including color codes). No support for cursor movement or any other control codes.
5//!
6//! This crate provides constant bindings for text-styling ANSI control codes like `BOLD` (bound to the string `\x1b[1m`) and `GREEN` (bound to `\x1b[32m`):
7//!
8//! ```
9//! use flower_pot::*;
10//!
11//! println!("{GREEN}ok{RESET}");           // prints a green "ok"
12//! println!("{BOLD}{RED}error!{RESET}");   // prints a bold, red "error!"
13//! println!("{BLUE_BG}cloud{RESET}");      // prints white text on a blue background
14//! ```
15//!
16//! Note that you must print the `RESET` code after the end of the text you want styled, or else all text printed to the terminal after that point will also be styled that way, including text outputted by other programs.
17//!
18//! It also provides functions to invoke the 8-bit color palette. This code prints text in "palette-color #237" (often a shade of grey) with a background color of "palette-color #214" (often a shade of orange):
19//!
20//! ```
21//! use flower_pot::*;
22//!
23//! println!("{}{}example text{RESET}", color_256(237), color_256_bg(214));
24//!
25//! ```
26//!
27//! And it provides functions that invoke truecolor functionality for terminals that support it. This code prints text in RGB color [127, 45, 68] with a background color of RGB color [0, 255, 255]:
28//!
29//! ```
30//! use flower_pot::*;
31//!
32//! println!("{}{}example text{RESET}", truecolor(127, 45, 68), truecolor_bg(0, 255, 255));
33//!
34//! ```
35//!
36//! The functions `color_256`, `color_256_bg`, `truecolor`, and `truecolor_bg` all return Strings.
37//!
38//! Note that not all terminals support all of the codes defined in this library. The basic workflow of ANSI control codes is that a program outputs sequences of special characters describing what it wants (such as "make the following text bold" or "make the following text green") to stdout, and then the terminal that the program is running in decides what to do with those characters. The codes themselves are reasonably well-standardized, but not every terminal understands all of them. Some terminals might ignore some codes, or might do weird things when you use them (such as displaying the text following the code incorrectly). This is a feature of the ANSI control code ecosystem, and not something a library can fix.
39//!
40//! Once you've outputted a control code, all text that follows it will be styled in the manner requested. If you want to go back to unstyled text, output the `RESET` code or one of the more specific style-resetting codes such as `NOT_UNDERLINED`.
41//!
42//! The list of control codes is taken from [the Wikipedia page on ANSI control codes](https://en.wikipedia.org/wiki/ANSI_escape_code). Codes which are not widely supported (as reported by Wikipedia) are marked as such below.
43//!
44//! The named colors covered by ANSI control codes are `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`, and these are available as foreground and background colors, along with "bright" versions which are also available as foreground and background colors. If you want shades of gray, you can try 8-bit colors in the range of **232** (darkest grey) to **255** (lightest grey) or use truecolor. Among the text-styling codes, I find `BOLD`, `DIM`, `ITALIC`, `UNDERLINE`, and `RESET` to be the most commonly useful.
45
46// Styles: 0-29.
47
48/// Unset all styles and return to default text formatting.
49pub const RESET:                    &'static str = "\x1b[0m";
50/// Make the following text bold.
51pub const BOLD:                     &'static str = "\x1b[1m";
52/// Make the following text dim.
53pub const DIM:                      &'static str = "\x1b[2m";
54/// Make the following text italic.
55pub const ITALIC:                   &'static str = "\x1b[3m";
56/// Underline the following text.
57pub const UNDERLINE:                &'static str = "\x1b[4m";
58/// Make the following text blink slowly.
59pub const SLOW_BLINK:               &'static str = "\x1b[5m";
60/// Make the following text blink quickly. Not widely supported according to Wikipedia.
61pub const RAPID_BLINK:              &'static str = "\x1b[6m";
62/// Swap the current foreground color and current background color for the following text.
63pub const INVERTED:                 &'static str = "\x1b[7m";
64/// Hide the following text. Not widely supported according to Wikipedia.
65pub const HIDDEN:                   &'static str = "\x1b[8m";
66/// Make the following text strikethrough. Not supported in Terminal.app according to Wikipedia.
67pub const STRIKETHROUGH:            &'static str = "\x1b[9m";
68/// Switch to the default font.
69pub const DEFAULT_FONT:             &'static str = "\x1b[10m";
70/// Switch to alternative font #1.
71pub const ALT_FONT_1:               &'static str = "\x1b[11m";
72/// Switch to alternative font #2.
73pub const ALT_FONT_2:               &'static str = "\x1b[12m";
74/// Switch to alternative font #3.
75pub const ALT_FONT_3:               &'static str = "\x1b[13m";
76/// Switch to alternative font #4.
77pub const ALT_FONT_4:               &'static str = "\x1b[14m";
78/// Switch to alternative font #5.
79pub const ALT_FONT_5:               &'static str = "\x1b[15m";
80/// Switch to alternative font #6.
81pub const ALT_FONT_6:               &'static str = "\x1b[16m";
82/// Switch to alternative font #7.
83pub const ALT_FONT_7:               &'static str = "\x1b[17m";
84/// Switch to alternative font #8.
85pub const ALT_FONT_8:               &'static str = "\x1b[18m";
86/// Switch to alternative font #9.
87pub const ALT_FONT_9:               &'static str = "\x1b[19m";
88/// Switch to Fraktur font. Rarely supported according to Wikipedia.
89pub const FRAKTUR:                  &'static str = "\x1b[20m";
90/// Double-underline the following text. **WARNING:** this constant contains the exact same control
91/// code as the constant `NOT_BOLD`, because different terminals interpret the code to mean
92/// different things. If you use either constant, be aware that your text may be rendered
93/// differently by different terminals.
94pub const DOUBLE_UNDERLINE:         &'static str = "\x1b[21m";
95/// Make the following text not bold. **WARNING:** this constant contains the exact same control
96/// code as the constant `DOUBLE_UNDERLINE`, because different terminals interpret the code to mean
97/// different things. If you use either constant, be aware that your text may be rendered
98/// differently by different terminals.
99pub const NOT_BOLD:                 &'static str = "\x1b[21m";
100/// Return to ordinary intensity (neither bold nor dim) for the following text.
101pub const NORMAL_INTENSITY:         &'static str = "\x1b[22m";
102/// Make the following text neither bold nor italic.
103pub const NEITHER_BOLD_NOR_ITALIC:  &'static str = "\x1b[23m";
104/// Make the following text not underlined.
105pub const NOT_UNDERLINED:           &'static str = "\x1b[24m";
106/// Make the following text not blink.
107pub const NOT_BLINKING:             &'static str = "\x1b[25m";
108/// Use a font with proportional spacing (i.e., a non-monospace font) for the following text.
109/// Rarely supported according to Wikipedia.
110pub const PROPORTIONAL_SPACING:     &'static str = "\x1b[26m";
111/// Unswap the foreground and background colors for the following text.
112pub const NOT_INVERTED:             &'static str = "\x1b[27m";
113/// Make the following text not hidden.
114pub const NOT_HIDDEN:               &'static str = "\x1b[28m";
115/// Make the following text not strikethrough.
116pub const NOT_STRIKETHROUGH:        &'static str = "\x1b[29m";
117
118/// Set forground color to black for the following text.
119pub const BLACK:                    &'static str = "\x1b[30m";
120/// Set foreground color to red for the following text.
121pub const RED:                      &'static str = "\x1b[31m";
122/// Set foreground color to green for the following text.
123pub const GREEN:                    &'static str = "\x1b[32m";
124/// Set foreground color to yellow for the following text.
125pub const YELLOW:                   &'static str = "\x1b[33m";
126/// Set foreground color to blue for the following text.
127pub const BLUE:                     &'static str = "\x1b[34m";
128/// Set foreground color to magenta for the following text.
129pub const MAGENTA:                  &'static str = "\x1b[35m";
130/// Set foreground color to cyan for the following text.
131pub const CYAN:                     &'static str = "\x1b[36m";
132/// Set foreground color to white for the following text.
133pub const WHITE:                    &'static str = "\x1b[37m";
134
135/// Set the foreground color for the following text to the *n*th color in the 256-color palette. Commonly, the set of 256 available colors consists of the 8 named foreground colors, the 8 bright versions of these colors, a 6×6×6 RGB cube (for a total of 216 colors distributed evenly across RGB-space), and then a scale of 24 shades of gray. Different terminals may differ in what colors they provide here.
136
137pub fn color_256(n: u8) -> String {
138    format!("\x1b[38;5;{n}m")
139}
140
141/// Set the foreground color to the RGB value (r, g, b). Not supported on all terminals. Terminals which do support this feature are called "truecolor terminals".
142
143pub fn truecolor(r: u8, g: u8, b: u8) -> String {
144    format!("\x1b[38;2;{r};{g};{b}m")
145}
146
147/// Return to the default foreground color for the following text.
148pub const DEFAULT:                  &'static str = "\x1b[39m";
149
150/// Set background color to black for the following text.
151pub const BLACK_BG:                 &'static str = "\x1b[40m";
152/// Set background color to red for the following text.
153pub const RED_BG:                   &'static str = "\x1b[41m";
154/// Set background color to green for the following text.
155pub const GREEN_BG:                 &'static str = "\x1b[42m";
156/// Set background color to yellow for the following text.
157pub const YELLOW_BG:                &'static str = "\x1b[43m";
158/// Set background color to blue for the following text.
159pub const BLUE_BG:                  &'static str = "\x1b[44m";
160/// Set background color to magenta for the following text.
161pub const MAGENTA_BG:               &'static str = "\x1b[45m";
162/// Set background color to cyan for the following text.
163pub const CYAN_BG:                  &'static str = "\x1b[46m";
164/// Set background color to white for the following text.
165pub const WHITE_BG:                 &'static str = "\x1b[47m";
166
167/// Set the background color for the following text to the *n*th color in the 256-color palette. Commonly, the set of 256 available colors consists of the 8 named background colors, the 8 bright versions of these colors, a 6×6×6 RGB cube (for a total of 216 colors distributed evenly across RGB-space), and then a scale of 24 shades of gray. Different terminals may differ in what colors they provide here.
168
169pub fn color_256_bg(n: u8) -> String {
170    format!("\x1b[48;5;{n}m")
171}
172
173/// Set the background color to the RGB value (r, g, b). Not supported on all terminals. Terminals which do support this feature are called "truecolor terminals".
174
175pub fn truecolor_bg(r: u8, g: u8, b: u8) -> String {
176    format!("\x1b[48;2;{r};{g};{b}m")
177}
178
179/// Return to the default background color for the following text.
180pub const DEFAULT_BG:               &'static str = "\x1b[49m";
181
182/// Return to a non-proportionally spaced font for the following text. Rarely meaningful because
183/// the `PROPORTIONAL_SPACING` control code is rarely supported to begin with.
184pub const NO_PROPORTIONAL_SPACING:  &'static str = "\x1b[50m";
185/// Frame the following text.
186pub const FRAMED:                   &'static str = "\x1b[51m";
187/// Encircle the following text.
188pub const ENCIRCLED:                &'static str = "\x1b[52m";
189/// Add an overline to the following text.
190pub const OVERLINE:                 &'static str = "\x1b[53m";
191/// Make the following text neither framed nor encircled.
192pub const NEITHER_FRAMED_NOR_ENCIRCLED:
193                                    &'static str = "\x1b[54m";
194/// Make the following text not overlined.
195pub const NOT_OVERLINED:            &'static str = "\x1b[55m";
196
197/// Set the foreground color to bright black for the following text.
198pub const BRIGHT_BLACK:             &'static str = "\x1b[90m";
199/// Set the foreground color to bright red for the following text.
200pub const BRIGHT_RED:               &'static str = "\x1b[91m";
201/// Set the foreground color to bright green for the following text.
202pub const BRIGHT_GREEN:             &'static str = "\x1b[92m";
203/// Set the foreground color to bright yellow for the following text.
204pub const BRIGHT_YELLOW:            &'static str = "\x1b[93m";
205/// Set the foreground color to bright blue for the following text.
206pub const BRIGHT_BLUE:              &'static str = "\x1b[94m";
207/// Set the foreground color to bright magenta for the following text.
208pub const BRIGHT_MAGENTA:           &'static str = "\x1b[95m";
209/// Set the foreground color to bright cyan for the following text.
210pub const BRIGHT_CYAN:              &'static str = "\x1b[96m";
211/// Set the foreground color to bright white for the following text.
212pub const BRIGHT_WHITE:             &'static str = "\x1b[97m";
213
214/// Set the background color to bright black for the following text.
215pub const BRIGHT_BLACK_BG:          &'static str = "\x1b[100m";
216/// Set the background color to bright red for the following text.
217pub const BRIGHT_RED_BG:            &'static str = "\x1b[101m";
218/// Set the background color to bright green for the following text.
219pub const BRIGHT_GREEN_BG:          &'static str = "\x1b[102m";
220/// Set the background color to bright yellow for the following text.
221pub const BRIGHT_YELLOW_BG:         &'static str = "\x1b[103m";
222/// Set the background color to bright blue for the following text.
223pub const BRIGHT_BLUE_BG:           &'static str = "\x1b[104m";
224/// Set the background color to bright magenta for the following text.
225pub const BRIGHT_MAGENTA_BG:        &'static str = "\x1b[105m";
226/// Set the background color to bright cyan for the following text.
227pub const BRIGHT_CYAN_BG:           &'static str = "\x1b[106m";
228/// Set the background color to bright white for the following text.
229pub const BRIGHT_WHITE_BG:          &'static str = "\x1b[107m";
230
231// Test (requires manual inspection of outputs).
232
233#[cfg(test)]
234mod tests {
235    use super::*;
236
237    #[test]
238    fn print_and_verify_visually() {
239        println!();
240        println!("{GREEN}green{RESET}");
241        println!("{BOLD}{RED}BOLD RED{RESET}");
242        println!("normal {WHITE}white {BRIGHT_WHITE}bright white{RESET}");
243        println!("{BLUE}blue {BRIGHT_BLUE}bright blue{RESET}");
244        println!("normal {ITALIC}italic {BOLD}and bold {UNDERLINE}and underline{RESET}");
245        println!("normal {DOUBLE_UNDERLINE}double underline{RESET}");
246        println!("normal {ENCIRCLED}encircled{RESET}");
247        println!("normal {FRAMED}framed{RESET}");
248        println!("normal {OVERLINE}overline{RESET}");
249
250        println!(
251            "{}g{}r{}e{}y{}s{}c{}a{}l{}e{} {}c{}o{}l{}o{}r{}s{}",
252            color_256(232),
253            color_256(235),
254            color_256(238),
255            color_256(241),
256            color_256(244),
257            color_256(247),
258            color_256(250),
259            color_256(253),
260            color_256(255),
261            RESET,
262            color_256_bg(255),
263            color_256_bg(251),
264            color_256_bg(247),
265            color_256_bg(243),
266            color_256_bg(239),
267            color_256_bg(235),
268            RESET,
269        );
270
271        println!(
272            "{}r{}a{}i{}n{}b{}o{}w{}i{}c{} {}c{}o{}l{}o{}r{}s{}",
273            color_256(132),
274            color_256(135),
275            color_256(138),
276            color_256(141),
277            color_256(144),
278            color_256(147),
279            color_256(150),
280            color_256(153),
281            color_256(155),
282            RESET,
283            color_256_bg(155),
284            color_256_bg(151),
285            color_256_bg(147),
286            color_256_bg(143),
287            color_256_bg(139),
288            color_256_bg(135),
289            RESET,
290        );
291
292        println!(
293            "{BOLD}{}t{}r{}u{}e{}c{}o{}l{}o{}r{} {BOLD}{}r{}a{}i{}n{}b{}o{}w{}",
294            truecolor(255, 0, 0),
295            truecolor(170, 0, 0),
296            truecolor(90, 0, 0),
297            truecolor(30, 0, 0),
298            truecolor(0, 30, 0),
299            truecolor(0, 90, 0),
300            truecolor(0, 170, 0),
301            truecolor(0, 200, 0),
302            truecolor(0, 255, 0),
303            RESET,
304            truecolor_bg(0, 255, 0),
305            truecolor_bg(0, 150, 0),
306            truecolor_bg(0, 50, 0),
307            truecolor_bg(0, 0, 50),
308            truecolor_bg(0, 0, 150),
309            truecolor_bg(0, 0, 170),
310            truecolor_bg(0, 0, 255),
311            RESET,
312        );
313
314        println!("hidden: {HIDDEN}hidden{NOT_HIDDEN} revealed");
315        println!("{}green fg {}reset fg", truecolor(0, 255, 0),    DEFAULT);
316        println!("{}green bg {}reset bg", truecolor_bg(0, 255, 0), DEFAULT_BG);
317        println!();
318
319        println!("{GREEN}ok{RESET}");           // prints a green "ok"
320        println!("{BOLD}{RED}error!{RESET}");   // prints a bold, red "error!"
321        println!("{BLUE_BG}cloud{RESET}");      // prints
322        println!();
323
324        println!("{}{}example text{RESET}", color_256(237), color_256_bg(214));
325        println!("{}{}truecolor text{RESET}", truecolor(127, 45, 68), truecolor_bg(0, 255, 255));
326        println!();
327
328        println!("{SLOW_BLINK}slow blink{RESET}");
329        println!("{RAPID_BLINK}rapid blink{RESET}");
330        println!("{ALT_FONT_1}alt font 1{RESET}");
331        println!("{ALT_FONT_2}alt font 2{RESET}");
332        println!("{ALT_FONT_3}alt font 3{RESET}");
333        println!("{FRAKTUR}Fraktur font{RESET}");
334        println!("{DEFAULT_FONT}default font{RESET}");
335        println!("{INVERTED}{GREEN}green fg but it's bg{RESET}");
336        println!();
337    }
338}
339