sai 0.3.0 → 0.3.1

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.
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
data/lib/sai/decorator.rb CHANGED
@@ -4,6 +4,13 @@ require 'sai'
4
4
  require 'sai/ansi'
5
5
  require 'sai/ansi/sequenced_string'
6
6
  require 'sai/conversion/color_sequence'
7
+ require 'sai/decorator/color_manipulations'
8
+ require 'sai/decorator/gradients'
9
+ require 'sai/decorator/hex_colors'
10
+ require 'sai/decorator/named_colors'
11
+ require 'sai/decorator/named_styles'
12
+ require 'sai/decorator/rgb_colors'
13
+ require 'sai/terminal/color_mode'
7
14
 
8
15
  module Sai
9
16
  # A decorator for applying ANSI styles and colors to text
@@ -12,7 +19,23 @@ module Sai
12
19
  # @since 0.1.0
13
20
  #
14
21
  # @api public
22
+ #
23
+ # @note For each named color, two methods are dynamically generated:
24
+ # * color_name - Applies the color to the foreground
25
+ # * on_color_name - Applies the color to the backgroundAll color methods return {Decorator}
26
+ # @see Sai::NamedColors Sai::NamedColors for available color names
27
+ #
28
+ # @example Using a named color
29
+ # decorator.azure.decorate('Hello') #=> "\e[38;2;0;127;255mHello\e[0m"
30
+ # decorator.on_azure.decorate('Hello') #=> "\e[48;2;0;127;255mHello\e[0m"
15
31
  class Decorator
32
+ include ColorManipulations
33
+ include Gradients
34
+ include HexColors
35
+ include NamedColors
36
+ include NamedStyles
37
+ include RGBColors
38
+
16
39
  # Initialize a new instance of Decorator
17
40
  #
18
41
  # @author {https://aaronmallen.me Aaron Allen}
@@ -26,660 +49,13 @@ module Sai
26
49
  # @rbs (?mode: Integer) -> void
27
50
  def initialize(mode: Sai.mode.auto)
28
51
  @background = nil
52
+ @background_sequence = nil
29
53
  @mode = mode
30
54
  @foreground = nil
55
+ @foreground_sequence = nil
31
56
  @styles = [] #: Array[Symbol]
32
57
  end
33
58
 
34
- # @!method black
35
- # Apply the named ANSI color "black" to the foreground
36
- #
37
- # @author {https://aaronmallen.me Aaron Allen}
38
- # @since 0.1.0
39
- #
40
- # @api public
41
- #
42
- # @example
43
- # decorator.black.decorate('Hello, world!').to_s #=> "\e[30mHello, world!\e[0m"
44
- #
45
- # @return [Decorator] a new instance of Decorator with the color applied
46
- #
47
- # @!method blue
48
- # Apply the named ANSI color "blue" to the foreground
49
- #
50
- # @author {https://aaronmallen.me Aaron Allen}
51
- # @since 0.1.0
52
- #
53
- # @api public
54
- #
55
- # @example
56
- # decorator.blue.decorate('Hello, world!').to_s #=> "\e[34mHello, world!\e[0m"
57
- #
58
- # @return [Decorator] a new instance of Decorator with the color applied
59
- #
60
- # @!method bright_black
61
- # Apply the named ANSI color "bright_black" to the foreground
62
- #
63
- # @author {https://aaronmallen.me Aaron Allen}
64
- # @since 0.1.0
65
- #
66
- # @api public
67
- #
68
- # @example
69
- # decorator.bright_black.decorate('Hello, world!').to_s #=> "\e[90mHello, world!\e[0m"
70
- #
71
- # @return [Decorator] a new instance of Decorator with the color applied
72
- #
73
- # @!method bright_blue
74
- # Apply the named ANSI color "bright_blue" to the foreground
75
- #
76
- # @api public
77
- #
78
- # @example
79
- # decorator.bright_blue.decorate('Hello, world!').to_s #=> "\e[94mHello, world!\e[0m"
80
- #
81
- # @return [Decorator] a new instance of Decorator with the color applied
82
- #
83
- # @!method bright_cyan
84
- # Apply the named ANSI color "bright_cyan" to the foreground
85
- #
86
- # @api public
87
- #
88
- # @example
89
- # decorator.bright_cyan.decorate('Hello, world!').to_s #=> "\e[96mHello, world!\e[0m"
90
- #
91
- # @return [Decorator] a new instance of Decorator with the color applied
92
- #
93
- # @!method bright_green
94
- # Apply the named ANSI color "bright_green" to the foreground
95
- #
96
- # @api public
97
- #
98
- # @example
99
- # decorator.bright_green.decorate('Hello, world!').to_s #=> "\e[92mHello, world!\e[0m"
100
- #
101
- # @return [Decorator] a new instance of Decorator with the color applied
102
- #
103
- # @!method bright_magenta
104
- # Apply the named ANSI color "bright_magenta" to the foreground
105
- #
106
- # @api public
107
- #
108
- # @example
109
- # decorator.bright_magenta.decorate('Hello, world!').to_s #=> "\e[95mHello, world!\e[0m"
110
- #
111
- # @return [Decorator] a new instance of Decorator with the color applied
112
- #
113
- # @!method bright_red
114
- # Apply the named ANSI color "bright_red" to the foreground
115
- #
116
- # @api public
117
- #
118
- # @example
119
- # decorator.bright_red.decorate('Hello, world!').to_s #=> "\e[91mHello, world!\e[0m"
120
- #
121
- # @return [Decorator] a new instance of Decorator with the color applied
122
- #
123
- # @!method bright_white
124
- # Apply the named ANSI color "bright_white" to the foreground
125
- #
126
- # @api public
127
- #
128
- # @example
129
- # decorator.bright_white.decorate('Hello, world!').to_s #=> "\e[97mHello, world!\e[0m"
130
- #
131
- # @return [Decorator] a new instance of Decorator with the color applied
132
- #
133
- # @!method bright_yellow
134
- # Apply the named ANSI color "bright_yellow" to the foreground
135
- #
136
- # @api public
137
- #
138
- # @example
139
- # decorator.bright_yellow.decorate('Hello, world!').to_s #=> "\e[93mHello, world!\e[0m"
140
- #
141
- # @return [Decorator] a new instance of Decorator with the color applied
142
- #
143
- # @!method cyan
144
- # Apply the named ANSI color "cyan" to the foreground
145
- #
146
- # @api public
147
- #
148
- # @example
149
- # decorator.cyan.decorate('Hello, world!').to_s #=> "\e[36mHello, world!\e[0m"
150
- #
151
- # @return [Decorator] a new instance of Decorator with the color applied
152
- #
153
- # @!method green
154
- # Apply the named ANSI color "green" to the foreground
155
- #
156
- # @api public
157
- #
158
- # @example
159
- # decorator.green.decorate('Hello, world!').to_s #=> "\e[32mHello, world!\e[0m"
160
- #
161
- # @return [Decorator] a new instance of Decorator with the color applied
162
- #
163
- # @!method magenta
164
- # Apply the named ANSI color "magenta" to the foreground
165
- #
166
- # @api public
167
- #
168
- # @example
169
- # decorator.magenta.decorate('Hello, world!').to_s #=> "\e[35mHello, world!\e[0m"
170
- #
171
- # @return [Decorator] a new instance of Decorator with the color applied
172
- #
173
- # @!method on_black
174
- # Apply the named ANSI color "black" to the background
175
- #
176
- # @author {https://aaronmallen.me Aaron Allen}
177
- # @since 0.1.0
178
- #
179
- # @api public
180
- #
181
- # @example
182
- # decorator.on_black.decorate('Hello, world!').to_s #=> "\e[40mHello, world!\e[0m"
183
- #
184
- # @return [Decorator] a new instance of Decorator with the color applied
185
- #
186
- # @!method on_blue
187
- # Apply the named ANSI color "blue" to the background
188
- #
189
- # @author {https://aaronmallen.me Aaron Allen}
190
- # @since 0.1.0
191
- #
192
- # @api public
193
- #
194
- # @example
195
- # decorator.on_blue.decorate('Hello, world!').to_s #=> "\e[44mHello, world!\e[0m"
196
- #
197
- # @return [Decorator] a new instance of Decorator with the color applied
198
- #
199
- # @!method on_bright_black
200
- # Apply the named ANSI color "bright_black" to the background
201
- #
202
- # @author {https://aaronmallen.me Aaron Allen}
203
- # @since 0.1.0
204
- #
205
- # @api public
206
- #
207
- # @example
208
- # decorator.on_bright_black.decorate('Hello, world!').to_s #=> "\e[100mHello, world!\e[0m"
209
- #
210
- # @return [Decorator] a new instance of Decorator with the color applied
211
- #
212
- # @!method on_bright_blue
213
- # Apply the named ANSI color "bright_blue" to the background
214
- #
215
- # @author {https://aaronmallen.me Aaron Allen}
216
- # @since 0.1.0
217
- #
218
- # @api public
219
- #
220
- # @example
221
- # decorator.on_bright_blue.decorate('Hello, world!').to_s #=> "\e[104mHello, world!\e[0m"
222
- #
223
- # @return [Decorator] a new instance of Decorator with the color applied
224
- #
225
- # @!method on_bright_cyan
226
- # Apply the named ANSI color "bright_cyan" to the background
227
- #
228
- # @author {https://aaronmallen.me Aaron Allen}
229
- # @since 0.1.0
230
- #
231
- # @api public
232
- #
233
- # @example
234
- # decorator.on_bright_cyan.decorate('Hello, world!').to_s #=> "\e[106mHello, world!\e[0m"
235
- #
236
- # @return [Decorator] a new instance of Decorator with the color applied
237
- #
238
- # @!method on_bright_green
239
- # Apply the named ANSI color "bright_green" to the background
240
- #
241
- # @author {https://aaronmallen.me Aaron Allen}
242
- # @since 0.1.0
243
- #
244
- # @api public
245
- #
246
- # @example
247
- # decorator.on_bright_green.decorate('Hello, world!').to_s #=> "\e[102mHello, world!\e[0m"
248
- #
249
- # @return [Decorator] a new instance of Decorator with the color applied
250
- #
251
- # @!method on_bright_magenta
252
- # Apply the named ANSI color "bright_magenta" to the background
253
- #
254
- # @author {https://aaronmallen.me Aaron Allen}
255
- # @since 0.1.0
256
- #
257
- # @api public
258
- #
259
- # @example
260
- # decorator.on_bright_magenta.decorate('Hello, world!').to_s #=> "\e[105mHello, world!\e[0m"
261
- #
262
- # @return [Decorator] a new instance of Decorator with the color applied
263
- #
264
- # @!method on_bright_red
265
- # Apply the named ANSI color "bright_red" to the background
266
- #
267
- # @author {https://aaronmallen.me Aaron Allen}
268
- # @since 0.1.0
269
- #
270
- # @api public
271
- #
272
- # @example
273
- # decorator.on_bright_red.decorate('Hello, world!').to_s #=> "\e[101mHello, world!\e[0m"
274
- #
275
- # @return [Decorator] a new instance of Decorator with the color applied
276
- #
277
- # @!method on_bright_white
278
- # Apply the named ANSI color "bright_white" to the background
279
- #
280
- # @author {https://aaronmallen.me Aaron Allen}
281
- # @since 0.1.0
282
- #
283
- # @api public
284
- #
285
- # @example
286
- # decorator.on_bright_white.decorate('Hello, world!').to_s #=> "\e[107mHello, world!\e[0m"
287
- #
288
- # @return [Decorator] a new instance of Decorator with the color applied
289
- #
290
- # @!method on_bright_yellow
291
- # Apply the named ANSI color "bright_yellow" to the background
292
- #
293
- # @author {https://aaronmallen.me Aaron Allen}
294
- # @since 0.1.0
295
- #
296
- # @api public
297
- #
298
- # @example
299
- # decorator.on_bright_yellow.decorate('Hello, world!').to_s #=> "\e[103mHello, world!\e[0m"
300
- #
301
- # @return [Decorator] a new instance of Decorator with the color applied
302
- #
303
- # @!method on_cyan
304
- # Apply the named ANSI color "cyan" to the background
305
- #
306
- # @author {https://aaronmallen.me Aaron Allen}
307
- # @since 0.1.0
308
- #
309
- # @api public
310
- #
311
- # @example
312
- # decorator.on_cyan.decorate('Hello, world!').to_s #=> "\e[46mHello, world!\e[0m"
313
- #
314
- # @return [Decorator] a new instance of Decorator with the color applied
315
- #
316
- # @!method on_green
317
- # Apply the named ANSI color "green" to the background
318
- #
319
- # @author {https://aaronmallen.me Aaron Allen}
320
- # @since 0.1.0
321
- #
322
- # @api public
323
- #
324
- # @example
325
- # decorator.on_green.decorate('Hello, world!').to_s #=> "\e[42mHello, world!\e[0m"
326
- #
327
- # @return [Decorator] a new instance of Decorator with the color applied
328
- #
329
- # @!method on_magenta
330
- # Apply the named ANSI color "magenta" to the background
331
- #
332
- # @author {https://aaronmallen.me Aaron Allen}
333
- # @since 0.1.0
334
- #
335
- # @api public
336
- #
337
- # @example
338
- # decorator.on_magenta.decorate('Hello, world!').to_s #=> "\e[45mHello, world!\e[0m"
339
- #
340
- # @return [Decorator] a new instance of Decorator with the color applied
341
- #
342
- # @!method on_red
343
- # Apply the named ANSI color "red" to the background
344
- #
345
- # @author {https://aaronmallen.me Aaron Allen}
346
- # @since 0.1.0
347
- #
348
- # @api public
349
- #
350
- # @example
351
- # decorator.on_red.decorate('Hello, world!').to_s #=> "\e[41mHello, world!\e[0m"
352
- #
353
- # @return [Decorator] a new instance of Decorator with the color applied
354
- #
355
- # @!method on_white
356
- # Apply the named ANSI color "white" to the background
357
- #
358
- # @author {https://aaronmallen.me Aaron Allen}
359
- # @since 0.1.0
360
- #
361
- # @api public
362
- #
363
- # @example
364
- # decorator.on_white.decorate('Hello, world!').to_s #=> "\e[47mHello, world!\e[0m"
365
- #
366
- # @return [Decorator] a new instance of Decorator with the color applied
367
- #
368
- # @!method on_yellow
369
- # Apply the named ANSI color "yellow" to the background
370
- #
371
- # @author {https://aaronmallen.me Aaron Allen}
372
- # @since 0.1.0
373
- #
374
- # @api public
375
- #
376
- # @example
377
- # decorator.on_yellow.decorate('Hello, world!').to_s #=> "\e[43mHello, world!\e[0m"
378
- #
379
- # @return [Decorator] a new instance of Decorator with the color applied
380
- #
381
- # @!method red
382
- # Apply the named ANSI color "red" to the foreground
383
- #
384
- # @api public
385
- #
386
- # @example
387
- # decorator.red.decorate('Hello, world!').to_s #=> "\e[31mHello, world!\e[0m"
388
- #
389
- # @return [Decorator] a new instance of Decorator with the color applied
390
- #
391
- # @!method white
392
- # Apply the named ANSI color "white" to the foreground
393
- #
394
- # @api public
395
- #
396
- # @example
397
- # decorator.white.decorate('Hello, world!').to_s #=> "\e[37mHello, world!\e[0m"
398
- #
399
- # @return [Decorator] a new instance of Decorator with the color applied
400
- #
401
- # @!method yellow
402
- # Apply the named ANSI color "yellow" to the foreground
403
- #
404
- # @api public
405
- #
406
- # @example
407
- # decorator.yellow.decorate('Hello, world!').to_s #=> "\e[33mHello, world!\e[0m"
408
- #
409
- # @return [Decorator] a new instance of Decorator with the color applied
410
- ANSI::COLOR_NAMES.each_key do |color|
411
- define_method(color) do
412
- apply_named_color(:foreground, color)
413
- end
414
- define_method(:"on_#{color}") do
415
- apply_named_color(:background, color)
416
- end
417
- end
418
- # @rbs!
419
- # def black: () -> Decorator
420
- # def blue: () -> Decorator
421
- # def bright_black: () -> Decorator
422
- # def bright_blue: () -> Decorator
423
- # def bright_cyan: () -> Decorator
424
- # def bright_green: () -> Decorator
425
- # def bright_magenta: () -> Decorator
426
- # def bright_red: () -> Decorator
427
- # def bright_white: () -> Decorator
428
- # def bright_yellow: () -> Decorator
429
- # def cyan: () -> Decorator
430
- # def green: () -> Decorator
431
- # def magenta: () -> Decorator
432
- # def on_black: () -> Decorator
433
- # def on_blue: () -> Decorator
434
- # def on_bright_black: () -> Decorator
435
- # def on_bright_blue: () -> Decorator
436
- # def on_bright_cyan: () -> Decorator
437
- # def on_bright_green: () -> Decorator
438
- # def on_bright_magenta: () -> Decorator
439
- # def on_bright_red: () -> Decorator
440
- # def on_bright_white: () -> Decorator
441
- # def on_bright_yellow: () -> Decorator
442
- # def on_cyan: () -> Decorator
443
- # def on_green: () -> Decorator
444
- # def on_magenta: () -> Decorator
445
- # def on_red: () -> Decorator
446
- # def on_white: () -> Decorator
447
- # def on_yellow: () -> Decorator
448
- # def red: () -> Decorator
449
- # def white: () -> Decorator
450
- # def yellow: () -> Decorator
451
-
452
- # @!method blink
453
- # Apply the ANSI style "blink" to the text
454
- #
455
- # @author {https://aaronmallen.me Aaron Allen}
456
- # @since 0.1.0
457
- #
458
- # @api public
459
- #
460
- # @example
461
- # decorator.blink.decorate('Hello, world!').to_s #=> "\e[5mHello, world!\e[0m"
462
- #
463
- # @return [Decorator] a new instance of Decorator with the style applied
464
- #
465
- # @!method bold
466
- # Apply the ANSI style "bold" to the text
467
- #
468
- # @author {https://aaronmallen.me Aaron Allen}
469
- # @since 0.1.0
470
- #
471
- # @api public
472
- #
473
- # @example
474
- # decorator.bold.decorate('Hello, world!').to_s #=> "\e[1mHello, world!\e[0m"
475
- #
476
- # @return [Decorator] a new instance of Decorator with the style applied
477
- #
478
- # @!method conceal
479
- # Apply the ANSI style "conceal" to the text
480
- #
481
- # @author {https://aaronmallen.me Aaron Allen}
482
- # @since 0.1.0
483
- #
484
- # @api public
485
- #
486
- # @example
487
- # decorator.conceal.decorate('Hello, world!').to_s #=> "\e[8mHello, world!\e[0m"
488
- #
489
- # @return [Decorator] a new instance of Decorator with the style applied
490
- #
491
- # @!method dim
492
- # Apply the ANSI style "dim" to the text
493
- #
494
- # @author {https://aaronmallen.me Aaron Allen}
495
- # @since 0.1.0
496
- #
497
- # @api public
498
- #
499
- # @example
500
- # decorator.dim.decorate('Hello, world!').to_s #=> "\e[2mHello, world!\e[0m"
501
- #
502
- # @return [Decorator] a new instance of Decorator with the style applied
503
- #
504
- # @!method italic
505
- # Apply the ANSI style "italic" to the text
506
- #
507
- # @author {https://aaronmallen.me Aaron Allen}
508
- # @since 0.1.0
509
- #
510
- # @api public
511
- #
512
- # @example
513
- # decorator.italic.decorate('Hello, world!').to_s #=> "\e[3mHello, world!\e[0m"
514
- #
515
- # @return [Decorator] a new instance of Decorator with the style applied
516
- #
517
- # @!method no_blink
518
- # Remove the ANSI style "blink" from the text
519
- #
520
- # @author {https://aaronmallen.me Aaron Allen}
521
- # @since 0.1.0
522
- #
523
- # @api public
524
- #
525
- # @example
526
- # decorator.no_blink.decorate('Hello, world!').to_s #=> "\e[25mHello, world!\e[0m"
527
- #
528
- # @return [Decorator] a new instance of Decorator with the style applied
529
- #
530
- # @!method no_conceal
531
- # Remove the ANSI style "conceal" from the text
532
- #
533
- # @author {https://aaronmallen.me Aaron Allen}
534
- # @since 0.1.0
535
- #
536
- # @api public
537
- #
538
- # @example
539
- # decorator.no_conceal.decorate('Hello, world!').to_s #=> "\e[28mHello, world!\e[0m"
540
- #
541
- # @return [Decorator] a new instance of Decorator with the style applied
542
- #
543
- # @!method no_italic
544
- # Remove the ANSI style "italic" from the text
545
- #
546
- # @author {https://aaronmallen.me Aaron Allen}
547
- # @since 0.1.0
548
- #
549
- # @api public
550
- #
551
- # @example
552
- # decorator.no_italic.decorate('Hello, world!').to_s #=> "\e[23mHello, world!\e[0m"
553
- #
554
- # @return [Decorator] a new instance of Decorator with the style applied
555
- #
556
- # @!method no_reverse
557
- # Remove the ANSI style "reverse" from the text
558
- #
559
- # @author {https://aaronmallen.me Aaron Allen}
560
- # @since 0.1.0
561
- #
562
- # @api public
563
- #
564
- # @example
565
- # decorator.no_reverse.decorate('Hello, world!').to_s #=> "\e[27mHello, world!\e[0m"
566
- #
567
- # @return [Decorator] a new instance of Decorator with the style applied
568
- #
569
- # @!method no_strike
570
- # Remove the ANSI style "strike" from the text
571
- #
572
- # @author {https://aaronmallen.me Aaron Allen}
573
- # @since 0.1.0
574
- #
575
- # @api public
576
- #
577
- # @example
578
- # decorator.no_strike.decorate('Hello, world!').to_s #=> "\e[29mHello, world!\e[0m"
579
- #
580
- # @return [Decorator] a new instance of Decorator with the style applied
581
- #
582
- # @!method no_underline
583
- # Remove the ANSI style "underline" from the text
584
- #
585
- # @author {https://aaronmallen.me Aaron Allen}
586
- # @since 0.1.0
587
- #
588
- # @api public
589
- #
590
- # @example
591
- # decorator.no_underline.decorate('Hello, world!').to_s #=> "\e[24mHello, world!\e[0m"
592
- #
593
- # @return [Decorator] a new instance of Decorator with the style applied
594
- #
595
- # @!method normal_intensity
596
- # Remove any intensity styles (bold or dim) from the text
597
- #
598
- # @author {https://aaronmallen.me Aaron Allen}
599
- # @since 0.1.0
600
- #
601
- # @api public
602
- #
603
- # @example
604
- # decorator.normal_intensity.decorate('Hello, world!').to_s #=> "\e[22mHello, world!\e[0m"
605
- #
606
- # @return [Decorator] a new instance of Decorator with the style applied
607
- #
608
- # @!method rapid_blink
609
- # Apply the ANSI style "rapid_blink" to the text
610
- #
611
- # @author {https://aaronmallen.me Aaron Allen}
612
- # @since 0.1.0
613
- #
614
- # @api public
615
- #
616
- # @example
617
- # decorator.rapid_blink.decorate('Hello, world!').to_s #=> "\e[6mHello, world!\e[0m"
618
- #
619
- # @return [Decorator] a new instance of Decorator with the style applied
620
- #
621
- # @!method reverse
622
- # Apply the ANSI style "reverse" to the text
623
- #
624
- # @author {https://aaronmallen.me Aaron Allen}
625
- # @since 0.1.0
626
- #
627
- # @api public
628
- #
629
- # @example
630
- # decorator.reverse.decorate('Hello, world!').to_s #=> "\e[7mHello, world!\e[0m"
631
- #
632
- # @return [Decorator] a new instance of Decorator with the style applied
633
- #
634
- # @!method strike
635
- # Apply the ANSI style "strike" to the text
636
- #
637
- # @author {https://aaronmallen.me Aaron Allen}
638
- # @since 0.1.0
639
- #
640
- # @api public
641
- #
642
- # @example
643
- # decorator.strike.decorate('Hello, world!').to_s #=> "\e[9mHello, world!\e[0m"
644
- #
645
- # @return [Decorator] a new instance of Decorator with the style applied
646
- #
647
- # @!method underline
648
- # Apply the ANSI style "underline" to the text
649
- #
650
- # @author {https://aaronmallen.me Aaron Allen}
651
- # @since 0.1.0
652
- #
653
- # @api public
654
- #
655
- # @example
656
- # decorator.underline.decorate('Hello, world!').to_s #=> "\e[4mHello, world!\e[0m"
657
- #
658
- # @return [Decorator] a new instance of Decorator with the style applied
659
- ANSI::STYLES.each_key do |style|
660
- define_method(style) do
661
- apply_style(style)
662
- end
663
- end
664
-
665
- # @rbs!
666
- # def blink: () -> Decorator
667
- # def bold: () -> Decorator
668
- # def conceal: () -> Decorator
669
- # def dim: () -> Decorator
670
- # def italic: () -> Decorator
671
- # def no_blink: () -> Decorator
672
- # def no_conceal: () -> Decorator
673
- # def no_italic: () -> Decorator
674
- # def no_reverse: () -> Decorator
675
- # def no_strike: () -> Decorator
676
- # def no_underline: () -> Decorator
677
- # def normal_intensity: () -> Decorator
678
- # def rapid_blink: () -> Decorator
679
- # def reverse: () -> Decorator
680
- # def strike: () -> Decorator
681
- # def underline: () -> Decorator
682
-
683
59
  # Apply the styles and colors to the text
684
60
  #
685
61
  # @author {https://aaronmallen.me Aaron Allen}
@@ -696,11 +72,12 @@ module Sai
696
72
  # @rbs (String text) -> ANSI::SequencedString
697
73
  def decorate(text)
698
74
  return ANSI::SequencedString.new(text) unless should_decorate?
75
+ return apply_sequence_gradient(text) if @foreground_sequence || @background_sequence
699
76
 
700
77
  sequences = [
701
78
  @foreground && Conversion::ColorSequence.resolve(@foreground, @mode),
702
79
  @background && Conversion::ColorSequence.resolve(@background, @mode, :background),
703
- @styles.map { |style| "\e[#{ANSI::STYLES[style]}m" }.join
80
+ style_sequences.join
704
81
  ].compact.join
705
82
 
706
83
  ANSI::SequencedString.new("#{sequences}#{text}#{ANSI::RESET}")
@@ -709,98 +86,6 @@ module Sai
709
86
  alias call decorate
710
87
  alias encode decorate
711
88
 
712
- # Apply a hexadecimal color to the foreground
713
- #
714
- # @author {https://aaronmallen.me Aaron Allen}
715
- # @since 0.1.0
716
- #
717
- # @api public
718
- #
719
- # @example
720
- # decorator.hex("#EB4133").decorate('Hello, world!').to_s #=> "\e[38;2;235;65;51mHello, world!\e[0m"
721
- #
722
- # @param code [String] the hex color code
723
- #
724
- # @raise [ArgumentError] if the hex code is invalid
725
- # @return [Decorator] a new instance of Decorator with the hex color applied
726
- # @rbs (String code) -> Decorator
727
- def hex(code)
728
- raise ArgumentError, "Invalid hex color code: #{code}" unless /^#?([A-Fa-f0-9]{6})$/.match?(code)
729
-
730
- dup.tap { |duped| duped.instance_variable_set(:@foreground, code) }
731
- end
732
-
733
- # Apply a hexadecimal color to the background
734
- #
735
- # @author {https://aaronmallen.me Aaron Allen}
736
- # @since 0.1.0
737
- #
738
- # @api public
739
- #
740
- # @example
741
- # decorator.on_hex("#EB4133").decorate('Hello, world!').to_s #=> "\e[48;2;235;65;51mHello, world!\e[0m"
742
- #
743
- # @param code [String] the hex color code
744
- #
745
- # @raise [ArgumentError] if the hex code is invalid
746
- # @return [Decorator] a new instance of Decorator with the hex color applied
747
- # @rbs (String code) -> Decorator
748
- def on_hex(code)
749
- raise ArgumentError, "Invalid hex color code: #{code}" unless /^#?([A-Fa-f0-9]{6})$/.match?(code)
750
-
751
- dup.tap { |duped| duped.instance_variable_set(:@background, code) }
752
- end
753
-
754
- # Apply an RGB color to the background
755
- #
756
- # @author {https://aaronmallen.me Aaron Allen}
757
- # @since 0.1.0
758
- #
759
- # @api public
760
- #
761
- # @example
762
- # decorator.on_rgb(235, 65, 51).decorate('Hello, world!').to_s #=> "\e[48;2;235;65;51mHello, world!\e[0m"
763
- #
764
- # @param red [Integer] the red component
765
- # @param green [Integer] the green component
766
- # @param blue [Integer] the blue component
767
- #
768
- # @raise [ArgumentError] if the RGB values are out of range
769
- # @return [Decorator] a new instance of Decorator with the RGB color applied
770
- # @rbs (Integer red, Integer green, Integer blue) -> Decorator
771
- def on_rgb(red, green, blue)
772
- [red, green, blue].each do |value|
773
- raise ArgumentError, "Invalid RGB value: #{red}, #{green}, #{blue}" unless value >= 0 && value <= 255
774
- end
775
-
776
- dup.tap { |duped| duped.instance_variable_set(:@background, [red, green, blue]) }
777
- end
778
-
779
- # Apply an RGB color to the foreground
780
- #
781
- # @author {https://aaronmallen.me Aaron Allen}
782
- # @since 0.1.0
783
- #
784
- # @api public
785
- #
786
- # @example
787
- # decorator.rgb(235, 65, 51).decorate('Hello, world!').to_s #=> "\e[38;2;235;65;51mHello, world!\e[0m"
788
- #
789
- # @param red [Integer] the red component
790
- # @param green [Integer] the green component
791
- # @param blue [Integer] the blue component
792
- #
793
- # @raise [ArgumentError] if the RGB values are out of range
794
- # @return [Decorator] a new instance of Decorator with the RGB color applied
795
- # @rbs (Integer red, Integer green, Integer blue) -> Decorator
796
- def rgb(red, green, blue)
797
- [red, green, blue].each do |value|
798
- raise ArgumentError, "Invalid RGB value: #{red}, #{green}, #{blue}" unless value >= 0 && value <= 255
799
- end
800
-
801
- dup.tap { |duped| duped.instance_variable_set(:@foreground, [red, green, blue]) }
802
- end
803
-
804
89
  # Apply a specific color mode to the decorator
805
90
  #
806
91
  # @author {https://aaronmallen.me Aaron Allen}
@@ -821,38 +106,6 @@ module Sai
821
106
 
822
107
  private
823
108
 
824
- # Apply a named color to the specified style type
825
- #
826
- # @author {https://aaronmallen.me Aaron Allen}
827
- # @since 0.1.0
828
- #
829
- # @api private
830
- #
831
- # @param style_type [Symbol] the style type to apply the color to
832
- # @param color [Symbol] the color to apply
833
- #
834
- # @return [Decorator] a new instance of Decorator with the color applied
835
- # @rbs (Conversion::ColorSequence::style_type style_type, Symbol color) -> Decorator
836
- def apply_named_color(style_type, color)
837
- dup.tap { |duped| duped.instance_variable_set(:"@#{style_type}", color) }
838
- end
839
-
840
- # Apply a style to the text
841
- #
842
- # @author {https://aaronmallen.me Aaron Allen}
843
- # @since 0.1.0
844
- #
845
- # @api private
846
- #
847
- # @param style [String, Symbol] the style to apply
848
- #
849
- # @return [Decorator] a new instance of Decorator with the style applied
850
- # @rbs (String | Symbol style) -> self
851
- def apply_style(style)
852
- style = style.to_s.downcase.to_sym
853
- dup.tap { |duped| duped.instance_variable_set(:@styles, (@styles + [style]).uniq) }
854
- end
855
-
856
109
  # Check if text should be decorated
857
110
  #
858
111
  # @author {https://aaronmallen.me Aaron Allen}
@@ -864,7 +117,8 @@ module Sai
864
117
  # @rbs () -> bool
865
118
  def should_decorate?
866
119
  return false if @mode == Terminal::ColorMode::NO_COLOR
867
- return false if @foreground.nil? && @background.nil? && @styles.empty?
120
+ return false if @foreground.nil? && @background.nil? && @styles.empty? &&
121
+ @foreground_sequence.nil? && @background_sequence.nil?
868
122
 
869
123
  true
870
124
  end