col 1.0.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/LICENCE +19 -0
- data/README +35 -0
- data/lib/col.rb +342 -0
- data/test/_setup.rb +2 -0
- data/test/col.rb +229 -0
- data/test/col_db.rb +14 -0
- metadata +90 -0
data/LICENCE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2005 Gavin Sinclair (gsinclair@gmail.com)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
col: high-level console color formatting for Ruby
|
2
|
+
|
3
|
+
If you want a dash of color in your Ruby console program, use Term::ANSIColor.
|
4
|
+
If your color formatting requirements are more complicated, use Col.
|
5
|
+
Col provides as much convenience as possible without modifying builtin classes.
|
6
|
+
|
7
|
+
Synopsis
|
8
|
+
|
9
|
+
require 'col'
|
10
|
+
|
11
|
+
puts Col("Hello world!").red.bold
|
12
|
+
puts Col("Hello world!").rb
|
13
|
+
puts Col("Hello world!").fmt [:red, :bold]
|
14
|
+
puts Col("Hello world!").fmt :rb
|
15
|
+
|
16
|
+
puts Col("Hello ", "world!").fmt :red, :green
|
17
|
+
puts Col("Hello ", "world!").fmt "r,g"
|
18
|
+
|
19
|
+
puts Col("Hello ", "world!").fmt [:red, :bold], [:green, :bold]
|
20
|
+
puts Col("Hello ", "world!").fmt "rb,gb"
|
21
|
+
|
22
|
+
puts Col("Hello ", "world!").fmt [:bold], [:cyan, :italic, :on_white]
|
23
|
+
puts Col("Hello ", "world!").fmt "_b,ciow"
|
24
|
+
|
25
|
+
puts Col("Hello ", "world!").fmt [:blue, :on_yellow], [:on_green]
|
26
|
+
puts Col("Hello ", "world!").fmt "b_oy,__og"
|
27
|
+
|
28
|
+
puts Col.inline( "Hello ", :red, "world!", :blue )
|
29
|
+
|
30
|
+
puts Col.inline(
|
31
|
+
"Hello ", [:red, :bold, :on_white],
|
32
|
+
"world!", :b_oy
|
33
|
+
)
|
34
|
+
|
35
|
+
See http://gsinclair.github.com/col.html for full details.
|
data/lib/col.rb
ADDED
@@ -0,0 +1,342 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'term/ansicolor'
|
3
|
+
|
4
|
+
# --------------------------------------------------------------------------- #
|
5
|
+
|
6
|
+
class Col
|
7
|
+
# args: array of strings (to_s is called on each)
|
8
|
+
def initialize(*args)
|
9
|
+
@strings = args.map { |a| a.to_s }
|
10
|
+
end
|
11
|
+
|
12
|
+
def Col.[](*args)
|
13
|
+
Col.new(*args)
|
14
|
+
end
|
15
|
+
|
16
|
+
COLORED_REGEXP = /\e\[ # opening character sequence
|
17
|
+
(?: [34][0-7] | [0-9] ) ? # optional code
|
18
|
+
( ; (?: [34][0-7] | [0-9] ))* # more optional codes
|
19
|
+
m # closing character
|
20
|
+
/x
|
21
|
+
|
22
|
+
# Convenience method to remove color codes from a string.
|
23
|
+
# Also available as Col.plain.
|
24
|
+
def Col.uncolored(string)
|
25
|
+
string.gsub(COLORED_REGEXP, '')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Convenience method to remove color codes from a string.
|
29
|
+
# Also available as Col.uncolored.
|
30
|
+
def Col.plain(string)
|
31
|
+
string.gsub(COLORED_REGEXP, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
def Col.inline(*args)
|
35
|
+
unless args.size.even?
|
36
|
+
raise Col::Error, "Col.inline requires an even number of arguments"
|
37
|
+
end
|
38
|
+
String.new.tap { |result|
|
39
|
+
args.each_slice(2) do |string, format|
|
40
|
+
result << Col(string.to_s).fmt(format)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
# e.g.
|
46
|
+
# Col("one", "two", "three", "four").fmt "rb,y,cb,_b"
|
47
|
+
# # same as:
|
48
|
+
# "one".red.bold + "two".yellow + "three".cyan.bold + "four".bold
|
49
|
+
#
|
50
|
+
# Col
|
51
|
+
def fmt(*spec)
|
52
|
+
::Col::Formatter.new(@strings, *spec).result
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
@strings.join
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(message, *args, &block)
|
60
|
+
unless args.empty?
|
61
|
+
super # We're not interested in a message with arguments; NoMethodError
|
62
|
+
end
|
63
|
+
if Col::DB.method?(message)
|
64
|
+
Col.new( self.fmt(message) ) # Col["..."].yellow -> Col
|
65
|
+
# to allow Col["..."].yellow.bold
|
66
|
+
else
|
67
|
+
self.fmt(message) # Col["..."].gbow -> String
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def Col(*args)
|
73
|
+
Col.new(*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
# --------------------------------------------------------------------------- #
|
77
|
+
|
78
|
+
class Col::Error < StandardError
|
79
|
+
end
|
80
|
+
|
81
|
+
# --------------------------------------------------------------------------- #
|
82
|
+
|
83
|
+
class Col::Formatter
|
84
|
+
def initialize(strings, *spec)
|
85
|
+
check_correct_number_of_arguments(strings, *spec)
|
86
|
+
@strings = strings
|
87
|
+
@format_spec = normalise_format_spec(*spec)
|
88
|
+
end
|
89
|
+
|
90
|
+
def result
|
91
|
+
unless @strings.size == @format_spec.size
|
92
|
+
raise Col::Error, "mismatching strings and specs"
|
93
|
+
end
|
94
|
+
String.new.tap { |str|
|
95
|
+
@strings.zip(@format_spec).each do |string, spec|
|
96
|
+
d = decorated_string(string, spec)
|
97
|
+
str << d
|
98
|
+
end
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
# e.g.
|
103
|
+
# string = "hello"
|
104
|
+
# spec = [:yellow, :bold, :on_red]
|
105
|
+
# result = "hello".send(:yellow).send(:bold).send(:on_red)
|
106
|
+
def decorated_string(string, spec)
|
107
|
+
raise Col::Error unless string.is_a? String and spec.is_a? Array \
|
108
|
+
and spec.all? { |e| e.is_a? Symbol }
|
109
|
+
spec.inject(string) { |str, symbol| Term::ANSIColor.send(symbol, str) }
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# In general, there should be the same number of arguments as there are
|
114
|
+
# strings:
|
115
|
+
#
|
116
|
+
# Col["one"].fmt( :b )
|
117
|
+
# Col["one", "two"].fmt( [:red, :on_white], [:bold, :negative] )
|
118
|
+
# Col["one", "two", "three"].fmt( :yellow, [:green, :bold], :italic )
|
119
|
+
# Col["one", "two", "three", "four"].fmt(:rb, :y, :cb, :m)
|
120
|
+
# Col["one", "two", "three", "four"].fmt "rb,y,cb,m"
|
121
|
+
#
|
122
|
+
# As a special case, if there is only one string, it can have any number of
|
123
|
+
# arguments:
|
124
|
+
#
|
125
|
+
# Col["string"].fmt( :yellow, :bold, :italic, :blink, :negative, :on_magenta )
|
126
|
+
#
|
127
|
+
# If the number of arguments is incorrect, a Col::Error is thrown.
|
128
|
+
#
|
129
|
+
def check_correct_number_of_arguments(strings, *spec)
|
130
|
+
nargs = spec.size
|
131
|
+
if nargs == 1 and spec.first.is_a? String
|
132
|
+
nargs = spec.first.split(/,/).size
|
133
|
+
end
|
134
|
+
if strings.size > 1 and nargs != strings.size
|
135
|
+
raise Col::Error, "incorrect number of arguments: #{render(spec)}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Each spec in the following groups is equivalent. The last one is
|
141
|
+
# normalised.
|
142
|
+
#
|
143
|
+
# [ :rb ]
|
144
|
+
# [ "rb" ]
|
145
|
+
# [ [:red, :bold] ]
|
146
|
+
#
|
147
|
+
# [ :rb, :_n, :y ]
|
148
|
+
# [ "rb", "_n", "y" ]
|
149
|
+
# [ [:red, :bold], [:negative], [:yellow] ]
|
150
|
+
#
|
151
|
+
# [ [:green, :concealed], :blue, :bold ]
|
152
|
+
# [ [:green, :concealed], [:blue], [:bold] ]
|
153
|
+
#
|
154
|
+
# [ "rb,y,_i,g_ow" ]
|
155
|
+
# [ "rb", "y", "_i", "g_ow" ]
|
156
|
+
# [ [:red, :bold], [:yellow], [:italic], [:green, :on_white] ]
|
157
|
+
#
|
158
|
+
# {spec} is definitely an array because it was gathered like this:
|
159
|
+
# def fmt(*spec)
|
160
|
+
#
|
161
|
+
# "Normalised" means an array with one element for each string.
|
162
|
+
# Each element is itself an array of all the properties that apply to that
|
163
|
+
# string.
|
164
|
+
#
|
165
|
+
def normalise_format_spec(*spec)
|
166
|
+
if spec.size == 1 and spec.first.is_a? String and spec.first.index(',')
|
167
|
+
# ^^^ "rb,y,_n"
|
168
|
+
spec = spec.first.split(',') # ['rb', 'y', '_n']
|
169
|
+
normalise_format_spec(*spec)
|
170
|
+
else
|
171
|
+
# We have an array of items. We need to treat each item individually and
|
172
|
+
# put the items together. We remove nil elements.
|
173
|
+
spec.map { |item| normalise_item(item) }.compact
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Examples
|
178
|
+
# Item Normalised item
|
179
|
+
# :r [:red]
|
180
|
+
# "r" [:red]
|
181
|
+
# :red [:red]
|
182
|
+
# [:red] [:red]
|
183
|
+
# "rb" [:red, :bold]
|
184
|
+
# :rb [:red, :bold]
|
185
|
+
# [:red, :bold] [:red, :bold]
|
186
|
+
# :b [:blue]
|
187
|
+
# :_b [:bold]
|
188
|
+
# :__b error
|
189
|
+
# :__ob [:on_blue]
|
190
|
+
# "gsow" [:green, :strikethrough, :on_white]
|
191
|
+
# "_noB" [:negative, :on_black]
|
192
|
+
# :_ []
|
193
|
+
# [:_] []
|
194
|
+
# [:_, :_] []
|
195
|
+
# (etc.)
|
196
|
+
def normalise_item(item)
|
197
|
+
case item
|
198
|
+
when Symbol then normalise_string(item.to_s)
|
199
|
+
when Array then normalise_array(item)
|
200
|
+
when String then normalise_string(item)
|
201
|
+
else raise Col::Error, "Invalid item type: #{item.class}"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Input: array of symbols
|
206
|
+
# Result: array of symbols, each of which is a legitimate ANSIColor method
|
207
|
+
# Note: underscores and nil items are removed from the array
|
208
|
+
def normalise_array(array)
|
209
|
+
array.reject! { |x| x.nil? or x == :_ or x == '_' }
|
210
|
+
invalid_items = array.select { |item| not Col::DB.method? item }
|
211
|
+
case invalid_items.size
|
212
|
+
when 0 then return array
|
213
|
+
when 1 then raise Col::Error, "Invalid item: #{invalid_items.first.inspect}"
|
214
|
+
else raise Col::Error, "Invalid items: #{invalid_items.inspect}"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Examples
|
219
|
+
# Input Output
|
220
|
+
# r [:red]
|
221
|
+
# b [:blue]
|
222
|
+
# rb [:red, :bold]
|
223
|
+
# red [:red]
|
224
|
+
# bold [:bold]
|
225
|
+
# gsow [:green, :strikethrough, :on_white]
|
226
|
+
# _b [:bold]
|
227
|
+
# __ob [:on_blue]
|
228
|
+
# _ []
|
229
|
+
def normalise_string(string)
|
230
|
+
# Is it already one of the methods? If so, easy. If not, split and parse.
|
231
|
+
if string == "_"
|
232
|
+
[]
|
233
|
+
elsif Col::DB.method? string
|
234
|
+
[ string.intern ]
|
235
|
+
elsif (1..4).include? string.size # say: "g", "gb", "gbow"
|
236
|
+
color, style, backg = extract(string)
|
237
|
+
color = Col::DB.color(color) # 'g' -> :green
|
238
|
+
style = Col::DB.style(style) # 'b' -> :bold
|
239
|
+
backg = Col::DB.background(backg) # 'ow' -> :on_white
|
240
|
+
[ color, style, backg ].compact # remove nil elements
|
241
|
+
else
|
242
|
+
raise Col::Error, "Invalid item: #{string.inspect}"
|
243
|
+
end
|
244
|
+
rescue Col::Error => e
|
245
|
+
raise Col::Error, "Invalid item: #{string.inspect} (#{e.message})"
|
246
|
+
end
|
247
|
+
|
248
|
+
# Extracts color, style and background color.
|
249
|
+
# "gbow" -> ["g", "b", "ow"]
|
250
|
+
# "g" -> ["g", nil, nil]
|
251
|
+
# "_b" -> [nil, "b", nil]
|
252
|
+
def extract(string)
|
253
|
+
string += " "
|
254
|
+
color, style, backg = /^(.)(.)(..)/.match(string).captures
|
255
|
+
color = nil if [' ', '_'].include? color
|
256
|
+
style = nil if [' ', '_'].include? style
|
257
|
+
backg = nil if [' ', '__'].include? backg
|
258
|
+
[color, style, backg]
|
259
|
+
end
|
260
|
+
|
261
|
+
def render(spec)
|
262
|
+
( (spec.size == 1) ? spec.first : spec ).inspect
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# --------------------------------------------------------------------------- #
|
267
|
+
|
268
|
+
class Col::DB
|
269
|
+
COLORS = {
|
270
|
+
'B' => :black,
|
271
|
+
'r' => :red,
|
272
|
+
'g' => :green,
|
273
|
+
'y' => :yellow,
|
274
|
+
'b' => :blue,
|
275
|
+
'm' => :magenta,
|
276
|
+
'c' => :cyan,
|
277
|
+
'w' => :white
|
278
|
+
}
|
279
|
+
|
280
|
+
STYLES = {
|
281
|
+
'b' => :bold,
|
282
|
+
'd' => :dark,
|
283
|
+
'i' => :italic,
|
284
|
+
'u' => :underline,
|
285
|
+
'U' => :underscore,
|
286
|
+
'k' => :blink,
|
287
|
+
'r' => :rapid_blink,
|
288
|
+
'n' => :negative,
|
289
|
+
'c' => :concealed,
|
290
|
+
's' => :strikethrough,
|
291
|
+
}
|
292
|
+
|
293
|
+
BACKGROUND = {
|
294
|
+
'oB' => :on_black,
|
295
|
+
'or' => :on_red,
|
296
|
+
'og' => :on_green,
|
297
|
+
'oy' => :on_yellow,
|
298
|
+
'ob' => :on_blue,
|
299
|
+
'om' => :on_magenta,
|
300
|
+
'oc' => :on_cyan,
|
301
|
+
'ow' => :on_white
|
302
|
+
}
|
303
|
+
|
304
|
+
ALL_METHODS_SYMBOL = COLORS.values + STYLES.values + BACKGROUND.values
|
305
|
+
ALL_METHODS_STRING = ALL_METHODS_SYMBOL.map { |x| x.to_s }
|
306
|
+
require 'set'
|
307
|
+
ALL_METHODS = Set[*ALL_METHODS_SYMBOL] + Set[*ALL_METHODS_STRING]
|
308
|
+
|
309
|
+
def self.method?(x)
|
310
|
+
ALL_METHODS.include? x
|
311
|
+
end
|
312
|
+
|
313
|
+
def self.color(key)
|
314
|
+
get_value COLORS, key, "color"
|
315
|
+
end
|
316
|
+
|
317
|
+
def self.style(key)
|
318
|
+
get_value STYLES, key, "style"
|
319
|
+
end
|
320
|
+
|
321
|
+
def self.background(key)
|
322
|
+
get_value BACKGROUND, key, "background color"
|
323
|
+
end
|
324
|
+
|
325
|
+
# If the 'key' is nil, we return nil. Otherwise, we insist that the key be a
|
326
|
+
# valid color, style or background color. If it's not, we raise an error
|
327
|
+
# (that's what 'name' is for).
|
328
|
+
#
|
329
|
+
# Return the method name sought: :green, :bold, :on_white, etc.
|
330
|
+
def self.get_value(hash, key, name)
|
331
|
+
if key.nil?
|
332
|
+
nil
|
333
|
+
else
|
334
|
+
method = hash[key.to_s]
|
335
|
+
if method.nil?
|
336
|
+
raise Col::Error, "Invalid #{name} code: #{key}"
|
337
|
+
end
|
338
|
+
method
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
end # Col::DB
|
data/test/_setup.rb
ADDED
data/test/col.rb
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
|
2
|
+
# This enhancement to String is needed for testing this file.
|
3
|
+
class String
|
4
|
+
require 'term/ansicolor'
|
5
|
+
include Term::ANSIColor
|
6
|
+
end
|
7
|
+
|
8
|
+
D "Simple formatting (single string)" do
|
9
|
+
D "yellow" do
|
10
|
+
Eq Col["string"].y.to_s, "string".yellow
|
11
|
+
Eq Col["string"].fmt("y"), "string".yellow
|
12
|
+
Eq Col["string"].fmt(:y), "string".yellow
|
13
|
+
end
|
14
|
+
D "red" do
|
15
|
+
Eq Col["string"].r.to_s, "string".red
|
16
|
+
Eq Col["string"].fmt(:r), "string".red
|
17
|
+
Eq Col["string"].fmt("r"), "string".red
|
18
|
+
end
|
19
|
+
D "red bold" do
|
20
|
+
Eq Col["string"].rb.to_s, "string".red.bold
|
21
|
+
Eq Col["string"].fmt(:rb), "string".red.bold
|
22
|
+
Eq (Col["string"].fmt [:red, :bold]), "string".red.bold
|
23
|
+
end
|
24
|
+
D "bold" do
|
25
|
+
Eq Col["string"]._b.to_s, "string".bold
|
26
|
+
Eq Col["string"].fmt(:_b), "string".bold
|
27
|
+
end
|
28
|
+
D "black" do
|
29
|
+
Eq Col["string"].B.to_s, "string".black
|
30
|
+
Eq Col["string"].fmt(:B), "string".black
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
D "General formatting (multiple strings)" do
|
35
|
+
D "example 1" do
|
36
|
+
str1 = Col("one", "two", "three", "four").fmt(:rb, :y, :cb, :m)
|
37
|
+
str2 = Col("one", "two", "three", "four").fmt "rb,y,cb,m"
|
38
|
+
expected = "one".red.bold + "two".yellow + "three".cyan.bold + "four".magenta
|
39
|
+
Eq str1, expected
|
40
|
+
Eq str2, expected
|
41
|
+
end
|
42
|
+
D "example 2" do
|
43
|
+
str1 = Col("one", "two", "three").fmt(:Bb, :_b, :w_) # the _ in w_ is optional
|
44
|
+
str2 = Col("one", "two", "three").fmt "Bb,_b,w_"
|
45
|
+
expected = "one".black.bold + "two".bold + "three".white
|
46
|
+
Eq str1, expected
|
47
|
+
Eq str2, expected
|
48
|
+
end
|
49
|
+
D "example 3" do
|
50
|
+
str1 = Col["one","two"].fmt "y,r"
|
51
|
+
expected = "one".yellow + "two".red
|
52
|
+
Eq str1, expected
|
53
|
+
end
|
54
|
+
D "including strings where no formatting is done" do
|
55
|
+
name, age = "Peter", 14
|
56
|
+
str1 = Col["Name: ", name, " Age: ", age].fmt(:_, :rb, :_, :gb)
|
57
|
+
str2 = Col["Name: ", name, " Age: ", age].fmt "_,rb,_,gb"
|
58
|
+
expected = "Name: " + name.red.bold + " Age: " + age.to_s.green.bold
|
59
|
+
Eq str1, expected
|
60
|
+
Eq str2, expected
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
D "More complex formatting (on_red, strikethrough, italic, dark, negative, ...)" do
|
65
|
+
D "all styles (part 1)" do
|
66
|
+
str1 = Col["one","two","three","four","five"].fmt(:_b, :_d, :_i, :_u, :_U)
|
67
|
+
str2 = Col["one","two","three","four","five"].fmt "_b,_d,_i,_u,_U"
|
68
|
+
expected = "one".bold + "two".dark + "three".italic + "four".underline \
|
69
|
+
+ "five".underscore
|
70
|
+
Eq str1, expected
|
71
|
+
Eq str2, expected
|
72
|
+
end
|
73
|
+
D "all styles (part 2)" do
|
74
|
+
str1 = Col["one","two","three","four","five"].fmt(:_k, :_r, :_n, :_c, :_s)
|
75
|
+
str2 = Col["one","two","three","four","five"].fmt "_k,_r,_n,_c,_s"
|
76
|
+
expected = "one".blink + "two".rapid_blink + "three".negative \
|
77
|
+
+ "four".concealed + "five".strikethrough
|
78
|
+
Eq str1, expected
|
79
|
+
Eq str2, expected
|
80
|
+
end
|
81
|
+
D "all backgrounds (part 1)" do
|
82
|
+
str1 = Col["one","two","three","four"].fmt(:__oB, :__or, :__og, :__oy)
|
83
|
+
str2 = Col["one","two","three","four"].fmt "__oB,__or,__og,__oy"
|
84
|
+
expected = "one".on_black + "two".on_red + "three".on_green + "four".on_yellow
|
85
|
+
Eq str1, expected
|
86
|
+
Eq str2, expected
|
87
|
+
end
|
88
|
+
D "all backgrounds (part 2)" do
|
89
|
+
str1 = Col["one","two","three","four"].fmt(:__ob, :__om, :__oc, :__ow)
|
90
|
+
str2 = Col["one","two","three","four"].fmt "__ob,__om,__oc,__ow"
|
91
|
+
expected = "one".on_blue + "two".on_magenta + "three".on_cyan + "four".on_white
|
92
|
+
Eq str1, expected
|
93
|
+
Eq str2, expected
|
94
|
+
end
|
95
|
+
D "mixed 1" do
|
96
|
+
str1 = Col["one","two","three","four"].fmt(:r_ow, :bnoy, :_d, :gs)
|
97
|
+
str2 = Col["one","two","three","four"].fmt "r_ow,bnoy,_d,gs"
|
98
|
+
expected = "one".red.on_white + "two".blue.negative.on_yellow \
|
99
|
+
+ "three".dark + "four".green.strikethrough
|
100
|
+
Eq str1, expected
|
101
|
+
Eq str2, expected
|
102
|
+
end
|
103
|
+
D "mixed 2" do
|
104
|
+
str1 = Col["one","two","three","four"].fmt(:cUob, :wkoB, :m_or, :yc)
|
105
|
+
str2 = Col["one","two","three","four"].fmt "cUob,wkoB,m_or,yc"
|
106
|
+
expected = "one".cyan.underscore.on_blue + "two".white.blink.on_black \
|
107
|
+
+ "three".magenta.on_red + "four".yellow.concealed
|
108
|
+
Eq str1, expected
|
109
|
+
Eq str2, expected
|
110
|
+
end
|
111
|
+
end # "More complex formatting..."
|
112
|
+
|
113
|
+
D ":_ (do-nothing) format specifiers" do
|
114
|
+
Eq Col["..."].fmt(:_), "..."
|
115
|
+
Eq Col["..."].fmt('_'), "..."
|
116
|
+
Eq Col["abc","123"].fmt(:_, :_), "abc123"
|
117
|
+
Eq Col["abc","123"].fmt('_,_'), "abc123"
|
118
|
+
D "totally empty arguments" do
|
119
|
+
Eq Col[].fmt(), ""
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
D "Esoteric options" do
|
124
|
+
D "italic,strikethrough,blink" do
|
125
|
+
D "separate" do
|
126
|
+
str1 = Col["one","two","three"].fmt(:italic, :strikethrough, :blink)
|
127
|
+
expected = "one".italic + "two".strikethrough + "three".blink
|
128
|
+
Eq str1, expected
|
129
|
+
end
|
130
|
+
D "combined" do
|
131
|
+
# one string, several symbols
|
132
|
+
str1 = Col["string"].fmt([:italic, :strikethrough, :blink])
|
133
|
+
expected = "string".italic.strikethrough.blink
|
134
|
+
Eq str1, expected
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
D "Verbose specification" do
|
140
|
+
D "example 1" do
|
141
|
+
str1 = Col["one","two"].fmt( [:bold, :yellow, :on_red], [:cyan, :dark] )
|
142
|
+
expected = "one".bold.yellow.on_red + "two".cyan.dark
|
143
|
+
Eq str1, expected
|
144
|
+
end
|
145
|
+
D "example 2" do
|
146
|
+
str1 = Col["one","two"].fmt([:negative, :dark], [:underscore, :rapid_blink])
|
147
|
+
expected = "one".negative.dark + "two".underscore.rapid_blink
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
D "Col.inline" do
|
152
|
+
D "with correct # arguments" do
|
153
|
+
str1 = Col.inline(
|
154
|
+
"foo", :blue,
|
155
|
+
"bar", :rb,
|
156
|
+
12345, [:white, :negative],
|
157
|
+
"qux", :_
|
158
|
+
)
|
159
|
+
expected = "foo".blue + "bar".red.bold + "12345".white.negative + "qux"
|
160
|
+
Eq str1, expected
|
161
|
+
end
|
162
|
+
D "with incorrect # arguments" do
|
163
|
+
E(Col::Error) do
|
164
|
+
Col.inline( "foo", :blue, "bar", :red, "quux" )
|
165
|
+
end
|
166
|
+
Mt Attest.exception.message, /even/i
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
D "Col.uncolored(string)" do
|
171
|
+
str = Col["foo"].yellow.bold.on_red.to_s
|
172
|
+
Eq Col.uncolored(str), "foo"
|
173
|
+
Eq Col.plain(str), "foo"
|
174
|
+
str = Col["foo","bar"].fmt('rboc,_i')
|
175
|
+
Eq Col.uncolored(str), "foobar"
|
176
|
+
Eq Col.plain(str), "foobar"
|
177
|
+
str = "\e[1;4;37;41mfoo\e[0m"
|
178
|
+
Eq Col.uncolored(str), "foo"
|
179
|
+
Eq Col.plain(str), "foo"
|
180
|
+
str = "foo"
|
181
|
+
Eq Col.uncolored(str), "foo"
|
182
|
+
Eq Col.plain(str), "foo"
|
183
|
+
end
|
184
|
+
|
185
|
+
D "Object properties" do
|
186
|
+
D "Col[...].green.on_white is still a Col object" do
|
187
|
+
c = Col["..."].green
|
188
|
+
Ko c, Col
|
189
|
+
c = Col["..."].green.on_white
|
190
|
+
Ko c, Col
|
191
|
+
end
|
192
|
+
D "other methods, like Col[...].rb, produce a String object" do
|
193
|
+
str = Col["foo"].yb
|
194
|
+
Ko str, String
|
195
|
+
str = Col["foo"].fmt [:yellow, :italic, :strikethrough, :on_green]
|
196
|
+
Ko str, String
|
197
|
+
str = Col["one","two"].fmt :g_ow, :yb
|
198
|
+
Ko str, String
|
199
|
+
end
|
200
|
+
D "a Col object is printable (implements to_s)" do
|
201
|
+
c = Col["one","two","three"]
|
202
|
+
Eq c.to_s, "onetwothree"
|
203
|
+
c = Col["..."].green.on_white
|
204
|
+
Eq c.to_s, "...".green.on_white
|
205
|
+
end
|
206
|
+
D "the string returned after formatting has nothing mixed in" do
|
207
|
+
# Whilesoever Term::ANSIColor is mixed in to String, as it is at the top of
|
208
|
+
# this file, I can't think of a way to test this property :(
|
209
|
+
# I could change all the "foo".red.bold to bold(foo("red")) but that's a
|
210
|
+
# _lot_ of work and will make this file quite ugly.
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
D "Erroneous specifications" do
|
215
|
+
D "incorrect number of arguments" do
|
216
|
+
E(Col::Error) { Col["one","two"].fmt :b }
|
217
|
+
Mt Attest.exception.message, /incorrect number of arguments/i
|
218
|
+
E(Col::Error) { Col["one","two"].fmt(:b, :r, :g) }
|
219
|
+
Mt Attest.exception.message, /incorrect number of arguments/i
|
220
|
+
E(Col::Error) { Col["one","two"].fmt(:b, :r, :g, :cbow) }
|
221
|
+
Mt Attest.exception.message, /incorrect number of arguments/i
|
222
|
+
end
|
223
|
+
|
224
|
+
D "invalid code" do
|
225
|
+
E(Col::Error) { Col["one","two"].fmt(:T, :r) }
|
226
|
+
E(Col::Error) { Col["one","two"].fmt "T,r" }
|
227
|
+
Mt Attest.exception.message, /invalid color code/i
|
228
|
+
end
|
229
|
+
end
|
data/test/col_db.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
D "Col::DB" do
|
2
|
+
D "method?" do
|
3
|
+
D "given symbol" do
|
4
|
+
T Col::DB.method? :yellow
|
5
|
+
T Col::DB.method? :blink
|
6
|
+
T Col::DB.method? :on_cyan
|
7
|
+
end
|
8
|
+
D "given string" do
|
9
|
+
T Col::DB.method? "yellow"
|
10
|
+
T Col::DB.method? "blink"
|
11
|
+
T Col::DB.method? "on_cyan"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: col
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Gavin Sinclair
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-25 00:00:00 +10:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: term-ansicolor
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
version: "1.0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: " Console color formatting library with abbreviations (e.g. 'rb' for\n red and bold), and the ability to format several strings easily.\n"
|
37
|
+
email: gsinclair@gmail.com
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- lib/col.rb
|
46
|
+
- LICENCE
|
47
|
+
- README
|
48
|
+
- test/col.rb
|
49
|
+
- test/col_db.rb
|
50
|
+
- test/_setup.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://gsinclair.github.com/col.html
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 59
|
66
|
+
segments:
|
67
|
+
- 1
|
68
|
+
- 8
|
69
|
+
- 6
|
70
|
+
version: 1.8.6
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.7
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: high-level console color formatting
|
87
|
+
test_files:
|
88
|
+
- test/col.rb
|
89
|
+
- test/col_db.rb
|
90
|
+
- test/_setup.rb
|