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.
data/lib/sai.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sai/conversion/color_sequence'
4
+ require 'sai/conversion/rgb'
3
5
  require 'sai/decorator'
6
+ require 'sai/mode_selector'
4
7
  require 'sai/support'
5
8
  require 'sai/terminal/capabilities'
6
- require 'singleton'
9
+ require 'sai/terminal/color_mode'
7
10
 
8
11
  # An elegant color management system for crafting sophisticated CLI applications
9
12
  #
@@ -23,7 +26,7 @@ require 'singleton'
23
26
  # decorations (apply, call, decorate, encode). These methods are directly delegated to a new {Decorator} instance
24
27
  #
25
28
  # @author {https://aaronmallen.me Aaron Allen}
26
- # @since unreleased
29
+ # @since 0.1.0
27
30
  #
28
31
  # @api public
29
32
  #
@@ -48,100 +51,121 @@ module Sai
48
51
  ignored_decorator_methods = %i[apply call decorate encode]
49
52
  Decorator.instance_methods(false).reject { |m| ignored_decorator_methods.include?(m) }.each do |method|
50
53
  define_method(method) do |*arguments, **keyword_arguments|
51
- Decorator.new(send(:color_mode)).public_send(method, *arguments, **keyword_arguments)
54
+ Decorator.new(mode: Sai.mode.auto).public_send(method, *arguments, **keyword_arguments)
52
55
  end
53
56
  end
54
57
 
58
+ # The Sai {ModeSelector mode selector}
59
+ #
60
+ # @author {https://aaronmallen.me Aaron Allen}
61
+ # @since 0.2.0
62
+ #
63
+ # @api public
64
+ #
65
+ # @example
66
+ # Sai.mode.auto #=> 4
67
+ #
68
+ # @return [ModeSelector] the mode selector
69
+ # @rbs () -> singleton(ModeSelector)
70
+ def mode
71
+ ModeSelector
72
+ end
73
+
55
74
  # @rbs!
56
- # def black: () -> self
57
- # def blink: () -> self
58
- # def blue: () -> self
59
- # def bold: () -> self
60
- # def bright_black: () -> self
61
- # def bright_blue: () -> self
62
- # def bright_cyan: () -> self
63
- # def bright_green: () -> self
64
- # def bright_magenta: () -> self
65
- # def bright_red: () -> self
66
- # def bright_white: () -> self
67
- # def bright_yellow: () -> self
68
- # def conceal: () -> self
69
- # def cyan: () -> self
70
- # def dim: () -> self
71
- # def green: () -> self
72
- # def italic: () -> self
73
- # def magenta: () -> self
74
- # def no_blink: () -> self
75
- # def no_conceal: () -> self
76
- # def no_italic: () -> self
77
- # def no_reverse: () -> self
78
- # def no_strike: () -> self
79
- # def no_underline: () -> self
80
- # def normal_intensity: () -> self
81
- # def on_black: () -> self
82
- # def on_blue: () -> self
83
- # def on_bright_black: () -> self
84
- # def on_bright_blue: () -> self
85
- # def on_bright_cyan: () -> self
86
- # def on_bright_green: () -> self
87
- # def on_bright_magenta: () -> self
88
- # def on_bright_red: () -> self
89
- # def on_bright_white: () -> self
90
- # def on_bright_yellow: () -> self
91
- # def on_cyan: () -> self
92
- # def on_green: () -> self
93
- # def on_magenta: () -> self
94
- # def on_red: () -> self
95
- # def on_white: () -> self
96
- # def on_yellow: () -> self
97
- # def rapid_blink: () -> self
98
- # def red: () -> self
99
- # def reverse: () -> self
100
- # def strike: () -> self
101
- # def underline: () -> self
102
- # def white: () -> self
103
- # def yellow: () -> self
75
+ # def black: () -> Decorator
76
+ # def blink: () -> Decorator
77
+ # def blue: () -> Decorator
78
+ # def bold: () -> Decorator
79
+ # def bright_black: () -> Decorator
80
+ # def bright_blue: () -> Decorator
81
+ # def bright_cyan: () -> Decorator
82
+ # def bright_green: () -> Decorator
83
+ # def bright_magenta: () -> Decorator
84
+ # def bright_red: () -> Decorator
85
+ # def bright_white: () -> Decorator
86
+ # def bright_yellow: () -> Decorator
87
+ # def conceal: () -> Decorator
88
+ # def cyan: () -> Decorator
89
+ # def dim: () -> Decorator
90
+ # def green: () -> Decorator
91
+ # def italic: () -> Decorator
92
+ # def magenta: () -> Decorator
93
+ # def no_blink: () -> Decorator
94
+ # def no_conceal: () -> Decorator
95
+ # def no_italic: () -> Decorator
96
+ # def no_reverse: () -> Decorator
97
+ # def no_strike: () -> Decorator
98
+ # def no_underline: () -> Decorator
99
+ # def normal_intensity: () -> Decorator
100
+ # def on_black: () -> Decorator
101
+ # def on_blue: () -> Decorator
102
+ # def on_bright_black: () -> Decorator
103
+ # def on_bright_blue: () -> Decorator
104
+ # def on_bright_cyan: () -> Decorator
105
+ # def on_bright_green: () -> Decorator
106
+ # def on_bright_magenta: () -> Decorator
107
+ # def on_bright_red: () -> Decorator
108
+ # def on_bright_white: () -> Decorator
109
+ # def on_bright_yellow: () -> Decorator
110
+ # def on_cyan: () -> Decorator
111
+ # def on_green: () -> Decorator
112
+ # def on_magenta: () -> Decorator
113
+ # def on_red: () -> Decorator
114
+ # def on_white: () -> Decorator
115
+ # def on_yellow: () -> Decorator
116
+ # def rapid_blink: () -> Decorator
117
+ # def red: () -> Decorator
118
+ # def reverse: () -> Decorator
119
+ # def strike: () -> Decorator
120
+ # def underline: () -> Decorator
121
+ # def white: () -> Decorator
122
+ # def yellow: () -> Decorator
104
123
 
105
124
  # The supported color modes for the terminal
106
125
  #
107
126
  # @author {https://aaronmallen.me Aaron Allen}
108
- # @since unreleased
127
+ # @since 0.1.0
109
128
  #
110
129
  # @api public
111
130
  #
112
131
  # @example Check the color support of the terminal
113
132
  # Sai.support.ansi? # => true
114
133
  # Sai.support.basic? # => true
115
- # Sai.support.bit8? # => true
134
+ # Sai.support.advanced? # => true
116
135
  # Sai.support.no_color? # => false
117
136
  # Sai.support.true_color? # => true
118
137
  #
119
138
  # @return [Support] the color support
120
- # @rbs () -> Support
139
+ # @rbs () -> singleton(Support)
121
140
  def support
122
- @support ||= Support.new(color_mode).freeze
141
+ Support
123
142
  end
143
+ end
124
144
 
125
- private
126
-
127
- # Detect the color capabilities of the terminal
128
- #
129
- # @author {https://aaronmallen.me Aaron Allen}
130
- # @since unreleased
131
- #
132
- # @api private
133
- #
134
- # @return [Integer] the color mode
135
- # @rbs () -> Integer
136
- def color_mode
137
- Thread.current[:sai_color_mode] ||= Terminal::Capabilities.detect_color_support
138
- end
145
+ # A helper method that provides Sai color modes
146
+ #
147
+ # @author {https://aaronmallen.me Aaron Allen}
148
+ # @since 0.2.0
149
+ #
150
+ # @api public
151
+ #
152
+ # @example
153
+ # class MyClass
154
+ # include Sai
155
+ # end
156
+ #
157
+ # MyClass.new.color_mode.ansi #=> 2
158
+ #
159
+ # @return [ModeSelector] the mode selector
160
+ # @rbs () -> singleton(ModeSelector)
161
+ def color_mode
162
+ ModeSelector
139
163
  end
140
164
 
141
165
  # A helper method to initialize an instance of {Decorator}
142
166
  #
143
167
  # @author {https://aaronmallen.me Aaron Allen}
144
- # @since unreleased
168
+ # @since 0.1.0
145
169
  #
146
170
  # @api public
147
171
  #
@@ -153,16 +177,21 @@ module Sai
153
177
  # MyClass.new.decorator.blue.on_red.bold.decorate('Hello, world!')
154
178
  # #=> "\e[38;5;21m\e[48;5;160m\e[1mHello, world!\e[0m"
155
179
  #
180
+ # MyClass.new.decorator(mode: Sai.mode.no_color)
181
+ # #=> "Hello, world!"
182
+ #
183
+ # @param mode [Integer] the color mode to use
184
+ #
156
185
  # @return [Decorator] the Decorator instance
157
- # @rbs () -> Decorator
158
- def decorator
159
- Decorator.new(Terminal::Capabilities.detect_color_support)
186
+ # @rbs (?mode: Integer) -> Decorator
187
+ def decorator(mode: Sai.mode.auto)
188
+ Decorator.new(mode:)
160
189
  end
161
190
 
162
191
  # The supported color modes for the terminal
163
192
  #
164
193
  # @author {https://aaronmallen.me Aaron Allen}
165
- # @since unreleased
194
+ # @since 0.1.0
166
195
  #
167
196
  # @api public
168
197
  #
@@ -173,13 +202,13 @@ module Sai
173
202
  #
174
203
  # MyClass.new.terminal_color_support.ansi? # => true
175
204
  # MyClass.new.terminal_color_support.basic? # => true
176
- # MyClass.new.terminal_color_support.bit8? # => true
205
+ # MyClass.new.terminal_color_support.advanced? # => true
177
206
  # MyClass.new.terminal_color_support.no_color? # => false
178
207
  # MyClass.new.terminal_color_support.true_color? # => true
179
208
  #
180
209
  # @return [Support] the color support
181
- # @rbs () -> Support
210
+ # @rbs () -> singleton(Support)
182
211
  def terminal_color_support
183
- Sai.support
212
+ Support
184
213
  end
185
214
  end
data/sig/sai/ansi.rbs 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 unreleased
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 unreleased
14
+ # @since 0.1.0
15
15
  #
16
16
  # @api private
17
17
  #
@@ -21,7 +21,7 @@ module Sai
21
21
  # Standard ANSI color names and their RGB values
22
22
  #
23
23
  # @author {https://aaronmallen.me Aaron Allen}
24
- # @since unreleased
24
+ # @since 0.1.0
25
25
  #
26
26
  # @api private
27
27
  #
@@ -31,7 +31,7 @@ module Sai
31
31
  # ANSI escape sequence for resetting text formatting
32
32
  #
33
33
  # @author {https://aaronmallen.me Aaron Allen}
34
- # @since unreleased
34
+ # @since 0.1.0
35
35
  #
36
36
  # @api private
37
37
  #
@@ -41,7 +41,7 @@ module Sai
41
41
  # Standard ANSI style codes
42
42
  #
43
43
  # @author {https://aaronmallen.me Aaron Allen}
44
- # @since unreleased
44
+ # @since 0.1.0
45
45
  #
46
46
  # @api private
47
47
  #
@@ -5,7 +5,7 @@ module Sai
5
5
  # ANSI escape sequence utilities
6
6
  #
7
7
  # @author {https://aaronmallen.me Aaron Allen}
8
- # @since unreleased
8
+ # @since 0.1.0
9
9
  #
10
10
  # @api private
11
11
  module ColorSequence
@@ -14,7 +14,7 @@ module Sai
14
14
  # Convert a color to the appropriate ANSI escape sequence
15
15
  #
16
16
  # @author {https://aaronmallen.me Aaron Allen}
17
- # @since unreleased
17
+ # @since 0.1.0
18
18
  #
19
19
  # @api private
20
20
  #
@@ -26,10 +26,24 @@ module Sai
26
26
  # @rbs (Array[Integer] | String | Symbol color, Integer mode, ?style_type style_type) -> String
27
27
  def self.resolve: (Array[Integer] | String | Symbol color, Integer mode, ?style_type style_type) -> String
28
28
 
29
+ # Convert RGB values to an 8-bit color sequence
30
+ #
31
+ # @author {https://aaronmallen.me Aaron Allen}
32
+ # @since 0.1.0
33
+ #
34
+ # @api private
35
+ #
36
+ # @param rgb [Array<Integer>] the RGB components
37
+ # @param style_type [Symbol] the type of color (foreground or background)
38
+ #
39
+ # @return [String] the ANSI escape sequence
40
+ # @rbs (Array[Integer] rgb, style_type type) -> String
41
+ private def self.advanced: (Array[Integer] rgb, style_type type) -> String
42
+
29
43
  # Convert RGB values to a 4-bit ANSI color sequence
30
44
  #
31
45
  # @author {https://aaronmallen.me Aaron Allen}
32
- # @since unreleased
46
+ # @since 0.1.0
33
47
  #
34
48
  # @api private
35
49
  #
@@ -43,7 +57,7 @@ module Sai
43
57
  # Convert a base color to a foreground or background sequence
44
58
  #
45
59
  # @author {https://aaronmallen.me Aaron Allen}
46
- # @since unreleased
60
+ # @since 0.1.0
47
61
  #
48
62
  # @api private
49
63
  #
@@ -57,7 +71,7 @@ module Sai
57
71
  # Convert RGB values to a 3-bit basic color sequence
58
72
  #
59
73
  # @author {https://aaronmallen.me Aaron Allen}
60
- # @since unreleased
74
+ # @since 0.1.0
61
75
  #
62
76
  # @api private
63
77
  #
@@ -68,24 +82,10 @@ module Sai
68
82
  # @rbs (Array[Integer] rgb, style_type style_type) -> String
69
83
  private def self.basic: (Array[Integer] rgb, style_type style_type) -> String
70
84
 
71
- # Convert RGB values to an 8-bit color sequence
72
- #
73
- # @author {https://aaronmallen.me Aaron Allen}
74
- # @since unreleased
75
- #
76
- # @api private
77
- #
78
- # @param rgb [Array<Integer>] the RGB components
79
- # @param style_type [Symbol] the type of color (foreground or background)
80
- #
81
- # @return [String] the ANSI escape sequence
82
- # @rbs (Array[Integer] rgb, style_type type) -> String
83
- private def self.bit8: (Array[Integer] rgb, style_type type) -> String
84
-
85
85
  # Convert RGB values to a true color (24-bit) sequence
86
86
  #
87
87
  # @author {https://aaronmallen.me Aaron Allen}
88
- # @since unreleased
88
+ # @since 0.1.0
89
89
  #
90
90
  # @api private
91
91
  #
@@ -99,7 +99,7 @@ module Sai
99
99
  # Validate a color style type
100
100
  #
101
101
  # @author {https://aaronmallen.me Aaron Allen}
102
- # @since unreleased
102
+ # @since 0.1.0
103
103
  #
104
104
  # @api private
105
105
  #
@@ -5,14 +5,14 @@ module Sai
5
5
  # RGB color conversion utilities
6
6
  #
7
7
  # @author {https://aaronmallen.me Aaron Allen}
8
- # @since unreleased
8
+ # @since 0.1.0
9
9
  #
10
10
  # @api private
11
11
  module RGB
12
12
  # Get closest ANSI color for RGB values
13
13
  #
14
14
  # @author {https://aaronmallen.me Aaron Allen}
15
- # @since unreleased
15
+ # @since 0.1.0
16
16
  #
17
17
  # @api private
18
18
  #
@@ -27,7 +27,7 @@ module Sai
27
27
  # Determine if a color is dark
28
28
  #
29
29
  # @author {https://aaronmallen.me Aaron Allen}
30
- # @since unreleased
30
+ # @since 0.1.0
31
31
  #
32
32
  # @api private
33
33
  #
@@ -42,7 +42,7 @@ module Sai
42
42
  # Determine if a color is grayscale
43
43
  #
44
44
  # @author {https://aaronmallen.me Aaron Allen}
45
- # @since unreleased
45
+ # @since 0.1.0
46
46
  #
47
47
  # @api private
48
48
  #
@@ -57,7 +57,7 @@ module Sai
57
57
  # Convert a color value to RGB components
58
58
  #
59
59
  # @author {https://aaronmallen.me Aaron Allen}
60
- # @since unreleased
60
+ # @since 0.1.0
61
61
  #
62
62
  # @api private
63
63
  #
@@ -71,7 +71,7 @@ module Sai
71
71
  # Convert RGB values to 256-color cube index
72
72
  #
73
73
  # @author {https://aaronmallen.me Aaron Allen}
74
- # @since unreleased
74
+ # @since 0.1.0
75
75
  #
76
76
  # @api private
77
77
  #
@@ -84,7 +84,7 @@ module Sai
84
84
  # Convert RGB values to grayscale index
85
85
  #
86
86
  # @author {https://aaronmallen.me Aaron Allen}
87
- # @since unreleased
87
+ # @since 0.1.0
88
88
  #
89
89
  # @api private
90
90
  #
@@ -97,7 +97,7 @@ module Sai
97
97
  # Check if RGB values represent cyan
98
98
  #
99
99
  # @author {https://aaronmallen.me Aaron Allen}
100
- # @since unreleased
100
+ # @since 0.1.0
101
101
  #
102
102
  # @api private
103
103
  #
@@ -112,7 +112,7 @@ module Sai
112
112
  # Convert a hex string to RGB values
113
113
  #
114
114
  # @author {https://aaronmallen.me Aaron Allen}
115
- # @since unreleased
115
+ # @since 0.1.0
116
116
  #
117
117
  # @api private
118
118
  #
@@ -125,7 +125,7 @@ module Sai
125
125
  # Check if RGB values represent magenta
126
126
  #
127
127
  # @author {https://aaronmallen.me Aaron Allen}
128
- # @since unreleased
128
+ # @since 0.1.0
129
129
  #
130
130
  # @api private
131
131
  #
@@ -140,7 +140,7 @@ module Sai
140
140
  # Convert a named color to RGB values
141
141
  #
142
142
  # @author {https://aaronmallen.me Aaron Allen}
143
- # @since unreleased
143
+ # @since 0.1.0
144
144
  #
145
145
  # @api private
146
146
  #
@@ -154,7 +154,7 @@ module Sai
154
154
  # Determine if RGB values represent a primary color
155
155
  #
156
156
  # @author {https://aaronmallen.me Aaron Allen}
157
- # @since unreleased
157
+ # @since 0.1.0
158
158
  #
159
159
  # @api private
160
160
  #
@@ -169,7 +169,7 @@ module Sai
169
169
  # Get the closest primary color
170
170
  #
171
171
  # @author {https://aaronmallen.me Aaron Allen}
172
- # @since unreleased
172
+ # @since 0.1.0
173
173
  #
174
174
  # @api private
175
175
  #
@@ -184,7 +184,7 @@ module Sai
184
184
  # Determine if RGB values represent a secondary color
185
185
  #
186
186
  # @author {https://aaronmallen.me Aaron Allen}
187
- # @since unreleased
187
+ # @since 0.1.0
188
188
  #
189
189
  # @api private
190
190
  #
@@ -199,7 +199,7 @@ module Sai
199
199
  # Get the closest secondary color
200
200
  #
201
201
  # @author {https://aaronmallen.me Aaron Allen}
202
- # @since unreleased
202
+ # @since 0.1.0
203
203
  #
204
204
  # @api private
205
205
  #
@@ -214,7 +214,7 @@ module Sai
214
214
  # Validate RGB values
215
215
  #
216
216
  # @author {https://aaronmallen.me Aaron Allen}
217
- # @since unreleased
217
+ # @since 0.1.0
218
218
  #
219
219
  # @api private
220
220
  #
@@ -227,7 +227,7 @@ module Sai
227
227
  # Check if RGB values represent yellow
228
228
  #
229
229
  # @author {https://aaronmallen.me Aaron Allen}
230
- # @since unreleased
230
+ # @since 0.1.0
231
231
  #
232
232
  # @api private
233
233
  #