sai 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/README.md +11 -3
  4. data/docs/USAGE.md +57 -9
  5. data/lib/sai/ansi/color_parser.rb +109 -0
  6. data/lib/sai/ansi/sequence_processor.rb +15 -126
  7. data/lib/sai/ansi/style_parser.rb +66 -0
  8. data/lib/sai/ansi.rb +0 -27
  9. data/lib/sai/conversion/color_sequence.rb +4 -4
  10. data/lib/sai/conversion/rgb/color_classifier.rb +209 -0
  11. data/lib/sai/conversion/rgb/color_indexer.rb +48 -0
  12. data/lib/sai/conversion/rgb/color_space.rb +192 -0
  13. data/lib/sai/conversion/rgb/color_transformer.rb +140 -0
  14. data/lib/sai/conversion/rgb.rb +23 -269
  15. data/lib/sai/decorator/color_manipulations.rb +157 -0
  16. data/lib/sai/decorator/delegation.rb +84 -0
  17. data/lib/sai/decorator/gradients.rb +363 -0
  18. data/lib/sai/decorator/hex_colors.rb +56 -0
  19. data/lib/sai/decorator/named_colors.rb +780 -0
  20. data/lib/sai/decorator/named_styles.rb +276 -0
  21. data/lib/sai/decorator/rgb_colors.rb +64 -0
  22. data/lib/sai/decorator.rb +29 -775
  23. data/lib/sai/named_colors.rb +437 -0
  24. data/lib/sai.rb +731 -23
  25. data/sig/sai/ansi/color_parser.rbs +77 -0
  26. data/sig/sai/ansi/sequence_processor.rbs +0 -75
  27. data/sig/sai/ansi/style_parser.rbs +59 -0
  28. data/sig/sai/ansi.rbs +0 -10
  29. data/sig/sai/conversion/rgb/color_classifier.rbs +165 -0
  30. data/sig/sai/conversion/rgb/color_indexer.rbs +41 -0
  31. data/sig/sai/conversion/rgb/color_space.rbs +129 -0
  32. data/sig/sai/conversion/rgb/color_transformer.rbs +99 -0
  33. data/sig/sai/conversion/rgb.rbs +15 -198
  34. data/sig/sai/decorator/color_manipulations.rbs +125 -0
  35. data/sig/sai/decorator/delegation.rbs +47 -0
  36. data/sig/sai/decorator/gradients.rbs +267 -0
  37. data/sig/sai/decorator/hex_colors.rbs +48 -0
  38. data/sig/sai/decorator/named_colors.rbs +1491 -0
  39. data/sig/sai/decorator/named_styles.rbs +72 -0
  40. data/sig/sai/decorator/rgb_colors.rbs +52 -0
  41. data/sig/sai/decorator.rbs +21 -195
  42. data/sig/sai/named_colors.rbs +65 -0
  43. data/sig/sai.rbs +1468 -44
  44. metadata +32 -4
@@ -9,50 +9,27 @@ module Sai
9
9
  #
10
10
  # @api private
11
11
  module RGB
12
- # Get closest ANSI color for RGB values
12
+ # Color classification utilities
13
13
  #
14
14
  # @author {https://aaronmallen.me Aaron Allen}
15
- # @since 0.1.0
15
+ # @since 0.3.1
16
16
  #
17
17
  # @api private
18
18
  #
19
- # @param red [Float] the red component (0-1)
20
- # @param green [Float] the green component (0-1)
21
- # @param blue [Float] the blue component (0-1)
22
- #
23
- # @return [Symbol] the closest ANSI color name
24
- # @rbs (Float red, Float green, Float blue) -> Symbol
25
- def self.closest_ansi_color: (Float red, Float green, Float blue) -> Symbol
19
+ # @return [Module<ColorClassifier>] the ColorClassifier module
20
+ # @rbs () -> singleton(ColorClassifier)
21
+ def self.classify: () -> singleton(ColorClassifier)
26
22
 
27
- # Determine if a color is dark
23
+ # Color indexing utilities
28
24
  #
29
25
  # @author {https://aaronmallen.me Aaron Allen}
30
- # @since 0.1.0
26
+ # @since 0.3.1
31
27
  #
32
28
  # @api private
33
29
  #
34
- # @param red [Float] the red component (0-1)
35
- # @param green [Float] the green component (0-1)
36
- # @param blue [Float] the blue component (0-1)
37
- #
38
- # @return [Boolean] true if color is dark
39
- # @rbs (Float red, Float green, Float blue) -> bool
40
- def self.dark?: (Float red, Float green, Float blue) -> bool
41
-
42
- # Determine if a color is grayscale
43
- #
44
- # @author {https://aaronmallen.me Aaron Allen}
45
- # @since 0.1.0
46
- #
47
- # @api private
48
- #
49
- # @param red [Float] the red component (0-1)
50
- # @param green [Float] the green component (0-1)
51
- # @param blue [Float] the blue component (0-1)
52
- #
53
- # @return [Boolean] true if color is grayscale
54
- # @rbs (Float red, Float green, Float blue) -> bool
55
- def self.grayscale?: (Float red, Float green, Float blue) -> bool
30
+ # @return [Module<ColorIndexer>] the ColorIndexer module
31
+ # @rbs () -> singleton(ColorIndexer)
32
+ def self.index: () -> singleton(ColorIndexer)
56
33
 
57
34
  # Convert a color value to RGB components
58
35
  #
@@ -68,176 +45,16 @@ module Sai
68
45
  # @rbs (Array[Integer] | String | Symbol color) -> Array[Integer]
69
46
  def self.resolve: (Array[Integer] | String | Symbol color) -> Array[Integer]
70
47
 
71
- # Convert RGB values to 256-color cube index
72
- #
73
- # @author {https://aaronmallen.me Aaron Allen}
74
- # @since 0.1.0
75
- #
76
- # @api private
77
- #
78
- # @param rgb [Array<Integer>] RGB values (0-255)
79
- #
80
- # @return [Integer] the color cube index
81
- # @rbs (Array[Integer] rgb) -> Integer
82
- def self.to_color_cube_index: (Array[Integer] rgb) -> Integer
83
-
84
- # Convert RGB values to grayscale index
85
- #
86
- # @author {https://aaronmallen.me Aaron Allen}
87
- # @since 0.1.0
88
- #
89
- # @api private
90
- #
91
- # @param rgb [Array<Integer>] RGB values
92
- #
93
- # @return [Integer] the grayscale index
94
- # @rbs (Array[Integer] rgb) -> Integer
95
- def self.to_grayscale_index: (Array[Integer] rgb) -> Integer
96
-
97
- # Check if RGB values represent cyan
98
- #
99
- # @author {https://aaronmallen.me Aaron Allen}
100
- # @since 0.1.0
101
- #
102
- # @api private
103
- #
104
- # @param red [Float] the red component (0-1)
105
- # @param green [Float] the green component (0-1)
106
- # @param blue [Float] the blue component (0-1)
107
- #
108
- # @return [Boolean] true if color is cyan
109
- # @rbs (Float red, Float green, Float blue) -> bool
110
- private def self.cyan?: (Float red, Float green, Float blue) -> bool
111
-
112
- # Convert a hex string to RGB values
113
- #
114
- # @author {https://aaronmallen.me Aaron Allen}
115
- # @since 0.1.0
116
- #
117
- # @api private
118
- #
119
- # @param hex [String] the hex color code
120
- #
121
- # @return [Array<Integer>] the RGB components
122
- # @rbs (String hex) -> Array[Integer]
123
- private def self.hex_to_rgb: (String hex) -> Array[Integer]
124
-
125
- # Check if RGB values represent magenta
48
+ # Transform RGB values
126
49
  #
127
50
  # @author {https://aaronmallen.me Aaron Allen}
128
- # @since 0.1.0
51
+ # @since 0.3.1
129
52
  #
130
53
  # @api private
131
54
  #
132
- # @param red [Float] the red component (0-1)
133
- # @param green [Float] the green component (0-1)
134
- # @param blue [Float] the blue component (0-1)
135
- #
136
- # @return [Boolean] true if color is magenta
137
- # @rbs (Float red, Float green, Float blue) -> bool
138
- private def self.magenta?: (Float red, Float green, Float blue) -> bool
139
-
140
- # Convert a named color to RGB values
141
- #
142
- # @author {https://aaronmallen.me Aaron Allen}
143
- # @since 0.1.0
144
- #
145
- # @api private
146
- #
147
- # @param color_name [String] the color name
148
- #
149
- # @raise [ArgumentError] if the color name is unknown
150
- # @return [Array<Integer>] the RGB components
151
- # @rbs (String color_name) -> Array[Integer]
152
- private def self.named_to_rgb: (String color_name) -> Array[Integer]
153
-
154
- # Determine if RGB values represent a primary color
155
- #
156
- # @author {https://aaronmallen.me Aaron Allen}
157
- # @since 0.1.0
158
- #
159
- # @api private
160
- #
161
- # @param red [Float] the red component (0-1)
162
- # @param green [Float] the green component (0-1)
163
- # @param blue [Float] the blue component (0-1)
164
- #
165
- # @return [Boolean] true if color is primary
166
- # @rbs (Float red, Float green, Float blue) -> bool
167
- private def self.primary?: (Float red, Float green, Float blue) -> bool
168
-
169
- # Get the closest primary color
170
- #
171
- # @author {https://aaronmallen.me Aaron Allen}
172
- # @since 0.1.0
173
- #
174
- # @api private
175
- #
176
- # @param red [Float] the red component (0-1)
177
- # @param green [Float] the green component (0-1)
178
- # @param blue [Float] the blue component (0-1)
179
- #
180
- # @return [Symbol] the primary color name
181
- # @rbs (Float red, Float green, Float blue) -> Symbol
182
- private def self.primary_color: (Float red, Float green, Float blue) -> Symbol
183
-
184
- # Determine if RGB values represent a secondary color
185
- #
186
- # @author {https://aaronmallen.me Aaron Allen}
187
- # @since 0.1.0
188
- #
189
- # @api private
190
- #
191
- # @param red [Float] the red component (0-1)
192
- # @param green [Float] the green component (0-1)
193
- # @param blue [Float] the blue component (0-1)
194
- #
195
- # @return [Boolean] true if color is secondary
196
- # @rbs (Float red, Float green, Float blue) -> bool
197
- private def self.secondary?: (Float red, Float green, Float blue) -> bool
198
-
199
- # Get the closest secondary color
200
- #
201
- # @author {https://aaronmallen.me Aaron Allen}
202
- # @since 0.1.0
203
- #
204
- # @api private
205
- #
206
- # @param red [Float] the red component (0-1)
207
- # @param green [Float] the green component (0-1)
208
- # @param blue [Float] the blue component (0-1)
209
- #
210
- # @return [Symbol] the secondary color name
211
- # @rbs (Float red, Float green, Float blue) -> Symbol
212
- private def self.secondary_color: (Float red, Float green, Float blue) -> Symbol
213
-
214
- # Validate RGB values
215
- #
216
- # @author {https://aaronmallen.me Aaron Allen}
217
- # @since 0.1.0
218
- #
219
- # @api private
220
- #
221
- # @param color [Array<Integer>] the RGB components to validate
222
- # @return [Array<Integer>] the validated RGB components
223
- # @raise [ArgumentError] if the RGB values are invalid
224
- # @rbs (Array[Integer] color) -> Array[Integer]
225
- private def self.validate_rgb: (Array[Integer] color) -> Array[Integer]
226
-
227
- # Check if RGB values represent yellow
228
- #
229
- # @author {https://aaronmallen.me Aaron Allen}
230
- # @since 0.1.0
231
- #
232
- # @api private
233
- #
234
- # @param red [Float] the red component (0-1)
235
- # @param green [Float] the green component (0-1)
236
- # @param blue [Float] the blue component (0-1)
237
- #
238
- # @return [Boolean] true if color is yellow
239
- # @rbs (Float red, Float green, Float blue) -> bool
240
- private def self.yellow?: (Float red, Float green, Float blue) -> bool
55
+ # @return [Module<ColorTransformer>] the color transformer
56
+ # @rbs () -> singleton(ColorTransformer)
57
+ def self.transform: () -> singleton(ColorTransformer)
241
58
  end
242
59
  end
243
60
  end
@@ -0,0 +1,125 @@
1
+ # Generated from lib/sai/decorator/color_manipulations.rb with RBS::Inline
2
+
3
+ module Sai
4
+ class Decorator
5
+ # Color manipulation methods for the {Decorator} class
6
+ #
7
+ # @author {https://aaronmallen.me Aaron Allen}
8
+ # @since 0.3.1
9
+ #
10
+ # @abstract This module is meant to be included in the {Decorator} class to provide color manipulation methods
11
+ # @api private
12
+ module ColorManipulations
13
+ # Darken the background color by a percentage
14
+ #
15
+ # @author {https://aaronmallen.me Aaron Allen}
16
+ # @since 0.3.1
17
+ #
18
+ # @api public
19
+ #
20
+ # @example
21
+ # decorator.on_blue.darken_text(0.5).decorate('Hello, world!').to_s #=> "\e[48;2;0;0;238mHello, world!\e[0m"
22
+ #
23
+ # @param amount [Float] the amount to darken the background color (0.0...1.0)
24
+ #
25
+ # @raise [ArgumentError] if the percentage is out of range
26
+ # @return [Decorator] a new instance of Decorator with the darkened background color
27
+ # @rbs (Float amount) -> Decorator
28
+ def darken_background: (Float amount) -> Decorator
29
+
30
+ alias darken_bg darken_background
31
+
32
+ # Darken the text color by a percentage
33
+ #
34
+ # @author {https://aaronmallen.me Aaron Allen}
35
+ # @since 0.3.1
36
+ #
37
+ # @api public
38
+ #
39
+ # @example
40
+ # decorator.blue.darken_text(0.5).decorate('Hello, world!').to_s #=> "\e[38;2;0;0;119mHello, world!\e[0m"
41
+ #
42
+ # @param amount [Float] the amount to darken the text color (0.0...1.0)
43
+ #
44
+ # @raise [ArgumentError] if the percentage is out of range
45
+ # @return [Decorator] a new instance of Decorator with the darkened text color
46
+ # @rbs (Float amount) -> Decorator
47
+ def darken_text: (Float amount) -> Decorator
48
+
49
+ alias darken_fg darken_text
50
+
51
+ alias darken_foreground darken_text
52
+
53
+ # Lighten the background color by a percentage
54
+ #
55
+ # @author {https://aaronmallen.me Aaron Allen}
56
+ # @since 0.3.1
57
+ #
58
+ # @api public
59
+ #
60
+ # @example
61
+ # decorator.on_blue.lighten_background(0.5).decorate('Hello, world!').to_s
62
+ # #=> "\e[48;2;0;0;255mHello, world!\e[0m"
63
+ #
64
+ # @param amount [Float] the amount to lighten the background color (0.0...1.0)
65
+ #
66
+ # @raise [ArgumentError] if the percentage is out of range
67
+ # @return [Decorator] a new instance of Decorator with the lightened background color
68
+ # @rbs (Float amount) -> Decorator
69
+ def lighten_background: (Float amount) -> Decorator
70
+
71
+ alias lighten_bg lighten_background
72
+
73
+ # Lighten the text color by a percentage
74
+ #
75
+ # @author {https://aaronmallen.me Aaron Allen}
76
+ # @since 0.3.1
77
+ #
78
+ # @api public
79
+ #
80
+ # @example
81
+ # decorator.blue.lighten_text(0.5).decorate('Hello, world!').to_s #=> "\e[38;2;0;0;127mHello, world!\e[0m"
82
+ #
83
+ # @param amount [Float] the amount to lighten the text color (0.0...1.0)
84
+ #
85
+ # @raise [ArgumentError] if the percentage is out of range
86
+ # @return [Decorator] a new instance of Decorator with the lightened text color
87
+ # @rbs (Float amount) -> Decorator
88
+ def lighten_text: (Float amount) -> Decorator
89
+
90
+ alias lighten_fg lighten_text
91
+
92
+ alias lighten_foreground lighten_text
93
+
94
+ private
95
+
96
+ # Darken the foreground or background color by a specified amount
97
+ #
98
+ # @author {https://aaronmallen.me Aaron Allen}
99
+ # @since 0.3.1
100
+ #
101
+ # @api private
102
+ #
103
+ # @param amount [Float] a value between 0.0 and 1.0 to darken the color by
104
+ # @param component [Symbol] the color component to darken
105
+ #
106
+ # @return [Decorator] a new instance of Decorator with the color darkened
107
+ # @rbs (Float amount, Symbol component) -> Decorator
108
+ def darken: (Float amount, Symbol component) -> Decorator
109
+
110
+ # Lighten the foreground or background color by a specified amount
111
+ #
112
+ # @author {https://aaronmallen.me Aaron Allen}
113
+ # @since 0.3.1
114
+ #
115
+ # @api private
116
+ #
117
+ # @param amount [Float] a value between 0.0 and 1.0 to lighten the color by
118
+ # @param component [Symbol] the color component to lighten
119
+ #
120
+ # @return [Decorator] a new instance of Decorator with the color lightened
121
+ # @rbs (Float amount, Symbol component) -> Decorator
122
+ def lighten: (Float amount, Symbol component) -> Decorator
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,47 @@
1
+ # Generated from lib/sai/decorator/delegation.rb with RBS::Inline
2
+
3
+ module Sai
4
+ class Decorator
5
+ # Delegates all methods from the Decorator class and its component modules
6
+ #
7
+ # @author {https://aaronmallen.me Aaron Allen}
8
+ # @since 0.3.1
9
+ #
10
+ # @api private
11
+ module Delegation
12
+ # The list of component modules to delegate methods from
13
+ #
14
+ # @author {https://aaronmallen.me Aaron Allen}
15
+ # @since 0.3.1
16
+ #
17
+ # @api private
18
+ #
19
+ # @return [Array<Symbol>] the list of component modules
20
+ COMPONENT_MODULES: Array[Symbol]
21
+
22
+ # Install delegated methods on the given class or module
23
+ #
24
+ # @author {https://aaronmallen.me Aaron Allen}
25
+ # @since 0.3.1
26
+ #
27
+ # @api private
28
+ #
29
+ # @param klass [Class, Module] the class or module to install the methods on
30
+ #
31
+ # @return [void]
32
+ # @rbs (Class | Module) -> void
33
+ def self.install: (Class | Module) -> void
34
+
35
+ # Collect all methods from the Decorator class and its component modules
36
+ #
37
+ # @author {https://aaronmallen.me Aaron Allen}
38
+ # @since 0.3.1
39
+ #
40
+ # @api private
41
+ #
42
+ # @return [Array<Symbol>] the list of methods to delegate
43
+ # @rbs () -> Array[Symbol]
44
+ private def self.collect_delegatable_methods: () -> Array[Symbol]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,267 @@
1
+ # Generated from lib/sai/decorator/gradients.rb with RBS::Inline
2
+
3
+ module Sai
4
+ class Decorator
5
+ # Color gradient methods for the {Decorator} class
6
+ #
7
+ # @author {https://aaronmallen.me Aaron Allen}
8
+ # @since 0.3.1
9
+ #
10
+ # @abstract This module is meant to be included in the {Decorator} class to provide color gradient methods
11
+ # @api private
12
+ module Gradients
13
+ # Build a foreground gradient between two colors for text decoration
14
+ #
15
+ # @author {https://aaronmallen.me Aaron Allen}
16
+ # @since 0.3.1
17
+ #
18
+ # @api public
19
+ #
20
+ # @example Create a foreground gradient from red to blue
21
+ # decorator.gradient(:red, :blue, 10).decorate('Hello, World!')
22
+ # #=> "\e[38;2;255;0;0mH\e[0m\e[38;2;204;0;51me\e[0m..."
23
+ #
24
+ # @param start_color [Array<Integer>, String, Symbol] the starting color
25
+ # @param end_color [Array<Integer>, String, Symbol] the ending color
26
+ # @param steps [Integer] the number of gradient steps (minimum 2)
27
+ #
28
+ # @raise [ArgumentError] if steps is less than 2
29
+ # @return [Decorator] a new instance of Decorator with foreground gradient colors
30
+ # @rbs (
31
+ # Array[Integer] | String | Symbol start_color,
32
+ # Array[Integer] | String | Symbol end_color,
33
+ # Integer steps
34
+ # ) -> Decorator
35
+ def gradient: (Array[Integer] | String | Symbol start_color, Array[Integer] | String | Symbol end_color, Integer steps) -> Decorator
36
+
37
+ # Build a background gradient between two colors for text decoration
38
+ #
39
+ # @author {https://aaronmallen.me Aaron Allen}
40
+ # @since 0.3.1
41
+ #
42
+ # @api public
43
+ #
44
+ # @example Create a background gradient from red to blue
45
+ # decorator.on_gradient(:red, :blue, 10).decorate('Hello, World!')
46
+ # #=> "\e[48;2;255;0;0mH\e[0m\e[48;2;204;0;51me\e[0m..."
47
+ #
48
+ # @param start_color [Array<Integer>, String, Symbol] the starting color
49
+ # @param end_color [Array<Integer>, String, Symbol] the ending color
50
+ # @param steps [Integer] the number of gradient steps (minimum 2)
51
+ #
52
+ # @raise [ArgumentError] if steps is less than 2
53
+ # @return [Decorator] a new instance of Decorator with background gradient colors
54
+ # @rbs (
55
+ # Array[Integer] | String | Symbol start_color,
56
+ # Array[Integer] | String | Symbol end_color,
57
+ # Integer steps
58
+ # ) -> Decorator
59
+ def on_gradient: (Array[Integer] | String | Symbol start_color, Array[Integer] | String | Symbol end_color, Integer steps) -> Decorator
60
+
61
+ # Build a background rainbow gradient for text decoration
62
+ #
63
+ # @author {https://aaronmallen.me Aaron Allen}
64
+ # @since 0.3.1
65
+ #
66
+ # @api public
67
+ #
68
+ # @example Create a rainbow background gradient
69
+ # decorator.on_rainbow(6).decorate('Hello, World!')
70
+ # #=> "\e[48;2;255;0;0mH\e[0m\e[48;2;255;255;0me\e[0m..."
71
+ #
72
+ # @param steps [Integer] the number of colors to generate (minimum 2)
73
+ #
74
+ # @raise [ArgumentError] if steps is less than 2
75
+ # @return [Decorator] a new instance of Decorator with background rainbow colors
76
+ # @rbs (Integer steps) -> Decorator
77
+ def on_rainbow: (Integer steps) -> Decorator
78
+
79
+ # Build a foreground rainbow gradient for text decoration
80
+ #
81
+ # @author {https://aaronmallen.me Aaron Allen}
82
+ # @since 0.3.1
83
+ #
84
+ # @api public
85
+ #
86
+ # @example Create a rainbow text gradient
87
+ # decorator.rainbow(6).decorate('Hello, World!')
88
+ # #=> "\e[38;2;255;0;0mH\e[0m\e[38;2;255;255;0me\e[0m..."
89
+ #
90
+ # @param steps [Integer] the number of colors to generate (minimum 2)
91
+ #
92
+ # @raise [ArgumentError] if steps is less than 2
93
+ # @return [Decorator] a new instance of Decorator with foreground rainbow colors
94
+ # @rbs (Integer steps) -> Decorator
95
+ def rainbow: (Integer steps) -> Decorator
96
+
97
+ private
98
+
99
+ # Adjust number of colors to match text length
100
+ #
101
+ # @author {https://aaronmallen.me Aaron Allen}
102
+ # @since 0.3.1
103
+ #
104
+ # @api private
105
+ #
106
+ # @param colors [Array<Array<Integer>>] original color sequence
107
+ # @param text_length [Integer] desired number of colors
108
+ #
109
+ # @return [Array<Array<Integer>>] adjusted color sequence
110
+ # @rbs (Array[Array[Integer]] colors, Integer text_length) -> Array[Array[Integer]]
111
+ def adjust_colors_to_text_length: (Array[Array[Integer]] colors, Integer text_length) -> Array[Array[Integer]]
112
+
113
+ # Apply color sequence gradients to text
114
+ #
115
+ # @author {https://aaronmallen.me Aaron Allen}
116
+ # @since 0.3.1
117
+ #
118
+ # @api private
119
+ #
120
+ # @param text [String] the text to apply the gradient to
121
+ #
122
+ # @return [ANSI::SequencedString] the text with gradient applied
123
+ # @rbs (String text) -> ANSI::SequencedString
124
+ def apply_sequence_gradient: (String text) -> ANSI::SequencedString
125
+
126
+ # Build color sequences for a single character
127
+ #
128
+ # @author {https://aaronmallen.me Aaron Allen}
129
+ # @since 0.3.1
130
+ #
131
+ # @api private
132
+ #
133
+ # @param colors [Hash] color sequences for foreground and background
134
+ # @param index [Integer] character position
135
+ #
136
+ # @return [Array<String>] ANSI sequences for the character
137
+ # @rbs (Hash[Symbol, Array[Array[Integer]]] colors, Integer index) -> Array[String]
138
+ def build_color_sequences: (Hash[Symbol, Array[Array[Integer]]] colors, Integer index) -> Array[String]
139
+
140
+ # Build gradient text from characters and color sequences
141
+ #
142
+ # @author {https://aaronmallen.me Aaron Allen}
143
+ # @since 0.3.1
144
+ #
145
+ # @api private
146
+ #
147
+ # @param chars [Array<String>] text characters
148
+ # @param colors [Hash] color sequences for foreground and background
149
+ #
150
+ # @return [Array<String>] colored characters
151
+ # @rbs (Array[String] chars, Hash[Symbol, Array[Array[Integer]]] colors) -> Array[String]
152
+ def build_gradient_text: (Array[String] chars, Hash[Symbol, Array[Array[Integer]]] colors) -> Array[String]
153
+
154
+ # Calculate indices and progress for color interpolation
155
+ #
156
+ # @author {https://aaronmallen.me Aaron Allen}
157
+ # @since 0.3.1
158
+ #
159
+ # @api private
160
+ #
161
+ # @param position [Integer] current position in sequence
162
+ # @param step_size [Float] size of each step
163
+ # @param max_index [Integer] maximum index allowed
164
+ #
165
+ # @return [Hash] interpolation indices and progress
166
+ # @rbs (Integer position, Float step_size, Integer max_index) -> Hash[Symbol, Integer | Float]
167
+ def calculate_interpolation_indices: (Integer position, Float step_size, Integer max_index) -> Hash[Symbol, Integer | Float]
168
+
169
+ # Get background sequence for a character
170
+ #
171
+ # @author {https://aaronmallen.me Aaron Allen}
172
+ # @since 0.3.1
173
+ #
174
+ # @api private
175
+ #
176
+ # @param colors [Array<Array<Integer>>, nil] background color sequence
177
+ # @param index [Integer] character position
178
+ #
179
+ # @return [String, nil] ANSI sequence for background
180
+ # @rbs (Array[Array[Integer]]? colors, Integer index) -> String?
181
+ def get_background_sequence: (Array[Array[Integer]]? colors, Integer index) -> String?
182
+
183
+ # Get foreground sequence for a character
184
+ #
185
+ # @author {https://aaronmallen.me Aaron Allen}
186
+ # @since 0.3.1
187
+ #
188
+ # @api private
189
+ #
190
+ # @param colors [Array<Array<Integer>>, nil] foreground color sequence
191
+ # @param index [Integer] character position
192
+ #
193
+ # @return [String, nil] ANSI sequence for foreground
194
+ # @rbs (Array[Array[Integer]]? colors, Integer index) -> String?
195
+ def get_foreground_sequence: (Array[Array[Integer]]? colors, Integer index) -> String?
196
+
197
+ # Interpolate between two colors in a sequence
198
+ #
199
+ # @author {https://aaronmallen.me Aaron Allen}
200
+ # @since 0.3.1
201
+ #
202
+ # @api private
203
+ #
204
+ # @param colors [Array<Array<Integer>>] color sequence
205
+ # @param indices [Hash] interpolation indices and progress
206
+ #
207
+ # @return [Array<Integer>] interpolated color
208
+ # @rbs (Array[Array[Integer]] colors, Hash[Symbol, Integer | Float]) -> Array[Integer]
209
+ def interpolate_sequence_colors: (Array[Array[Integer]] colors, Hash[Symbol, Integer | Float]) -> Array[Integer]
210
+
211
+ # Prepare foreground and background color sequences for text
212
+ #
213
+ # @author {https://aaronmallen.me Aaron Allen}
214
+ # @since 0.3.1
215
+ #
216
+ # @api private
217
+ #
218
+ # @param text_length [Integer] length of text to color
219
+ #
220
+ # @return [Hash] adjusted color sequences
221
+ # @rbs (Integer text_length) -> Hash[Symbol, Array[Array[Integer]]]
222
+ def prepare_color_sequences: (Integer text_length) -> Hash[Symbol, Array[Array[Integer]]]
223
+
224
+ # Prepare a single color sequence
225
+ #
226
+ # @author {https://aaronmallen.me Aaron Allen}
227
+ # @since 0.3.1
228
+ #
229
+ # @api private
230
+ #
231
+ # @param sequence [Array<Array<Integer>>, nil] color sequence to prepare
232
+ # @param text_length [Integer] length of text to color
233
+ #
234
+ # @return [Array<Array<Integer>>, nil] adjusted color sequence
235
+ # @rbs (Array[Array[Integer]]? sequence, Integer text_length) -> Array[Array[Integer]]?
236
+ def prepare_sequence: (Array[Array[Integer]]? sequence, Integer text_length) -> Array[Array[Integer]]?
237
+
238
+ # Shrink a color sequence to fit desired length
239
+ #
240
+ # @author {https://aaronmallen.me Aaron Allen}
241
+ # @since 0.3.1
242
+ #
243
+ # @api private
244
+ #
245
+ # @param colors [Array<Array<Integer>>] original color sequence
246
+ # @param target_length [Integer] desired number of colors
247
+ #
248
+ # @return [Array<Array<Integer>>] shrunk color sequence
249
+ # @rbs (Array[Array[Integer]] colors, Integer target_length) -> Array[Array[Integer]]
250
+ def shrink_colors: (Array[Array[Integer]] colors, Integer target_length) -> Array[Array[Integer]]
251
+
252
+ # Stretch a color sequence to fit desired length
253
+ #
254
+ # @author {https://aaronmallen.me Aaron Allen}
255
+ # @since 0.3.1
256
+ #
257
+ # @api private
258
+ #
259
+ # @param colors [Array<Array<Integer>>] original color sequence
260
+ # @param target_length [Integer] desired number of colors
261
+ #
262
+ # @return [Array<Array<Integer>>] stretched color sequence
263
+ # @rbs (Array[Array[Integer]] colors, Integer target_length) -> Array[Array[Integer]]
264
+ def stretch_colors: (Array[Array[Integer]] colors, Integer target_length) -> Array[Array[Integer]]
265
+ end
266
+ end
267
+ end