colorable 0.0.8 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd1ee00539ef3544f0938729f93a1abc32c3b3ec
4
- data.tar.gz: 72879c844b5456ad6908cf0875cc5468f553b0ea
3
+ metadata.gz: b79f5456ff48188f4232decead4443e0c511ba3f
4
+ data.tar.gz: cf8e2236927be3b23baaec50d220d112190076b5
5
5
  SHA512:
6
- metadata.gz: a04a172d115e8c82c5f0d6746bebebd90670e74ac8a7a97bf8369c961a37de9e2825ef7ba6f57199862ef0253910af6d79d20ff20ef7bdc8ed925c7296d2694a
7
- data.tar.gz: fe15f0a313eea761fbd741398159dad8d8aaa26d4f56f74b9ff1ff45a48cfaa571537578b4ccb95db1f02a88919b10ab91ea52ef8f10a3f79e8d4f25eb83a6a2
6
+ metadata.gz: a7fc1f13cefb37d408c10491150020f788445693855b9a07d39c3653298d739f5f4b3f4de4f8d7e3fe5e2db58f0d3976d0982a167b330c54558c9abb768bc87d
7
+ data.tar.gz: 66a27bbed8977cd6b543b86eb947a7fa5b9ece0fa5a40d1d7e0e7d110ac26b2472f3b69348bb9a83e7b7c69651459512a91c856c7e7b84fc91dfdda5280f6368
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Colorable
2
2
 
3
- A simple color handler which provide a conversion between colorname, RGB, HSB and HEX. It also provides a colorset which can be sorted by above color units.
3
+ Colorable is a color handler written in Ruby which include Color and Colorset classes.
4
+ A color object provide a conversion between X11 colorname, RGB, HSB and HEX or other manipulations. a colorset object represent X11 colorset which can be manipulated like enumerable object.
4
5
 
5
6
  ## Installation
6
7
 
@@ -21,33 +22,103 @@ Or install it yourself as:
21
22
  Create a color object:
22
23
 
23
24
  require "colorable"
25
+ include Colorable
24
26
 
25
- # Accept X11 color names
26
- c = Colorable::Color.new(:green) #=> #<Colorable::Color:0x007fa449954ee0 @name="Green", @rgb=[0, 255, 0], @hex=nil, @hsb=nil, @esc=nil>
27
- c.name #=> "Green"
28
- c.hsb #=> [120, 100, 100]
29
- c.hex #=> "#00FF00"
30
- c.to_s #=> "rgb(0,255,0)"
31
-
32
- # or RGB
33
- c2 = Colorable::Color.new([240, 248, 255]) #=> #<Colorable::Color:0x007fa449a69c90 @name="Alice Blue", @rgb=[240, 248, 255], @hex=nil, @hsb=nil, @esc=nil>
34
- c2.name #=> "Alice Blue"
35
- c2.rgb #=> [240, 248, 255]
36
- c2.hsb #=> [208, 6, 100]
37
- c2.hex #=> "#F0F8FF"
38
- c2.to_s #=> "rgb(240,248,255)"
39
-
40
- Create a colorset object:
41
-
42
- # Default colorset sequence is by its color name order.
43
- cs = Colorable::Colorset.new #=> #<Colorset 0/144 pos='Alice Blue:rgb(240,248,255)'>
44
- cs.at #=> #<Colorable::Color:0x007fa448beb2b8 @name="Alice Blue", @rgb=[240, 248, 255], @hex=nil, @hsb=nil, @esc=nil>
45
- 10.times.map { cs.next.name } #=> ["Antique White", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "Blanched Almond", "Blue", "Blue Violet"]
46
-
47
- # Using Colorset#[], the order of the sequence is specified.
48
- cs2 = Colorable::Colorset[:hsb] #=> #<Colorset 0/144 pos='Black:rgb(0,0,0)'>
49
- cs2.at #=> #<Colorable::Color:0x007fa448a913e0 @name="Black", @rgb=[0, 0, 0], @hex=nil, @hsb=[0, 0, 0], @esc=nil>
50
- 10.times.map { cs2.next.hsb } #=> [[0, 0, 41], [0, 0, 50], [0, 0, 66], [0, 0, 75], [0, 0, 75], [0, 0, 83], [0, 0, 86], [0, 0, 96], [0, 0, 100], [0, 2, 100]]
27
+ # with a X11 colorname
28
+ c = Color.new :lime_green
29
+ c.to_s #=> "Lime Green"
30
+ c.rgb.to_a #=> [50, 205, 50]
31
+ c.hsb.to_a #=> [120, 76, 80]
32
+ c.hex.to_s #=> "#32CD32"
33
+ c.dark? #=> false
34
+
35
+ # with Array of RGB values
36
+ c = Color.new [50, 205, 50]
37
+ c.to_s #=> "rgb(50,205,50)"
38
+ c.name.to_s #=> "Lime Green"
39
+ c.hsb.to_a #=> [120, 76, 80]
40
+ c.hex.to_s #=> "#32CD32"
41
+
42
+ # with a HEX string
43
+ c = Color.new '#32CD32'
44
+ c.to_s #=> "#32CD32"
45
+
46
+ # with a RGB, HSB or HEX object
47
+ c = Color.new RGB.new(50, 205, 50)
48
+ c = Color.new HSB.new(120, 76, 80)
49
+ c = Color.new HEX.new('#32CD32')
50
+
51
+ Manipulate color object:
52
+
53
+ c = Color.new :lime_green
54
+
55
+ c.to_s #=> "Lime Green"
56
+ c.rgb.to_a #=> [50, 205, 50]
57
+ c.hsb.to_a #=> [120, 76, 80]
58
+ c.hex.to_s #=> "#32CD32"
59
+ c.dark? #=> false
60
+
61
+ # info returns information of the color
62
+ c.info #=> {:NAME=>"Lime Green", :RGB=>[50, 205, 50], :HSB=>[120, 76, 80], :HEX=>"#32CD32", :MODE=>:NAME, :DARK=>false}
63
+
64
+ # next, prev returns next, prev color object in X11 color sequence
65
+ c.next.to_s #=> "Linen"
66
+ c.next(2).to_s #=> "Magenta"
67
+ c.prev.to_s #=> "Lime"
68
+ c.prev(2).to_s #=> "Light Yellow"
69
+
70
+ # +, - returns incremented or decremented color object
71
+ (c + 1).to_s #=> "Linen"
72
+ (c + 2).to_s #=> "Magenta"
73
+ (c - 1).to_s #=> "Lime"
74
+ (c - 2).to_s #=> "Light Yellow"
75
+
76
+ Color object has a mode which represent output mode of the color. Behaviours of `#to_s`, `next`, `prev`, `+`, `-` will be changed based on the mode. You can change the mode with `#mode=` between :NAME, :RGB, :HSB, :HEX.
77
+
78
+ c = Color.new 'Lime Green'
79
+ c.mode = :NAME
80
+ c.to_s #=> "Lime Green"
81
+ c.next.to_s #=> "Linen"
82
+
83
+ c.mode = :RGB
84
+ c.to_s #=> "rgb(50,205,50)"
85
+ c.next.to_s #=> "rgb(60,179,113)"
86
+ c.next.name.to_s #=> "Medium Sea Green"
87
+ (c + 10).to_s #=> "rgb(60,215,60)"
88
+ (c + [0, 50, 100]).to_s #=> "rgb(50, 255, 150)"
89
+
90
+
91
+ Create a X11 colorset object:
92
+
93
+ include Colorable
94
+
95
+ cs = Colorset.new #=> #<Colorset 0/144 pos='Alice Blue/rgb(240,248,255)/hsb(208,6,100)'>
96
+
97
+ # with option
98
+ cs = Colorset.new(order: :RGB) #=> #<Colorset 0/144 pos='Black/rgb(0,0,0)/hsb(0,0,0)'>
99
+ cs = Colorset.new(order: :HSB, dir: :-) #=> #<Colorset 0/144 pos='Light Pink/rgb(255,182,193)/hsb(352,29,100)'>
100
+
101
+ Manupilate colorset:
102
+
103
+ cs = Colorset.new
104
+ cs.size #=> 144
105
+ cs.at.to_s #=> "Alice Blue"
106
+ cs.at(1).to_s #=> "Antique White"
107
+ cs.at(2).to_s #=> "Aqua"
108
+
109
+ # next(prev) methods moves cursor position
110
+ cs.next.to_s #=> "Antique White"
111
+ cs.at.to_s #=> "Antique White"
112
+ cs.next.to_s #=> "Aqua"
113
+ cs.at.to_s #=> "Aqua"
114
+ cs.rewind
115
+ cs.at.to_s #=> "Alice Blue"
116
+
117
+ cs.map(&:to_s).take(10) #=> ["Alice Blue", "Antique White", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "Blanched Almond", "Blue"]
118
+
119
+ cs.sort_by(&:rgb).map(&:to_s).take(10) #=> ["Black", "Navy", "Dark Blue", "Medium Blue", "Blue", "Dark Green", "Green2", "Teal", "Dark Cyan", "Deep Sky Blue"]
120
+
121
+ cs.sort_by(&:hsb).map(&:to_s).take(10) #=> ["Black", "Dim Gray", "Gray2", "Dark Gray", "Gray", "Silver", "Light Gray", "Gainsboro", "White Smoke", "White"]
51
122
 
52
123
 
53
124
  ## Contributing
data/lib/colorable.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "colorable/version"
2
- %w(system_extension converter color colorset).each { |lib| require_relative "colorable/" + lib }
2
+ %w(system_extension converter color colorset color_space).each { |lib| require_relative "colorable/" + lib }
3
3
 
4
4
  module Colorable
5
5
 
@@ -1,71 +1,161 @@
1
1
  module Colorable
2
2
  class Color
3
- class ColorNameError < StandardError; end
4
- include Colorable::Converter
3
+ class NameError < StandardError; end
5
4
  include Comparable
6
5
  attr_reader :name, :rgb
7
6
 
8
- def initialize(name_or_rgb)
9
- @name, @rgb, @hex, @hsb, @esc = nil
10
- case name_or_rgb
11
- when String, Symbol
12
- @name = varidate_name(name_or_rgb)
13
- @rgb = name2rgb(@name)
14
- when Array
15
- @rgb = validate_rgb(name_or_rgb)
16
- @name = rgb2name(@rgb)
17
- else
18
- raise ArgumentError, "'#{name_or_rgb}' is wrong argument. Only colorname and RGB value are acceptable"
19
- end
7
+ # Create a Color object which has several representations of a color.
8
+ #
9
+ # +arg+ can be:
10
+ # String or Symbol of color name
11
+ # String of HEX color
12
+ # Array of RGB values
13
+ # NAME, RGB, HSB, HEX objects
14
+ #
15
+ # Color object has output mode, which is determined by +arg+ type.
16
+ def initialize(arg)
17
+ @name, @rgb, @hsb, @hex, @mode = set_variables(arg)
18
+ end
19
+
20
+ # Returns a current output mode
21
+ def mode
22
+ "#{@mode.class}"[/\w+$/].intern
23
+ end
24
+
25
+ # Set output mode.
26
+ def mode=(mode)
27
+ modes = [rgb, hsb, name, hex]
28
+ @mode = modes.detect { |m| m.class.to_s.match /#{mode}/i } || begin
29
+ raise ArgumentError, "Invalid mode given"
30
+ end
20
31
  end
21
32
 
22
33
  def to_s
23
- "rgb(%i,%i,%i)" % rgb
34
+ @mode.to_s
35
+ end
36
+
37
+ # Returns information of the color object
38
+ def info
39
+ {
40
+ NAME: name.to_s,
41
+ RGB: rgb.to_a,
42
+ HSB: hsb.to_a,
43
+ HEX: hex.to_s,
44
+ MODE: mode,
45
+ DARK: dark?
46
+ }
24
47
  end
25
48
 
26
49
  def hex
27
- @hex ||= rgb2hex(rgb)
50
+ @hex ||= HEX.new rgb.to_hex
28
51
  end
29
52
 
30
53
  def hsb
31
- @hsb ||= rgb2hsb(rgb)
54
+ @hsb ||= HSB.new *rgb.to_hsb
32
55
  end
33
56
  alias :hsv :hsb
34
57
 
35
- %w(red green blue).each_with_index do |c, i|
36
- define_method(c) { rgb[i] }
58
+ %w(red green blue).each do |c|
59
+ define_method(c) { rgb.send c }
37
60
  end
38
61
 
39
- %w(hue sat bright).each_with_index do |n, i|
40
- define_method(n) { hsb[i] }
62
+ %w(hue sat bright).each do |c|
63
+ define_method(c) { hsb.send c }
41
64
  end
42
65
 
43
66
  def <=>(other)
44
- self.name <=> other.name
67
+ self.rgb <=> other.rgb
45
68
  end
46
69
 
47
70
  @@colorset = {}
48
- def next(set=:name, n=1)
49
- @@colorset[set] ||= Colorable::Colorset[set]
50
- idx = @@colorset[set].find_index(self)
51
- @@colorset[set].at(idx+n) if idx
71
+ # Returns a next color object in X11 colors.
72
+ # The color sequence is determined by its color mode.
73
+ def next(n=1)
74
+ @@colorset[mode] ||= Colorable::Colorset.new(order: mode)
75
+ idx = @@colorset[mode].find_index(self)
76
+ @@colorset[mode].at(idx+n).tap{|c| c.mode = mode } if idx
52
77
  end
53
78
 
54
- def prev(set=:name, n=1)
55
- self.next(set, -n)
79
+ # Returns a previous color object in X11 colors.
80
+ # The color sequence is determined by its color mode.
81
+ def prev(n=1)
82
+ self.next(-n)
56
83
  end
57
84
 
58
85
  def dark?
59
- DARK_COLORS.detect { |d| d == self.name }
86
+ !!DARK_COLORS.detect { |d| d == name.to_s }
87
+ end
88
+
89
+ # Returns a color object which has incremented color values.
90
+ # Array of values or a Fixnum is acceptable as an argument.
91
+ # Which values are affected is determined by its color mode.
92
+ def +(arg)
93
+ self.class.new @mode + arg
94
+ end
95
+
96
+ # Returns a color object which has decremented color values.
97
+ # Array of values or a Fixnum is acceptable as an argument.
98
+ # Which values are affected is determined by its color mode.
99
+ def -(arg)
100
+ self.class.new @mode - arg
60
101
  end
61
102
 
62
103
  private
63
- def varidate_name(name)
64
- COLORNAMES.detect do |label, _|
65
- [label, name].same? { |str| "#{str}".gsub(/[_\s]/,'').downcase }
66
- end.tap do |res, _|
67
- raise ColorNameError, "'#{name}' is not a valid colorname" unless res
68
- break res
104
+ def set_variables(arg)
105
+ case arg
106
+ when String, Symbol
107
+ begin
108
+ hex = HEX.new(arg)
109
+ name = NAME.new(hex.to_name) rescue nil
110
+ rgb = RGB.new *hex.to_rgb
111
+ hsb = nil
112
+ mode = hex
113
+ rescue ArgumentError
114
+ name = validate_name(arg)
115
+ rgb = RGB.new *name.to_rgb
116
+ hsb = nil
117
+ hex = nil
118
+ mode = name
119
+ end
120
+ when Array
121
+ rgb = RGB.new *arg
122
+ name = NAME.new(rgb.to_name) rescue nil
123
+ hsb = nil
124
+ hex = nil
125
+ mode = rgb
126
+ when RGB
127
+ rgb = arg
128
+ name = NAME.new(rgb.to_name) rescue nil
129
+ hsb = nil
130
+ hex = nil
131
+ mode = rgb
132
+ when HSB
133
+ hsb = arg
134
+ rgb = RGB.new *hsb.to_rgb
135
+ name = NAME.new(rgb.to_name) rescue nil
136
+ hex = nil
137
+ mode = hsb
138
+ when NAME
139
+ name = arg
140
+ rgb = RGB.new *name.to_rgb
141
+ hsb = nil
142
+ hex = nil
143
+ mode = name
144
+ when HEX
145
+ hex = arg
146
+ name = NAME.new(hex.to_name) rescue nil
147
+ rgb = RGB.new *hex.to_rgb
148
+ hsb = nil
149
+ mode = hex
150
+ else
151
+ raise ArgumentError
152
+ end
153
+ return name, rgb, hsb, hex, mode
154
+ end
155
+
156
+ def validate_name(name)
157
+ NAME.new(name).tap do |res|
158
+ raise NameError, "Invalid color name given" unless res.name
69
159
  end
70
160
  end
71
161
  end
@@ -0,0 +1,260 @@
1
+ module Colorable
2
+ class ColorSpace
3
+ include Colorable::Converter
4
+ include Comparable
5
+
6
+ def <=>(other)
7
+ self.to_a <=> other.to_a
8
+ end
9
+
10
+ def move_to_top(idx)
11
+ arr = self.to_a
12
+ arr.insert 0, arr.delete_at(idx)
13
+ end
14
+
15
+ def +(arg)
16
+ raise "Subclass must implement it"
17
+ end
18
+
19
+ def -(arg)
20
+ arg = arg.is_a?(Fixnum) ? -arg : arg.map(&:-@)
21
+ self + arg
22
+ end
23
+
24
+ def coerce(arg)
25
+ [self, arg]
26
+ end
27
+
28
+ def to_s
29
+ name = "#{self.class}"[/\w+$/].downcase
30
+ "#{name}(%i,%i,%i)" % to_a
31
+ end
32
+
33
+ private
34
+ def validate(pattern, data)
35
+ case Array(data)
36
+ when Pattern[*Array(pattern)] then data
37
+ else
38
+ raise ArgumentError, "'#{data}' is invalid for a #{self.class} value"
39
+ end
40
+ end
41
+ end
42
+
43
+ class RGB < ColorSpace
44
+ attr_accessor :rgb, :r, :g, :b
45
+ def initialize(r=0,g=0,b=0)
46
+ @r, @g, @b = @rgb = validate_rgb([r, g, b])
47
+ end
48
+ alias :red :r
49
+ alias :green :g
50
+ alias :blue :b
51
+ alias :to_a :rgb
52
+
53
+ # Pass Array of [r, g, b] or a Fixnum.
54
+ # Returns new RGB object with added RGB.
55
+ def +(arg)
56
+ arg =
57
+ case arg
58
+ when Fixnum
59
+ [arg] * 3
60
+ when Array
61
+ raise ArgumentError, "Must be three numbers contained" unless arg.size==3
62
+ arg
63
+ else
64
+ raise ArgumentError, "Accept only Array of three numbers or a Fixnum"
65
+ end
66
+ new_rgb = self.rgb.zip(arg).map { |x, y| x + y }
67
+ self.class.new *new_rgb
68
+ end
69
+
70
+ def to_name
71
+ rgb2name(self.to_a)
72
+ end
73
+
74
+ def to_hsb
75
+ rgb2hsb(self.to_a)
76
+ end
77
+
78
+ def to_hex
79
+ rgb2hex(self.to_a)
80
+ end
81
+
82
+ private
83
+ def validate_rgb(rgb)
84
+ validate([0..255, 0..255, 0..255], rgb)
85
+ end
86
+ end
87
+
88
+ class HSB < ColorSpace
89
+ attr_accessor :hsb, :h, :s, :b
90
+ def initialize(h=0,s=0,b=0)
91
+ @h, @s, @b = @hsb = validate_hsb([h, s, b])
92
+ end
93
+ alias :hue :h
94
+ alias :sat :s
95
+ alias :bright :b
96
+ alias :to_a :hsb
97
+ undef :coerce
98
+
99
+ # Pass Array of [h, s, b] or a Fixnum.
100
+ # Returns new HSB object with added HSB.
101
+ def +(arg)
102
+ arg =
103
+ case arg
104
+ when Array
105
+ raise ArgumentError, "Must be three numbers contained" unless arg.size==3
106
+ arg
107
+ else
108
+ raise ArgumentError, "Accept only Array of three numbers"
109
+ end
110
+ new_hsb = self.hsb.zip(arg).map { |x, y| x + y }
111
+ self.class.new *new_hsb
112
+ end
113
+
114
+ def to_name
115
+ rgb2name(self.to_rgb)
116
+ end
117
+
118
+ def to_rgb
119
+ hsb2rgb(self.to_a)
120
+ end
121
+
122
+ def to_hex
123
+ rgb2hex(self.to_rgb)
124
+ end
125
+
126
+ private
127
+ def validate_hsb(hsb)
128
+ validate([0..359, 0..100, 0..100], hsb)
129
+ end
130
+ end
131
+
132
+ class HEX < ColorSpace
133
+ attr_reader :hex
134
+ def initialize(hex='#FFFFFF')
135
+ @hex = validate_hex(hex)
136
+ end
137
+ alias :to_s :hex
138
+
139
+ def to_a
140
+ @hex.unpack('A1A2A2A2').drop(1)
141
+ end
142
+
143
+ def +(arg)
144
+ build_hex_with(:+, arg)
145
+ end
146
+
147
+ def -(arg)
148
+ build_hex_with(:-, arg)
149
+ end
150
+
151
+ def to_rgb
152
+ hex2rgb(self.to_s)
153
+ end
154
+
155
+ def to_hsb
156
+ rgb2hsb(self.to_rgb)
157
+ end
158
+
159
+ def to_name
160
+ rgb2name(self.to_rgb)
161
+ end
162
+
163
+ private
164
+ def validate_hex(hex)
165
+ hex = hex.join if hex.is_a?(Array)
166
+ validate(/^#[0-9A-F]{6}$/i, hex_norm(hex))
167
+ end
168
+
169
+ def hex_norm(hex)
170
+ hex = hex.to_s.sub(/^#/, '').upcase
171
+ .sub(/^([0-9A-F])([0-9A-F])([0-9A-F])$/, '\1\1\2\2\3\3')
172
+ "##{hex}"
173
+ end
174
+
175
+ def rgb2hex(rgb)
176
+ hex = rgb.map do |val|
177
+ val.to_s(16).tap { |h| break "0#{h}" if h.size==1 }
178
+ end
179
+ '#' + hex.join.upcase
180
+ end
181
+
182
+ def hex2rgb(hex)
183
+ _, *hex = hex.unpack('A1A2A2A2')
184
+ hex.map { |val| val.to_i(16) }
185
+ end
186
+
187
+ def build_hex_with(op, arg)
188
+ _rgb =
189
+ case arg
190
+ when Fixnum
191
+ [arg] * 3
192
+ when String
193
+ hex2rgb(validate_hex arg)
194
+ else
195
+ raise ArgumentError, "Accept only a Hex string or a Fixnum"
196
+ end
197
+ rgb = hex2rgb(self.hex).zip(_rgb).map { |x, y| x.send(op, y) }
198
+ self.class.new rgb2hex(rgb)
199
+ end
200
+ end
201
+
202
+ class NAME < ColorSpace
203
+ attr_accessor :name
204
+ attr_reader :sym
205
+ def initialize(name)
206
+ @name = find_name(name)
207
+ @sym = nil
208
+ end
209
+
210
+ alias :to_s :name
211
+
212
+ def sym
213
+ @name.gsub(/\s/, '_').downcase.intern if @name
214
+ end
215
+
216
+ def dark?
217
+ DARK_COLORS.detect { |d| d == self.name }
218
+ end
219
+
220
+ def <=>(other)
221
+ self.name <=> other.name
222
+ end
223
+
224
+ def +(n)
225
+ raise ArgumentError, 'Only accept a Fixnum' unless n.is_a?(Fixnum)
226
+ pos = COLORNAMES.find_index{|n,_| n==self.name} + n
227
+ self.class.new COLORNAMES.at(pos % COLORNAMES.size)[0]
228
+ end
229
+
230
+ def -(n)
231
+ raise ArgumentError, 'Only accept a Fixnum' unless n.is_a?(Fixnum)
232
+ self + -n
233
+ end
234
+
235
+ def coerce(arg)
236
+ [self, arg]
237
+ end
238
+
239
+ def to_rgb
240
+ name2rgb(self.to_s)
241
+ end
242
+
243
+ def to_hsb
244
+ rgb2hsb(self.to_rgb)
245
+ end
246
+
247
+ def to_hex
248
+ rgb2hex(self.to_rgb)
249
+ end
250
+
251
+ private
252
+ def find_name(name)
253
+ COLORNAMES.map(&:first).detect { |c|
254
+ [c, name].same? { |str| "#{str}".gsub(/[_\s]/,'').downcase }
255
+ } || begin
256
+ raise ArgumentError, "'#{name}' is not in X11 colorset."
257
+ end
258
+ end
259
+ end
260
+ end