ansi256 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
- # Ansi256
1
+ # ansi256
2
2
 
3
- Decorate text with 256-color ANSI codes.
3
+ ansi256 is a rubygem for colorizing text with 256-color ANSI codes.
4
+
5
+ Features:
6
+
7
+ - Supports both named color codes and numeric 256-color codes
8
+ - Allows nesting of colored text
9
+ - Generates optimal(shortest) code sequence
4
10
 
5
11
  ## Installation
6
12
 
@@ -9,6 +15,8 @@ Decorate text with 256-color ANSI codes.
9
15
  Basic usage
10
16
  -----------
11
17
 
18
+ ### 256-colors
19
+
12
20
  ```ruby
13
21
  require 'ansi256'
14
22
 
@@ -27,26 +35,22 @@ puts "Colorize me".fg(111).bg(226).underline.plain
27
35
 
28
36
  ![colorize-me](https://github.com/junegunn/ansi256/raw/master/colorize-me.png)
29
37
 
30
- Added methods (`fg`, `bg`, `underline`, and `plain`)
31
- return new String object and do not modify the original String.
32
-
33
- 256-color table
34
- ---------------
38
+ ### 16 named colors
35
39
 
36
40
  ```ruby
37
- require 'ansi256'
38
-
39
- def cfmt col
40
- col.to_s.rjust(5).fg(232).bg(col)
41
- end
42
-
43
- puts (0..7).map { |col| cfmt col }.join
44
- puts (8..15).map { |col| cfmt col }.join
45
- (16..255).each_slice(6) do |slice|
46
- puts slice.map { |col| cfmt col }.join
47
- end
41
+ s = "Colorize me"
42
+ puts [ s.black, s.black.bold, s.white.bold.on_black ].join ' '
43
+ puts [ s.red, s.red.bold, s.white.bold.on_red ].join ' '
44
+ puts [ s.green, s.green.bold, s.white.bold.on_green ].join ' '
45
+ puts [ s.yellow, s.yellow.bold, s.white.bold.on_yellow ].join ' '
46
+ puts [ s.blue, s.blue.bold, s.white.bold.on_blue ].join ' '
47
+ puts [ s.magenta, s.magenta.bold, s.white.bold.on_magenta ].join ' '
48
+ puts [ s.cyan, s.cyan.bold, s.white.bold.on_cyan ].join ' '
49
+ puts [ s.white, s.white.bold, s.white.bold.on_white ].join ' '
48
50
  ```
49
51
 
52
+ ![colorize-me-16](https://github.com/junegunn/ansi256/raw/master/colorize-me-16.png)
53
+
50
54
  Nesting
51
55
  -------
52
56
 
@@ -63,12 +67,15 @@ puts say_hello_world.plain.fg(27)
63
67
 
64
68
  ![say-hello-world](https://github.com/junegunn/ansi256/raw/master/say-hello-world.png)
65
69
 
66
- _"Just gimme the code"_
70
+ _"Just gimme the code!"_
67
71
  -----------------------
68
72
 
69
73
  ```ruby
70
74
  Ansi256.fg(232)
71
75
  Ansi256.bg(226)
76
+ Ansi256.green
77
+ Ansi256.on_green
78
+ Ansi256.bold
72
79
  Ansi256.underline
73
80
  Ansi256.reset
74
81
  ```
@@ -77,7 +84,7 @@ Ansi256.reset
77
84
  ansi256 executable
78
85
  ------------------
79
86
 
80
- Ansi256 comes with ansi256 script which can be used as follows
87
+ Ansi256 comes with `ansi256` script which can be used as follows
81
88
 
82
89
  ```bash
83
90
  > ansi256
@@ -90,7 +97,31 @@ usage: ansi256 [-u] <[fg][/bg]> [mesage]
90
97
  > ansi256 30 "Say '$(ansi256 230/75 "Hello $(ansi256 -u 232/226 World)")'"
91
98
  ```
92
99
 
93
- ## Contributing
100
+ Color chart
101
+ -----------
102
+
103
+ ### 256-color table
104
+
105
+ ```ruby
106
+ require 'ansi256'
107
+
108
+ def cfmt col
109
+ col.to_s.rjust(5).fg(232).bg(col)
110
+ end
111
+
112
+ puts (0..7).map { |col| cfmt col }.join
113
+ puts (8..15).map { |col| cfmt col }.join
114
+ (16..255).each_slice(6) do |slice|
115
+ puts slice.map { |col| cfmt col }.join
116
+ end
117
+ ```
118
+
119
+ ### Reference chart
120
+
121
+ ![xterm-color-chart.png](https://github.com/junegunn/ansi256/raw/master/xterm-color-chart.png)
122
+
123
+ Contributing
124
+ ------------
94
125
 
95
126
  1. Fork it
96
127
  2. Create your feature branch (`git checkout -b my-new-feature`)
data/lib/ansi256.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require "ansi256/version"
2
+ require "ansi256/code"
2
3
  require "ansi256/mixin"
4
+ require 'set'
3
5
 
4
6
  module Ansi256
5
- RESET = "\e[0m"
6
-
7
7
  class << self
8
8
  def fg code, str = nil
9
9
  if str
@@ -21,60 +21,79 @@ module Ansi256
21
21
  end
22
22
  end
23
23
 
24
- def underline str = nil
25
- if str
26
- wrap str, Ansi256.underline
27
- else
28
- "\e[4m"
24
+ CODE.each do |name, code|
25
+ define_method name do |*arg|
26
+ if str = arg.first
27
+ wrap str, "\e[#{code}m"
28
+ else
29
+ "\e[#{code}m"
30
+ end
29
31
  end
30
32
  end
31
33
 
32
- def reset
33
- RESET
34
- end
35
-
36
34
  def plain str
37
35
  str.gsub(PATTERN, '')
38
36
  end
39
37
 
40
38
  private
41
- PATTERN = /\e\[(?:[34]8;5;)?[0-9]+m/
42
- MULTI_PATTERN = /(?:\e\[(?:[34]8;5;)?[0-9]+m)+/
39
+ PATTERN = /\e\[[0-9;]+m/
40
+ MULTI_PATTERN = /(?:\e\[[0-9;]+m)+/
41
+ EMPTY_TRIPLE = [nil, nil, Set.new]
42
+
43
+ def ansify prev, curr
44
+ nums = []
45
+ nums << curr[0] if prev[0] != curr[0]
46
+ nums << curr[1] if prev[1] != curr[1]
47
+ nums.concat curr[2].to_a if prev[2] != curr[2]
48
+ "\e[#{nums.compact.join ';'}m"
49
+ end
43
50
 
44
51
  def wrap str, color
45
- current = [nil, nil, nil]
52
+ current = [nil, nil, Set.new]
46
53
 
47
54
  (color + str.gsub(PATTERN) { |m|
48
- if m =~ /\e\[0m/
55
+ if m =~ /\e\[[^m]*\b0m/
49
56
  m + color
50
57
  else
51
58
  m
52
59
  end
53
- } << RESET).gsub(MULTI_PATTERN) { |codes|
60
+ } << reset).gsub(MULTI_PATTERN) { |ansi|
54
61
  prev = current.dup
55
- codes.split(/(?<=m)/).each do |code|
56
- case code
57
- when /\e\[38/
58
- current[0] = code
59
- when /\e\[48/
60
- current[1] = code
61
- when /\e\[0m/
62
- current = [nil, nil, nil]
62
+ prev[2] = prev[2].dup
63
+ codes = ansi.scan(/\d+/).map(&:to_i)
64
+
65
+ idx = -1
66
+ while (idx += 1) < codes.length
67
+ case code = codes[idx]
68
+ when 38
69
+ current[0] = codes[idx, 3].join ';'
70
+ idx += 2 # 38;5;11
71
+ when 48
72
+ current[1] = codes[idx, 3].join ';'
73
+ idx += 2 # 38;5;11
74
+ when 30..37
75
+ current[0] = codes[idx]
76
+ when 40..47
77
+ current[1] = codes[idx]
78
+ when 0
79
+ current[0] = current[1] = nil
80
+ current[2].clear
63
81
  else
64
- current[2] = code
82
+ current[2] << code
65
83
  end
66
84
  end
67
85
 
68
86
  if current == prev
69
87
  ''
70
- elsif current == [nil, nil, nil]
71
- RESET
88
+ elsif current == EMPTY_TRIPLE
89
+ reset
72
90
  else
73
- if (0..2).any? { |i| prev[i] && !current[i] }
74
- RESET
91
+ if (0..1).any? { |i| prev[i] && !current[i] } || current[2].proper_subset?(prev[2])
92
+ prev = EMPTY_TRIPLE
93
+ reset
75
94
  else
76
95
  ''
77
- end + current.join
96
+ end + ansify(prev, current)
78
97
  end
79
98
  }
80
99
  end
@@ -0,0 +1,25 @@
1
+ module Ansi256
2
+ CODE = {
3
+ :reset => 0,
4
+ :bold => 1,
5
+ :underline => 4,
6
+
7
+ :black => 30,
8
+ :red => 31,
9
+ :green => 32,
10
+ :yellow => 33,
11
+ :blue => 34,
12
+ :magenta => 35,
13
+ :cyan => 36,
14
+ :white => 37,
15
+
16
+ :on_black => 40,
17
+ :on_red => 41,
18
+ :on_green => 42,
19
+ :on_yellow => 43,
20
+ :on_blue => 44,
21
+ :on_magenta => 45,
22
+ :on_cyan => 46,
23
+ :on_white => 47,
24
+ }
25
+ end
data/lib/ansi256/mixin.rb CHANGED
@@ -12,8 +12,10 @@ module Ansi256
12
12
  Ansi256.plain self
13
13
  end
14
14
 
15
- def underline
16
- Ansi256.underline self
15
+ Ansi256::CODE.each do |name, code|
16
+ define_method name do
17
+ Ansi256.send name, self
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,3 +1,3 @@
1
1
  module Ansi256
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/test/test_ansi256.rb CHANGED
@@ -26,3 +26,26 @@ puts hello = "Hello #{world} !".fg(230).bg(75)
26
26
  puts say_hello_world = "Say '#{hello}'".fg(30)
27
27
  puts say_hello_world.plain.fg(27)
28
28
 
29
+ # Nesting 2
30
+ puts world = "World".bg(226).blue.underline
31
+ puts hello = "Hello #{world} Hello".white.bold
32
+ puts say_hello_world = "Say '#{hello}'".fg(30).underline
33
+ puts say_hello_world.plain.fg(27)
34
+
35
+ # Nesting 3
36
+ puts world = "World".blue.underline
37
+ puts hello = "Hello #{world} Hello".blue.bold
38
+ puts say_hello_world = "Say '#{hello}'".fg(30).underline
39
+ puts say_hello_world.plain.fg(27)
40
+
41
+ # Named colors
42
+ s = "Colorize me"
43
+ puts [ s.black, s.black.bold, s.white.bold.on_black ].join ' '
44
+ puts [ s.red, s.red.bold, s.white.bold.on_red ].join ' '
45
+ puts [ s.green, s.green.bold, s.white.bold.on_green ].join ' '
46
+ puts [ s.yellow, s.yellow.bold, s.white.bold.on_yellow ].join ' '
47
+ puts [ s.blue, s.blue.bold, s.white.bold.on_blue ].join ' '
48
+ puts [ s.magenta, s.magenta.bold, s.white.bold.on_magenta ].join ' '
49
+ puts [ s.cyan, s.cyan.bold, s.white.bold.on_cyan ].join ' '
50
+ puts [ s.white, s.white.bold, s.white.bold.on_white ].join ' '
51
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansi256
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -59,6 +59,7 @@ files:
59
59
  - ansi256.gemspec
60
60
  - bin/ansi256
61
61
  - lib/ansi256.rb
62
+ - lib/ansi256/code.rb
62
63
  - lib/ansi256/mixin.rb
63
64
  - lib/ansi256/version.rb
64
65
  - test/test_ansi256.rb
@@ -77,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
78
  version: '0'
78
79
  segments:
79
80
  - 0
80
- hash: 863938328980395766
81
+ hash: 2355104005458200198
81
82
  required_rubygems_version: !ruby/object:Gem::Requirement
82
83
  none: false
83
84
  requirements:
@@ -86,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
87
  version: '0'
87
88
  segments:
88
89
  - 0
89
- hash: 863938328980395766
90
+ hash: 2355104005458200198
90
91
  requirements: []
91
92
  rubyforge_project:
92
93
  rubygems_version: 1.8.25