ansi256 0.1.0 → 0.2.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/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