sai 0.1.0 → 0.3.0

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