tco 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,590 @@
1
+ # tco - terminal colouring application and library
2
+ # Copyright (c) 2013, 2014 Radek Pazdera
3
+
4
+ # MIT License
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ module Tco
25
+ class Colour
26
+ attr_reader :rgb, :lab
27
+
28
+ def initialize(rgb, lab=nil)
29
+ @rgb = rgb
30
+ @lab = lab ? lab : rgb_to_lab(rgb)
31
+ @hsl = nil
32
+ @yiq = nil
33
+ end
34
+
35
+ def -(other)
36
+ delta_e_2000 @lab, other.lab
37
+ end
38
+
39
+ def <=>(other)
40
+ self.hsl[0] <=> other.hsl[0]
41
+ end
42
+
43
+ def to_s
44
+ values = @rgb.map do |v|
45
+ v = v.to_i.to_s 16
46
+
47
+ case v.length
48
+ when 0 then "00"
49
+ when 1 then "0" + v
50
+ when 2 then v
51
+ end
52
+ end
53
+
54
+ "#" + values.join("")
55
+ end
56
+
57
+ def hsl
58
+ if @hsl == nil
59
+ @hsl = rgb_to_hsl @rgb
60
+ else
61
+ @hsl
62
+ end
63
+ end
64
+
65
+ def yiq
66
+ if @yiq == nil
67
+ @yiq = rgb_to_yiq @rgb
68
+ else
69
+ @yiq
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ # source: http://www.easyrgb.com/index.php?X=MATH&H=02#text2
76
+ def rgb_to_xyz(colour)
77
+ r, g, b = colour.map do |v|
78
+ v /= 255.0
79
+ if v > 0.04045
80
+ v = ((v + 0.055 ) / 1.055)**2.4
81
+ else
82
+ v = v / 12.92
83
+ end
84
+ v *= 100
85
+ end
86
+
87
+ #Observer = 2°, Illuminant = D65
88
+ x = r * 0.4124 + g * 0.3576 + b * 0.1805
89
+ y = r * 0.2126 + g * 0.7152 + b * 0.0722
90
+ z = r * 0.0193 + g * 0.1192 + b * 0.9505
91
+
92
+ return [x, y, z]
93
+ end
94
+
95
+ def xyz_to_lab(colour)
96
+ f = lambda { |t|
97
+ return t**(1.0/3) if t > (6.0 / 29)**3
98
+ return (1.0 / 3) * ((29.0 / 6)**2) * t + (4.0 / 29)
99
+ }
100
+
101
+ x, y, z = colour
102
+ xn, yn, zn = rgb_to_xyz([255, 255, 255])
103
+ l = 116 * f.call(y/yn) - 16
104
+ a = 500 * (f.call(x/xn) - f.call(y/yn))
105
+ b = 200 * (f.call(y/yn) - f.call(z/zn))
106
+
107
+ return [l, a, b]
108
+ end
109
+
110
+ def rgb_to_lab(rgb_val)
111
+ xyz_to_lab rgb_to_xyz rgb_val
112
+ end
113
+
114
+ def rgb_to_hsl(rgb_val)
115
+ r, g, b = rgb_val.map { |v| v / 255.0 }
116
+
117
+ min, max = [r, g, b].minmax
118
+ delta = max - min
119
+
120
+ lig = (max + min) / 2.0
121
+
122
+ if delta == 0
123
+ hue = 0
124
+ sat = 0
125
+ else
126
+ sat = if lig < 0.5
127
+ delta / (0.0 + (max + min))
128
+ else
129
+ delta / (2.0 - max - min)
130
+ end
131
+
132
+ delta_r = (((max - r) / 6.0 ) + (delta / 2.0)) / delta
133
+ delta_g = (((max - g) / 6.0 ) + (delta / 2.0)) / delta
134
+ delta_b = (((max - b) / 6.0 ) + (delta / 2.0)) / delta
135
+
136
+ hue = case max
137
+ when r then delta_b - delta_g
138
+ when g then (1.0/3) + delta_r - delta_b
139
+ when b then (2.0/3) + delta_g - delta_r
140
+ end
141
+
142
+ hue += 1 if hue < 0
143
+ hue -= 1 if hue > 1
144
+ end
145
+
146
+ [360 * hue, 100 * sat, 100 * lig]
147
+ end
148
+
149
+ def rgb_to_yiq(rgb_val)
150
+ r, g, b = rgb_val
151
+
152
+ y = 0.299*r + 0.587*g + 0.114*b
153
+ i = 0.569*r - 0.275*g - 0.321*b
154
+ q = 0.212*r - 0.523*g + 0.311*b
155
+
156
+ [y, i, q]
157
+ end
158
+
159
+ def rad_to_deg(v)
160
+ (v * 180) / Math::PI
161
+ end
162
+
163
+ def deg_to_rad(v)
164
+ (v * Math::PI) / 180
165
+ end
166
+
167
+ def CieLab2Hue(a, b)
168
+ bias = 0
169
+ return 0 if (a >= 0 && b == 0)
170
+ return 180 if (a < 0 && b == 0)
171
+ return 90 if (a == 0 && b > 0)
172
+ return 270 if (a == 0 && b < 0)
173
+
174
+ bias = case
175
+ when a > 0 && b > 0 then 0
176
+ when a < 0 then 180
177
+ when a > 0 && b < 0 then 360
178
+ end
179
+
180
+ rad_to_deg(Math.atan(b / a)) + bias
181
+ end
182
+
183
+ def delta_e_2000(lab1, lab2)
184
+ l1, a1, b1 = lab1
185
+ l2, a2, b2 = lab2
186
+ kl, kc, kh = [1, 1, 1]
187
+
188
+ xC1 = Math.sqrt(a1**2 + b1**2)
189
+ xC2 = Math.sqrt(a2**2 + b2**2)
190
+ xCX = (xC1 + xC2) / 2
191
+ xGX = 0.5 * (1 - Math.sqrt(xCX**7 / (xCX**7 + 25**7)))
192
+ xNN = (1 + xGX) * a1
193
+ xC1 = Math.sqrt(xNN**2 + b1**2)
194
+ xH1 = CieLab2Hue(xNN, b1)
195
+ xNN = (1 + xGX) * a2
196
+ xC2 = Math.sqrt(xNN**2 + b2**2)
197
+ xH2 = CieLab2Hue(xNN, b2)
198
+ xDL = l2 - l1
199
+ xDC = xC2 - xC1
200
+ if (xC1 * xC2) == 0
201
+ xDH = 0
202
+ else
203
+ xNN = (xH2 - xH1).round(12)
204
+ if xNN.abs <= 180
205
+ xDH = xH2 - xH1
206
+ else
207
+ if xNN > 180
208
+ xDH = xH2 - xH1 - 360
209
+ else
210
+ xDH = xH2 - xH1 + 360
211
+ end
212
+ end
213
+ end
214
+ xDH = 2 * Math.sqrt(xC1 * xC2) * Math.sin(deg_to_rad(xDH / 2.0))
215
+ xLX = (l1 + l2) / 2.0
216
+ xCY = (xC1 + xC2) / 2.0
217
+ if xC1 * xC2 == 0
218
+ xHX = xH1 + xH2
219
+ else
220
+ xNN = (xH1 - xH2).round(12).abs
221
+ if xNN > 180
222
+ if xH2 + xH1 < 360
223
+ xHX = xH1 + xH2 + 360
224
+ else
225
+ xHX = xH1 + xH2 - 360
226
+ end
227
+ else
228
+ xHX = xH1 + xH2
229
+ end
230
+ xHX /= 2.0
231
+ end
232
+ xTX = 1 - 0.17 * Math.cos(deg_to_rad(xHX - 30)) + 0.24 *
233
+ Math.cos(deg_to_rad(2 * xHX)) + 0.32 *
234
+ Math.cos(deg_to_rad(3 * xHX + 6)) - 0.20 *
235
+ Math.cos(deg_to_rad(4 * xHX - 63 ))
236
+ xPH = 30 * Math.exp(-((xHX - 275) / 25.0) * ((xHX - 275) / 25.0))
237
+ xRC = 2 * Math.sqrt(xCY**7 / (xCY**7 + 25**7))
238
+ xSL = 1 + ((0.015 * ((xLX - 50) * (xLX - 50))) /
239
+ Math.sqrt(20 + ((xLX - 50) * (xLX - 50))))
240
+ xSC = 1 + 0.045 * xCY
241
+ xSH = 1 + 0.015 * xCY * xTX
242
+ xRT = -Math.sin(deg_to_rad(2 * xPH)) * xRC
243
+ xDL = xDL / (kl * xSL)
244
+ xDC = xDC / (kc * xSC)
245
+ xDH = xDH / (kh * xSH)
246
+ de = Math.sqrt(xDL**2 + xDC**2 + xDH**2 + xRT * xDC * xDH)
247
+ end
248
+ end
249
+
250
+ class Palette
251
+ attr_reader :type
252
+
253
+ def initialize(type)
254
+ set_type type
255
+
256
+ @cache = {}
257
+ @palette = [
258
+ # ANSI colours (the first 16) are configurable by users in most
259
+ # terminals. Therefore, they're not used for colour matching, unless
260
+ # they were explicitly configured in tco.conf.
261
+ #
262
+ # The colour values in comments are the defaults for xterm.
263
+ nil, # [0, 0, 0]
264
+ nil, # [205, 0, 0]
265
+ nil, # [0, 205, 0]
266
+ nil, # [205, 205, 0]
267
+ nil, # [0, 0, 238]
268
+ nil, # [205, 0, 205]
269
+ nil, # [0, 205, 205]
270
+ nil, # [229, 229, 229]
271
+ nil, # [127, 127, 127]
272
+ nil, # [255, 0, 0]
273
+ nil, # [0, 255, 0]
274
+ nil, # [255, 255, 0]
275
+ nil, # [92, 92, 255]
276
+ nil, # [255, 0, 255]
277
+ nil, # [0, 255, 255]
278
+ nil, # [255, 255, 255]
279
+
280
+ # The colours bellow are the definitions from xterm extended
281
+ # colour palette. They should be the same across terminals.
282
+ Colour.new([0, 0, 0]),
283
+ Colour.new([0, 0, 95]),
284
+ Colour.new([0, 0, 135]),
285
+ Colour.new([0, 0, 175]),
286
+ Colour.new([0, 0, 215]),
287
+ Colour.new([0, 0, 255]),
288
+ Colour.new([0, 95, 0]),
289
+ Colour.new([0, 95, 95]),
290
+ Colour.new([0, 95, 135]),
291
+ Colour.new([0, 95, 175]),
292
+ Colour.new([0, 95, 215]),
293
+ Colour.new([0, 95, 255]),
294
+ Colour.new([0, 135, 0]),
295
+ Colour.new([0, 135, 95]),
296
+ Colour.new([0, 135, 135]),
297
+ Colour.new([0, 135, 175]),
298
+ Colour.new([0, 135, 215]),
299
+ Colour.new([0, 135, 255]),
300
+ Colour.new([0, 175, 0]),
301
+ Colour.new([0, 175, 95]),
302
+ Colour.new([0, 175, 135]),
303
+ Colour.new([0, 175, 175]),
304
+ Colour.new([0, 175, 215]),
305
+ Colour.new([0, 175, 255]),
306
+ Colour.new([0, 215, 0]),
307
+ Colour.new([0, 215, 95]),
308
+ Colour.new([0, 215, 135]),
309
+ Colour.new([0, 215, 175]),
310
+ Colour.new([0, 215, 215]),
311
+ Colour.new([0, 215, 255]),
312
+ Colour.new([0, 255, 0]),
313
+ Colour.new([0, 255, 95]),
314
+ Colour.new([0, 255, 135]),
315
+ Colour.new([0, 255, 175]),
316
+ Colour.new([0, 255, 215]),
317
+ Colour.new([0, 255, 255]),
318
+ Colour.new([95, 0, 0]),
319
+ Colour.new([95, 0, 95]),
320
+ Colour.new([95, 0, 135]),
321
+ Colour.new([95, 0, 175]),
322
+ Colour.new([95, 0, 215]),
323
+ Colour.new([95, 0, 255]),
324
+ Colour.new([95, 95, 0]),
325
+ Colour.new([95, 95, 95]),
326
+ Colour.new([95, 95, 135]),
327
+ Colour.new([95, 95, 175]),
328
+ Colour.new([95, 95, 215]),
329
+ Colour.new([95, 95, 255]),
330
+ Colour.new([95, 135, 0]),
331
+ Colour.new([95, 135, 95]),
332
+ Colour.new([95, 135, 135]),
333
+ Colour.new([95, 135, 175]),
334
+ Colour.new([95, 135, 215]),
335
+ Colour.new([95, 135, 255]),
336
+ Colour.new([95, 175, 0]),
337
+ Colour.new([95, 175, 95]),
338
+ Colour.new([95, 175, 135]),
339
+ Colour.new([95, 175, 175]),
340
+ Colour.new([95, 175, 215]),
341
+ Colour.new([95, 175, 255]),
342
+ Colour.new([95, 215, 0]),
343
+ Colour.new([95, 215, 95]),
344
+ Colour.new([95, 215, 135]),
345
+ Colour.new([95, 215, 175]),
346
+ Colour.new([95, 215, 215]),
347
+ Colour.new([95, 215, 255]),
348
+ Colour.new([95, 255, 0]),
349
+ Colour.new([95, 255, 95]),
350
+ Colour.new([95, 255, 135]),
351
+ Colour.new([95, 255, 175]),
352
+ Colour.new([95, 255, 215]),
353
+ Colour.new([95, 255, 255]),
354
+ Colour.new([135, 0, 0]),
355
+ Colour.new([135, 0, 95]),
356
+ Colour.new([135, 0, 135]),
357
+ Colour.new([135, 0, 175]),
358
+ Colour.new([135, 0, 215]),
359
+ Colour.new([135, 0, 255]),
360
+ Colour.new([135, 95, 0]),
361
+ Colour.new([135, 95, 95]),
362
+ Colour.new([135, 95, 135]),
363
+ Colour.new([135, 95, 175]),
364
+ Colour.new([135, 95, 215]),
365
+ Colour.new([135, 95, 255]),
366
+ Colour.new([135, 135, 0]),
367
+ Colour.new([135, 135, 95]),
368
+ Colour.new([135, 135, 135]),
369
+ Colour.new([135, 135, 175]),
370
+ Colour.new([135, 135, 215]),
371
+ Colour.new([135, 135, 255]),
372
+ Colour.new([135, 175, 0]),
373
+ Colour.new([135, 175, 95]),
374
+ Colour.new([135, 175, 135]),
375
+ Colour.new([135, 175, 175]),
376
+ Colour.new([135, 175, 215]),
377
+ Colour.new([135, 175, 255]),
378
+ Colour.new([135, 215, 0]),
379
+ Colour.new([135, 215, 95]),
380
+ Colour.new([135, 215, 135]),
381
+ Colour.new([135, 215, 175]),
382
+ Colour.new([135, 215, 215]),
383
+ Colour.new([135, 215, 255]),
384
+ Colour.new([135, 255, 0]),
385
+ Colour.new([135, 255, 95]),
386
+ Colour.new([135, 255, 135]),
387
+ Colour.new([135, 255, 175]),
388
+ Colour.new([135, 255, 215]),
389
+ Colour.new([135, 255, 255]),
390
+ Colour.new([175, 0, 0]),
391
+ Colour.new([175, 0, 95]),
392
+ Colour.new([175, 0, 135]),
393
+ Colour.new([175, 0, 175]),
394
+ Colour.new([175, 0, 215]),
395
+ Colour.new([175, 0, 255]),
396
+ Colour.new([175, 95, 0]),
397
+ Colour.new([175, 95, 95]),
398
+ Colour.new([175, 95, 135]),
399
+ Colour.new([175, 95, 175]),
400
+ Colour.new([175, 95, 215]),
401
+ Colour.new([175, 95, 255]),
402
+ Colour.new([175, 135, 0]),
403
+ Colour.new([175, 135, 95]),
404
+ Colour.new([175, 135, 135]),
405
+ Colour.new([175, 135, 175]),
406
+ Colour.new([175, 135, 215]),
407
+ Colour.new([175, 135, 255]),
408
+ Colour.new([175, 175, 0]),
409
+ Colour.new([175, 175, 95]),
410
+ Colour.new([175, 175, 135]),
411
+ Colour.new([175, 175, 175]),
412
+ Colour.new([175, 175, 215]),
413
+ Colour.new([175, 175, 255]),
414
+ Colour.new([175, 215, 0]),
415
+ Colour.new([175, 215, 95]),
416
+ Colour.new([175, 215, 135]),
417
+ Colour.new([175, 215, 175]),
418
+ Colour.new([175, 215, 215]),
419
+ Colour.new([175, 215, 255]),
420
+ Colour.new([175, 255, 0]),
421
+ Colour.new([175, 255, 95]),
422
+ Colour.new([175, 255, 135]),
423
+ Colour.new([175, 255, 175]),
424
+ Colour.new([175, 255, 215]),
425
+ Colour.new([175, 255, 255]),
426
+ Colour.new([215, 0, 0]),
427
+ Colour.new([215, 0, 95]),
428
+ Colour.new([215, 0, 135]),
429
+ Colour.new([215, 0, 175]),
430
+ Colour.new([215, 0, 215]),
431
+ Colour.new([215, 0, 255]),
432
+ Colour.new([215, 95, 0]),
433
+ Colour.new([215, 95, 95]),
434
+ Colour.new([215, 95, 135]),
435
+ Colour.new([215, 95, 175]),
436
+ Colour.new([215, 95, 215]),
437
+ Colour.new([215, 95, 255]),
438
+ Colour.new([215, 135, 0]),
439
+ Colour.new([215, 135, 95]),
440
+ Colour.new([215, 135, 135]),
441
+ Colour.new([215, 135, 175]),
442
+ Colour.new([215, 135, 215]),
443
+ Colour.new([215, 135, 255]),
444
+ Colour.new([215, 175, 0]),
445
+ Colour.new([215, 175, 95]),
446
+ Colour.new([215, 175, 135]),
447
+ Colour.new([215, 175, 175]),
448
+ Colour.new([215, 175, 215]),
449
+ Colour.new([215, 175, 255]),
450
+ Colour.new([215, 215, 0]),
451
+ Colour.new([215, 215, 95]),
452
+ Colour.new([215, 215, 135]),
453
+ Colour.new([215, 215, 175]),
454
+ Colour.new([215, 215, 215]),
455
+ Colour.new([215, 215, 255]),
456
+ Colour.new([215, 255, 0]),
457
+ Colour.new([215, 255, 95]),
458
+ Colour.new([215, 255, 135]),
459
+ Colour.new([215, 255, 175]),
460
+ Colour.new([215, 255, 215]),
461
+ Colour.new([215, 255, 255]),
462
+ Colour.new([255, 0, 0]),
463
+ Colour.new([255, 0, 95]),
464
+ Colour.new([255, 0, 135]),
465
+ Colour.new([255, 0, 175]),
466
+ Colour.new([255, 0, 215]),
467
+ Colour.new([255, 0, 255]),
468
+ Colour.new([255, 95, 0]),
469
+ Colour.new([255, 95, 95]),
470
+ Colour.new([255, 95, 135]),
471
+ Colour.new([255, 95, 175]),
472
+ Colour.new([255, 95, 215]),
473
+ Colour.new([255, 95, 255]),
474
+ Colour.new([255, 135, 0]),
475
+ Colour.new([255, 135, 95]),
476
+ Colour.new([255, 135, 135]),
477
+ Colour.new([255, 135, 175]),
478
+ Colour.new([255, 135, 215]),
479
+ Colour.new([255, 135, 255]),
480
+ Colour.new([255, 175, 0]),
481
+ Colour.new([255, 175, 95]),
482
+ Colour.new([255, 175, 135]),
483
+ Colour.new([255, 175, 175]),
484
+ Colour.new([255, 175, 215]),
485
+ Colour.new([255, 175, 255]),
486
+ Colour.new([255, 215, 0]),
487
+ Colour.new([255, 215, 95]),
488
+ Colour.new([255, 215, 135]),
489
+ Colour.new([255, 215, 175]),
490
+ Colour.new([255, 215, 215]),
491
+ Colour.new([255, 215, 255]),
492
+ Colour.new([255, 255, 0]),
493
+ Colour.new([255, 255, 95]),
494
+ Colour.new([255, 255, 135]),
495
+ Colour.new([255, 255, 175]),
496
+ Colour.new([255, 255, 215]),
497
+ Colour.new([255, 255, 255]),
498
+ Colour.new([8, 8, 8]),
499
+ Colour.new([18, 18, 18]),
500
+ Colour.new([28, 28, 28]),
501
+ Colour.new([38, 38, 38]),
502
+ Colour.new([48, 48, 48]),
503
+ Colour.new([58, 58, 58]),
504
+ Colour.new([68, 68, 68]),
505
+ Colour.new([78, 78, 78]),
506
+ Colour.new([88, 88, 88]),
507
+ Colour.new([98, 98, 98]),
508
+ Colour.new([108, 108, 108]),
509
+ Colour.new([118, 118, 118]),
510
+ Colour.new([128, 128, 128]),
511
+ Colour.new([138, 138, 138]),
512
+ Colour.new([148, 148, 148]),
513
+ Colour.new([158, 158, 158]),
514
+ Colour.new([168, 168, 168]),
515
+ Colour.new([178, 178, 178]),
516
+ Colour.new([188, 188, 188]),
517
+ Colour.new([198, 198, 198]),
518
+ Colour.new([208, 208, 208]),
519
+ Colour.new([218, 218, 218]),
520
+ Colour.new([228, 228, 228]),
521
+ Colour.new([238, 238, 238])
522
+ ]
523
+ end
524
+
525
+ def set_colour_value(id, rgb_colour)
526
+ raise "Id '#{id}' out of range." unless id.between?(0, @palette.length-1)
527
+ @palette[id] = Colour.new(rgb_colour)
528
+ end
529
+
530
+ def get_colour_value(id)
531
+ raise "Id '#{id}' out of range." unless id.between?(0, @palette.length-1)
532
+ @palette[id].rgb if @palette[id]
533
+ end
534
+
535
+ # Returns an index of the closest colour in the palette
536
+ def match_colour(colour)
537
+ unless colour.is_a? Colour
538
+ msg = "Unsupported argument type '#{colour.class}', must be 'Colour'."
539
+ raise ArgumentError.new msg
540
+ end
541
+
542
+ colours = case @type
543
+ when "extended" then @palette
544
+ when "ansi" then @palette[0,8]
545
+ end
546
+
547
+ if @cache.has_key? colour.to_s
548
+ @cache[colour.to_s]
549
+ else
550
+ distances = colours.map { |c| c ? c - colour : Float::INFINITY }
551
+ colour_index = distances.each_with_index.min[1]
552
+
553
+ # TODO: No cache eviction is currently in place
554
+ # We assume that applications won't use milions of different colours.
555
+ @cache[colour.to_s] = colour_index
556
+ colour_index
557
+ end
558
+ end
559
+
560
+ def colours
561
+ if @type == "extended"
562
+ @palette
563
+ else
564
+ @palette[0,8]
565
+ end
566
+ end
567
+
568
+ def type=(type)
569
+ set_type type
570
+ end
571
+
572
+ private
573
+ def set_type(type)
574
+ @type = case type
575
+ when "auto"[0, type.length]
576
+ if ENV.has_key? "TERM" and ENV["TERM"] == "xterm-256color"
577
+ "extended"
578
+ else
579
+ "ansi"
580
+ end
581
+ when "ansi"[0, type.length]
582
+ "ansi"
583
+ when "extended"[0, type.length]
584
+ "extended"
585
+ else
586
+ raise "Unknown palette type '#{type}'."
587
+ end
588
+ end
589
+ end
590
+ end