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