ansi256 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 895f492a5984cb96d47fd0ba832e2ef911e6da13e3205a0be1efbb9d67042f05
4
+ data.tar.gz: ea8063500db6e69974b45b37ab0545fe6cdb316f2dba8fcdca507b6e6050d6e9
5
+ SHA512:
6
+ metadata.gz: 1202cbc808123db06151190557d6db5b30115337a295677a58176797a67eae0acf431459b0c9e2caf0a7b3e1c29325f2c89d4d7d175730eaba1a22355872ce08
7
+ data.tar.gz: 5fa74dfb02d803ed6230cf318f27111275e1f54c28b4de7533f39ec0bcbad41906062859a316d8f86eaad86e50f70e8d754574ef66af9b6ea57770f6a651cb40
data/README.md CHANGED
@@ -51,6 +51,16 @@ puts [ s.white, s.white.bold, s.white.bold.on_white ].join ' '
51
51
 
52
52
  ![colorize-me-16](https://github.com/junegunn/ansi256/raw/master/colorize-me-16.png)
53
53
 
54
+ ### RGB color approximated to 256-color ANSI code
55
+
56
+ ```ruby
57
+ puts "RGB Color (RRGGBB)".fg('ff9930').bg('203366')
58
+
59
+ puts "RGB Color (R-G-B-)".fg('f90').bg('036')
60
+
61
+ puts "RGB Color (Monochrome)".fg('ef').bg('3f')
62
+ ```
63
+
54
64
  Nesting
55
65
  -------
56
66
 
@@ -67,8 +77,8 @@ puts say_hello_world.plain.fg(27)
67
77
 
68
78
  ![say-hello-world](https://github.com/junegunn/ansi256/raw/master/say-hello-world.png)
69
79
 
70
- _"Just gimme the code!"_
71
- -----------------------
80
+ Ansi256 methods
81
+ ---------------
72
82
 
73
83
  ```ruby
74
84
  Ansi256.fg(232)
@@ -76,10 +86,29 @@ Ansi256.bg(226)
76
86
  Ansi256.green
77
87
  Ansi256.on_green
78
88
  Ansi256.bold
89
+ Ansi256.dim
90
+ Ansi256.italic
79
91
  Ansi256.underline
80
92
  Ansi256.reset
93
+
94
+ Ansi256.fg(232, 'Hello')
95
+ Ansi256.bg(226, 'World')
96
+ Ansi256.green('Hello World')
81
97
  ```
82
98
 
99
+ Disabling extended String methods
100
+ ---------------------------------
101
+
102
+ ```ruby
103
+ Ansi256.enabled?
104
+ # true
105
+
106
+ # Print colored output only when STDOUT is tty
107
+ Ansi256.enabled = $stdout.tty?
108
+
109
+ "Hello".fg(232)
110
+ # Hello
111
+ ```
83
112
 
84
113
  ansi256 executable
85
114
  ------------------
@@ -87,7 +116,7 @@ ansi256 executable
87
116
  Ansi256 comes with `ansi256` script which can be used as follows
88
117
 
89
118
  ```bash
90
- usage: ansi256 [-u] <[fg][/bg]> [mesage]
119
+ usage: ansi256 [-b] [-d] [-i] [-u] <[fg][/bg]> [message]
91
120
 
92
121
  # Numeric color codes
93
122
  ansi256 232 "Hello world"
@@ -99,6 +128,9 @@ ansi256 yellow "Hello world"
99
128
  ansi256 /blue "Hello world"
100
129
  ansi256 yellow/blue "Hello world"
101
130
 
131
+ # RGB colors (only support 6-letter hex codes)
132
+ ansi256 ff9900/000033 "Hello world"
133
+
102
134
  # Mixed color codes
103
135
  ansi256 yellow/232 "Hello world"
104
136
 
data/ansi256.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler", ">= 2.2.33"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "minitest"
23
24
  end
data/bin/ansi256 CHANGED
@@ -1,36 +1,45 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'rubygems'
3
5
  require 'ansi256'
4
6
 
5
- bold = ARGV.delete '-b'
6
- underline = ARGV.delete '-u'
7
+ attrs = [
8
+ ARGV.delete('-b') && :bold,
9
+ ARGV.delete('-d') && :dim,
10
+ ARGV.delete('-i') && :italic,
11
+ ARGV.delete('-u') && :underline
12
+ ].compact
7
13
 
8
- if ARGV.length < 1
9
- puts 'usage: ansi256 [-b] [-u] <[fg][/bg]> [message]'
14
+ if ARGV.empty?
15
+ puts 'usage: ansi256 [-b] [-d] [-i] [-u] <[fg][/bg]> [message]'
10
16
  exit 1
11
17
  end
12
18
 
13
- fgbg, *msg = ARGV
14
- fg, bg = fgbg.split('/').map { |e|
15
- if !e.to_s.empty?
16
- (e =~ /^\d+$/) ? e.to_i : e.downcase.to_sym
19
+ fgbg, *rest = ARGV
20
+ fg, bg = fgbg.split('/').map do |e|
21
+ next if e.empty?
22
+
23
+ case e
24
+ when /^#?[0-9a-f]{6}$/i then e
25
+ when /^\d+$/ then e.to_i
26
+ else e.downcase.to_sym
17
27
  end
18
- }
28
+ end
19
29
 
20
- def output msg, fg, bg, ul, b
21
- msg = msg.fg(fg) if fg
22
- msg = msg.bg(bg) if bg
23
- msg = msg.underline if ul
24
- msg = msg.bold if b
30
+ output = lambda do |msg|
31
+ msg = msg.fg(fg) if fg
32
+ msg = msg.bg(bg) if bg
33
+ msg = attrs.reduce(msg) { |m, a| m.send(a) }
25
34
  puts msg
26
35
  end
27
36
 
28
- if !msg.empty?
29
- msg.each do |m|
30
- output m, fg, bg, underline, bold
37
+ if !rest.empty?
38
+ rest.each do |m|
39
+ output.call(m)
31
40
  end
32
41
  else
33
- while msg = $stdin.gets
34
- output msg.chomp, fg, bg, underline, bold
42
+ while (msg = $stdin.gets)
43
+ output.call(msg.chomp)
35
44
  end
36
45
  end
data/lib/ansi256/code.rb CHANGED
@@ -2,6 +2,8 @@ module Ansi256
2
2
  CODE = {
3
3
  :reset => 0,
4
4
  :bold => 1,
5
+ :dim => 2,
6
+ :italic => 3,
5
7
  :underline => 4,
6
8
 
7
9
  :black => 30,
data/lib/ansi256/mixin.rb CHANGED
@@ -1,21 +1,74 @@
1
1
  module Ansi256
2
- module Mixin
3
- def fg code
4
- Ansi256.fg(code, self)
5
- end
2
+ class << self
3
+ def enabled= bool
4
+ if bool
5
+ String.class_eval do
6
+ [:fg, :bg, :plain].each do |name|
7
+ undef_method(name) if method_defined?(name)
8
+ end
6
9
 
7
- def bg code
8
- Ansi256.bg(code, self)
9
- end
10
+ def fg code
11
+ Ansi256.fg(code, self)
12
+ end
10
13
 
11
- def plain
12
- Ansi256.plain self
13
- end
14
+ def bg code
15
+ Ansi256.bg(code, self)
16
+ end
17
+
18
+ def plain
19
+ Ansi256.plain self
20
+ end
21
+
22
+ Ansi256::CODE.each do |name, code|
23
+ undef_method(name) if method_defined?(name)
24
+ define_method name do
25
+ Ansi256.send name, self
26
+ end
27
+ end
28
+ end
14
29
 
15
- Ansi256::CODE.each do |name, code|
16
- define_method name do
17
- Ansi256.send name, self
30
+ Ansi256.class_eval do
31
+ class << self
32
+ undef_method(:enabled?) if method_defined?(:enabled?)
33
+ def enabled?
34
+ true
35
+ end
36
+ end
37
+ end
38
+ else
39
+ String.class_eval do
40
+ [:fg, :bg, :plain].each do |name|
41
+ undef_method(name) if method_defined?(name)
42
+ end
43
+
44
+ def fg code
45
+ self
46
+ end
47
+ alias bg fg
48
+
49
+ def plain
50
+ Ansi256.plain self
51
+ end
52
+
53
+ Ansi256::CODE.each do |name, code|
54
+ undef_method(name) if method_defined?(name)
55
+ define_method name do
56
+ self
57
+ end
58
+ end
59
+ end
60
+
61
+ Ansi256.class_eval do
62
+ class << self
63
+ undef_method(:enabled?) if method_defined?(:enabled?)
64
+ def enabled?
65
+ false
66
+ end
67
+ end
68
+ end
18
69
  end
70
+
71
+ bool
19
72
  end
20
73
  end
21
74
  end
@@ -1,3 +1,3 @@
1
1
  module Ansi256
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ansi256.rb CHANGED
@@ -12,6 +12,8 @@ module Ansi256
12
12
  "\e[#{CODE[code]}m"
13
13
  elsif code.is_a?(Fixnum) && (0..255).include?(code)
14
14
  "\e[38;5;#{code}m"
15
+ elsif ansirgb = ansicode_for_rgb(code)
16
+ "\e[38;5;#{ansirgb}m"
15
17
  else
16
18
  raise ArgumentError, "Invalid color code: #{code}"
17
19
  end
@@ -24,6 +26,8 @@ module Ansi256
24
26
  "\e[#{CODE[code] + 10}m"
25
27
  elsif code.is_a?(Fixnum) && (0..255).include?(code)
26
28
  "\e[48;5;#{code}m"
29
+ elsif ansirgb = ansicode_for_rgb(code)
30
+ "\e[48;5;#{ansirgb}m"
27
31
  else
28
32
  raise ArgumentError, "Invalid color code: #{code}"
29
33
  end
@@ -56,6 +60,27 @@ module Ansi256
56
60
  "\e[#{nums.compact.join ';'}m"
57
61
  end
58
62
 
63
+ def ansicode_for_rgb rgb
64
+ return unless rgb.is_a?(String) &&
65
+ rgb =~ /^#?([0-9a-f]+)$/i
66
+ rgb = $1
67
+
68
+ case rgb.length
69
+ when 2
70
+ m = (256 - 231) * rgb.to_i(16) / 256
71
+ return m == 0 ? 16 : (231 + m)
72
+ when 3
73
+ r, g, b = rgb.each_char.map { |e| (e * 2).to_i(16) }
74
+ when 6
75
+ r, g, b = rgb.each_char.each_slice(2).map { |e| e.join.to_i(16) }
76
+ else
77
+ return
78
+ end
79
+
80
+ r, g, b = [r, g, b].map { |e| 6 * e / 256 }
81
+ r * 36 + g * 6 + b + 16
82
+ end
83
+
59
84
  def wrap str, color
60
85
  current = [nil, nil, Set.new]
61
86
 
@@ -108,7 +133,4 @@ module Ansi256
108
133
  end
109
134
  end
110
135
 
111
- class String
112
- include Ansi256::Mixin
113
- end
114
-
136
+ Ansi256.enabled = true
data/test/test_ansi256.rb CHANGED
@@ -67,6 +67,8 @@ class TestAnsi256 < MiniTest::Unit::TestCase
67
67
  def test_just_code
68
68
  assert_equal "\e[0m", Ansi256.reset
69
69
  assert_equal "\e[1m", Ansi256.bold
70
+ assert_equal "\e[2m", Ansi256.dim
71
+ assert_equal "\e[3m", Ansi256.italic
70
72
  assert_equal "\e[4m", Ansi256.underline
71
73
 
72
74
  assert_equal "\e[30m", Ansi256.black
@@ -115,6 +117,8 @@ class TestAnsi256 < MiniTest::Unit::TestCase
115
117
  assert_raises(ArgumentError) { Ansi256.fg(300) }
116
118
  assert_raises(ArgumentError) { Ansi256.bg(-1) }
117
119
  assert_raises(ArgumentError) { Ansi256.bg(300) }
120
+ assert_raises(ArgumentError) { Ansi256.bg('ffaa') }
121
+ assert_raises(ArgumentError) { Ansi256.bg('ffeeffaa') }
118
122
  end
119
123
 
120
124
  def test_fg_bg_underline
@@ -139,4 +143,76 @@ class TestAnsi256 < MiniTest::Unit::TestCase
139
143
  assert_equal "\e[32;48;5;200;1mWow \e[38;5;100;44;1;4mhello\e[0m\e[32;48;5;200;1m world\e[0m",
140
144
  "Wow #{'hello'.fg(100).underline.on_blue} world".green.bold.bg(200)
141
145
  end
146
+
147
+ def test_rgb
148
+ {
149
+ '00' => 16,
150
+ '000000' => 16,
151
+ '111' => 16,
152
+ '11' => 232,
153
+ '101010' => 16,
154
+ '1a' => 233,
155
+ '1a1a1a' => 16,
156
+ '20' => 234,
157
+ '22' => 234,
158
+ '202020' => 16,
159
+ '222222' => 16,
160
+ '222222' => 16,
161
+ 'ff' => 255,
162
+ 'ffffff' => 231,
163
+ 'FFFFFF' => 231,
164
+ 'ff0' => 226,
165
+ 'ffff00' => 226,
166
+ 'ff0000' => 196,
167
+ '00ff00' => 46,
168
+ '0000ff' => 21,
169
+ 'ff9900' => 214,
170
+ '00ffff' => 51,
171
+ '0ff' => 51,
172
+ }.each do |rgb, ansi|
173
+ assert_equal ansi, Ansi256.fg(rgb).scan(/[0-9]+/).last.to_i
174
+ assert_equal ansi, Ansi256.bg(rgb).scan(/[0-9]+/).last.to_i
175
+ end
176
+ [:bg, :fg].each do |m|
177
+ (0..255).each do |r|
178
+ color = r.to_s(16).rjust(2, '0') * 3
179
+ print Ansi256.send(m, color, color + ' ')
180
+ end
181
+ (0..255).each do |r|
182
+ color = r.to_s(16).rjust(2, '0')
183
+ print Ansi256.send(m, color, color + ' ')
184
+ end
185
+ end
186
+ 0.step(255, 20) do |r|
187
+ 0.step(255, 20) do |g|
188
+ 0.step(255, 20) do |b|
189
+ color = [r, g, b].map { |c| c.to_s(16).rjust(2, '0') }.join
190
+ print Ansi256.bg(color, color + ' ')
191
+ end
192
+ end
193
+ end
194
+ puts "RGB Color".fg('ff9900').bg('003366')
195
+ puts "RGB Color".fg('f90').bg('#036')
196
+ puts "RGB Color".fg('#ff9900').bg('#003366')
197
+ puts "RGB Color (Monochrome)".fg('ef').bg('3a')
198
+ end
199
+
200
+ def test_enabled
201
+ 2.times do
202
+ [:fg, :bg].each do |m|
203
+ assert Ansi256.enabled?
204
+ hello = "hello".send(m, 'f90')
205
+ assert_equal 'hello', hello.plain
206
+
207
+ Ansi256.enabled = false
208
+ assert !Ansi256.enabled?
209
+ assert hello.length > "hello".send(m, 'f90').length
210
+ assert_equal 'hello', hello.plain
211
+
212
+ Ansi256.enabled = true
213
+ assert Ansi256.enabled?
214
+ assert_equal hello, "hello".send(m, 'f90')
215
+ end
216
+ end
217
+ end
142
218
  end
metadata CHANGED
@@ -1,46 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansi256
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Junegunn Choi
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-11 00:00:00.000000000 Z
11
+ date: 2021-12-13 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: '1.3'
19
+ version: 2.2.33
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '1.3'
26
+ version: 2.2.33
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
44
53
  - !ruby/object:Gem::Version
45
54
  version: '0'
46
55
  description: Colorize text using 256-color ANSI codes
@@ -51,7 +60,7 @@ executables:
51
60
  extensions: []
52
61
  extra_rdoc_files: []
53
62
  files:
54
- - .gitignore
63
+ - ".gitignore"
55
64
  - Gemfile
56
65
  - LICENSE.txt
57
66
  - README.md
@@ -66,33 +75,25 @@ files:
66
75
  homepage: https://github.com/junegunn/ansi256
67
76
  licenses:
68
77
  - MIT
69
- post_install_message:
78
+ metadata: {}
79
+ post_install_message:
70
80
  rdoc_options: []
71
81
  require_paths:
72
82
  - lib
73
83
  required_ruby_version: !ruby/object:Gem::Requirement
74
- none: false
75
84
  requirements:
76
- - - ! '>='
85
+ - - ">="
77
86
  - !ruby/object:Gem::Version
78
87
  version: '0'
79
- segments:
80
- - 0
81
- hash: -3827977892707263520
82
88
  required_rubygems_version: !ruby/object:Gem::Requirement
83
- none: false
84
89
  requirements:
85
- - - ! '>='
90
+ - - ">="
86
91
  - !ruby/object:Gem::Version
87
92
  version: '0'
88
- segments:
89
- - 0
90
- hash: -3827977892707263520
91
93
  requirements: []
92
- rubyforge_project:
93
- rubygems_version: 1.8.25
94
- signing_key:
95
- specification_version: 3
94
+ rubygems_version: 3.2.3
95
+ signing_key:
96
+ specification_version: 4
96
97
  summary: Colorize text using 256-color ANSI codes
97
98
  test_files:
98
99
  - test/test_ansi256.rb