ansi 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module ANSI
2
+
3
+ # Converts {CHART} and {SPECIAL_CHART} entries into constants.
4
+ module Constants
5
+
6
+ require 'ansi/chart'
7
+
8
+ CHART.each do |name, code|
9
+ const_set(name.to_s.upcase, "\e[#{code}m")
10
+ end
11
+
12
+ SPECIAL_CHART.each do |name, code|
13
+ const_set(name.to_s.upcase, code)
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,24 @@
1
+ require 'ansi/code'
2
+
3
+ class ::String
4
+ #
5
+ def ansi(*codes)
6
+ ANSI::Code.ansi(self, *codes)
7
+ end
8
+
9
+ #
10
+ def ansi!(*codes)
11
+ replace(ansi(*codes))
12
+ end
13
+
14
+ #
15
+ def unansi
16
+ ANSI::Code.unansi(self)
17
+ end
18
+
19
+ #
20
+ def unansi!
21
+ replace(unansi)
22
+ end
23
+ end
24
+
@@ -3,8 +3,6 @@ require 'ansi/code'
3
3
  module ANSI
4
4
 
5
5
  # Diff can produced a colorized difference of two string or objects.
6
- #
7
- # IMPORTANT! This class is still a very much a work in progress.
8
6
  class Diff
9
7
 
10
8
  #
@@ -34,65 +32,8 @@ module ANSI
34
32
 
35
33
  # Take two plain strings and produce colorized
36
34
  # versions of each highlighting their differences.
37
- #
38
- # TODO: I am sure there are better ways to do this,
39
- # but for now this suffices.
40
- def diff_string(str1, str2)
41
- i1, i2 = 0, 0
42
- m1, m2 = nil, nil
43
- s1, s2 = "", ""
44
- t1, t2 = "", ""
45
- c = 0
46
-
47
- loop do
48
- if str1[i1,1] == str2[i2,1]
49
- s1 << red(t1); t1 = "" unless t1 == ""
50
- s2 << red(t2); t2 = "" unless t2 == ""
51
- s1 << str1[i1,1].to_s
52
- s2 << str2[i2,1].to_s
53
- i1 += 1; i2 += 1
54
- #m1 += 1; m2 += 1
55
- else
56
- if m1 && str1[m1,1] == str2[i2,1]
57
- s2 << color1(t2)
58
- t1, t2 = "", ""
59
- i1 = m1
60
- m1, m2 = nil, nil
61
- elsif m2 && str1[i1,1] == str2[m2,1]
62
- s1 << color2(t1)
63
- t1, t2 = "", ""
64
- i2 = m2
65
- m1, m2 = nil, nil
66
- else
67
- t1 << str1[i1,1].to_s
68
- t2 << str2[i2,1].to_s
69
- m1, m2 = i1, i2 if m1 == nil
70
- i1 += 1; i2 += 1
71
- end
72
- end
73
- break if i1 >= str1.size && i2 >= str2.size
74
- end
75
- s1 << red(t1); t1 = "" unless t1 == ""
76
- s2 << red(t2); t2 = "" unless t2 == ""
77
- #s1 << ANSI::Code::CLEAR
78
- #s2 << ANSI::Code::CLEAR
79
-
80
- return s1, s2
81
- end
82
-
83
- #
84
- def red(str)
85
- ANSI.color(:red){ str }
86
- end
87
-
88
- #
89
- def color1(str)
90
- ANSI.color(:blue){ str }
91
- end
92
-
93
- #
94
- def color2(str)
95
- ANSI.color(:green){ str }
35
+ def diff_string(string1, string2)
36
+ compare(string1, string2)
96
37
  end
97
38
 
98
39
  # Ensure the object of comparison is a string. If +object+ is not
@@ -108,6 +49,102 @@ module ANSI
108
49
  end
109
50
  end
110
51
 
52
+ # Rotation of colors for diff output.
53
+ COLORS = [:red, :yellow, :magenta]
54
+
55
+ #
56
+ def compare(x, y)
57
+ c = common(x, y)
58
+ a = x.dup
59
+ b = y.dup
60
+ oi = 0
61
+ oj = 0
62
+ c.each_with_index do |m, q|
63
+ i = a.index(m, oi)
64
+ j = b.index(m, oj)
65
+ a[i,m.size] = ANSI.ansi(m, COLORS[q%3]) if i
66
+ b[j,m.size] = ANSI.ansi(m, COLORS[q%3]) if j
67
+ oi = i + m.size if i
68
+ oj = j + m.size if j
69
+ end
70
+ return a, b
71
+ end
72
+
73
+ #
74
+ def common(x,y)
75
+ c = lcs(x, y)
76
+
77
+ i = x.index(c)
78
+ j = y.index(c)
79
+
80
+ ix = i + c.size
81
+ jx = j + c.size
82
+
83
+ if i == 0
84
+ l = y[0...j]
85
+ elsif j == 0
86
+ l = x[0...i]
87
+ else
88
+ l = common(x[0...i], y[0...j])
89
+ end
90
+
91
+ if ix == x.size - 1
92
+ r = y[jx..-1]
93
+ elsif jx = y.size - 1
94
+ r = x[ix..-1]
95
+ else
96
+ r = common(x[ix..-1], y[jx..-1])
97
+ end
98
+
99
+ [l, c, r].flatten.reject{ |s| s.empty? }
100
+ end
101
+
102
+ #
103
+ def lcs_size(s1, s2)
104
+ num=Array.new(s1.size){Array.new(s2.size)}
105
+ len,ans=0
106
+ s1.scan(/./).each_with_index do |l1,i |
107
+ s2.scan(/./).each_with_index do |l2,j |
108
+ unless l1==l2
109
+ num[i][j]=0
110
+ else
111
+ (i==0 || j==0)? num[i][j]=1 : num[i][j]=1 + num[i-1][j-1]
112
+ len = ans = num[i][j] if num[i][j] > len
113
+ end
114
+ end
115
+ end
116
+ ans
117
+ end
118
+
119
+ #
120
+ def lcs(s1, s2)
121
+ res=""
122
+ num=Array.new(s1.size){Array.new(s2.size)}
123
+ len,ans=0
124
+ lastsub=0
125
+ s1.scan(/./).each_with_index do |l1,i |
126
+ s2.scan(/./).each_with_index do |l2,j |
127
+ unless l1==l2
128
+ num[i][j]=0
129
+ else
130
+ (i==0 || j==0)? num[i][j]=1 : num[i][j]=1 + num[i-1][j-1]
131
+ if num[i][j] > len
132
+ len = ans = num[i][j]
133
+ thissub = i
134
+ thissub -= num[i-1][j-1] unless num[i-1][j-1].nil?
135
+ if lastsub==thissub
136
+ res+=s1[i,1]
137
+ else
138
+ lastsub=thissub
139
+ res=s1[lastsub, (i+1)-lastsub]
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ res
146
+ end
147
+
111
148
  end
112
149
 
113
150
  end
@@ -1,23 +1,22 @@
1
1
  require 'ansi/code'
2
2
  #require 'ansi/layout/split'
3
- #require 'clio/facets/string'
4
3
 
5
4
  # Create a new Ansi::String object.
6
5
  def ANSI.string(str)
7
6
  ANSI::String.new(str)
8
7
  end
9
8
 
10
- # = String
9
+ # IMPORTANT! ANSI::String is experimental!!!
11
10
  #
12
- # ANSI Strings store a regular string (@text) and
13
- # a Hash mapping character index to ANSI codes (@marks).
11
+ # ANSI::String stores a regular string (`@text`) and an associative
12
+ # array that ties a character index to an ANSI code (`marks`).
14
13
  # For example is we have the string:
15
14
  #
16
15
  # "Big Apple"
17
16
  #
18
- # And applied the color red to it, the marks hash would be:
17
+ # And applied the color red to it, the marks list would be:
19
18
  #
20
- # { 0=>[:red] , 9=>[:clear] }
19
+ # [[0, :red], [9, :clear]]
21
20
  #
22
21
  # TODO: In the future we may be able to subclass String,
23
22
  # instead of delegating via @text, but not until it is more
@@ -25,7 +24,7 @@ end
25
24
  #
26
25
  class ANSI::String
27
26
 
28
- CLR = ANSI::Code.clear
27
+ CLR = ANSI::Code::CLEAR
29
28
 
30
29
  attr :text
31
30
  attr :marks
@@ -41,7 +40,7 @@ class ANSI::String
41
40
  # This converts the intental markup codes to ANSI codes.
42
41
  def to_s
43
42
  s = text.dup
44
- m = marks.sort do |(a,b)|
43
+ m = marks.sort do |a,b|
45
44
  v = b[0] <=> a[0]
46
45
  if v == 0
47
46
  (b[1] == :clear or b[1] == :reset) ? -1 : 1
@@ -16,10 +16,10 @@ module ANSI
16
16
 
17
17
  modes = %w{win32 termios curses stty}
18
18
 
19
- #
20
19
  # This section builds character reading and terminal size functions
21
- # to suit the proper platform we're running on. Be warned: Here be
22
- # dragons!
20
+ # to suit the proper platform we're running on.
21
+ #
22
+ # Be warned: Here be dragons!
23
23
  #
24
24
  begin
25
25
  require 'ansi/terminal/' + (mode = modes.pop)
@@ -44,13 +44,6 @@ As well as combined color methods.
44
44
  str = white_on_red + "Hello"
45
45
  str.assert == "\e[37m\e[41mHello"
46
46
 
47
- In addition the library offers an extension to String class
48
- called #ansi, which allows some of the ANSI::Code methods
49
- to be called in a more object-oriented fashion.
50
-
51
- str = "Hello".ansi(:red) + "World".ansi(:blue)
52
- str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
53
-
54
47
  The ANSI::Code module supports most standard ANSI codes, though
55
48
  not all platforms support every code, so YMMV.
56
49
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  diff = ANSI::Diff.new(a,b)
9
9
 
10
- puts diff.to_s
10
+ diff.to_s.assert == "\e[31mabc\e[0m\e[33mYefg\e[0m\n\e[31mabc\e[0mXefg"
11
11
 
12
12
  Try another.
13
13
 
@@ -16,7 +16,7 @@ Try another.
16
16
 
17
17
  diff = ANSI::Diff.new(a,b)
18
18
 
19
- puts diff.to_s
19
+ diff.to_s.assert == "\e[31mabc\e[0m\n\e[31mabc\e[0mdef"
20
20
 
21
21
  And another.
22
22
 
@@ -25,7 +25,7 @@ And another.
25
25
 
26
26
  diff = ANSI::Diff.new(a,b)
27
27
 
28
- puts diff.to_s
28
+ diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXXghi\e[0m\n\e[31mabc\e[0mdefghi"
29
29
 
30
30
  And another.
31
31
 
@@ -34,7 +34,7 @@ And another.
34
34
 
35
35
  diff = ANSI::Diff.new(a,b)
36
36
 
37
- puts diff.to_s
37
+ diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXX\e[0m\e[35mdefghi\e[0m\n\e[31mabc\e[0m\e[35mdefghi\e[0m"
38
38
 
39
39
  Comparison that is mostly different.
40
40
 
@@ -43,5 +43,5 @@ Comparison that is mostly different.
43
43
 
44
44
  diff = ANSI::Diff.new(a,b)
45
45
 
46
- puts diff.to_s
46
+ diff.to_s.assert == "\e[31mabc\e[0m\e[33mpppz123\e[0m\n\e[31mabc\e[0mxyzzz43"
47
47
 
@@ -0,0 +1,11 @@
1
+ = String Extensions
2
+
3
+ In addition the library offers an extension to String class
4
+ called #ansi, which allows some of the ANSI::Code methods
5
+ to be called in a more object-oriented fashion.
6
+
7
+ require 'ansi/core'
8
+
9
+ str = "Hello".ansi(:red) + "World".ansi(:blue)
10
+ str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
11
+
@@ -1,19 +1,29 @@
1
1
  require 'ansi/code'
2
2
 
3
- class TestANSICode < KO::TestCase
3
+ testcase ANSI::Code do
4
4
 
5
- include ANSI::Code
5
+ unit :red do
6
+ str = ANSI::Code.red
7
+ out = "\e[31m"
8
+ out.assert == str
9
+ end
10
+
11
+ unit :red => "with block notation" do
12
+ str = ANSI::Code.red { "Hello" }
13
+ out = "\e[31mHello\e[0m"
14
+ out.assert == str
15
+ end
6
16
 
7
- test "base methods" do
8
- str = red + "Hello" + blue + "World"
9
- out = "\e[31mHello\e[34mWorld"
10
- out == str
17
+ unit :blue do
18
+ str = ANSI::Code.blue
19
+ out = "\e[34m"
20
+ out.assert == str
11
21
  end
12
22
 
13
- test "block notation" do
14
- str = red { "Hello" } + blue { "World" }
15
- out = "\e[31mHello\e[0m\e[34mWorld\e[0m"
16
- out == str
23
+ unit :blue => "with block notation" do
24
+ str = ANSI::Code.blue { "World" }
25
+ out = "\e[34mWorld\e[0m"
26
+ out.assert == str
17
27
  end
18
28
 
19
29
  end
@@ -1,28 +1,27 @@
1
1
  require 'ansi/bbcode'
2
2
 
3
- class TC_BBCode < KO::TestCase
3
+ testcase ANSI::BBCode do
4
4
 
5
- test "to_ansi" do
5
+ meta :bbcode_to_ansi do
6
6
  str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]"
7
7
  out = "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n"
8
- out == ANSI::BBCode.bbcode_to_ansi(str)
8
+ out.assert == ANSI::BBCode.bbcode_to_ansi(str)
9
9
  end
10
10
 
11
- test "to_html" do
11
+ meta :bbcode_to_html do
12
12
  str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]"
13
13
  out = "this is <font color=\"red\">red</font>, this is <strong>bold</strong><br />\n"
14
- out == ANSI::BBCode.bbcode_to_html(str)
14
+ out.assert == ANSI::BBCode.bbcode_to_html(str)
15
15
  end
16
16
 
17
- test "ansi_to_html" do
17
+ meta :ansi_to_html do
18
18
  str = "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" +
19
19
  "this is a line without any ansi code\n" +
20
20
  "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n"
21
21
  out = "this is <font color=\"red\">red</font>, this is <strong>bold</strong><br />\n" +
22
22
  "this is a line without any ansi code<br />\n" +
23
23
  "this is <font color=\"red\">red</font>, this is <strong>bold</strong><br />\n"
24
- out == ANSI::BBCode.ansi_to_html(str)
24
+ out.assert == ANSI::BBCode.ansi_to_html(str)
25
25
  end
26
26
 
27
27
  end
28
-
@@ -1,21 +1,28 @@
1
1
  require 'ansi/mixin'
2
2
 
3
- class TestANSIMixin < KO::TestCase
3
+ testcase ANSI::Mixin do
4
4
 
5
+ # TODO: subclass
5
6
  class ::String
6
7
  include ANSI::Mixin
7
8
  end
8
9
 
9
- test "methods" do
10
- str = "Hello".red + "World".blue
11
- out = "\e[31mHello\e[0m\e[34mWorld\e[0m"
12
- out == str
10
+ unit :red do
11
+ str = "Hello".red
12
+ out = "\e[31mHello\e[0m"
13
+ out.assert == str
13
14
  end
14
15
 
15
- test "display" do
16
+ unit :blue do
17
+ str = "World".blue
18
+ out = "\e[34mWorld\e[0m"
19
+ out.assert == str
20
+ end
21
+
22
+ unit :display do
16
23
  str = "Hello".display(4,10)
17
24
  out = "\e[s\e[4;10HHello\e[u"
18
- out == str
25
+ out.assert == str
19
26
  end
20
27
 
21
28
  end