rainbow 1.1.4 → 1.99.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.
@@ -0,0 +1,16 @@
1
+ module Rainbow
2
+
3
+ class << self; attr_accessor :enabled; end
4
+ @enabled = true
5
+
6
+ TERM_EFFECTS = {
7
+ :reset => 0,
8
+ :bright => 1,
9
+ :italic => 3,
10
+ :underline => 4,
11
+ :blink => 5,
12
+ :inverse => 7,
13
+ :hide => 8,
14
+ }
15
+
16
+ end
@@ -0,0 +1,14 @@
1
+ module Sickill
2
+ module Rainbow
3
+
4
+ def self.enabled=(value)
5
+ STDERR.puts "Rainbow gem notice: Sickill::Rainbow.enabled= is deprecated, use Rainbow.enabled= instead."
6
+ ::Rainbow.enabled = value
7
+ end
8
+
9
+ def self.enabled
10
+ ::Rainbow.enabled
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ require 'rainbow'
2
+
3
+ module Rainbow
4
+ module String
5
+ module InstanceMethods
6
+
7
+ def foreground(*color)
8
+ Rainbow(self).foreground(*color)
9
+ end
10
+
11
+ alias_method :color, :foreground
12
+ alias_method :colour, :foreground
13
+
14
+ def background(*color)
15
+ Rainbow(self).background(*color)
16
+ end
17
+
18
+ def reset
19
+ Rainbow(self).reset
20
+ end
21
+
22
+ def bright
23
+ Rainbow(self).bright
24
+ end
25
+
26
+ def italic
27
+ Rainbow(self).italic
28
+ end
29
+
30
+ def underline
31
+ Rainbow(self).underline
32
+ end
33
+
34
+ def blink
35
+ Rainbow(self).blink
36
+ end
37
+
38
+ def inverse
39
+ Rainbow(self).inverse
40
+ end
41
+
42
+ def hide
43
+ Rainbow(self).hide
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+
50
+ ::String.send(:include, Rainbow::String::InstanceMethods)
@@ -0,0 +1,23 @@
1
+ module Rainbow
2
+ class StringUtils
3
+
4
+ def self.wrap_with_sgr(string, codes)
5
+ return string if codes.empty?
6
+
7
+ seq = "\e[" + codes.join(";") + "m"
8
+ match = string.match(/^(\e\[([\d;]+)m)*/)
9
+
10
+ if match
11
+ seq_pos = match.end(0)
12
+ string = string[0...seq_pos] + seq + string[seq_pos..-1]
13
+ else
14
+ string = seq + string
15
+ end
16
+
17
+ string = string + "\e[0m" unless string =~ /\e\[0m$/
18
+
19
+ string
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Rainbow
2
+ VERSION = "1.99.0".freeze
3
+ end
@@ -0,0 +1,76 @@
1
+ require 'rainbow/core'
2
+ require 'rainbow/string_utils'
3
+ require 'rainbow/color'
4
+
5
+ module Rainbow
6
+
7
+ class Wrapper < ::String
8
+
9
+ # Sets foreground color of this text.
10
+ def foreground(*values)
11
+ wrap_with_sgr(Color.build(:foreground, values).codes)
12
+ end
13
+
14
+ alias_method :color, :foreground
15
+ alias_method :colour, :foreground
16
+
17
+ # Sets background color of this text.
18
+ def background(*values)
19
+ wrap_with_sgr(Color.build(:background, values).codes)
20
+ end
21
+
22
+ # Resets terminal to default colors/backgrounds.
23
+ #
24
+ # It shouldn't be needed to use this method because all methods
25
+ # append terminal reset code to end of string.
26
+ def reset
27
+ wrap_with_sgr(TERM_EFFECTS[:reset])
28
+ end
29
+
30
+ # Turns on bright/bold for this text.
31
+ def bright
32
+ wrap_with_sgr(TERM_EFFECTS[:bright])
33
+ end
34
+
35
+ # Turns on italic style for this text (not well supported by terminal
36
+ # emulators).
37
+ def italic
38
+ wrap_with_sgr(TERM_EFFECTS[:italic])
39
+ end
40
+
41
+ # Turns on underline decoration for this text.
42
+ def underline
43
+ wrap_with_sgr(TERM_EFFECTS[:underline])
44
+ end
45
+
46
+ # Turns on blinking attribute for this text (not well supported by terminal
47
+ # emulators).
48
+ def blink
49
+ wrap_with_sgr(TERM_EFFECTS[:blink])
50
+ end
51
+
52
+ # Inverses current foreground/background colors.
53
+ def inverse
54
+ wrap_with_sgr(TERM_EFFECTS[:inverse])
55
+ end
56
+
57
+ # Hides this text (set its color to the same as background).
58
+ def hide
59
+ wrap_with_sgr(TERM_EFFECTS[:hide])
60
+ end
61
+
62
+ private
63
+
64
+ def wrap_with_sgr(codes) #:nodoc:
65
+ return self unless Rainbow.enabled
66
+
67
+ self.class.new(StringUtils.wrap_with_sgr(self, [*codes]))
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ def Rainbow(string)
75
+ Rainbow::Wrapper.new(string.to_s)
76
+ end
data/rainbow.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rainbow/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rainbow"
8
+ spec.version = Rainbow::VERSION
9
+ spec.authors = ["Marcin Kulik"]
10
+ spec.email = ["m@ku1ik.com"]
11
+ spec.description = %q{Colorize printed text on ANSI terminals}
12
+ spec.summary = %q{Colorize printed text on ANSI terminals}
13
+ spec.homepage = "https://github.com/sickill/rainbow"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency 'mime-types', '< 2.0.0' if RUBY_VERSION < "1.9.0"
25
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+ require 'rainbow'
3
+
4
+ describe 'Rainbow() wrapper' do
5
+
6
+ it 'allows foreground coloring by color number' do
7
+ result = Rainbow('hello').foreground(5)
8
+ expect(result).to eq("\e[35mhello\e[0m")
9
+ end
10
+
11
+ it 'allows foreground coloring by color name' do
12
+ result = Rainbow('hello').foreground(:red)
13
+ expect(result).to eq("\e[31mhello\e[0m")
14
+ end
15
+
16
+ it 'allows foreground coloring by color name (color alias)' do
17
+ result = Rainbow('hello').color(:red)
18
+ expect(result).to eq("\e[31mhello\e[0m")
19
+ end
20
+
21
+ it 'allows foreground coloring by color name (colour alias)' do
22
+ result = Rainbow('hello').colour(:red)
23
+ expect(result).to eq("\e[31mhello\e[0m")
24
+ end
25
+
26
+ it 'allows foreground coloring by color rgb' do
27
+ result = Rainbow('hello').foreground(255, 128, 64)
28
+ expect(result).to eq("\e[38;5;215mhello\e[0m")
29
+ end
30
+
31
+ it 'allows foreground coloring by color rgb (hex string)' do
32
+ result = Rainbow('hello').foreground('ff8040')
33
+ expect(result).to eq("\e[38;5;215mhello\e[0m")
34
+ end
35
+
36
+ it 'allows background coloring by color number' do
37
+ result = Rainbow('hello').background(3)
38
+ expect(result).to eq("\e[43mhello\e[0m")
39
+ end
40
+
41
+ it 'allows background coloring by color name' do
42
+ result = Rainbow('hello').background(:green)
43
+ expect(result).to eq("\e[42mhello\e[0m")
44
+ end
45
+
46
+ it 'allows background coloring by color rgb' do
47
+ result = Rainbow('hello').background(255, 128, 64)
48
+ expect(result).to eq("\e[48;5;215mhello\e[0m")
49
+ end
50
+
51
+ it 'allows background coloring by color rgb (hex string)' do
52
+ result = Rainbow('hello').background('ff8040')
53
+ expect(result).to eq("\e[48;5;215mhello\e[0m")
54
+ end
55
+
56
+ it 'allows making text bright' do
57
+ result = Rainbow('hello').bright
58
+ expect(result).to eq("\e[1mhello\e[0m")
59
+ end
60
+
61
+ it 'allows making text italic' do
62
+ result = Rainbow('hello').italic
63
+ expect(result).to eq("\e[3mhello\e[0m")
64
+ end
65
+
66
+ it 'allows making text underlined' do
67
+ result = Rainbow('hello').underline
68
+ expect(result).to eq("\e[4mhello\e[0m")
69
+ end
70
+
71
+ it 'allows making text blinking' do
72
+ result = Rainbow('hello').blink
73
+ expect(result).to eq("\e[5mhello\e[0m")
74
+ end
75
+
76
+ it 'allows making text inversed' do
77
+ result = Rainbow('hello').inverse
78
+ expect(result).to eq("\e[7mhello\e[0m")
79
+ end
80
+
81
+ it 'allows making text hidden' do
82
+ result = Rainbow('hello').hide
83
+ expect(result).to eq("\e[8mhello\e[0m")
84
+ end
85
+
86
+ it 'allows resetting all the attributes' do
87
+ result = Rainbow('hello').reset
88
+ expect(result).to eq("\e[0mhello\e[0m")
89
+ end
90
+
91
+ it 'allows chaining' do
92
+ result = Rainbow('hello').
93
+ foreground(:red).
94
+ bright.
95
+ italic.
96
+ background('#ff8040').
97
+ underline.
98
+ color(:blue).
99
+ blink.
100
+ inverse.
101
+ hide
102
+
103
+ expect(result).to eq("\e[31m\e[1m\e[3m\e[48;5;215m\e[4m\e[34m\e[5m\e[7m\e[8mhello\e[0m")
104
+ end
105
+
106
+ context "when Rainbow is disabled" do
107
+ before do
108
+ @enabled = Rainbow.enabled
109
+ Rainbow.enabled = false
110
+ end
111
+
112
+ after do
113
+ Rainbow.enabled = @enabled
114
+ end
115
+
116
+ it "allows chaining but doesn't wrap with escape codes" do
117
+ result = Rainbow('hello').
118
+ foreground(:red).
119
+ bright.
120
+ italic.
121
+ background('#ff8040').
122
+ underline.
123
+ color(:blue).
124
+ blink.
125
+ inverse.
126
+ hide
127
+
128
+ expect(result).to eq('hello')
129
+ end
130
+ end
131
+
132
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'rainbow/string'
3
+
4
+ describe 'String mixin' do
5
+
6
+ it 'proxies foreground to Rainbow().foreground' do
7
+ expect('hello'.foreground(:red)).to eq(Rainbow('hello').foreground(:red))
8
+ end
9
+
10
+ it 'proxies color to Rainbow().color' do
11
+ expect('hello'.color(:red)).to eq(Rainbow('hello').color(:red))
12
+ end
13
+
14
+ it 'proxies colour to Rainbow().colour' do
15
+ expect('hello'.colour(:red)).to eq(Rainbow('hello').colour(:red))
16
+ end
17
+
18
+ it 'proxies background to Rainbow().background' do
19
+ expect('hello'.background(:red)).to eq(Rainbow('hello').background(:red))
20
+ end
21
+
22
+ it 'proxies bright to Rainbow().bright' do
23
+ expect('hello'.bright).to eq(Rainbow('hello').bright)
24
+ end
25
+
26
+ it 'proxies italic to Rainbow().italic' do
27
+ expect('hello'.italic).to eq(Rainbow('hello').italic)
28
+ end
29
+
30
+ it 'proxies underline to Rainbow().underline' do
31
+ expect('hello'.underline).to eq(Rainbow('hello').underline)
32
+ end
33
+
34
+ it 'proxies blink to Rainbow().blink' do
35
+ expect('hello'.blink).to eq(Rainbow('hello').blink)
36
+ end
37
+
38
+ it 'proxies inverse to Rainbow().inverse' do
39
+ expect('hello'.inverse).to eq(Rainbow('hello').inverse)
40
+ end
41
+
42
+ it 'proxies hide to Rainbow().hide' do
43
+ expect('hello'.hide).to eq(Rainbow('hello').hide)
44
+ end
45
+
46
+ it 'proxies reset to Rainbow().reset' do
47
+ expect('hello'.reset).to eq(Rainbow('hello').reset)
48
+ end
49
+
50
+ end
@@ -0,0 +1,10 @@
1
+ if ENV["CI"] && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby")
2
+ require 'coveralls'
3
+ Coveralls.wear!
4
+ end
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ Rainbow.enabled = true
9
+ end
10
+ end
@@ -0,0 +1,244 @@
1
+ require 'spec_helper'
2
+ require 'rainbow/color'
3
+
4
+ module Rainbow
5
+ describe Color do
6
+ describe '.build' do
7
+
8
+ subject { described_class.build(ground, values) }
9
+
10
+ let(:ground) { :foreground }
11
+
12
+ context "when single fixnum given" do
13
+ let(:values) { [1] }
14
+
15
+ it { should be_a(Color) }
16
+ end
17
+
18
+ context "when single symbol given" do
19
+ let(:values) { [:red] }
20
+
21
+ it { should be_a(Color) }
22
+ end
23
+
24
+ context "when single string given" do
25
+ let(:values) { ['#dead00'] }
26
+
27
+ it { should be_a(Color) }
28
+ end
29
+
30
+ context "when 2 elements" do
31
+ let(:values) { [1, 2] }
32
+
33
+ it 'raises ArgumentError' do
34
+ expect { subject }.to raise_error(ArgumentError)
35
+ end
36
+ end
37
+
38
+ context "when 3 elements given" do
39
+ let(:values) { [1, 2, 3] }
40
+
41
+ it { should be_a(Color) }
42
+ end
43
+
44
+ context "when 4 elements" do
45
+ let(:values) { [1, 2, 3, 4] }
46
+
47
+ it 'raises ArgumentError' do
48
+ expect { subject }.to raise_error(ArgumentError)
49
+ end
50
+ end
51
+
52
+ end
53
+ end
54
+
55
+ describe Color::Indexed do
56
+ let(:color) { described_class.new(ground, 5) }
57
+
58
+ describe '#codes' do
59
+ subject { color.codes }
60
+
61
+ context "when ground is :foreground" do
62
+ let(:ground) { :foreground }
63
+
64
+ it { should eq([35]) }
65
+ end
66
+
67
+ context "when ground is :background" do
68
+ let(:ground) { :background }
69
+
70
+ it { should eq([45]) }
71
+ end
72
+ end
73
+ end
74
+
75
+ describe Color::Named do
76
+ let(:color) { described_class.new(ground, name) }
77
+
78
+ describe '#codes' do
79
+ subject { color.codes }
80
+
81
+ context "when ground is :foreground" do
82
+ let(:ground) { :foreground }
83
+
84
+ context "and name is :black" do
85
+ let(:name) { :black }
86
+
87
+ it { should eq([30]) }
88
+ end
89
+
90
+ context "and name is :red" do
91
+ let(:name) { :red }
92
+
93
+ it { should eq([31]) }
94
+ end
95
+
96
+ context "and name is :green" do
97
+ let(:name) { :green }
98
+
99
+ it { should eq([32]) }
100
+ end
101
+
102
+ context "and name is :yellow" do
103
+ let(:name) { :yellow }
104
+
105
+ it { should eq([33]) }
106
+ end
107
+
108
+ context "and name is :blue" do
109
+ let(:name) { :blue }
110
+
111
+ it { should eq([34]) }
112
+ end
113
+
114
+ context "and name is :magenta" do
115
+ let(:name) { :magenta }
116
+
117
+ it { should eq([35]) }
118
+ end
119
+
120
+ context "and name is :cyan" do
121
+ let(:name) { :cyan }
122
+
123
+ it { should eq([36]) }
124
+ end
125
+
126
+ context "and name is :white" do
127
+ let(:name) { :white }
128
+
129
+ it { should eq([37]) }
130
+ end
131
+
132
+ context "and name is invalid" do
133
+ let(:name) { :foo }
134
+
135
+ it 'raises ArgumentError' do
136
+ expect { subject }.to raise_error(ArgumentError)
137
+ end
138
+ end
139
+ end
140
+
141
+ context "when ground is :background" do
142
+ let(:ground) { :background }
143
+
144
+ context "and name is :black" do
145
+ let(:name) { :black }
146
+
147
+ it { should eq([40]) }
148
+ end
149
+
150
+ context "and name is :red" do
151
+ let(:name) { :red }
152
+
153
+ it { should eq([41]) }
154
+ end
155
+
156
+ context "and name is :green" do
157
+ let(:name) { :green }
158
+
159
+ it { should eq([42]) }
160
+ end
161
+
162
+ context "and name is :yellow" do
163
+ let(:name) { :yellow }
164
+
165
+ it { should eq([43]) }
166
+ end
167
+
168
+ context "and name is :blue" do
169
+ let(:name) { :blue }
170
+
171
+ it { should eq([44]) }
172
+ end
173
+
174
+ context "and name is :magenta" do
175
+ let(:name) { :magenta }
176
+
177
+ it { should eq([45]) }
178
+ end
179
+
180
+ context "and name is :cyan" do
181
+ let(:name) { :cyan }
182
+
183
+ it { should eq([46]) }
184
+ end
185
+
186
+ context "and name is :white" do
187
+ let(:name) { :white }
188
+
189
+ it { should eq([47]) }
190
+ end
191
+
192
+ context "and name is invalid" do
193
+ let(:name) { :foo }
194
+
195
+ it 'raises ArgumentError' do
196
+ expect { subject }.to raise_error(ArgumentError)
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ describe Color::RGB do
204
+ let(:color) { described_class.new(ground, r, g, b) }
205
+
206
+ describe '#codes' do
207
+ subject { color.codes }
208
+
209
+ let(:ground) { :foreground }
210
+ let(:r) { 0 }
211
+ let(:g) { 128 }
212
+ let(:b) { 255 }
213
+
214
+ context "when ground is :foreground" do
215
+ let(:ground) { :foreground }
216
+
217
+ it { should eq([38, 5, 39]) }
218
+ end
219
+
220
+ context "when ground is :background" do
221
+ let(:ground) { :background }
222
+
223
+ it { should eq([48, 5, 39]) }
224
+ end
225
+
226
+ context "when a component is lower than 0" do
227
+ let(:r) { -1 }
228
+
229
+ it 'raises ArgumentError' do
230
+ expect { subject }.to raise_error(ArgumentError)
231
+ end
232
+ end
233
+
234
+ context "when a component is greater than 255" do
235
+ let(:b) { 256 }
236
+
237
+ it 'raises ArgumentError' do
238
+ expect { subject }.to raise_error(ArgumentError)
239
+ end
240
+ end
241
+
242
+ end
243
+ end
244
+ end