sai 0.1.0 → 0.2.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/CHANGELOG.md +16 -1
- data/README.md +40 -7
- 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 +201 -171
- 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 +106 -77
- 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 +103 -76
- 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 +92 -66
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d27e2e0d0202e3dc41887be8cfa58f3d862fdee0c9fc3dbd0db792bac1d8f91
|
4
|
+
data.tar.gz: c1a6cd0918fd89b72fe1bd22479192354293a270803297fe901df818032fbfb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 958aae38da9095a09347a97dd5eddca62a2ac2b4f2eddf51ee4e5b11f4ffdeed26918dad6f00bd85129f82de8eafbde5eb1ed6e3c6a8136d6d5ad6cf3b3765fe
|
7
|
+
data.tar.gz: cce26cf788ae60731b58cf2460cea923bda925db36a75f009ec4846046edf47afbd10a81990c7651a0cde21d1090c725dbc7b5e290f412968b83c0dc5f61e1db
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,20 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.0] - 2025-01-20
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
* [#3](https://github.com/aaronmallen/sai/pull/3) - mode selection via `Sai::ModeSelector`by
|
14
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
* [#2](https://github.com/aaronmallen/sai/pull/2) - Immutable method chaining for `Sai::Decorator` by
|
19
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
20
|
+
* [#3](https://github.com/aaronmallen/sai/pull/3) - `Sia::Support` from class to module for improved API design by
|
21
|
+
[@aaronmallen](https://github.com/aaronmallen)
|
22
|
+
|
9
23
|
## 0.1.0 - 2025-01-19
|
10
24
|
|
11
25
|
* Initial release
|
@@ -15,4 +29,5 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
|
|
15
29
|
|
16
30
|
<!-- versions -->
|
17
31
|
|
18
|
-
[Unreleased]: https://github.com/aaronmallen/sai/compare/0.
|
32
|
+
[Unreleased]: https://github.com/aaronmallen/sai/compare/0.2.0..HEAD
|
33
|
+
[0.2.0]: https://github.com/aaronmallen/sai/compare/0.1.0..0.2.0
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/sai)
|
4
4
|
[](./LICENSE)
|
5
|
-
[](https://rubydoc.info/gems/sai/0.
|
5
|
+
[](https://rubydoc.info/gems/sai/0.2.0)
|
6
6
|
[](https://github.com/aaronmallen/sai/issues?q=state%3Aopen%20)
|
7
7
|
|
8
8
|
An elegant color management system for crafting sophisticated CLI applications
|
@@ -73,10 +73,10 @@ puts Sai.red.bold.italic.decorate('Error!')
|
|
73
73
|
|
74
74
|
# Complex combinations
|
75
75
|
puts Sai.bright_cyan
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
76
|
+
.on_blue
|
77
|
+
.bold
|
78
|
+
.italic
|
79
|
+
.decorate('Styled text')
|
80
80
|
```
|
81
81
|
|
82
82
|
### Module Inclusion
|
@@ -94,7 +94,7 @@ class CLI
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def success(message)
|
97
|
-
puts decorator.green.decorate(message)
|
97
|
+
puts decorator.with_mode(color_mode.ansi_auto).green.decorate(message)
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -235,6 +235,39 @@ Sai automatically detects your terminal's color capabilities and adapts the outp
|
|
235
235
|
> [!NOTE]
|
236
236
|
> This automatic downgrading ensures your application looks great across all terminal types without any extra code!
|
237
237
|
|
238
|
+
### Color Mode Selection
|
239
|
+
|
240
|
+
Sai provides flexible color mode selection through its `mode` interface:
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
# Use automatic mode detection (default)
|
244
|
+
Sai.with_mode(Sai.mode.auto)
|
245
|
+
|
246
|
+
# Force specific color modes
|
247
|
+
puts Sai.with_mode(Sai.mode.true_color).red.decorate('24-bit color')
|
248
|
+
puts Sai.with_mode(Sai.mode.advanced).red.decorate('256 colors')
|
249
|
+
puts Sai.with_mode(Sai.mode.ansi).red.decorate('16 colors')
|
250
|
+
puts Sai.with_mode(Sai.mode.basic).red.decorate('8 colors')
|
251
|
+
puts Sai.with_mode(Sai.mode.no_color).red.decorate('No color')
|
252
|
+
|
253
|
+
# Use automatic downgrading
|
254
|
+
puts Sai.with_mode(Sai.mode.advanced_auto).red.decorate('256 colors or less')
|
255
|
+
puts Sai.with_mode(Sai.mode.ansi_auto).red.decorate('16 colors or less')
|
256
|
+
puts Sai.with_mode(Sai.mode.basic_auto).red.decorate('8 colors or less')
|
257
|
+
```
|
258
|
+
|
259
|
+
> [!WARNING]
|
260
|
+
> When using fixed color modes (like `true_color` or `advanced`), Sai will not automatically downgrade colors for
|
261
|
+
> terminals with lower color support. For automatic color mode adjustment, use modes ending in `_auto`
|
262
|
+
> (like `advanced_auto` or `ansi_auto`).
|
263
|
+
|
264
|
+
This allows you to:
|
265
|
+
|
266
|
+
* Explicitly set specific color modes
|
267
|
+
* Use automatic mode detection (default)
|
268
|
+
* Set maximum color modes with automatic downgrading
|
269
|
+
* Disable colors entirely
|
270
|
+
|
238
271
|
### Terminal Support Detection
|
239
272
|
|
240
273
|
You can check the terminal's capabilities:
|
@@ -242,7 +275,7 @@ You can check the terminal's capabilities:
|
|
242
275
|
```ruby
|
243
276
|
# Using directly
|
244
277
|
Sai.support.true_color? # => true/false
|
245
|
-
Sai.support.
|
278
|
+
Sai.support.advanced? # => true/false
|
246
279
|
Sai.support.ansi? # => true/false
|
247
280
|
Sai.support.basic? # => true/false
|
248
281
|
Sai.support.color? # => true/false
|
data/lib/sai/ansi.rb
CHANGED
@@ -4,14 +4,14 @@ module Sai
|
|
4
4
|
# ANSI constants for encoding text styles and colors
|
5
5
|
#
|
6
6
|
# @author {https://aaronmallen.me Aaron Allen}
|
7
|
-
# @since
|
7
|
+
# @since 0.1.0
|
8
8
|
#
|
9
9
|
# @api private
|
10
10
|
module ANSI
|
11
11
|
# ANSI color code mappings
|
12
12
|
#
|
13
13
|
# @author {https://aaronmallen.me Aaron Allen}
|
14
|
-
# @since
|
14
|
+
# @since 0.1.0
|
15
15
|
#
|
16
16
|
# @api private
|
17
17
|
#
|
@@ -30,7 +30,7 @@ module Sai
|
|
30
30
|
# Standard ANSI color names and their RGB values
|
31
31
|
#
|
32
32
|
# @author {https://aaronmallen.me Aaron Allen}
|
33
|
-
# @since
|
33
|
+
# @since 0.1.0
|
34
34
|
#
|
35
35
|
# @api private
|
36
36
|
#
|
@@ -57,7 +57,7 @@ module Sai
|
|
57
57
|
# ANSI escape sequence for resetting text formatting
|
58
58
|
#
|
59
59
|
# @author {https://aaronmallen.me Aaron Allen}
|
60
|
-
# @since
|
60
|
+
# @since 0.1.0
|
61
61
|
#
|
62
62
|
# @api private
|
63
63
|
#
|
@@ -67,7 +67,7 @@ module Sai
|
|
67
67
|
# Standard ANSI style codes
|
68
68
|
#
|
69
69
|
# @author {https://aaronmallen.me Aaron Allen}
|
70
|
-
# @since
|
70
|
+
# @since 0.1.0
|
71
71
|
#
|
72
72
|
# @api private
|
73
73
|
#
|
@@ -9,7 +9,7 @@ module Sai
|
|
9
9
|
# ANSI escape sequence utilities
|
10
10
|
#
|
11
11
|
# @author {https://aaronmallen.me Aaron Allen}
|
12
|
-
# @since
|
12
|
+
# @since 0.1.0
|
13
13
|
#
|
14
14
|
# @api private
|
15
15
|
module ColorSequence
|
@@ -20,7 +20,7 @@ module Sai
|
|
20
20
|
# Convert a color to the appropriate ANSI escape sequence
|
21
21
|
#
|
22
22
|
# @author {https://aaronmallen.me Aaron Allen}
|
23
|
-
# @since
|
23
|
+
# @since 0.1.0
|
24
24
|
#
|
25
25
|
# @api private
|
26
26
|
#
|
@@ -36,7 +36,7 @@ module Sai
|
|
36
36
|
|
37
37
|
case mode
|
38
38
|
when Terminal::ColorMode::TRUE_COLOR then true_color(rgb, style_type)
|
39
|
-
when Terminal::ColorMode::
|
39
|
+
when Terminal::ColorMode::ADVANCED then advanced(rgb, style_type)
|
40
40
|
when Terminal::ColorMode::ANSI then ansi(rgb, style_type)
|
41
41
|
when Terminal::ColorMode::BASIC then basic(rgb, style_type)
|
42
42
|
else
|
@@ -46,10 +46,33 @@ module Sai
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
+
# Convert RGB values to an 8-bit color sequence
|
50
|
+
#
|
51
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
52
|
+
# @since 0.1.0
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
# @param rgb [Array<Integer>] the RGB components
|
57
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
58
|
+
#
|
59
|
+
# @return [String] the ANSI escape sequence
|
60
|
+
# @rbs (Array[Integer] rgb, style_type type) -> String
|
61
|
+
def advanced(rgb, style_type)
|
62
|
+
code = style_type == :background ? 48 : 38
|
63
|
+
color_code = if rgb.uniq.size == 1
|
64
|
+
RGB.to_grayscale_index(rgb)
|
65
|
+
else
|
66
|
+
RGB.to_color_cube_index(rgb)
|
67
|
+
end
|
68
|
+
|
69
|
+
"\e[#{code};5;#{color_code}m"
|
70
|
+
end
|
71
|
+
|
49
72
|
# Convert RGB values to a 4-bit ANSI color sequence
|
50
73
|
#
|
51
74
|
# @author {https://aaronmallen.me Aaron Allen}
|
52
|
-
# @since
|
75
|
+
# @since 0.1.0
|
53
76
|
#
|
54
77
|
# @api private
|
55
78
|
#
|
@@ -72,7 +95,7 @@ module Sai
|
|
72
95
|
# Convert a base color to a foreground or background sequence
|
73
96
|
#
|
74
97
|
# @author {https://aaronmallen.me Aaron Allen}
|
75
|
-
# @since
|
98
|
+
# @since 0.1.0
|
76
99
|
#
|
77
100
|
# @api private
|
78
101
|
#
|
@@ -88,7 +111,7 @@ module Sai
|
|
88
111
|
# Convert RGB values to a 3-bit basic color sequence
|
89
112
|
#
|
90
113
|
# @author {https://aaronmallen.me Aaron Allen}
|
91
|
-
# @since
|
114
|
+
# @since 0.1.0
|
92
115
|
#
|
93
116
|
# @api private
|
94
117
|
#
|
@@ -104,33 +127,10 @@ module Sai
|
|
104
127
|
"\e[#{code}m"
|
105
128
|
end
|
106
129
|
|
107
|
-
# Convert RGB values to an 8-bit color sequence
|
108
|
-
#
|
109
|
-
# @author {https://aaronmallen.me Aaron Allen}
|
110
|
-
# @since unreleased
|
111
|
-
#
|
112
|
-
# @api private
|
113
|
-
#
|
114
|
-
# @param rgb [Array<Integer>] the RGB components
|
115
|
-
# @param style_type [Symbol] the type of color (foreground or background)
|
116
|
-
#
|
117
|
-
# @return [String] the ANSI escape sequence
|
118
|
-
# @rbs (Array[Integer] rgb, style_type type) -> String
|
119
|
-
def bit8(rgb, style_type)
|
120
|
-
code = style_type == :background ? 48 : 38
|
121
|
-
color_code = if rgb.uniq.size == 1
|
122
|
-
RGB.to_grayscale_index(rgb)
|
123
|
-
else
|
124
|
-
RGB.to_color_cube_index(rgb)
|
125
|
-
end
|
126
|
-
|
127
|
-
"\e[#{code};5;#{color_code}m"
|
128
|
-
end
|
129
|
-
|
130
130
|
# Convert RGB values to a true color (24-bit) sequence
|
131
131
|
#
|
132
132
|
# @author {https://aaronmallen.me Aaron Allen}
|
133
|
-
# @since
|
133
|
+
# @since 0.1.0
|
134
134
|
#
|
135
135
|
# @api private
|
136
136
|
#
|
@@ -147,7 +147,7 @@ module Sai
|
|
147
147
|
# Validate a color style type
|
148
148
|
#
|
149
149
|
# @author {https://aaronmallen.me Aaron Allen}
|
150
|
-
# @since
|
150
|
+
# @since 0.1.0
|
151
151
|
#
|
152
152
|
# @api private
|
153
153
|
#
|
data/lib/sai/conversion/rgb.rb
CHANGED
@@ -7,7 +7,7 @@ module Sai
|
|
7
7
|
# RGB color conversion utilities
|
8
8
|
#
|
9
9
|
# @author {https://aaronmallen.me Aaron Allen}
|
10
|
-
# @since
|
10
|
+
# @since 0.1.0
|
11
11
|
#
|
12
12
|
# @api private
|
13
13
|
module RGB
|
@@ -15,7 +15,7 @@ module Sai
|
|
15
15
|
# Get closest ANSI color for RGB values
|
16
16
|
#
|
17
17
|
# @author {https://aaronmallen.me Aaron Allen}
|
18
|
-
# @since
|
18
|
+
# @since 0.1.0
|
19
19
|
#
|
20
20
|
# @api private
|
21
21
|
#
|
@@ -37,7 +37,7 @@ module Sai
|
|
37
37
|
# Determine if a color is dark
|
38
38
|
#
|
39
39
|
# @author {https://aaronmallen.me Aaron Allen}
|
40
|
-
# @since
|
40
|
+
# @since 0.1.0
|
41
41
|
#
|
42
42
|
# @api private
|
43
43
|
#
|
@@ -54,7 +54,7 @@ module Sai
|
|
54
54
|
# Determine if a color is grayscale
|
55
55
|
#
|
56
56
|
# @author {https://aaronmallen.me Aaron Allen}
|
57
|
-
# @since
|
57
|
+
# @since 0.1.0
|
58
58
|
#
|
59
59
|
# @api private
|
60
60
|
#
|
@@ -71,7 +71,7 @@ module Sai
|
|
71
71
|
# Convert a color value to RGB components
|
72
72
|
#
|
73
73
|
# @author {https://aaronmallen.me Aaron Allen}
|
74
|
-
# @since
|
74
|
+
# @since 0.1.0
|
75
75
|
#
|
76
76
|
# @api private
|
77
77
|
#
|
@@ -96,7 +96,7 @@ module Sai
|
|
96
96
|
# Convert RGB values to 256-color cube index
|
97
97
|
#
|
98
98
|
# @author {https://aaronmallen.me Aaron Allen}
|
99
|
-
# @since
|
99
|
+
# @since 0.1.0
|
100
100
|
#
|
101
101
|
# @api private
|
102
102
|
#
|
@@ -112,7 +112,7 @@ module Sai
|
|
112
112
|
# Convert RGB values to grayscale index
|
113
113
|
#
|
114
114
|
# @author {https://aaronmallen.me Aaron Allen}
|
115
|
-
# @since
|
115
|
+
# @since 0.1.0
|
116
116
|
#
|
117
117
|
# @api private
|
118
118
|
#
|
@@ -129,7 +129,7 @@ module Sai
|
|
129
129
|
# Check if RGB values represent cyan
|
130
130
|
#
|
131
131
|
# @author {https://aaronmallen.me Aaron Allen}
|
132
|
-
# @since
|
132
|
+
# @since 0.1.0
|
133
133
|
#
|
134
134
|
# @api private
|
135
135
|
#
|
@@ -146,7 +146,7 @@ module Sai
|
|
146
146
|
# Convert a hex string to RGB values
|
147
147
|
#
|
148
148
|
# @author {https://aaronmallen.me Aaron Allen}
|
149
|
-
# @since
|
149
|
+
# @since 0.1.0
|
150
150
|
#
|
151
151
|
# @api private
|
152
152
|
#
|
@@ -166,7 +166,7 @@ module Sai
|
|
166
166
|
# Check if RGB values represent magenta
|
167
167
|
#
|
168
168
|
# @author {https://aaronmallen.me Aaron Allen}
|
169
|
-
# @since
|
169
|
+
# @since 0.1.0
|
170
170
|
#
|
171
171
|
# @api private
|
172
172
|
#
|
@@ -183,7 +183,7 @@ module Sai
|
|
183
183
|
# Convert a named color to RGB values
|
184
184
|
#
|
185
185
|
# @author {https://aaronmallen.me Aaron Allen}
|
186
|
-
# @since
|
186
|
+
# @since 0.1.0
|
187
187
|
#
|
188
188
|
# @api private
|
189
189
|
#
|
@@ -201,7 +201,7 @@ module Sai
|
|
201
201
|
# Determine if RGB values represent a primary color
|
202
202
|
#
|
203
203
|
# @author {https://aaronmallen.me Aaron Allen}
|
204
|
-
# @since
|
204
|
+
# @since 0.1.0
|
205
205
|
#
|
206
206
|
# @api private
|
207
207
|
#
|
@@ -220,7 +220,7 @@ module Sai
|
|
220
220
|
# Get the closest primary color
|
221
221
|
#
|
222
222
|
# @author {https://aaronmallen.me Aaron Allen}
|
223
|
-
# @since
|
223
|
+
# @since 0.1.0
|
224
224
|
#
|
225
225
|
# @api private
|
226
226
|
#
|
@@ -242,7 +242,7 @@ module Sai
|
|
242
242
|
# Determine if RGB values represent a secondary color
|
243
243
|
#
|
244
244
|
# @author {https://aaronmallen.me Aaron Allen}
|
245
|
-
# @since
|
245
|
+
# @since 0.1.0
|
246
246
|
#
|
247
247
|
# @api private
|
248
248
|
#
|
@@ -263,7 +263,7 @@ module Sai
|
|
263
263
|
# Get the closest secondary color
|
264
264
|
#
|
265
265
|
# @author {https://aaronmallen.me Aaron Allen}
|
266
|
-
# @since
|
266
|
+
# @since 0.1.0
|
267
267
|
#
|
268
268
|
# @api private
|
269
269
|
#
|
@@ -284,7 +284,7 @@ module Sai
|
|
284
284
|
# Validate RGB values
|
285
285
|
#
|
286
286
|
# @author {https://aaronmallen.me Aaron Allen}
|
287
|
-
# @since
|
287
|
+
# @since 0.1.0
|
288
288
|
#
|
289
289
|
# @api private
|
290
290
|
#
|
@@ -303,7 +303,7 @@ module Sai
|
|
303
303
|
# Check if RGB values represent yellow
|
304
304
|
#
|
305
305
|
# @author {https://aaronmallen.me Aaron Allen}
|
306
|
-
# @since
|
306
|
+
# @since 0.1.0
|
307
307
|
#
|
308
308
|
# @api private
|
309
309
|
#
|