ansi 1.4.1 → 1.4.2
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/.ruby +9 -7
- data/{LICENSE.rdoc → COPYING.rdoc} +170 -8
- data/HISTORY.rdoc +21 -0
- data/QED.rdoc +84 -27
- data/README.rdoc +11 -7
- data/lib/ansi.rb +4 -0
- data/lib/ansi.yml +9 -7
- data/lib/ansi/bbcode.rb +5 -10
- data/lib/ansi/chain.rb +50 -0
- data/lib/ansi/chart.rb +1 -0
- data/lib/ansi/code.rb +7 -8
- data/lib/ansi/columns.rb +85 -27
- data/lib/ansi/constants.rb +9 -2
- data/lib/ansi/core.rb +7 -1
- data/lib/ansi/diff.rb +88 -23
- data/lib/ansi/mixin.rb +2 -4
- data/lib/ansi/progressbar.rb +5 -2
- data/lib/ansi/terminal.rb +2 -2
- data/lib/ansi/terminal/curses.rb +2 -2
- data/lib/ansi/terminal/stty.rb +12 -5
- data/lib/ansi/terminal/termios.rb +11 -6
- data/lib/ansi/version.rb +2 -3
- data/qed/{10_core.rdoc → 02_core.rdoc} +0 -0
- data/qed/{09_diff.rb → 09_diff.rdoc} +0 -0
- data/qed/{02_bbcode.rdoc → 10_bbcode.rdoc} +0 -0
- data/qed/11_terminal.rdoc +8 -0
- data/qed/applique/ae.rb +1 -0
- metadata +22 -20
- data/NOTICE.rdoc +0 -156
- data/lib/ansi.rbz +0 -40
data/lib/ansi/bbcode.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# BBCode
|
2
2
|
#
|
3
3
|
# Copyright (c) 2002 Thomas-Ivo Heinen
|
4
4
|
#
|
@@ -9,31 +9,26 @@
|
|
9
9
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
10
10
|
# FOR A PARTICULAR PURPOSE.
|
11
11
|
|
12
|
+
#
|
12
13
|
module ANSI
|
13
14
|
|
14
|
-
#
|
15
|
-
|
15
|
+
# TODO: Integrate BBCode with Code module.
|
16
|
+
|
16
17
|
# The BBCode module helps ease the separation of core and frontend with the
|
17
18
|
# core (or submodules) being still able to say, what colors shall be used
|
18
19
|
# in it's responses. This is achieved by encoding formatting information
|
19
20
|
# using the BBCode tokens. This enables you to "pipe" layout information
|
20
|
-
# such as colors, style,
|
21
|
+
# such as colors, style, font, size and alignment through the core to
|
21
22
|
# the frontend.
|
22
23
|
#
|
23
24
|
# Additionally it converts markups/codes between ANSI, HTML and BBCode
|
24
25
|
# almost freely ;)
|
25
26
|
#
|
26
|
-
# == Usage
|
27
|
-
#
|
28
27
|
# # Converting a bbcode string to ANSI and XHTML
|
29
|
-
#
|
30
28
|
# str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]"
|
31
29
|
# print( BBCode.bbcode_to_ansi(str) )
|
32
30
|
# print( BBCode.bbcode_to_html(str) )
|
33
31
|
#
|
34
|
-
#--
|
35
|
-
# TODO: integrate with Code module.
|
36
|
-
#++
|
37
32
|
module BBCode
|
38
33
|
|
39
34
|
## ANSIname => ANSIcode LUT
|
data/lib/ansi/chain.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'ansi/code'
|
2
|
+
|
3
|
+
module ANSI
|
4
|
+
|
5
|
+
# ANSI::Chain was inspired by Kazuyoshi Tlacaelel's Isna library.
|
6
|
+
#
|
7
|
+
class Chain
|
8
|
+
|
9
|
+
#
|
10
|
+
def initialize(string)
|
11
|
+
@string = string.to_s
|
12
|
+
@codes = []
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
attr :string
|
17
|
+
|
18
|
+
#
|
19
|
+
attr :codes
|
20
|
+
|
21
|
+
#
|
22
|
+
def method_missing(s, *a, &b)
|
23
|
+
if ANSI::CHART.key?(s)
|
24
|
+
@codes << s
|
25
|
+
self
|
26
|
+
else
|
27
|
+
super(s, *a, &b)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
def to_s
|
33
|
+
if codes.empty?
|
34
|
+
result = @string
|
35
|
+
else
|
36
|
+
result = Code.ansi(@string, *codes)
|
37
|
+
codes.clear
|
38
|
+
end
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def to_str
|
44
|
+
to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
data/lib/ansi/chart.rb
CHANGED
data/lib/ansi/code.rb
CHANGED
@@ -17,6 +17,8 @@ module ANSI
|
|
17
17
|
# NOTE: This has no effect of methods that return ANSI codes.
|
18
18
|
$ansi = true
|
19
19
|
|
20
|
+
# TODO: up, down, right, left, etc could have yielding methods too?
|
21
|
+
|
20
22
|
# ANSI Codes
|
21
23
|
#
|
22
24
|
# Ansi::Code module makes it very easy to use ANSI codes.
|
@@ -32,10 +34,6 @@ module ANSI
|
|
32
34
|
#
|
33
35
|
# See {ANSI::Code::CHART} for list of all supported codes.
|
34
36
|
#
|
35
|
-
#--
|
36
|
-
# TODO: up, down, right, left, etc could have yielding methods too?
|
37
|
-
#++
|
38
|
-
|
39
37
|
module Code
|
40
38
|
extend self
|
41
39
|
|
@@ -235,9 +233,13 @@ module ANSI
|
|
235
233
|
|
236
234
|
return string unless $ansi
|
237
235
|
|
238
|
-
code(*codes)
|
236
|
+
c = code(*codes)
|
237
|
+
|
238
|
+
c + string.gsub(ENDCODE, ENDCODE + c) + ENDCODE
|
239
239
|
end
|
240
240
|
|
241
|
+
# TODO: Allow selective removal using *codes argument?
|
242
|
+
|
241
243
|
# Remove ANSI codes from string or block value.
|
242
244
|
#
|
243
245
|
# @param [String]
|
@@ -246,9 +248,6 @@ module ANSI
|
|
246
248
|
# @return [String]
|
247
249
|
# String wrapped ANSI code.
|
248
250
|
#
|
249
|
-
#--
|
250
|
-
# TODO: Allow selective removal using *codes argument?
|
251
|
-
#++
|
252
251
|
def unansi(string=nil) #:yield:
|
253
252
|
if block_given?
|
254
253
|
string = yield.to_s
|
data/lib/ansi/columns.rb
CHANGED
@@ -3,32 +3,47 @@ require 'ansi/terminal'
|
|
3
3
|
|
4
4
|
module ANSI
|
5
5
|
|
6
|
+
#
|
6
7
|
class Columns
|
7
8
|
|
8
9
|
# Create a column-based layout.
|
9
10
|
#
|
10
|
-
#
|
11
|
+
# @param [String,Array] list
|
12
|
+
# Multiline String or Array of strings to columnize.
|
11
13
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
14
|
+
# @param [Hash] options
|
15
|
+
# Options to customize columnization.
|
16
|
+
#
|
17
|
+
# @option options [Fixnum] :columns
|
18
|
+
# Number of columns.
|
19
|
+
#
|
20
|
+
# @option options [Symbol] :align
|
21
|
+
# Column alignment, either :left, :right or :center.
|
22
|
+
#
|
23
|
+
# @option options [String,Fixnum] :padding
|
24
|
+
# String or number or spaces to append to each column.
|
15
25
|
#
|
16
26
|
# The +format+ block MUST return ANSI codes.
|
17
27
|
def initialize(list, options={}, &format)
|
18
28
|
self.list = list
|
19
29
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
30
|
+
self.columns = options[:columns] || options[:cols]
|
31
|
+
self.padding = options[:padding] || 1
|
32
|
+
self.align = options[:align] || :left
|
33
|
+
#self.ansi = options[:ansi]
|
34
|
+
self.format = format
|
25
35
|
|
26
|
-
|
36
|
+
#@columns = nil if @columns == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
def inspect
|
41
|
+
"#<#{self.class}:#{object_id} #{list.inspect} x #{columns}>"
|
27
42
|
end
|
28
43
|
|
29
44
|
# List layout into columns. Each new line is taken to be
|
30
45
|
# a row-column cell.
|
31
|
-
|
46
|
+
attr :list
|
32
47
|
|
33
48
|
def list=(list)
|
34
49
|
case list
|
@@ -41,38 +56,80 @@ module ANSI
|
|
41
56
|
|
42
57
|
# Default number of columns to display. If nil then the number
|
43
58
|
# of coumns is estimated from the size of the terminal.
|
44
|
-
|
59
|
+
attr :columns
|
60
|
+
|
61
|
+
# Set column count ensuring value is either an integer or nil.
|
62
|
+
# The the value given is zero, it will be taken to mean the same
|
63
|
+
# as nil, which means fit-to-screen.
|
64
|
+
def columns=(integer)
|
65
|
+
integer = integer.to_i
|
66
|
+
@columns = (integer.zero? ? nil : integer)
|
67
|
+
end
|
45
68
|
|
46
69
|
# Padding size to apply to cells.
|
47
|
-
|
70
|
+
attr :padding
|
71
|
+
|
72
|
+
# Set padding to string or number (of spaces).
|
73
|
+
def padding=(pad)
|
74
|
+
case pad
|
75
|
+
when Numeric
|
76
|
+
@padding = ' ' * pad.to_i
|
77
|
+
else
|
78
|
+
@padding = pad.to_s
|
79
|
+
end
|
80
|
+
end
|
48
81
|
|
49
82
|
# Alignment to apply to cells.
|
50
|
-
|
83
|
+
attr :align
|
84
|
+
|
85
|
+
# Set alignment ensuring value is a symbol.
|
86
|
+
#
|
87
|
+
# @param [Symbol] Either `:right`, `:left` or `:center`.
|
88
|
+
def align=(symbol)
|
89
|
+
symbol = symbol.to_sym
|
90
|
+
raise ArgumentError, "invalid alignment -- #{symbol.inspect}" \
|
91
|
+
unless [:left, :right, :center].include?(symbol)
|
92
|
+
@align = symbol
|
93
|
+
end
|
51
94
|
|
52
95
|
# Formating to apply to cells.
|
53
|
-
|
96
|
+
attr :format
|
97
|
+
|
98
|
+
# Set formatting procedure. The procedure must return
|
99
|
+
# ANSI codes, suitable for passing to String#ansi method.
|
100
|
+
def format=(procedure)
|
101
|
+
@format = procedure ? procedure.to_proc : nil
|
102
|
+
end
|
103
|
+
|
104
|
+
# TODO: Should #to_s also take options and formatting block?
|
105
|
+
# Maybe instead have hoin take all these and leave #to_s bare.
|
54
106
|
|
55
107
|
# Return string in column layout. The number of columns is determined
|
56
108
|
# by the `columns` property or overriden by +cols+ argument.
|
57
|
-
#--
|
58
|
-
# TODO: Allow #to_s to take options and formating block?
|
59
|
-
#++
|
60
109
|
def to_s(cols=nil)
|
61
110
|
to_s_columns(cols || columns)
|
62
111
|
end
|
63
112
|
|
64
|
-
|
113
|
+
#
|
114
|
+
def join(cols=nil)
|
115
|
+
to_s_columns(cols || columns)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
65
119
|
|
66
120
|
# Layout string lines into columns.
|
67
121
|
#
|
68
|
-
#
|
122
|
+
# @todo Put in empty strings for blank cells.
|
123
|
+
# @todo Centering look like it's off by one to the right.
|
124
|
+
#
|
69
125
|
def to_s_columns(columns=nil)
|
70
126
|
lines = list.to_a
|
71
127
|
count = lines.size
|
72
128
|
max = lines.map{ |l| l.size }.max
|
129
|
+
|
73
130
|
if columns.nil?
|
74
131
|
width = Terminal.terminal_width
|
75
|
-
columns = (width / (max + padding)).to_i
|
132
|
+
columns = (width / (max + padding.size)).to_i
|
76
133
|
end
|
77
134
|
|
78
135
|
rows = []
|
@@ -83,12 +140,12 @@ module ANSI
|
|
83
140
|
(rows[index % mod] ||=[]) << line.strip
|
84
141
|
end
|
85
142
|
|
86
|
-
pad =
|
143
|
+
pad = padding
|
87
144
|
tmp = template(max, pad)
|
88
145
|
str = ""
|
89
146
|
rows.each_with_index do |row, ri|
|
90
147
|
row.each_with_index do |cell, ci|
|
91
|
-
ansi_codes =
|
148
|
+
ansi_codes = ansi_formatting(cell, ci, ri)
|
92
149
|
if ansi_codes.empty?
|
93
150
|
str << (tmp % cell)
|
94
151
|
else
|
@@ -102,10 +159,11 @@ module ANSI
|
|
102
159
|
end
|
103
160
|
|
104
161
|
# Aligns the cell left or right.
|
105
|
-
#
|
106
|
-
# TODO: Handle centered alignment.
|
107
162
|
def template(max, pad)
|
108
163
|
case align
|
164
|
+
when :center, 'center'
|
165
|
+
offset = " " * (max / 2)
|
166
|
+
"#{offset}%#{max}s#{offset}#{pad}"
|
109
167
|
when :right, 'right'
|
110
168
|
"%#{max}s#{pad}"
|
111
169
|
else
|
@@ -113,8 +171,8 @@ module ANSI
|
|
113
171
|
end
|
114
172
|
end
|
115
173
|
|
116
|
-
# Used to apply ANSI
|
117
|
-
def
|
174
|
+
# Used to apply ANSI formatting to each cell.
|
175
|
+
def ansi_formatting(cell, col, row)
|
118
176
|
if @format
|
119
177
|
case @format.arity
|
120
178
|
when 0
|
data/lib/ansi/constants.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
module ANSI
|
2
2
|
|
3
|
+
require 'ansi/chart'
|
4
|
+
|
3
5
|
# Converts {CHART} and {SPECIAL_CHART} entries into constants.
|
6
|
+
# So for example, the CHART entry for :red becomes:
|
7
|
+
#
|
8
|
+
# ANSI::Constants::RED #=> "\e[31m"
|
9
|
+
#
|
10
|
+
# The ANSI Constants are include into ANSI::Code and can be included
|
11
|
+
# any where will they would be of use.
|
12
|
+
#
|
4
13
|
module Constants
|
5
14
|
|
6
|
-
require 'ansi/chart'
|
7
|
-
|
8
15
|
CHART.each do |name, code|
|
9
16
|
const_set(name.to_s.upcase, "\e[#{code}m")
|
10
17
|
end
|
data/lib/ansi/core.rb
CHANGED
data/lib/ansi/diff.rb
CHANGED
@@ -2,9 +2,33 @@ require 'ansi/code'
|
|
2
2
|
|
3
3
|
module ANSI
|
4
4
|
|
5
|
-
# Diff
|
5
|
+
# Diff produces colorized differences of two string or objects.
|
6
|
+
#
|
6
7
|
class Diff
|
7
8
|
|
9
|
+
# Highlights the differnce between two strings.
|
10
|
+
#
|
11
|
+
# This class method is equivalent to calling:
|
12
|
+
#
|
13
|
+
# ANSI::Diff.new(object1, object2).to_a
|
14
|
+
#
|
15
|
+
def self.diff(object1, object2, options={})
|
16
|
+
new(object1, object2, options={}).to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
# Setup new Diff object. If the objects given are not Strings
|
20
|
+
# and do not have `#to_str` defined to coerce them to such, then
|
21
|
+
# their `#inspect` methods are used to convert them to strings
|
22
|
+
# for comparison.
|
23
|
+
#
|
24
|
+
# @param [Object] object1
|
25
|
+
# First object to compare.
|
26
|
+
#
|
27
|
+
# @param [Object] object2
|
28
|
+
# Second object to compare.
|
29
|
+
#
|
30
|
+
# @param [Hash] options
|
31
|
+
# Options for contoller the way difference is shown. (Not yet used.)
|
8
32
|
#
|
9
33
|
def initialize(object1, object2, options={})
|
10
34
|
@object1 = convert(object1)
|
@@ -13,25 +37,56 @@ module ANSI
|
|
13
37
|
@diff1, @diff2 = diff_string(@object1, @object2)
|
14
38
|
end
|
15
39
|
|
16
|
-
#
|
40
|
+
# Returns the first object's difference string.
|
17
41
|
def diff1
|
18
42
|
@diff1
|
19
43
|
end
|
20
44
|
|
21
|
-
#
|
45
|
+
# Returns the second object's difference string.
|
22
46
|
def diff2
|
23
47
|
@diff2
|
24
48
|
end
|
25
49
|
|
50
|
+
# Returns both first and second difference strings separated by a
|
51
|
+
# new line character.
|
26
52
|
#
|
53
|
+
# @todo Should we use `$/` record separator instead?
|
54
|
+
#
|
55
|
+
# @return [String] Joined difference strings.
|
27
56
|
def to_s
|
28
57
|
"#{@diff1}\n#{@diff2}"
|
29
58
|
end
|
30
59
|
|
31
|
-
|
60
|
+
# Returns both first and second difference strings separated by a
|
61
|
+
# the given `separator`. The default is `$/`, the record separator.
|
62
|
+
#
|
63
|
+
# @param [String] separator
|
64
|
+
# The string to use as the separtor between the difference strings.
|
65
|
+
#
|
66
|
+
# @return [String] Joined difference strings.
|
67
|
+
def join(separator=$/)
|
68
|
+
"#{@diff1}#{separator}#{@diff2}"
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the first and second difference strings in an array.
|
72
|
+
#
|
73
|
+
# @return [Array] Both difference strings.
|
74
|
+
def to_a
|
75
|
+
[diff1, diff2]
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
32
79
|
|
33
80
|
# Take two plain strings and produce colorized
|
34
81
|
# versions of each highlighting their differences.
|
82
|
+
#
|
83
|
+
# @param [String] string1
|
84
|
+
# First string to compare.
|
85
|
+
#
|
86
|
+
# @param [String] string2
|
87
|
+
# Second string to compare.
|
88
|
+
#
|
89
|
+
# @return [Array<String>] The two difference strings.
|
35
90
|
def diff_string(string1, string2)
|
36
91
|
compare(string1, string2)
|
37
92
|
end
|
@@ -52,7 +107,16 @@ module ANSI
|
|
52
107
|
# Rotation of colors for diff output.
|
53
108
|
COLORS = [:red, :yellow, :magenta]
|
54
109
|
|
110
|
+
# Take two plain strings and produce colorized
|
111
|
+
# versions of each highlighting their differences.
|
55
112
|
#
|
113
|
+
# @param [String] string1
|
114
|
+
# First string to compare.
|
115
|
+
#
|
116
|
+
# @param [String] string2
|
117
|
+
# Second string to compare.
|
118
|
+
#
|
119
|
+
# @return [Array<String>] The two difference strings.
|
56
120
|
def compare(x, y)
|
57
121
|
c = common(x, y)
|
58
122
|
a = x.dup
|
@@ -70,7 +134,8 @@ module ANSI
|
|
70
134
|
return a, b
|
71
135
|
end
|
72
136
|
|
73
|
-
#
|
137
|
+
# Oh, I should have documented this will I knew what the
|
138
|
+
# hell it was doing ;)
|
74
139
|
def common(x,y)
|
75
140
|
c = lcs(x, y)
|
76
141
|
|
@@ -99,24 +164,7 @@ module ANSI
|
|
99
164
|
[l, c, r].flatten.reject{ |s| s.empty? }
|
100
165
|
end
|
101
166
|
|
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
|
-
#
|
167
|
+
# Least common string.
|
120
168
|
def lcs(s1, s2)
|
121
169
|
res=""
|
122
170
|
num=Array.new(s1.size){Array.new(s2.size)}
|
@@ -145,6 +193,23 @@ module ANSI
|
|
145
193
|
res
|
146
194
|
end
|
147
195
|
|
196
|
+
# Hmm... is this even useful?
|
197
|
+
def lcs_size(s1, s2)
|
198
|
+
num=Array.new(s1.size){Array.new(s2.size)}
|
199
|
+
len,ans=0,0
|
200
|
+
s1.scan(/./).each_with_index do |l1,i |
|
201
|
+
s2.scan(/./).each_with_index do |l2,j |
|
202
|
+
unless l1==l2
|
203
|
+
num[i][j]=0
|
204
|
+
else
|
205
|
+
(i==0 || j==0)? num[i][j]=1 : num[i][j]=1 + num[i-1][j-1]
|
206
|
+
len = ans = num[i][j] if num[i][j] > len
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
ans
|
211
|
+
end
|
212
|
+
|
148
213
|
end
|
149
214
|
|
150
215
|
end
|