sai 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/CHANGELOG.md +32 -1
- data/README.md +32 -209
- data/docs/USAGE.md +303 -0
- data/lib/sai/ansi/sequence_processor.rb +380 -0
- data/lib/sai/ansi/sequenced_string.rb +475 -0
- data/lib/sai/ansi.rb +5 -5
- data/lib/sai/conversion/color_sequence.rb +31 -31
- data/lib/sai/conversion/rgb.rb +17 -17
- data/lib/sai/decorator.rb +256 -240
- data/lib/sai/mode_selector.rb +298 -0
- data/lib/sai/support.rb +99 -98
- data/lib/sai/terminal/capabilities.rb +22 -22
- data/lib/sai/terminal/color_mode.rb +7 -7
- data/lib/sai.rb +128 -77
- data/sig/manifest.yaml +3 -0
- data/sig/sai/ansi/sequence_processor.rbs +253 -0
- data/sig/sai/ansi/sequenced_string.rbs +380 -0
- data/sig/sai/ansi.rbs +5 -5
- data/sig/sai/conversion/color_sequence.rbs +21 -21
- data/sig/sai/conversion/rgb.rbs +17 -17
- data/sig/sai/decorator.rbs +111 -87
- data/sig/sai/mode_selector.rbs +319 -0
- data/sig/sai/support.rbs +50 -37
- data/sig/sai/terminal/capabilities.rbs +16 -16
- data/sig/sai/terminal/color_mode.rbs +7 -7
- data/sig/sai.rbs +109 -66
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77b862fa47bb8861e21f03dc023a4b411b22b40e345a7e74895eab4c2d7e416b
|
4
|
+
data.tar.gz: b579615c7b59bc268ac222ec678b3d4656a886f892229c794429f82d400c3d68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 131c38f0d73c9899fe2b7baf6a98af00bb1afdbfd26141d630362ba08da157430ad3cd5cd89a3cf0b2e5c786630f29a06cdd087704807c882db0ba96ccbbaedd
|
7
|
+
data.tar.gz: 8ea163a5901b333aa06589434b553a3655225b222341ad542ffdb078e96916f89b8feee995c2efb7058fae882871c2f35e891c3186fd1d488ad7fcdc3f1ca15a
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,35 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.3.0] - 2025-01-20
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
* [#6](https://github.com/aaronmallen/sai/pull/6) - Add `Sai::ANSI::SequencedString` for ANSI string manipulation by
|
14
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
* [#5](https://github.com/aaronmallen/sai/pull/5) - Remove unnecessary error handling in `Sai::Decorator` by
|
19
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
20
|
+
|
21
|
+
* [#6](https://github.com/aaronmallen/sai/pull/6) - Changed `Sai::Decorator#decorate` now returns a
|
22
|
+
`Sai::ANSI::SequencedString` by [@aaronmallen](https://github.com/aaronmallen)
|
23
|
+
|
24
|
+
## [0.2.0] - 2025-01-20
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
* [#3](https://github.com/aaronmallen/sai/pull/3) - mode selection via `Sai::ModeSelector`by
|
29
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
30
|
+
|
31
|
+
### Changed
|
32
|
+
|
33
|
+
* [#2](https://github.com/aaronmallen/sai/pull/2) - Immutable method chaining for `Sai::Decorator` by
|
34
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
35
|
+
* [#3](https://github.com/aaronmallen/sai/pull/3) - `Sia::Support` from class to module for improved API design by
|
36
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
37
|
+
|
9
38
|
## 0.1.0 - 2025-01-19
|
10
39
|
|
11
40
|
* Initial release
|
@@ -15,4 +44,6 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
|
|
15
44
|
|
16
45
|
<!-- versions -->
|
17
46
|
|
18
|
-
[Unreleased]: https://github.com/aaronmallen/sai/compare/0.
|
47
|
+
[Unreleased]: https://github.com/aaronmallen/sai/compare/0.3.0..HEAD
|
48
|
+
[0.3.0]: https://github.com/aaronmallen/sai/compare/0.2.0..0.3.0
|
49
|
+
[0.2.0]: https://github.com/aaronmallen/sai/compare/0.1.0..0.2.0
|
data/README.md
CHANGED
@@ -1,36 +1,39 @@
|
|
1
1
|
# Sai
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/sai)
|
4
|
+
[](https://app.codacy.com/gh/aaronmallen/sai)
|
5
|
+
[](https://app.codacy.com/gh/aaronmallen/sai/coverage)
|
4
6
|
[](./LICENSE)
|
5
|
-
[](https://rubydoc.info/gems/sai/0.
|
7
|
+
[](https://rubydoc.info/gems/sai/0.3.0)
|
6
8
|
[](https://github.com/aaronmallen/sai/issues?q=state%3Aopen%20)
|
7
9
|
|
8
10
|
An elegant color management system for crafting sophisticated CLI applications
|
9
11
|
|
10
12
|
```ruby
|
11
|
-
|
12
|
-
puts Sai.
|
13
|
-
puts Sai.
|
13
|
+
# Create beautiful CLI applications with intuitive color management
|
14
|
+
puts Sai.rgb(255, 128, 0).bold.decorate('Warning: Battery Low')
|
15
|
+
puts Sai.hex('#4834d4').italic.decorate('Processing request...')
|
16
|
+
puts Sai.bright_cyan.on_blue.underline.decorate('Download Complete!')
|
17
|
+
|
18
|
+
# Analyze and manipulate ANSI-encoded text
|
19
|
+
text = Sai.sequence("\e[31mError:\e[0m Connection failed")
|
20
|
+
puts text.without_color # Keep formatting, remove colors
|
21
|
+
puts text.stripped # Get plain text without any formatting
|
14
22
|
```
|
15
23
|
|
16
24
|
Sai (彩) - meaning 'coloring' or 'paint' in Japanese - is a powerful and intuitive system for managing color output in
|
17
25
|
command-line applications. Drawing inspiration from traditional Japanese artistic techniques, Sai brings vibrancy and
|
18
26
|
harmony to terminal interfaces through its sophisticated color management.
|
19
27
|
|
20
|
-
Sai empowers developers to create beautiful, colorful CLI applications that maintain visual consistency across different
|
21
|
-
terminal capabilities. Like its artistic namesake, it combines simplicity and sophistication to bring rich, adaptive
|
22
|
-
color to your terminal interfaces.
|
23
|
-
|
24
28
|
## Features
|
25
29
|
|
26
|
-
*
|
27
|
-
*
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
*
|
30
|
+
* Rich color support (True Color, 256 colors, ANSI, and basic modes)
|
31
|
+
* Automatic terminal capability detection and color mode adaptation
|
32
|
+
* RGB, Hex, and named color support with bright variants
|
33
|
+
* Comprehensive text styling (bold, italic, underline, etc.)
|
34
|
+
* Advanced ANSI sequence parsing and manipulation
|
35
|
+
* Intelligent color downgrading for compatibility
|
32
36
|
* Respects NO_COLOR environment variable
|
33
|
-
* Can be used directly or included in classes/modules
|
34
37
|
|
35
38
|
## Installation
|
36
39
|
|
@@ -42,20 +45,20 @@ gem 'sai'
|
|
42
45
|
|
43
46
|
Or install it yourself as:
|
44
47
|
|
45
|
-
```
|
48
|
+
```ruby
|
46
49
|
gem install sai
|
47
50
|
```
|
48
51
|
|
49
|
-
|
52
|
+
> [!IMPORTANT]
|
53
|
+
> If you're upgrading from version 0.2.0, please see our [Migration Guide](docs/migrations/0.2.0-0.3.0.md) for
|
54
|
+
> important changes.
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
### Direct Usage
|
56
|
+
## Quick Start
|
54
57
|
|
55
58
|
```ruby
|
56
59
|
require 'sai'
|
57
60
|
|
58
|
-
#
|
61
|
+
# Basic usage
|
59
62
|
puts Sai.red.decorate('Error!')
|
60
63
|
puts Sai.bright_blue.on_white.decorate('Info')
|
61
64
|
|
@@ -63,201 +66,21 @@ puts Sai.bright_blue.on_white.decorate('Info')
|
|
63
66
|
puts Sai.rgb(255, 128, 0).decorate('Custom color')
|
64
67
|
puts Sai.on_rgb(0, 255, 128).decorate('Custom background')
|
65
68
|
|
66
|
-
# Using hex colors
|
67
|
-
puts Sai.hex('#FF8000').decorate('Hex color')
|
68
|
-
puts Sai.on_hex('#00FF80').decorate('Hex background')
|
69
|
-
|
70
69
|
# Applying styles
|
71
70
|
puts Sai.bold.underline.decorate('Important')
|
72
71
|
puts Sai.red.bold.italic.decorate('Error!')
|
73
72
|
|
74
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
.decorate('Styled text')
|
80
|
-
```
|
81
|
-
|
82
|
-
### Module Inclusion
|
83
|
-
|
84
|
-
```ruby
|
85
|
-
class CLI
|
86
|
-
include Sai
|
87
|
-
|
88
|
-
def error(message)
|
89
|
-
puts decorator.red.bold.decorate(message)
|
90
|
-
end
|
91
|
-
|
92
|
-
def info(message)
|
93
|
-
puts decorator.bright_blue.decorate(message)
|
94
|
-
end
|
95
|
-
|
96
|
-
def success(message)
|
97
|
-
puts decorator.green.decorate(message)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
cli = CLI.new
|
102
|
-
cli.error('Something went wrong!')
|
103
|
-
cli.info('Processing...')
|
104
|
-
cli.success('Done!')
|
105
|
-
```
|
106
|
-
|
107
|
-
### Defining Reusable Styles
|
108
|
-
|
109
|
-
Sai decorators can be assigned to constants to create reusable styles throughout your application:
|
110
|
-
|
111
|
-
```ruby
|
112
|
-
module Style
|
113
|
-
ERROR = Sai.bold.bright_white.on_red
|
114
|
-
WARNING = Sai.black.on_yellow
|
115
|
-
SUCCESS = Sai.bright_green
|
116
|
-
INFO = Sai.bright_blue
|
117
|
-
HEADER = Sai.bold.bright_cyan.underline
|
118
|
-
end
|
119
|
-
|
120
|
-
# Use your defined styles
|
121
|
-
puts Style::ERROR.decorate('Something went wrong!')
|
122
|
-
puts Style::SUCCESS.decorate('Operation completed successfully')
|
123
|
-
|
124
|
-
# Styles can be further customized when needed
|
125
|
-
puts Style::ERROR.italic.decorate('Critical error!')
|
73
|
+
# Working with ANSI sequences
|
74
|
+
text = Sai.sequence("\e[31mError:\e[0m Details here")
|
75
|
+
puts text.without_color # Remove colors but keep formatting
|
76
|
+
puts text.without_style # Remove formatting but keep colors
|
77
|
+
puts text.stripped # Get plain text
|
126
78
|
```
|
127
79
|
|
128
|
-
|
129
|
-
> This pattern is particularly useful for maintaining consistent styling across your application and creating theme
|
130
|
-
> systems. You can even build on existing styles:
|
131
|
-
>
|
132
|
-
> ```ruby
|
133
|
-
> module Theme
|
134
|
-
> PRIMARY = Sai.rgb(63, 81, 181)
|
135
|
-
> SECONDARY = Sai.rgb(255, 87, 34)
|
136
|
-
>
|
137
|
-
> BUTTON = PRIMARY.bold
|
138
|
-
> LINK = SECONDARY.underline
|
139
|
-
> HEADER = PRIMARY.bold.underline
|
140
|
-
> end
|
141
|
-
> ```
|
142
|
-
|
143
|
-
## Features
|
144
|
-
|
145
|
-
### Color Support
|
146
|
-
|
147
|
-
Sai supports up to 16.7 million colors (true color/24-bit) depending on your terminal's capabilities. Colors can be
|
148
|
-
specified in several ways:
|
80
|
+
## Documentation
|
149
81
|
|
150
|
-
|
151
|
-
|
152
|
-
```ruby
|
153
|
-
# Specify any RGB color (0-255 per channel)
|
154
|
-
Sai.rgb(255, 128, 0).decorate('Orange text')
|
155
|
-
Sai.on_rgb(0, 255, 128).decorate('Custom green background')
|
156
|
-
```
|
157
|
-
|
158
|
-
#### Hex Colors
|
159
|
-
|
160
|
-
```ruby
|
161
|
-
# Use any hex color code
|
162
|
-
Sai.hex('#FF8000').decorate('Orange text')
|
163
|
-
Sai.on_hex('#00FF80').decorate('Custom green background')
|
164
|
-
```
|
165
|
-
|
166
|
-
#### Named Color Shortcuts
|
167
|
-
|
168
|
-
For convenience, Sai provides shortcuts for common ANSI colors:
|
169
|
-
|
170
|
-
Standard colors:
|
171
|
-
|
172
|
-
```ruby
|
173
|
-
Sai.red.decorate('Red text')
|
174
|
-
Sai.blue.decorate('Blue text')
|
175
|
-
Sai.on_green.decorate('Green background')
|
176
|
-
```
|
177
|
-
|
178
|
-
Bright variants:
|
179
|
-
|
180
|
-
```ruby
|
181
|
-
Sai.bright_red.decorate('Bright red text')
|
182
|
-
Sai.bright_blue.decorate('Bright blue text')
|
183
|
-
Sai.on_bright_green.decorate('Bright green background')
|
184
|
-
```
|
185
|
-
|
186
|
-
Available named colors:
|
187
|
-
|
188
|
-
* black/bright_black
|
189
|
-
* red/bright_red
|
190
|
-
* green/bright_green
|
191
|
-
* yellow/bright_yellow
|
192
|
-
* blue/bright_blue
|
193
|
-
* magenta/bright_magenta
|
194
|
-
* cyan/bright_cyan
|
195
|
-
* white/bright_white
|
196
|
-
|
197
|
-
> [!TIP]
|
198
|
-
> While named colors provide convenient shortcuts, remember that Sai supports the full RGB color space. Don't feel
|
199
|
-
> limited to just these predefined colors!
|
200
|
-
|
201
|
-
### Text Styles
|
202
|
-
|
203
|
-
Available styles:
|
204
|
-
|
205
|
-
* bold
|
206
|
-
* dim
|
207
|
-
* italic
|
208
|
-
* underline
|
209
|
-
* blink
|
210
|
-
* rapid_blink
|
211
|
-
* reverse
|
212
|
-
* conceal
|
213
|
-
* strike
|
214
|
-
|
215
|
-
Style removal:
|
216
|
-
|
217
|
-
* no_blink
|
218
|
-
* no_italic
|
219
|
-
* no_underline
|
220
|
-
* no_reverse
|
221
|
-
* no_conceal
|
222
|
-
* no_strike
|
223
|
-
* normal_intensity
|
224
|
-
|
225
|
-
### Color Mode Detection & Downgrading
|
226
|
-
|
227
|
-
Sai automatically detects your terminal's color capabilities and adapts the output appropriately:
|
228
|
-
|
229
|
-
* True Color terminals (24-bit): Full access to all 16.7 million colors
|
230
|
-
* 256-color terminals (8-bit): Colors are mapped to the closest available color in the 256-color palette
|
231
|
-
* ANSI terminals (4-bit): Colors are mapped to the 16 standard ANSI colors
|
232
|
-
* Basic terminals (3-bit): Colors are mapped to the 8 basic ANSI colors
|
233
|
-
* NO_COLOR: All color sequences are stripped when the NO_COLOR environment variable is set
|
234
|
-
|
235
|
-
> [!NOTE]
|
236
|
-
> This automatic downgrading ensures your application looks great across all terminal types without any extra code!
|
237
|
-
|
238
|
-
### Terminal Support Detection
|
239
|
-
|
240
|
-
You can check the terminal's capabilities:
|
241
|
-
|
242
|
-
```ruby
|
243
|
-
# Using directly
|
244
|
-
Sai.support.true_color? # => true/false
|
245
|
-
Sai.support.bit8? # => true/false
|
246
|
-
Sai.support.ansi? # => true/false
|
247
|
-
Sai.support.basic? # => true/false
|
248
|
-
Sai.support.color? # => true/false
|
249
|
-
|
250
|
-
# Using included module
|
251
|
-
class CLI
|
252
|
-
include Sai
|
253
|
-
|
254
|
-
def check_support
|
255
|
-
if terminal_color_support.true_color?
|
256
|
-
puts "Terminal supports true color!"
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
```
|
82
|
+
* [Complete Usage Guide](docs/USAGE.md) - Comprehensive documentation of all features
|
83
|
+
* [API Documentation](https://rubydoc.info/gems/sai/0.3.0) - Detailed API reference
|
261
84
|
|
262
85
|
## Contributing
|
263
86
|
|
data/docs/USAGE.md
ADDED
@@ -0,0 +1,303 @@
|
|
1
|
+
# Sai Usage Guide
|
2
|
+
|
3
|
+
This guide provides comprehensive documentation for using Sai in your applications.
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
* [Basic Usage](#basic-usage)
|
8
|
+
* [Color Support](#color-support)
|
9
|
+
* [RGB Colors](#rgb-colors)
|
10
|
+
* [Hex Colors](#hex-colors)
|
11
|
+
* [Named Colors](#named-colors)
|
12
|
+
* [Text Styles](#text-styles)
|
13
|
+
* [ANSI Sequence Manipulation](#ansi-sequence-manipulation)
|
14
|
+
* [Color Mode Management](#color-mode-management)
|
15
|
+
* [Terminal Capabilities](#terminal-capabilities)
|
16
|
+
* [Integration Patterns](#integration-patterns)
|
17
|
+
* [Best Practices](#best-practices)
|
18
|
+
|
19
|
+
## Basic Usage
|
20
|
+
|
21
|
+
Sai can be used directly or included in your own classes and modules:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Direct usage
|
25
|
+
puts Sai.red.decorate('Error!')
|
26
|
+
puts Sai.bright_blue.on_white.decorate('Info')
|
27
|
+
|
28
|
+
# Include in your own classes
|
29
|
+
class CLI
|
30
|
+
include Sai
|
31
|
+
|
32
|
+
def error(message)
|
33
|
+
puts decorator.red.bold.decorate(message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def info(message)
|
37
|
+
puts decorator.bright_blue.decorate(message)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
## Color Support
|
43
|
+
|
44
|
+
### RGB Colors
|
45
|
+
|
46
|
+
Use any RGB color (0-255 per channel):
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
# Foreground colors
|
50
|
+
Sai.rgb(255, 128, 0).decorate('Orange text')
|
51
|
+
Sai.rgb(100, 149, 237).decorate('Cornflower blue')
|
52
|
+
|
53
|
+
# Background colors
|
54
|
+
Sai.on_rgb(0, 255, 128).decorate('Custom green background')
|
55
|
+
```
|
56
|
+
|
57
|
+
### Hex Colors
|
58
|
+
|
59
|
+
Use any hex color code:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# Foreground colors
|
63
|
+
Sai.hex('#FF8000').decorate('Orange text')
|
64
|
+
Sai.hex('#6495ED').decorate('Cornflower blue')
|
65
|
+
|
66
|
+
# Background colors
|
67
|
+
Sai.on_hex('#00FF80').decorate('Custom green background')
|
68
|
+
```
|
69
|
+
|
70
|
+
### Named Colors
|
71
|
+
|
72
|
+
Common ANSI colors have convenient shortcuts:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# Standard colors
|
76
|
+
Sai.red.decorate('Red text')
|
77
|
+
Sai.blue.decorate('Blue text')
|
78
|
+
Sai.on_green.decorate('Green background')
|
79
|
+
|
80
|
+
# Bright variants
|
81
|
+
Sai.bright_red.decorate('Bright red text')
|
82
|
+
Sai.bright_blue.decorate('Bright blue text')
|
83
|
+
Sai.on_bright_green.decorate('Bright green background')
|
84
|
+
```
|
85
|
+
|
86
|
+
Available named colors:
|
87
|
+
* black/bright_black
|
88
|
+
* red/bright_red
|
89
|
+
* green/bright_green
|
90
|
+
* yellow/bright_yellow
|
91
|
+
* blue/bright_blue
|
92
|
+
* magenta/bright_magenta
|
93
|
+
* cyan/bright_cyan
|
94
|
+
* white/bright_white
|
95
|
+
|
96
|
+
> [!TIP]
|
97
|
+
> While named colors provide convenient shortcuts, remember that Sai supports the full RGB color space. Don't feel
|
98
|
+
> limited to just these predefined colors!
|
99
|
+
|
100
|
+
## Text Styles
|
101
|
+
|
102
|
+
Sai supports a variety of text styles:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Sai.bold.decorate('Bold text')
|
106
|
+
Sai.italic.decorate('Italic text')
|
107
|
+
Sai.underline.decorate('Underlined text')
|
108
|
+
Sai.strike.decorate('Strikethrough text')
|
109
|
+
```
|
110
|
+
|
111
|
+
Available styles:
|
112
|
+
* bold
|
113
|
+
* dim
|
114
|
+
* italic
|
115
|
+
* underline
|
116
|
+
* blink
|
117
|
+
* rapid_blink
|
118
|
+
* reverse
|
119
|
+
* conceal
|
120
|
+
* strike
|
121
|
+
|
122
|
+
Style removal:
|
123
|
+
* no_blink
|
124
|
+
* no_italic
|
125
|
+
* no_underline
|
126
|
+
* no_reverse
|
127
|
+
* no_conceal
|
128
|
+
* no_strike
|
129
|
+
* normal_intensity
|
130
|
+
|
131
|
+
## ANSI Sequence Manipulation
|
132
|
+
|
133
|
+
Sai provides powerful tools for working with ANSI-encoded strings:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# Create a SequencedString from decorated text
|
137
|
+
text = Sai.red.bold.decorate("Warning!")
|
138
|
+
|
139
|
+
# Or parse existing ANSI text
|
140
|
+
text = Sai.sequence("\e[31mred\e[0m and \e[32mgreen\e[0m")
|
141
|
+
|
142
|
+
# Get plain text without formatting
|
143
|
+
plain = text.stripped # => "red and green"
|
144
|
+
|
145
|
+
# Remove specific attributes
|
146
|
+
text.without_color # Remove all colors but keep styles
|
147
|
+
text.without_style # Remove all styles but keep colors
|
148
|
+
text.without_style(:bold, :italic) # Remove specific styles
|
149
|
+
|
150
|
+
# Access individual segments
|
151
|
+
text.each do |segment|
|
152
|
+
puts "Text: #{segment.text}"
|
153
|
+
puts "Foreground: #{segment.foreground}"
|
154
|
+
puts "Background: #{segment.background}"
|
155
|
+
puts "Styles: #{segment.styles}"
|
156
|
+
puts "Position: #{segment.encoded_location.start_position}..#{segment.encoded_location.end_position}"
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
## Color Mode Management
|
161
|
+
|
162
|
+
Sai by default automatically detects your terminal's capabilities and automatically downgrades colors based on those
|
163
|
+
capabilities but also allows manual control:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
# Use automatic mode detection (default)
|
167
|
+
Sai.with_mode(Sai.mode.auto)
|
168
|
+
|
169
|
+
# Force specific color modes
|
170
|
+
puts Sai.with_mode(Sai.mode.true_color).red.decorate('24-bit color')
|
171
|
+
puts Sai.with_mode(Sai.mode.advanced).red.decorate('256 colors')
|
172
|
+
puts Sai.with_mode(Sai.mode.ansi).red.decorate('16 colors')
|
173
|
+
puts Sai.with_mode(Sai.mode.basic).red.decorate('8 colors')
|
174
|
+
puts Sai.with_mode(Sai.mode.no_color).red.decorate('No color')
|
175
|
+
|
176
|
+
# Use automatic downgrading
|
177
|
+
puts Sai.with_mode(Sai.mode.advanced_auto).red.decorate('256 colors or less')
|
178
|
+
puts Sai.with_mode(Sai.mode.ansi_auto).red.decorate('16 colors or less')
|
179
|
+
puts Sai.with_mode(Sai.mode.basic_auto).red.decorate('8 colors or less')
|
180
|
+
```
|
181
|
+
|
182
|
+
> [!WARNING]
|
183
|
+
> When using fixed color modes (like `true_color` or `advanced`), Sai will not automatically downgrade colors for
|
184
|
+
> terminals with lower color support. For automatic color mode adjustment, use modes ending in `_auto`
|
185
|
+
> (like `advanced_auto` or `ansi_auto`).
|
186
|
+
|
187
|
+
Color Mode Hierarchy:
|
188
|
+
|
189
|
+
1. True Color (24-bit): 16.7 million colors
|
190
|
+
2. Advanced (8-bit): 256 colors
|
191
|
+
3. ANSI (4-bit): 16 colors
|
192
|
+
4. Basic (3-bit): 8 colors
|
193
|
+
5. No Color: All formatting stripped
|
194
|
+
|
195
|
+
## Terminal Capabilities
|
196
|
+
|
197
|
+
Check terminal color support:
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
# Using directly
|
201
|
+
Sai.support.true_color? # => true/false
|
202
|
+
Sai.support.advanced? # => true/false
|
203
|
+
Sai.support.ansi? # => true/false
|
204
|
+
Sai.support.basic? # => true/false
|
205
|
+
Sai.support.color? # => true/false
|
206
|
+
|
207
|
+
# Using included module
|
208
|
+
class CLI
|
209
|
+
include Sai
|
210
|
+
|
211
|
+
def check_support
|
212
|
+
if terminal_color_support.true_color?
|
213
|
+
puts "Terminal supports true color!"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
```
|
218
|
+
|
219
|
+
## Integration Patterns
|
220
|
+
|
221
|
+
### Defining Reusable Styles
|
222
|
+
|
223
|
+
Create consistent styling across your application:
|
224
|
+
|
225
|
+
```ruby
|
226
|
+
module Style
|
227
|
+
ERROR = Sai.bold.bright_white.on_red
|
228
|
+
WARNING = Sai.black.on_yellow
|
229
|
+
SUCCESS = Sai.bright_green
|
230
|
+
INFO = Sai.bright_blue
|
231
|
+
HEADER = Sai.bold.bright_cyan.underline
|
232
|
+
end
|
233
|
+
|
234
|
+
# Use your defined styles
|
235
|
+
puts Style::ERROR.decorate('Something went wrong!')
|
236
|
+
puts Style::SUCCESS.decorate('Operation completed successfully')
|
237
|
+
|
238
|
+
# Styles can be further customized
|
239
|
+
puts Style::ERROR.italic.decorate('Critical error!')
|
240
|
+
```
|
241
|
+
|
242
|
+
> [!TIP]
|
243
|
+
> This pattern is particularly useful for maintaining consistent styling across your application and creating theme
|
244
|
+
> systems. You can even build on existing styles:
|
245
|
+
>
|
246
|
+
> ```ruby
|
247
|
+
> module Theme
|
248
|
+
> PRIMARY = Sai.rgb(63, 81, 181)
|
249
|
+
> SECONDARY = Sai.rgb(255, 87, 34)
|
250
|
+
>
|
251
|
+
> BUTTON = PRIMARY.bold
|
252
|
+
> LINK = SECONDARY.underline
|
253
|
+
> HEADER = PRIMARY.bold.underline
|
254
|
+
> end
|
255
|
+
> ```
|
256
|
+
|
257
|
+
### Class Integration
|
258
|
+
|
259
|
+
Integrate Sai into your classes:
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
class Logger
|
263
|
+
include Sai
|
264
|
+
|
265
|
+
def error(message)
|
266
|
+
puts decorator.red.bold.decorate(message)
|
267
|
+
end
|
268
|
+
|
269
|
+
def warn(message)
|
270
|
+
puts decorator.yellow.decorate(message)
|
271
|
+
end
|
272
|
+
|
273
|
+
def info(message)
|
274
|
+
puts decorator.with_mode(color_mode.true_color).bright_blue.decorate(message)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
```
|
278
|
+
|
279
|
+
## Best Practices
|
280
|
+
|
281
|
+
1. **Automatic Mode Detection**
|
282
|
+
* Use `Sai.mode.auto` by default to respect terminal capabilities
|
283
|
+
* Only force specific color modes when necessary
|
284
|
+
|
285
|
+
2. **Color Usage**
|
286
|
+
* Use named colors for standard indicators (red for errors, etc.)
|
287
|
+
* Use RGB/Hex for brand colors or specific design requirements
|
288
|
+
* Consider color blindness when choosing colors
|
289
|
+
|
290
|
+
3. **Style Organization**
|
291
|
+
* Create reusable styles for consistency
|
292
|
+
* Group related styles in modules
|
293
|
+
* Consider creating a theme system for larger applications
|
294
|
+
|
295
|
+
4. **Performance**
|
296
|
+
* Cache decorator instances when using repeatedly
|
297
|
+
* Use `SequencedString` parsing for complex manipulations
|
298
|
+
* Consider terminal capabilities when designing output
|
299
|
+
|
300
|
+
5. **Accessibility**
|
301
|
+
* Don't rely solely on color for important information
|
302
|
+
* Use styles (bold, underline) to enhance meaning
|
303
|
+
* Respect NO_COLOR environment variable
|