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