1 | use std::fmt::Display;
|
2 |
|
3 | #[cfg (feature = "serde" )]
|
4 | use serde::{Deserialize, Serialize};
|
5 |
|
6 | use super::super::SetAttribute;
|
7 |
|
8 | // This macro generates the Attribute enum, its iterator
|
9 | // function, and the static array containing the sgr code
|
10 | // of each attribute
|
11 | macro_rules! Attribute {
|
12 | (
|
13 | $(
|
14 | $(#[$inner:ident $($args:tt)*])*
|
15 | $name:ident = $sgr:expr,
|
16 | )*
|
17 | ) => {
|
18 | /// Represents an attribute.
|
19 | ///
|
20 | /// # Platform-specific Notes
|
21 | ///
|
22 | /// * Only UNIX and Windows 10 terminals do support text attributes.
|
23 | /// * Keep in mind that not all terminals support all attributes.
|
24 | /// * Crossterm implements almost all attributes listed in the
|
25 | /// [SGR parameters](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters).
|
26 | ///
|
27 | /// | Attribute | Windows | UNIX | Notes |
|
28 | /// | :-- | :--: | :--: | :-- |
|
29 | /// | `Reset` | ✓ | ✓ | |
|
30 | /// | `Bold` | ✓ | ✓ | |
|
31 | /// | `Dim` | ✓ | ✓ | |
|
32 | /// | `Italic` | ? | ? | Not widely supported, sometimes treated as inverse. |
|
33 | /// | `Underlined` | ✓ | ✓ | |
|
34 | /// | `SlowBlink` | ? | ? | Not widely supported, sometimes treated as inverse. |
|
35 | /// | `RapidBlink` | ? | ? | Not widely supported. MS-DOS ANSI.SYS; 150+ per minute. |
|
36 | /// | `Reverse` | ✓ | ✓ | |
|
37 | /// | `Hidden` | ✓ | ✓ | Also known as Conceal. |
|
38 | /// | `Fraktur` | ✗ | ✓ | Legible characters, but marked for deletion. |
|
39 | /// | `DefaultForegroundColor` | ? | ? | Implementation specific (according to standard). |
|
40 | /// | `DefaultBackgroundColor` | ? | ? | Implementation specific (according to standard). |
|
41 | /// | `Framed` | ? | ? | Not widely supported. |
|
42 | /// | `Encircled` | ? | ? | This should turn on the encircled attribute. |
|
43 | /// | `OverLined` | ? | ? | This should draw a line at the top of the text. |
|
44 | ///
|
45 | /// # Examples
|
46 | ///
|
47 | /// Basic usage:
|
48 | ///
|
49 | /// ```no_run
|
50 | /// use crossterm::style::Attribute;
|
51 | ///
|
52 | /// println!(
|
53 | /// "{} Underlined {} No Underline",
|
54 | /// Attribute::Underlined,
|
55 | /// Attribute::NoUnderline
|
56 | /// );
|
57 | /// ```
|
58 | ///
|
59 | /// Style existing text:
|
60 | ///
|
61 | /// ```no_run
|
62 | /// use crossterm::style::Stylize;
|
63 | ///
|
64 | /// println!("{}", "Bold text".bold());
|
65 | /// println!("{}", "Underlined text".underlined());
|
66 | /// println!("{}", "Negative text".negative());
|
67 | /// ```
|
68 | #[cfg_attr(feature = "serde" , derive(Serialize, Deserialize))]
|
69 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
70 | #[non_exhaustive]
|
71 | pub enum Attribute {
|
72 | $(
|
73 | $(#[$inner $($args)*])*
|
74 | $name,
|
75 | )*
|
76 | }
|
77 |
|
78 | pub static SGR: &'static[i16] = &[
|
79 | $($sgr,)*
|
80 | ];
|
81 |
|
82 | impl Attribute {
|
83 | /// Iterates over all the variants of the Attribute enum.
|
84 | pub fn iterator() -> impl Iterator<Item = Attribute> {
|
85 | use self::Attribute::*;
|
86 | [ $($name,)* ].iter().copied()
|
87 | }
|
88 | }
|
89 | }
|
90 | }
|
91 |
|
92 | Attribute! {
|
93 | /// Resets all the attributes.
|
94 | Reset = 0,
|
95 | /// Increases the text intensity.
|
96 | Bold = 1,
|
97 | /// Decreases the text intensity.
|
98 | Dim = 2,
|
99 | /// Emphasises the text.
|
100 | Italic = 3,
|
101 | /// Underlines the text.
|
102 | Underlined = 4,
|
103 |
|
104 | // Other types of underlining
|
105 | /// Double underlines the text.
|
106 | DoubleUnderlined = 2,
|
107 | /// Undercurls the text.
|
108 | Undercurled = 3,
|
109 | /// Underdots the text.
|
110 | Underdotted = 4,
|
111 | /// Underdashes the text.
|
112 | Underdashed = 5,
|
113 |
|
114 | /// Makes the text blinking (< 150 per minute).
|
115 | SlowBlink = 5,
|
116 | /// Makes the text blinking (>= 150 per minute).
|
117 | RapidBlink = 6,
|
118 | /// Swaps foreground and background colors.
|
119 | Reverse = 7,
|
120 | /// Hides the text (also known as Conceal).
|
121 | Hidden = 8,
|
122 | /// Crosses the text.
|
123 | CrossedOut = 9,
|
124 | /// Sets the [Fraktur](https://en.wikipedia.org/wiki/Fraktur) typeface.
|
125 | ///
|
126 | /// Mostly used for [mathematical alphanumeric symbols](https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols).
|
127 | Fraktur = 20,
|
128 | /// Turns off the `Bold` attribute. - Inconsistent - Prefer to use NormalIntensity
|
129 | NoBold = 21,
|
130 | /// Switches the text back to normal intensity (no bold, italic).
|
131 | NormalIntensity = 22,
|
132 | /// Turns off the `Italic` attribute.
|
133 | NoItalic = 23,
|
134 | /// Turns off the `Underlined` attribute.
|
135 | NoUnderline = 24,
|
136 | /// Turns off the text blinking (`SlowBlink` or `RapidBlink`).
|
137 | NoBlink = 25,
|
138 | /// Turns off the `Reverse` attribute.
|
139 | NoReverse = 27,
|
140 | /// Turns off the `Hidden` attribute.
|
141 | NoHidden = 28,
|
142 | /// Turns off the `CrossedOut` attribute.
|
143 | NotCrossedOut = 29,
|
144 | /// Makes the text framed.
|
145 | Framed = 51,
|
146 | /// Makes the text encircled.
|
147 | Encircled = 52,
|
148 | /// Draws a line at the top of the text.
|
149 | OverLined = 53,
|
150 | /// Turns off the `Frame` and `Encircled` attributes.
|
151 | NotFramedOrEncircled = 54,
|
152 | /// Turns off the `OverLined` attribute.
|
153 | NotOverLined = 55,
|
154 | }
|
155 |
|
156 | impl Display for Attribute {
|
157 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> std::fmt::Result {
|
158 | write!(f, " {}" , SetAttribute(*self))?;
|
159 | Ok(())
|
160 | }
|
161 | }
|
162 |
|
163 | impl Attribute {
|
164 | /// Returns a u32 with one bit set, which is the
|
165 | /// signature of this attribute in the Attributes
|
166 | /// bitset.
|
167 | ///
|
168 | /// The +1 enables storing Reset (whose index is 0)
|
169 | /// in the bitset Attributes.
|
170 | #[inline (always)]
|
171 | pub const fn bytes(self) -> u32 {
|
172 | 1 << ((self as u32) + 1)
|
173 | }
|
174 | /// Returns the SGR attribute value.
|
175 | ///
|
176 | /// See <https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters>
|
177 | pub fn sgr(self) -> String {
|
178 | if (self as usize) > 4 && (self as usize) < 9 {
|
179 | return "4:" .to_string() + SGR[self as usize].to_string().as_str();
|
180 | }
|
181 | SGR[self as usize].to_string()
|
182 | }
|
183 | }
|
184 | |