1 //! This is a library for controlling colours and formatting, such as 2 //! red bold text or blue underlined text, on ANSI terminals. 3 //! 4 //! 5 //! ## Basic usage 6 //! 7 //! There are three main types in this crate that you need to be 8 //! concerned with: [`ANSIString`], [`Style`], and [`Colour`]. 9 //! 10 //! A `Style` holds stylistic information: foreground and background colours, 11 //! whether the text should be bold, or blinking, or other properties. The 12 //! [`Colour`] enum represents the available colours. And an [`ANSIString`] is a 13 //! string paired with a [`Style`]. 14 //! 15 //! [`Color`] is also available as an alias to `Colour`. 16 //! 17 //! To format a string, call the `paint` method on a `Style` or a `Colour`, 18 //! passing in the string you want to format as the argument. For example, 19 //! here’s how to get some red text: 20 //! 21 //! ``` 22 //! use ansi_term::Colour::Red; 23 //! 24 //! println!("This is in red: {}", Red.paint("a red string")); 25 //! ``` 26 //! 27 //! It’s important to note that the `paint` method does *not* actually return a 28 //! string with the ANSI control characters surrounding it. Instead, it returns 29 //! an [`ANSIString`] value that has a [`Display`] implementation that, when 30 //! formatted, returns the characters. This allows strings to be printed with a 31 //! minimum of [`String`] allocations being performed behind the scenes. 32 //! 33 //! If you *do* want to get at the escape codes, then you can convert the 34 //! [`ANSIString`] to a string as you would any other `Display` value: 35 //! 36 //! ``` 37 //! use ansi_term::Colour::Red; 38 //! 39 //! let red_string = Red.paint("a red string").to_string(); 40 //! ``` 41 //! 42 //! 43 //! ## Bold, underline, background, and other styles 44 //! 45 //! For anything more complex than plain foreground colour changes, you need to 46 //! construct `Style` values themselves, rather than beginning with a `Colour`. 47 //! You can do this by chaining methods based on a new `Style`, created with 48 //! [`Style::new()`]. Each method creates a new style that has that specific 49 //! property set. For example: 50 //! 51 //! ``` 52 //! use ansi_term::Style; 53 //! 54 //! println!("How about some {} and {}?", 55 //! Style::new().bold().paint("bold"), 56 //! Style::new().underline().paint("underline")); 57 //! ``` 58 //! 59 //! For brevity, these methods have also been implemented for `Colour` values, 60 //! so you can give your styles a foreground colour without having to begin with 61 //! an empty `Style` value: 62 //! 63 //! ``` 64 //! use ansi_term::Colour::{Blue, Yellow}; 65 //! 66 //! println!("Demonstrating {} and {}!", 67 //! Blue.bold().paint("blue bold"), 68 //! Yellow.underline().paint("yellow underline")); 69 //! 70 //! println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!")); 71 //! ``` 72 //! 73 //! The complete list of styles you can use are: [`bold`], [`dimmed`], [`italic`], 74 //! [`underline`], [`blink`], [`reverse`], [`hidden`], [`strikethrough`], and [`on`] for 75 //! background colours. 76 //! 77 //! In some cases, you may find it easier to change the foreground on an 78 //! existing `Style` rather than starting from the appropriate `Colour`. 79 //! You can do this using the [`fg`] method: 80 //! 81 //! ``` 82 //! use ansi_term::Style; 83 //! use ansi_term::Colour::{Blue, Cyan, Yellow}; 84 //! 85 //! println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!")); 86 //! println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!")); 87 //! ``` 88 //! 89 //! You can turn a `Colour` into a `Style` with the [`normal`] method. 90 //! This will produce the exact same `ANSIString` as if you just used the 91 //! `paint` method on the `Colour` directly, but it’s useful in certain cases: 92 //! for example, you may have a method that returns `Styles`, and need to 93 //! represent both the “red bold” and “red, but not bold” styles with values of 94 //! the same type. The `Style` struct also has a [`Default`] implementation if you 95 //! want to have a style with *nothing* set. 96 //! 97 //! ``` 98 //! use ansi_term::Style; 99 //! use ansi_term::Colour::Red; 100 //! 101 //! Red.normal().paint("yet another red string"); 102 //! Style::default().paint("a completely regular string"); 103 //! ``` 104 //! 105 //! 106 //! ## Extended colours 107 //! 108 //! You can access the extended range of 256 colours by using the `Colour::Fixed` 109 //! variant, which takes an argument of the colour number to use. This can be 110 //! included wherever you would use a `Colour`: 111 //! 112 //! ``` 113 //! use ansi_term::Colour::Fixed; 114 //! 115 //! Fixed(134).paint("A sort of light purple"); 116 //! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup"); 117 //! ``` 118 //! 119 //! The first sixteen of these values are the same as the normal and bold 120 //! standard colour variants. There’s nothing stopping you from using these as 121 //! `Fixed` colours instead, but there’s nothing to be gained by doing so 122 //! either. 123 //! 124 //! You can also access full 24-bit colour by using the `Colour::RGB` variant, 125 //! which takes separate `u8` arguments for red, green, and blue: 126 //! 127 //! ``` 128 //! use ansi_term::Colour::RGB; 129 //! 130 //! RGB(70, 130, 180).paint("Steel blue"); 131 //! ``` 132 //! 133 //! ## Combining successive coloured strings 134 //! 135 //! The benefit of writing ANSI escape codes to the terminal is that they 136 //! *stack*: you do not need to end every coloured string with a reset code if 137 //! the text that follows it is of a similar style. For example, if you want to 138 //! have some blue text followed by some blue bold text, it’s possible to send 139 //! the ANSI code for blue, followed by the ANSI code for bold, and finishing 140 //! with a reset code without having to have an extra one between the two 141 //! strings. 142 //! 143 //! This crate can optimise the ANSI codes that get printed in situations like 144 //! this, making life easier for your terminal renderer. The [`ANSIStrings`] 145 //! type takes a slice of several [`ANSIString`] values, and will iterate over 146 //! each of them, printing only the codes for the styles that need to be updated 147 //! as part of its formatting routine. 148 //! 149 //! The following code snippet uses this to enclose a binary number displayed in 150 //! red bold text inside some red, but not bold, brackets: 151 //! 152 //! ``` 153 //! use ansi_term::Colour::Red; 154 //! use ansi_term::{ANSIString, ANSIStrings}; 155 //! 156 //! let some_value = format!("{:b}", 42); 157 //! let strings: &[ANSIString<'static>] = &[ 158 //! Red.paint("["), 159 //! Red.bold().paint(some_value), 160 //! Red.paint("]"), 161 //! ]; 162 //! 163 //! println!("Value: {}", ANSIStrings(strings)); 164 //! ``` 165 //! 166 //! There are several things to note here. Firstly, the [`paint`] method can take 167 //! *either* an owned [`String`] or a borrowed [`&str`]. Internally, an [`ANSIString`] 168 //! holds a copy-on-write ([`Cow`]) string value to deal with both owned and 169 //! borrowed strings at the same time. This is used here to display a `String`, 170 //! the result of the `format!` call, using the same mechanism as some 171 //! statically-available `&str` slices. Secondly, that the [`ANSIStrings`] value 172 //! works in the same way as its singular counterpart, with a [`Display`] 173 //! implementation that only performs the formatting when required. 174 //! 175 //! ## Byte strings 176 //! 177 //! This library also supports formatting `\[u8]` byte strings; this supports 178 //! applications working with text in an unknown encoding. [`Style`] and 179 //! [`Colour`] support painting `\[u8]` values, resulting in an [`ANSIByteString`]. 180 //! This type does not implement [`Display`], as it may not contain UTF-8, but 181 //! it does provide a method [`write_to`] to write the result to any value that 182 //! implements [`Write`]: 183 //! 184 //! ``` 185 //! use ansi_term::Colour::Green; 186 //! 187 //! Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap(); 188 //! ``` 189 //! 190 //! Similarly, the type [`ANSIByteStrings`] supports writing a list of 191 //! [`ANSIByteString`] values with minimal escape sequences: 192 //! 193 //! ``` 194 //! use ansi_term::Colour::Green; 195 //! use ansi_term::ANSIByteStrings; 196 //! 197 //! ANSIByteStrings(&[ 198 //! Green.paint("user data 1\n".as_bytes()), 199 //! Green.bold().paint("user data 2\n".as_bytes()), 200 //! ]).write_to(&mut std::io::stdout()).unwrap(); 201 //! ``` 202 //! 203 //! [`Cow`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html 204 //! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html 205 //! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html 206 //! [`String`]: https://doc.rust-lang.org/std/string/struct.String.html 207 //! [`&str`]: https://doc.rust-lang.org/std/primitive.str.html 208 //! [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 209 //! [`Style`]: struct.Style.html 210 //! [`Style::new()`]: struct.Style.html#method.new 211 //! [`Color`]: enum.Color.html 212 //! [`Colour`]: enum.Colour.html 213 //! [`ANSIString`]: type.ANSIString.html 214 //! [`ANSIStrings`]: type.ANSIStrings.html 215 //! [`ANSIByteString`]: type.ANSIByteString.html 216 //! [`ANSIByteStrings`]: type.ANSIByteStrings.html 217 //! [`write_to`]: type.ANSIByteString.html#method.write_to 218 //! [`paint`]: type.ANSIByteString.html#method.write_to 219 //! [`normal`]: enum.Colour.html#method.normal 220 //! 221 //! [`bold`]: struct.Style.html#method.bold 222 //! [`dimmed`]: struct.Style.html#method.dimmed 223 //! [`italic`]: struct.Style.html#method.italic 224 //! [`underline`]: struct.Style.html#method.underline 225 //! [`blink`]: struct.Style.html#method.blink 226 //! [`reverse`]: struct.Style.html#method.reverse 227 //! [`hidden`]: struct.Style.html#method.hidden 228 //! [`strikethrough`]: struct.Style.html#method.strikethrough 229 //! [`fg`]: struct.Style.html#method.fg 230 //! [`on`]: struct.Style.html#method.on 231 232 #![crate_name = "ansi_term"] 233 #![crate_type = "rlib"] 234 #![crate_type = "dylib"] 235 236 #![warn(missing_copy_implementations)] 237 #![warn(missing_docs)] 238 #![warn(trivial_casts, trivial_numeric_casts)] 239 #![warn(unused_extern_crates, unused_qualifications)] 240 241 #[cfg(target_os="windows")] 242 extern crate winapi; 243 #[cfg(test)] 244 #[macro_use] 245 extern crate doc_comment; 246 247 #[cfg(test)] 248 doctest!("../README.md"); 249 250 mod ansi; 251 pub use ansi::{Prefix, Infix, Suffix}; 252 253 mod style; 254 pub use style::{Colour, Style}; 255 256 /// Color is a type alias for `Colour`. 257 pub use Colour as Color; 258 259 mod difference; 260 mod display; 261 pub use display::*; 262 263 mod write; 264 265 mod windows; 266 pub use windows::*; 267 268 mod util; 269 pub use util::*; 270 271 mod debug; 272