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
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sai
4
+ class Decorator
5
+ # Named style 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 named style methods
11
+ # @api private
12
+ module NamedStyles
13
+ # @rbs!
14
+ # def blink: () -> Decorator
15
+ # def bold: () -> Decorator
16
+ # def conceal: () -> Decorator
17
+ # def dim: () -> Decorator
18
+ # def italic: () -> Decorator
19
+ # def no_blink: () -> Decorator
20
+ # def no_conceal: () -> Decorator
21
+ # def no_italic: () -> Decorator
22
+ # def no_reverse: () -> Decorator
23
+ # def no_strike: () -> Decorator
24
+ # def no_underline: () -> Decorator
25
+ # def normal_intensity: () -> Decorator
26
+ # def rapid_blink: () -> Decorator
27
+ # def reverse: () -> Decorator
28
+ # def strike: () -> Decorator
29
+ # def underline: () -> Decorator
30
+
31
+ # @!method blink
32
+ # Apply the ANSI style "blink" to the text
33
+ #
34
+ # @author {https://aaronmallen.me Aaron Allen}
35
+ # @since 0.1.0
36
+ #
37
+ # @api public
38
+ #
39
+ # @example
40
+ # decorator.blink.decorate('Hello, world!').to_s #=> "\e[5mHello, world!\e[0m"
41
+ #
42
+ # @return [Decorator] a new instance of Decorator with the style applied
43
+ #
44
+ # @!method bold
45
+ # Apply the ANSI style "bold" to the text
46
+ #
47
+ # @author {https://aaronmallen.me Aaron Allen}
48
+ # @since 0.1.0
49
+ #
50
+ # @api public
51
+ #
52
+ # @example
53
+ # decorator.bold.decorate('Hello, world!').to_s #=> "\e[1mHello, world!\e[0m"
54
+ #
55
+ # @return [Decorator] a new instance of Decorator with the style applied
56
+ #
57
+ # @!method conceal
58
+ # Apply the ANSI style "conceal" to the text
59
+ #
60
+ # @author {https://aaronmallen.me Aaron Allen}
61
+ # @since 0.1.0
62
+ #
63
+ # @api public
64
+ #
65
+ # @example
66
+ # decorator.conceal.decorate('Hello, world!').to_s #=> "\e[8mHello, world!\e[0m"
67
+ #
68
+ # @return [Decorator] a new instance of Decorator with the style applied
69
+ #
70
+ # @!method dim
71
+ # Apply the ANSI style "dim" to the text
72
+ #
73
+ # @author {https://aaronmallen.me Aaron Allen}
74
+ # @since 0.1.0
75
+ #
76
+ # @api public
77
+ #
78
+ # @example
79
+ # decorator.dim.decorate('Hello, world!').to_s #=> "\e[2mHello, world!\e[0m"
80
+ #
81
+ # @return [Decorator] a new instance of Decorator with the style applied
82
+ #
83
+ # @!method italic
84
+ # Apply the ANSI style "italic" to the text
85
+ #
86
+ # @author {https://aaronmallen.me Aaron Allen}
87
+ # @since 0.1.0
88
+ #
89
+ # @api public
90
+ #
91
+ # @example
92
+ # decorator.italic.decorate('Hello, world!').to_s #=> "\e[3mHello, world!\e[0m"
93
+ #
94
+ # @return [Decorator] a new instance of Decorator with the style applied
95
+ #
96
+ # @!method no_blink
97
+ # Remove the ANSI style "blink" from the text
98
+ #
99
+ # @author {https://aaronmallen.me Aaron Allen}
100
+ # @since 0.1.0
101
+ #
102
+ # @api public
103
+ #
104
+ # @example
105
+ # decorator.no_blink.decorate('Hello, world!').to_s #=> "\e[25mHello, world!\e[0m"
106
+ #
107
+ # @return [Decorator] a new instance of Decorator with the style applied
108
+ #
109
+ # @!method no_conceal
110
+ # Remove the ANSI style "conceal" from the text
111
+ #
112
+ # @author {https://aaronmallen.me Aaron Allen}
113
+ # @since 0.1.0
114
+ #
115
+ # @api public
116
+ #
117
+ # @example
118
+ # decorator.no_conceal.decorate('Hello, world!').to_s #=> "\e[28mHello, world!\e[0m"
119
+ #
120
+ # @return [Decorator] a new instance of Decorator with the style applied
121
+ #
122
+ # @!method no_italic
123
+ # Remove the ANSI style "italic" from the text
124
+ #
125
+ # @author {https://aaronmallen.me Aaron Allen}
126
+ # @since 0.1.0
127
+ #
128
+ # @api public
129
+ #
130
+ # @example
131
+ # decorator.no_italic.decorate('Hello, world!').to_s #=> "\e[23mHello, world!\e[0m"
132
+ #
133
+ # @return [Decorator] a new instance of Decorator with the style applied
134
+ #
135
+ # @!method no_reverse
136
+ # Remove the ANSI style "reverse" from the text
137
+ #
138
+ # @author {https://aaronmallen.me Aaron Allen}
139
+ # @since 0.1.0
140
+ #
141
+ # @api public
142
+ #
143
+ # @example
144
+ # decorator.no_reverse.decorate('Hello, world!').to_s #=> "\e[27mHello, world!\e[0m"
145
+ #
146
+ # @return [Decorator] a new instance of Decorator with the style applied
147
+ #
148
+ # @!method no_strike
149
+ # Remove the ANSI style "strike" from the text
150
+ #
151
+ # @author {https://aaronmallen.me Aaron Allen}
152
+ # @since 0.1.0
153
+ #
154
+ # @api public
155
+ #
156
+ # @example
157
+ # decorator.no_strike.decorate('Hello, world!').to_s #=> "\e[29mHello, world!\e[0m"
158
+ #
159
+ # @return [Decorator] a new instance of Decorator with the style applied
160
+ #
161
+ # @!method no_underline
162
+ # Remove the ANSI style "underline" from the text
163
+ #
164
+ # @author {https://aaronmallen.me Aaron Allen}
165
+ # @since 0.1.0
166
+ #
167
+ # @api public
168
+ #
169
+ # @example
170
+ # decorator.no_underline.decorate('Hello, world!').to_s #=> "\e[24mHello, world!\e[0m"
171
+ #
172
+ # @return [Decorator] a new instance of Decorator with the style applied
173
+ #
174
+ # @!method normal_intensity
175
+ # Remove any intensity styles (bold or dim) from the text
176
+ #
177
+ # @author {https://aaronmallen.me Aaron Allen}
178
+ # @since 0.1.0
179
+ #
180
+ # @api public
181
+ #
182
+ # @example
183
+ # decorator.normal_intensity.decorate('Hello, world!').to_s #=> "\e[22mHello, world!\e[0m"
184
+ #
185
+ # @return [Decorator] a new instance of Decorator with the style applied
186
+ #
187
+ # @!method rapid_blink
188
+ # Apply the ANSI style "rapid_blink" to the text
189
+ #
190
+ # @author {https://aaronmallen.me Aaron Allen}
191
+ # @since 0.1.0
192
+ #
193
+ # @api public
194
+ #
195
+ # @example
196
+ # decorator.rapid_blink.decorate('Hello, world!').to_s #=> "\e[6mHello, world!\e[0m"
197
+ #
198
+ # @return [Decorator] a new instance of Decorator with the style applied
199
+ #
200
+ # @!method reverse
201
+ # Apply the ANSI style "reverse" to the text
202
+ #
203
+ # @author {https://aaronmallen.me Aaron Allen}
204
+ # @since 0.1.0
205
+ #
206
+ # @api public
207
+ #
208
+ # @example
209
+ # decorator.reverse.decorate('Hello, world!').to_s #=> "\e[7mHello, world!\e[0m"
210
+ #
211
+ # @return [Decorator] a new instance of Decorator with the style applied
212
+ #
213
+ # @!method strike
214
+ # Apply the ANSI style "strike" to the text
215
+ #
216
+ # @author {https://aaronmallen.me Aaron Allen}
217
+ # @since 0.1.0
218
+ #
219
+ # @api public
220
+ #
221
+ # @example
222
+ # decorator.strike.decorate('Hello, world!').to_s #=> "\e[9mHello, world!\e[0m"
223
+ #
224
+ # @return [Decorator] a new instance of Decorator with the style applied
225
+ #
226
+ # @!method underline
227
+ # Apply the ANSI style "underline" to the text
228
+ #
229
+ # @author {https://aaronmallen.me Aaron Allen}
230
+ # @since 0.1.0
231
+ #
232
+ # @api public
233
+ #
234
+ # @example
235
+ # decorator.underline.decorate('Hello, world!').to_s #=> "\e[4mHello, world!\e[0m"
236
+ #
237
+ # @return [Decorator] a new instance of Decorator with the style applied
238
+ ANSI::STYLES.each_key do |style|
239
+ define_method(style) do
240
+ apply_style(style)
241
+ end
242
+ end
243
+
244
+ private
245
+
246
+ # Apply a style to the text
247
+ #
248
+ # @author {https://aaronmallen.me Aaron Allen}
249
+ # @since 0.1.0
250
+ #
251
+ # @api private
252
+ #
253
+ # @param style [String, Symbol] the style to apply
254
+ #
255
+ # @return [Decorator] a new instance of Decorator with the style applied
256
+ # @rbs (String | Symbol style) -> Decorator
257
+ def apply_style(style)
258
+ style = style.to_s.downcase.to_sym
259
+ dup.tap { |duped| duped.instance_variable_set(:@styles, (@styles + [style]).uniq) } #: Decorator
260
+ end
261
+
262
+ # Get style sequences
263
+ #
264
+ # @author {https://aaronmallen.me Aaron Allen}
265
+ # @since 0.3.1
266
+ #
267
+ # @api private
268
+ #
269
+ # @return [Array<String>] ANSI sequences for styles
270
+ # @rbs () -> Array[String]
271
+ def style_sequences
272
+ @styles.map { |style| "\e[#{ANSI::STYLES[style]}m" }
273
+ end
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sai
4
+ class Decorator
5
+ # RGB color 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 RGB color methods
11
+ # @api private
12
+ module RGBColors
13
+ # Apply an RGB color to the background
14
+ #
15
+ # @author {https://aaronmallen.me Aaron Allen}
16
+ # @since 0.1.0
17
+ #
18
+ # @api public
19
+ #
20
+ # @example
21
+ # decorator.on_rgb(235, 65, 51).decorate('Hello, world!').to_s #=> "\e[48;2;235;65;51mHello, world!\e[0m"
22
+ #
23
+ # @param red [Integer] the red component
24
+ # @param green [Integer] the green component
25
+ # @param blue [Integer] the blue component
26
+ #
27
+ # @raise [ArgumentError] if the RGB values are out of range
28
+ # @return [Decorator] a new instance of Decorator with the RGB color applied
29
+ # @rbs (Integer red, Integer green, Integer blue) -> Decorator
30
+ def on_rgb(red, green, blue)
31
+ [red, green, blue].each do |value|
32
+ raise ArgumentError, "Invalid RGB value: #{red}, #{green}, #{blue}" unless value >= 0 && value <= 255
33
+ end
34
+
35
+ dup.tap { |duped| duped.instance_variable_set(:@background, [red, green, blue]) } #: Decorator
36
+ end
37
+
38
+ # Apply an RGB color to the foreground
39
+ #
40
+ # @author {https://aaronmallen.me Aaron Allen}
41
+ # @since 0.1.0
42
+ #
43
+ # @api public
44
+ #
45
+ # @example
46
+ # decorator.rgb(235, 65, 51).decorate('Hello, world!').to_s #=> "\e[38;2;235;65;51mHello, world!\e[0m"
47
+ #
48
+ # @param red [Integer] the red component
49
+ # @param green [Integer] the green component
50
+ # @param blue [Integer] the blue component
51
+ #
52
+ # @raise [ArgumentError] if the RGB values are out of range
53
+ # @return [Decorator] a new instance of Decorator with the RGB color applied
54
+ # @rbs (Integer red, Integer green, Integer blue) -> Decorator
55
+ def rgb(red, green, blue)
56
+ [red, green, blue].each do |value|
57
+ raise ArgumentError, "Invalid RGB value: #{red}, #{green}, #{blue}" unless value >= 0 && value <= 255
58
+ end
59
+
60
+ dup.tap { |duped| duped.instance_variable_set(:@foreground, [red, green, blue]) } #: Decorator
61
+ end
62
+ end
63
+ end
64
+ end