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
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