ansi 1.4.3 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.index +77 -0
- data/DEMO.md +451 -0
- data/{HISTORY.rdoc → HISTORY.md} +35 -15
- data/LICENSE.txt +23 -0
- data/NOTICE.md +170 -0
- data/{README.rdoc → README.md} +34 -30
- data/demo/01_ansicode.md +65 -0
- data/demo/{02_core.rdoc → 02_core.md} +4 -4
- data/demo/03_logger.md +30 -0
- data/demo/04_progressbar.md +62 -0
- data/demo/{05_mixin.rdoc → 05_mixin.md} +11 -11
- data/demo/{06_string.rdoc → 06_string.md} +18 -18
- data/demo/07_columns.md +89 -0
- data/demo/08_table.md +28 -0
- data/demo/09_diff.md +47 -0
- data/demo/10_bbcode.md +24 -0
- data/demo/11_terminal.md +8 -0
- data/lib/ansi.yml +57 -43
- data/lib/ansi/chart.rb +12 -10
- data/lib/ansi/code.rb +78 -82
- data/lib/ansi/columns.rb +0 -1
- data/lib/ansi/terminal.rb +1 -1
- data/lib/ansi/terminal/curses.rb +1 -2
- data/lib/ansi/terminal/stty.rb +2 -2
- data/test/case_ansicode.rb +29 -17
- data/test/case_mixin.rb +18 -12
- data/test/case_progressbar.rb +11 -9
- metadata +90 -53
- data/.ruby +0 -63
- data/COPYING.rdoc +0 -612
- data/Config.rb +0 -13
- data/DEMO.rdoc +0 -455
- data/demo/01_ansicode.rdoc +0 -49
- data/demo/03_logger.rdoc +0 -31
- data/demo/04_progressbar.rdoc +0 -63
- data/demo/07_columns.rdoc +0 -90
- data/demo/08_table.rdoc +0 -28
- data/demo/09_diff.rdoc +0 -47
- data/demo/10_bbcode.rdoc +0 -24
- data/demo/11_terminal.rdoc +0 -8
data/demo/01_ansicode.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# ANSI::Code
|
2
|
+
|
3
|
+
Require the library.
|
4
|
+
|
5
|
+
require 'ansi/code'
|
6
|
+
|
7
|
+
ANSI::Code can be used as a functions module.
|
8
|
+
|
9
|
+
str = ANSI::Code.red + "Hello" + ANSI::Code.blue + "World"
|
10
|
+
str.assert == "\e[31mHello\e[34mWorld"
|
11
|
+
|
12
|
+
If a block is supplied to each method then yielded value will
|
13
|
+
be wrapped in the ANSI code and clear code.
|
14
|
+
|
15
|
+
str = ANSI::Code.red{ "Hello" } + ANSI::Code.blue{ "World" }
|
16
|
+
str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
|
17
|
+
|
18
|
+
More conveniently the ANSI::Code module extends ANSI itself.
|
19
|
+
|
20
|
+
str = ANSI.red + "Hello" + ANSI.blue + "World"
|
21
|
+
str.assert == "\e[31mHello\e[34mWorld"
|
22
|
+
|
23
|
+
str = ANSI.red{ "Hello" } + ANSI.blue{ "World" }
|
24
|
+
str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
|
25
|
+
|
26
|
+
ANSI also supports XTerm 256 color mode using red, blue and green values
|
27
|
+
with the `#rgb` method.
|
28
|
+
|
29
|
+
str = ANSI::Code.rgb(0, 255, 0)
|
30
|
+
str.assert == "\e[38;5;46m"
|
31
|
+
|
32
|
+
Or using CSS style hex codes as well.
|
33
|
+
|
34
|
+
str = ANSI::Code.rgb("#00FF00")
|
35
|
+
str.assert == "\e[38;5;46m"
|
36
|
+
|
37
|
+
Both of these methods can take blocks to wrap text in the color and clear codes.
|
38
|
+
|
39
|
+
str = ANSI::Code.rgb("#00FF00"){ "Hello" }
|
40
|
+
str.assert == "\e[38;5;46mHello\e[0m"
|
41
|
+
|
42
|
+
In the appropriate context the ANSI::Code module can also be
|
43
|
+
included, making its methods directly accessible.
|
44
|
+
|
45
|
+
include ANSI::Code
|
46
|
+
|
47
|
+
str = red + "Hello" + blue + "World"
|
48
|
+
str.assert == "\e[31mHello\e[34mWorld"
|
49
|
+
|
50
|
+
str = red{ "Hello" } + blue{ "World" }
|
51
|
+
str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
|
52
|
+
|
53
|
+
Along with the single font colors, the library include background colors.
|
54
|
+
|
55
|
+
str = on_red + "Hello"
|
56
|
+
str.assert == "\e[41mHello"
|
57
|
+
|
58
|
+
As well as combined color methods.
|
59
|
+
|
60
|
+
str = white_on_red + "Hello"
|
61
|
+
str.assert == "\e[37m\e[41mHello"
|
62
|
+
|
63
|
+
The ANSI::Code module supports most standard ANSI codes, though
|
64
|
+
not all platforms support every code, so YMMV.
|
65
|
+
|
@@ -1,11 +1,11 @@
|
|
1
|
-
|
1
|
+
# String Extensions
|
2
2
|
|
3
3
|
In addition the library offers an extension to String class
|
4
4
|
called #ansi, which allows some of the ANSI::Code methods
|
5
5
|
to be called in a more object-oriented fashion.
|
6
6
|
|
7
|
-
|
7
|
+
require 'ansi/core'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
str = "Hello".ansi(:red) + "World".ansi(:blue)
|
10
|
+
str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m"
|
11
11
|
|
data/demo/03_logger.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# ANSI::Logger
|
2
|
+
|
3
|
+
Require the ANSI::Logger library.
|
4
|
+
|
5
|
+
require 'ansi/logger'
|
6
|
+
|
7
|
+
Create a new ANSI::Logger
|
8
|
+
|
9
|
+
log = ANSI::Logger.new(STDOUT)
|
10
|
+
|
11
|
+
Info logging appears normal.
|
12
|
+
|
13
|
+
log.info{"Info logs are green.\n"}
|
14
|
+
|
15
|
+
Warn logging appears yellow.
|
16
|
+
|
17
|
+
log.warn{"Warn logs are yellow.\n"}
|
18
|
+
|
19
|
+
Debug logging appears cyan.
|
20
|
+
|
21
|
+
log.debug{"Debug logs are cyan.\n"}
|
22
|
+
|
23
|
+
Error logging appears red.
|
24
|
+
|
25
|
+
log.error{"Error logs are red.\n"}
|
26
|
+
|
27
|
+
Fatal logging appears bright red.
|
28
|
+
|
29
|
+
log.fatal{"Fatal logs are bold red!\n"}
|
30
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# ANSI::Progressbar
|
2
|
+
|
3
|
+
Pretty progress bars are easy to construct.
|
4
|
+
|
5
|
+
require 'ansi/progressbar'
|
6
|
+
|
7
|
+
pbar = ANSI::Progressbar.new("Test Bar", 100)
|
8
|
+
|
9
|
+
Running the bar simply requires calling the #inc method during
|
10
|
+
a loop and calling `#finish` when done.
|
11
|
+
|
12
|
+
100.times do |i|
|
13
|
+
sleep 0.01
|
14
|
+
pbar.inc
|
15
|
+
end
|
16
|
+
pbar.finish
|
17
|
+
|
18
|
+
We will use this same rountine in all the examples below, so lets
|
19
|
+
make a quick macro for it. Notice we have to use `#reset` first
|
20
|
+
before reusing the same progress bar.
|
21
|
+
|
22
|
+
def run(pbar)
|
23
|
+
pbar.reset
|
24
|
+
100.times do |i|
|
25
|
+
sleep 0.01
|
26
|
+
pbar.inc
|
27
|
+
end
|
28
|
+
pbar.finish
|
29
|
+
puts
|
30
|
+
end
|
31
|
+
|
32
|
+
The progress bar can be stylized in almost any way.
|
33
|
+
The `#format` setter provides control over the parts
|
34
|
+
that appear on the line. For example, by default the
|
35
|
+
format is:
|
36
|
+
|
37
|
+
pbar.format("%-14s %3d%% %s %s", :title, :percentage, :bar, :stat)
|
38
|
+
|
39
|
+
So lets vary it up to demonstrate the case.
|
40
|
+
|
41
|
+
pbar.format("%-14s %3d%% %s %s", :title, :percentage, :stat, :bar)
|
42
|
+
run(pbar)
|
43
|
+
|
44
|
+
The progress bar has an extra build in format intended for use with
|
45
|
+
file downloads called `#transer_mode`.
|
46
|
+
|
47
|
+
pbar.transfer_mode
|
48
|
+
run(pbar)
|
49
|
+
|
50
|
+
Calling this methods is the same as calling:
|
51
|
+
|
52
|
+
pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer)
|
53
|
+
run(pbar)
|
54
|
+
|
55
|
+
The `#style` setter allows each part of the line be modified with ANSI codes. And the
|
56
|
+
`#bar_mark` writer can be used to change the character used to make the bar.
|
57
|
+
|
58
|
+
pbar.standard_mode
|
59
|
+
pbar.style(:title => [:red], :bar=>[:blue])
|
60
|
+
pbar.bar_mark = "="
|
61
|
+
run(pbar)
|
62
|
+
|
@@ -1,37 +1,37 @@
|
|
1
|
-
|
1
|
+
# ANSI::Mixin
|
2
2
|
|
3
3
|
The ANSI::Mixin module is design for including into
|
4
4
|
String-like classes. It will support any class that defines
|
5
5
|
a #to_s method.
|
6
6
|
|
7
|
-
|
7
|
+
require 'ansi/mixin'
|
8
8
|
|
9
9
|
In this demonstration we will simply include it in the
|
10
10
|
core String class.
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
class ::String
|
13
|
+
include ANSI::Mixin
|
14
|
+
end
|
15
15
|
|
16
16
|
Now all strings will have access to ANSI's style and color
|
17
17
|
codes via simple method calls.
|
18
18
|
|
19
|
-
|
19
|
+
"roses".red.assert == "\e[31mroses\e[0m"
|
20
20
|
|
21
|
-
|
21
|
+
"violets".blue.assert == "\e[34mviolets\e[0m"
|
22
22
|
|
23
|
-
|
23
|
+
"sugar".italic.assert == "\e[3msugar\e[0m"
|
24
24
|
|
25
25
|
The method can be combined, of course.
|
26
26
|
|
27
|
-
|
27
|
+
"you".italic.bold.assert == "\e[1m\e[3myou\e[0m\e[0m"
|
28
28
|
|
29
29
|
The mixin also supports background methods.
|
30
30
|
|
31
|
-
|
31
|
+
"envy".on_green.assert == "\e[42menvy\e[0m"
|
32
32
|
|
33
33
|
And it also supports the combined foreground-on-background
|
34
34
|
methods.
|
35
35
|
|
36
|
-
|
36
|
+
"b&w".white_on_black.assert == "\e[37m\e[40mb&w\e[0m"
|
37
37
|
|
@@ -1,52 +1,52 @@
|
|
1
|
-
|
1
|
+
# ANSI::String
|
2
2
|
|
3
3
|
The ANSI::String class is a very sophisticated implementation
|
4
4
|
of Ruby's standard String class, but one that can handle
|
5
5
|
ANSI codes seamlessly.
|
6
6
|
|
7
|
-
|
7
|
+
require 'ansi/string'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
flower1 = ANSI::String.new("Roses")
|
10
|
+
flower2 = ANSI::String.new("Violets")
|
11
11
|
|
12
12
|
Like any other string.
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
flower1.to_s.assert == "Roses"
|
15
|
+
flower2.to_s.assert == "Violets"
|
16
16
|
|
17
17
|
Bet now we can add color.
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
flower1.red!
|
20
|
+
flower2.blue!
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
flower1.to_s.assert == "\e[31mRoses\e[0m"
|
23
|
+
flower2.to_s.assert == "\e[34mViolets\e[0m"
|
24
24
|
|
25
25
|
Despite that the string representation now contains ANSI codes,
|
26
26
|
we can still manipulate the string in much the same way that
|
27
27
|
we manipulate an ordinary string.
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
flower1.size.assert == 5
|
30
|
+
flower2.size.assert == 7
|
31
31
|
|
32
32
|
Like ordinary strings we can concatenate the two strings
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
flowers = flower1 + ' ' + flower2
|
35
|
+
flowers.to_s.assert == "\e[31mRoses\e[0m \e[34mViolets\e[0m"
|
36
36
|
|
37
|
-
|
37
|
+
flowers.size.assert == 13
|
38
38
|
|
39
39
|
Standard case conversion such as #upcase and #downcase work.
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
flower1.upcase.to_s.assert == "\e[31mROSES\e[0m"
|
42
|
+
flower1.downcase.to_s.assert == "\e[31mroses\e[0m"
|
43
43
|
|
44
44
|
Some of the most difficult methods to re-implement were the
|
45
45
|
substitution methods such as #sub and #gsub. They are still
|
46
46
|
somewhat more limited than the original string methods, but
|
47
47
|
their primary functionality should work.
|
48
48
|
|
49
|
-
|
49
|
+
flower1.gsub('s', 'z').to_s.assert == "\e[31mRozez\e[0m"
|
50
50
|
|
51
51
|
There are still a number of methods that need implementation.
|
52
52
|
ANSI::String is currently a very partial implementation. But
|
data/demo/07_columns.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# ANSI::Columns
|
2
|
+
|
3
|
+
The +Columns+ class makes it easy to create nice looking text columns,
|
4
|
+
sorted from top to bottom, right to left (as opposed to the other way
|
5
|
+
around).
|
6
|
+
|
7
|
+
require 'ansi/columns'
|
8
|
+
|
9
|
+
list = %w{a b c d e f g h i j k l}
|
10
|
+
|
11
|
+
columns = ANSI::Columns.new(list)
|
12
|
+
|
13
|
+
columns.to_s(4)
|
14
|
+
|
15
|
+
The output will be:
|
16
|
+
|
17
|
+
a d g j
|
18
|
+
b e h k
|
19
|
+
c f i l
|
20
|
+
|
21
|
+
Besides an array of elements, Columns.new can take a string in which
|
22
|
+
the elements are divided by newlines characters. The default column
|
23
|
+
size can also be given to the initializer.
|
24
|
+
|
25
|
+
list = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl"
|
26
|
+
|
27
|
+
columns = ANSI::Columns.new(list, :columns=>6)
|
28
|
+
|
29
|
+
columns.to_s
|
30
|
+
|
31
|
+
The output will be:
|
32
|
+
|
33
|
+
a c e g i k
|
34
|
+
b d f h j l
|
35
|
+
|
36
|
+
If the column count is +nil+, then the number of columns will be calculated
|
37
|
+
as a best fit for the current terminal window.
|
38
|
+
|
39
|
+
## Padding
|
40
|
+
|
41
|
+
Columns can adjust the padding between cells.
|
42
|
+
|
43
|
+
list = %w{a b c d e f g h i j k l}
|
44
|
+
|
45
|
+
columns = ANSI::Columns.new(list, :padding=>2)
|
46
|
+
|
47
|
+
columns.to_s(4)
|
48
|
+
|
49
|
+
The output will be:
|
50
|
+
|
51
|
+
a d g j
|
52
|
+
b e h k
|
53
|
+
c f i l
|
54
|
+
|
55
|
+
## Alignment
|
56
|
+
|
57
|
+
Columns can also be aligned either left or right.
|
58
|
+
|
59
|
+
list = %w{xx xx xx yy y yy z zz z}
|
60
|
+
|
61
|
+
columns = ANSI::Columns.new(list, :align=>:right)
|
62
|
+
|
63
|
+
columns.to_s(3)
|
64
|
+
|
65
|
+
The output will be:
|
66
|
+
|
67
|
+
xx yy z
|
68
|
+
xx y zz
|
69
|
+
xx yy z
|
70
|
+
|
71
|
+
## Format
|
72
|
+
|
73
|
+
Lastly, columns can be augmented with ANSI codes. This is done through
|
74
|
+
a formatting block. The block can take up to three parameters, the cell
|
75
|
+
content, the column and row numbers, or the cell and the column and row
|
76
|
+
numbers.
|
77
|
+
|
78
|
+
list = %w{a b c d e f g h i j k l}
|
79
|
+
|
80
|
+
columns = ANSI::Columns.new(list){ |c,r| r % 2 == 0 ? :red : :blue }
|
81
|
+
|
82
|
+
out = columns.to_s(4)
|
83
|
+
|
84
|
+
out.assert == (
|
85
|
+
"\e[31ma \e[0m\e[31md \e[0m\e[31mg \e[0m\e[31mj \e[0m\n" +
|
86
|
+
"\e[34mb \e[0m\e[34me \e[0m\e[34mh \e[0m\e[34mk \e[0m\n" +
|
87
|
+
"\e[31mc \e[0m\e[31mf \e[0m\e[31mi \e[0m\e[31ml \e[0m\n"
|
88
|
+
)
|
89
|
+
|
data/demo/08_table.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# ANSI::Table
|
2
|
+
|
3
|
+
The ANSI::Table class can be used to output tabular data with nicely
|
4
|
+
formated ASCII cell borders.
|
5
|
+
|
6
|
+
require 'ansi/table'
|
7
|
+
|
8
|
+
The constructor takes an 2-dimensional array.
|
9
|
+
|
10
|
+
data = [
|
11
|
+
[ 10, 20, 30 ],
|
12
|
+
[ 20, 10, 20 ],
|
13
|
+
[ 50, 40, 20 ]
|
14
|
+
]
|
15
|
+
|
16
|
+
table = ANSI::Table.new(data)
|
17
|
+
|
18
|
+
table.to_s
|
19
|
+
|
20
|
+
The output will be:
|
21
|
+
|
22
|
+
+----+----+----+
|
23
|
+
| 10 | 20 | 30 |
|
24
|
+
| 20 | 10 | 20 |
|
25
|
+
| 50 | 40 | 20 |
|
26
|
+
+----+----+----+
|
27
|
+
|
28
|
+
|
data/demo/09_diff.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# ANSI::Diff
|
2
|
+
|
3
|
+
require 'ansi/diff'
|
4
|
+
|
5
|
+
a = 'abcYefg'
|
6
|
+
b = 'abcXefg'
|
7
|
+
|
8
|
+
diff = ANSI::Diff.new(a,b)
|
9
|
+
|
10
|
+
diff.to_s.assert == "\e[31mabc\e[0m\e[33mYefg\e[0m\n\e[31mabc\e[0mXefg"
|
11
|
+
|
12
|
+
Try another.
|
13
|
+
|
14
|
+
a = 'abc'
|
15
|
+
b = 'abcdef'
|
16
|
+
|
17
|
+
diff = ANSI::Diff.new(a,b)
|
18
|
+
|
19
|
+
diff.to_s.assert == "\e[31mabc\e[0m\n\e[31mabc\e[0mdef"
|
20
|
+
|
21
|
+
And another.
|
22
|
+
|
23
|
+
a = 'abcXXXghi'
|
24
|
+
b = 'abcdefghi'
|
25
|
+
|
26
|
+
diff = ANSI::Diff.new(a,b)
|
27
|
+
|
28
|
+
diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXXghi\e[0m\n\e[31mabc\e[0mdefghi"
|
29
|
+
|
30
|
+
And another.
|
31
|
+
|
32
|
+
a = 'abcXXXdefghi'
|
33
|
+
b = 'abcdefghi'
|
34
|
+
|
35
|
+
diff = ANSI::Diff.new(a,b)
|
36
|
+
|
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
|
+
|
39
|
+
Comparison that is mostly different.
|
40
|
+
|
41
|
+
a = 'abcpppz123'
|
42
|
+
b = 'abcxyzzz43'
|
43
|
+
|
44
|
+
diff = ANSI::Diff.new(a,b)
|
45
|
+
|
46
|
+
diff.to_s.assert == "\e[31mabc\e[0m\e[33mpppz123\e[0m\n\e[31mabc\e[0mxyzzz43"
|
47
|
+
|