term-ansicolor 1.8.0 → 1.10.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.utilsrc +26 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/term_colortab +27 -1
- data/bin/term_display +5 -3
- data/bin/term_mandel +11 -13
- data/bin/term_snow +13 -13
- data/examples/example.rb +29 -1
- data/lib/term/ansicolor/attribute/color256.rb +38 -36
- data/lib/term/ansicolor/attribute/color8.rb +16 -16
- data/lib/term/ansicolor/attribute/text.rb +18 -15
- data/lib/term/ansicolor/attribute/underline.rb +34 -0
- data/lib/term/ansicolor/attribute.rb +85 -45
- data/lib/term/ansicolor/ppm_reader.rb +9 -4
- data/lib/term/ansicolor/version.rb +1 -1
- data/lib/term/ansicolor.rb +42 -40
- data/term-ansicolor.gemspec +7 -6
- data/tests/ansicolor_test.rb +61 -2
- data/tests/attribute_test.rb +45 -6
- data/tests/hsl_triple_test.rb +1 -1
- data/tests/hyperlink_test.rb +5 -1
- data/tests/ppm_reader_test.rb +8 -0
- metadata +20 -4
- data/.tool-versions +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b4b022358ec0c08c813fd02b38a04f434d49fcd75db660e25b8fe99a7b1e847
|
4
|
+
data.tar.gz: a829c2406f9a20c5738297253bcf3e3dc46f497fbb0c3433bef01fa488cd9c10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ee33e17663543ec540ae88b5e84ff8ea6651394d62fe71086258f1294e556180c3255a3f2615dba39f54ab712927b5d862607995e41e7a86cbd43e3ffc89230
|
7
|
+
data.tar.gz: b17b3b732562f3132f478d01c6ba8b96ae9c158d50ad0ca147c722ddc232125301d911574996e023a4e25696ef574bfce986df05b5a487bd43fb5d82fb6ba4ae
|
data/.gitignore
CHANGED
data/.utilsrc
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim: set ft=ruby:
|
2
|
+
|
3
|
+
search do
|
4
|
+
prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
|
5
|
+
skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|tags|~\z)/i
|
6
|
+
end
|
7
|
+
|
8
|
+
discover do
|
9
|
+
prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
|
10
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
11
|
+
binary false
|
12
|
+
end
|
13
|
+
|
14
|
+
strip_spaces do
|
15
|
+
prune_dirs /\A(\..*|CVS|pkg)\z/
|
16
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
17
|
+
end
|
18
|
+
|
19
|
+
probe do
|
20
|
+
test_framework :"test-unit"
|
21
|
+
end
|
22
|
+
|
23
|
+
ssh_tunnel do
|
24
|
+
terminal_multiplexer :tmux
|
25
|
+
end
|
26
|
+
|
data/Rakefile
CHANGED
@@ -15,12 +15,13 @@ GemHadar do
|
|
15
15
|
|
16
16
|
test_dir 'tests'
|
17
17
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.rvmrc', 'coverage',
|
18
|
-
'tags', '.bundle', '.byebug_history'
|
18
|
+
'tags', '.bundle', '.byebug_history', 'errors.lst'
|
19
19
|
|
20
20
|
readme 'README.md'
|
21
21
|
executables.merge Dir['bin/*'].map { |x| File.basename(x) }
|
22
22
|
|
23
23
|
dependency 'tins', '~>1.0'
|
24
|
+
dependency 'mize'
|
24
25
|
development_dependency 'simplecov'
|
25
26
|
development_dependency 'test-unit'
|
26
27
|
development_dependency 'utils'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.10.0
|
data/bin/term_colortab
CHANGED
@@ -15,6 +15,32 @@ def print_color(c)
|
|
15
15
|
print ("%3u #{color.rgb.html} " % c).on_color(color.name).color(text.name)
|
16
16
|
end
|
17
17
|
|
18
|
+
if Term::ANSIColor.true_coloring = ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/
|
19
|
+
|
20
|
+
puts "True colors".bold, ""
|
21
|
+
step = 36
|
22
|
+
(0..255).step(step) do |g|
|
23
|
+
(0..255).step(step) do |r|
|
24
|
+
(0..255).step(step) do |b|
|
25
|
+
print Term::ANSIColor.on_color(Term::ANSIColor::RGBTriple.new(r, g, b)) { ' ' }
|
26
|
+
end
|
27
|
+
print ' '
|
28
|
+
end
|
29
|
+
puts
|
30
|
+
end
|
31
|
+
|
32
|
+
puts
|
33
|
+
(0..255).step(4) do |g|
|
34
|
+
print Term::ANSIColor.on_color(Term::ANSIColor::RGBTriple.new(g, g, g)) { ' ' }
|
35
|
+
end
|
36
|
+
puts
|
37
|
+
puts
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
Term::ANSIColor.true_coloring = false
|
42
|
+
|
43
|
+
puts "256 colors".bold, ""
|
18
44
|
for c in 0..3
|
19
45
|
print_color c
|
20
46
|
end
|
@@ -40,10 +66,10 @@ for c in 16..231
|
|
40
66
|
(c - 16) % 36 == 0 and puts
|
41
67
|
print_color c
|
42
68
|
end
|
69
|
+
puts
|
43
70
|
|
44
71
|
for c in 232..255
|
45
72
|
(c - 16) % 6 == 0 and puts
|
46
|
-
(c - 16) % 12 == 0 and puts
|
47
73
|
print_color c
|
48
74
|
end
|
49
75
|
puts
|
data/bin/term_display
CHANGED
@@ -65,13 +65,14 @@ Options are
|
|
65
65
|
-a ASPECT x:y aspect, defaults to 2.2
|
66
66
|
-C COLS number of columns for rendering with aspect, defaults to max
|
67
67
|
-R ROWS number of rows for rendering with aspect, defaults to max - 1
|
68
|
+
-t use true colors
|
68
69
|
-h this help
|
69
70
|
|
70
71
|
EOT
|
71
72
|
exit rc
|
72
73
|
end
|
73
74
|
|
74
|
-
opts = go 'hm:g:s:a:C:R:'
|
75
|
+
opts = go 'hm:g:s:a:C:R:t'
|
75
76
|
opts['h'] and usage
|
76
77
|
filename = ARGV.shift or usage 1
|
77
78
|
metric = Term::ANSIColor::RGBColorMetrics.metric(opts['m'] || 'CIELab')
|
@@ -84,8 +85,9 @@ opts['R'] ||= [ Tins::Terminal.rows - 1, 0 ].max
|
|
84
85
|
file = provide_ppm_file(filename, opts)
|
85
86
|
ppm = Term::ANSIColor::PPMReader.new(
|
86
87
|
file,
|
87
|
-
:metric
|
88
|
-
:gray
|
88
|
+
metric: metric,
|
89
|
+
gray: gray,
|
90
|
+
true_coloring: opts[?t]
|
89
91
|
)
|
90
92
|
|
91
93
|
puts ppm
|
data/bin/term_mandel
CHANGED
@@ -15,16 +15,12 @@ def draw_set(rx, ry)
|
|
15
15
|
sx = (rx.end - rx.begin).abs / @width
|
16
16
|
sy = (ry.end - ry.begin).abs / @height
|
17
17
|
|
18
|
-
ac
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
|
25
|
-
ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
|
26
|
-
ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
|
27
|
-
ac::Attribute[ color_random ].gradient_to(ac::Attribute['#000'], :steps => 16)
|
18
|
+
ac = Term::ANSIColor
|
19
|
+
steps = 16
|
20
|
+
color = (5.times.map { color_random } + [ 0, 0, 0 ]).map { ac::Attribute[_1] }
|
21
|
+
color = color[1..-1].inject(color[0,1]) { |c, x|
|
22
|
+
c + c.last.gradient_to(x, steps:)
|
23
|
+
}
|
28
24
|
iters = color.size - 2
|
29
25
|
|
30
26
|
text = ''
|
@@ -44,9 +40,11 @@ def draw_set(rx, ry)
|
|
44
40
|
puts text
|
45
41
|
end
|
46
42
|
|
47
|
-
opts = go 'x:y
|
43
|
+
opts = go 'x:y'
|
48
44
|
|
49
|
-
|
50
|
-
|
45
|
+
Term::ANSIColor.true_coloring = ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/
|
46
|
+
|
47
|
+
rx = opts[?x].full? { |r| Range.new(*(r.split('..', 2).map(&:to_f))) } || (-2.0..1.0)
|
48
|
+
ry = opts[?y].full? { |r| Range.new(*(r.split('..', 2).map(&:to_f))) } || (-1.0..1.0)
|
51
49
|
|
52
50
|
draw_set rx, ry
|
data/bin/term_snow
CHANGED
@@ -9,23 +9,23 @@ class SnowFlake
|
|
9
9
|
extend Term::ANSIColor
|
10
10
|
|
11
11
|
def initialize(x, y, shape: %w[ ❄ ❅ ❆ • • · · . . ])
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
@x, @y, @shape = x, y, Array(shape).sample
|
13
|
+
@shape.size != 1 and raise ArgumentError, "#@shape needs to be a character"
|
14
|
+
end
|
15
15
|
|
16
|
-
|
16
|
+
attr_accessor :x
|
17
17
|
|
18
|
-
|
18
|
+
attr_accessor :y
|
19
19
|
|
20
|
-
|
20
|
+
attr_accessor :shape
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def to_s
|
23
|
+
move_to(y, x) { white on_black @shape }
|
24
|
+
end
|
25
25
|
end
|
26
26
|
|
27
|
-
opts
|
28
|
-
new_snowflakes
|
27
|
+
opts = go 'n:s:'
|
28
|
+
new_snowflakes = (opts[?n] || 3).to_i
|
29
29
|
sleep_duration = (opts[?s] || 0.2).to_f
|
30
30
|
|
31
31
|
flakes = []
|
@@ -51,7 +51,7 @@ loop do
|
|
51
51
|
sf.x = SnowFlake.terminal_columns
|
52
52
|
end
|
53
53
|
else
|
54
|
-
sf.x
|
54
|
+
sf.x += 1
|
55
55
|
if sf.x > SnowFlake.terminal_columns
|
56
56
|
sf.x = 1
|
57
57
|
end
|
@@ -64,7 +64,7 @@ loop do
|
|
64
64
|
flakes << SnowFlake.new(rand(1..SnowFlake.terminal_columns), 1)
|
65
65
|
end
|
66
66
|
|
67
|
-
print
|
67
|
+
print(*flakes)
|
68
68
|
|
69
69
|
sleep sleep_duration
|
70
70
|
rescue Interrupt
|
data/examples/example.rb
CHANGED
@@ -76,11 +76,39 @@ print "clear".clear, "reset".reset, "bold".bold, "dark".dark,
|
|
76
76
|
|
77
77
|
symbols = Term::ANSIColor::attributes
|
78
78
|
print red { bold { "All supported attributes = " } },
|
79
|
-
symbols.map { |s| __send__(s, s.inspect) } *
|
79
|
+
symbols.map { |s| __send__(s, s.inspect) } * ",\n", "\n\n"
|
80
80
|
|
81
81
|
print "Send symbols to strings:".send(:red).send(:bold), "\n"
|
82
82
|
print symbols[12, 8].map { |c| c.to_s.send(c) } * '', "\n\n"
|
83
83
|
|
84
|
+
print red { bold { "Use true colors if supported" } }, "\n"
|
85
|
+
|
86
|
+
colors = Term::ANSIColor::Attribute['#ff0000'].gradient_to(
|
87
|
+
Term::ANSIColor::Attribute['#ffff00'],
|
88
|
+
true_coloring: true,
|
89
|
+
step: 16
|
90
|
+
)
|
91
|
+
colors += Term::ANSIColor::Attribute[colors.last].gradient_to(
|
92
|
+
Term::ANSIColor::Attribute['#00ff00'],
|
93
|
+
true_coloring: true,
|
94
|
+
step: 16
|
95
|
+
)
|
96
|
+
colors += Term::ANSIColor::Attribute[colors.last].gradient_to(
|
97
|
+
Term::ANSIColor::Attribute['#00ffff'],
|
98
|
+
true_coloring: true,
|
99
|
+
step: 16
|
100
|
+
)
|
101
|
+
colors += Term::ANSIColor::Attribute[colors.last].gradient_to(
|
102
|
+
Term::ANSIColor::Attribute['#0000ff'],
|
103
|
+
true_coloring: true,
|
104
|
+
step: 16
|
105
|
+
)
|
106
|
+
|
107
|
+
chars = %w[ ⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷ ]
|
108
|
+
colors.each_with_index { |c, i| print c.apply { chars[i % chars.size] } }
|
109
|
+
puts
|
110
|
+
puts
|
111
|
+
|
84
112
|
print red { bold { "Make strings monochromatic again:" } }, "\n"
|
85
113
|
print [
|
86
114
|
"red".red,
|
@@ -2,65 +2,67 @@ module Term
|
|
2
2
|
module ANSIColor
|
3
3
|
class Attribute
|
4
4
|
class Color256
|
5
|
-
Attribute.set :color0, 0, :
|
6
|
-
Attribute.set :color1, 1, :
|
7
|
-
Attribute.set :color2, 2, :
|
8
|
-
Attribute.set :color3, 3, :
|
9
|
-
Attribute.set :color4, 4, :
|
10
|
-
Attribute.set :color5, 5, :
|
11
|
-
Attribute.set :color6, 6, :
|
12
|
-
Attribute.set :color7, 7, :
|
5
|
+
Attribute.set :color0, 0, html: '#000000'
|
6
|
+
Attribute.set :color1, 1, html: '#800000'
|
7
|
+
Attribute.set :color2, 2, html: '#808000'
|
8
|
+
Attribute.set :color3, 3, html: '#808000'
|
9
|
+
Attribute.set :color4, 4, html: '#000080'
|
10
|
+
Attribute.set :color5, 5, html: '#800080'
|
11
|
+
Attribute.set :color6, 6, html: '#008080'
|
12
|
+
Attribute.set :color7, 7, html: '#c0c0c0'
|
13
13
|
|
14
|
-
Attribute.set :color8, 8, :
|
15
|
-
Attribute.set :color9, 9, :
|
16
|
-
Attribute.set :color10, 10, :
|
17
|
-
Attribute.set :color11, 11, :
|
18
|
-
Attribute.set :color12, 12, :
|
19
|
-
Attribute.set :color13, 13, :
|
20
|
-
Attribute.set :color14, 14, :
|
21
|
-
Attribute.set :color15, 15, :
|
14
|
+
Attribute.set :color8, 8, html: '#808080'
|
15
|
+
Attribute.set :color9, 9, html: '#ff0000'
|
16
|
+
Attribute.set :color10, 10, html: '#00ff00'
|
17
|
+
Attribute.set :color11, 11, html: '#ffff00'
|
18
|
+
Attribute.set :color12, 12, html: '#0000ff'
|
19
|
+
Attribute.set :color13, 13, html: '#ff00ff'
|
20
|
+
Attribute.set :color14, 14, html: '#00ffff'
|
21
|
+
Attribute.set :color15, 15, html: '#ffffff'
|
22
22
|
|
23
23
|
steps = [ 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff ]
|
24
24
|
|
25
25
|
for i in 16..231
|
26
26
|
red, green, blue = (i - 16).to_s(6).rjust(3, '0').each_char.map { |c| steps[c.to_i] }
|
27
|
-
Attribute.set "color#{i}", i, :
|
27
|
+
Attribute.set "color#{i}", i, red: red, green: green, blue: blue
|
28
28
|
end
|
29
29
|
|
30
30
|
grey = 8
|
31
31
|
for i in 232..255
|
32
|
-
Attribute.set "color#{i}", i, :
|
32
|
+
Attribute.set "color#{i}", i, red: grey, green: grey, blue: grey
|
33
33
|
grey += 10
|
34
34
|
end
|
35
35
|
|
36
|
-
Attribute.set :on_color0, 0, :
|
37
|
-
Attribute.set :on_color1, 1, :
|
38
|
-
Attribute.set :on_color2, 2, :
|
39
|
-
Attribute.set :on_color3, 3, :
|
40
|
-
Attribute.set :on_color4, 4, :
|
41
|
-
Attribute.set :on_color5, 5, :
|
42
|
-
Attribute.set :on_color6, 6, :
|
43
|
-
Attribute.set :on_color7, 7, :
|
36
|
+
Attribute.set :on_color0, 0, html: '#000000', background: true
|
37
|
+
Attribute.set :on_color1, 1, html: '#800000', background: true
|
38
|
+
Attribute.set :on_color2, 2, html: '#808000', background: true
|
39
|
+
Attribute.set :on_color3, 3, html: '#808000', background: true
|
40
|
+
Attribute.set :on_color4, 4, html: '#000080', background: true
|
41
|
+
Attribute.set :on_color5, 5, html: '#800080', background: true
|
42
|
+
Attribute.set :on_color6, 6, html: '#008080', background: true
|
43
|
+
Attribute.set :on_color7, 7, html: '#c0c0c0'
|
44
44
|
|
45
|
-
Attribute.set :on_color8, 8, :
|
46
|
-
Attribute.set :on_color9, 9, :
|
47
|
-
Attribute.set :on_color10, 10, :
|
48
|
-
Attribute.set :on_color11, 11, :
|
49
|
-
Attribute.set :on_color12, 12, :
|
50
|
-
Attribute.set :on_color13, 13, :
|
51
|
-
Attribute.set :on_color14, 14, :
|
52
|
-
Attribute.set :on_color15, 15, :
|
45
|
+
Attribute.set :on_color8, 8, html: '#808080', background: true
|
46
|
+
Attribute.set :on_color9, 9, html: '#ff0000', background: true
|
47
|
+
Attribute.set :on_color10, 10, html: '#00ff00', background: true
|
48
|
+
Attribute.set :on_color11, 11, html: '#ffff00', background: true
|
49
|
+
Attribute.set :on_color12, 12, html: '#0000ff', background: true
|
50
|
+
Attribute.set :on_color13, 13, html: '#ff00ff', background: true
|
51
|
+
Attribute.set :on_color14, 14, html: '#00ffff', background: true
|
52
|
+
Attribute.set :on_color15, 15, html: '#ffffff', background: true
|
53
53
|
|
54
54
|
steps = [ 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff ]
|
55
55
|
|
56
56
|
for i in 16..231
|
57
57
|
red, green, blue = (i - 16).to_s(6).rjust(3, '0').each_char.map { |c| steps[c.to_i] }
|
58
|
-
Attribute.set "on_color#{i}", i,
|
58
|
+
Attribute.set "on_color#{i}", i,
|
59
|
+
red: red, green: green, blue: blue, background: true
|
59
60
|
end
|
60
61
|
|
61
62
|
grey = 8
|
62
63
|
for i in 232..255
|
63
|
-
Attribute.set "on_color#{i}", i,
|
64
|
+
Attribute.set "on_color#{i}", i,
|
65
|
+
red: grey, green: grey, blue: grey, background: true
|
64
66
|
grey += 10
|
65
67
|
end
|
66
68
|
end
|
@@ -2,23 +2,23 @@ module Term
|
|
2
2
|
module ANSIColor
|
3
3
|
class Attribute
|
4
4
|
class Color8
|
5
|
-
Attribute.set :black, 30
|
6
|
-
Attribute.set :red, 31
|
7
|
-
Attribute.set :green, 32
|
8
|
-
Attribute.set :yellow, 33
|
9
|
-
Attribute.set :blue, 34
|
10
|
-
Attribute.set :magenta, 35
|
11
|
-
Attribute.set :cyan, 36
|
12
|
-
Attribute.set :white, 37
|
5
|
+
Attribute.set :black, 30, color8: '#000000'
|
6
|
+
Attribute.set :red, 31, color8: '#800000'
|
7
|
+
Attribute.set :green, 32, color8: '#008000'
|
8
|
+
Attribute.set :yellow, 33, color8: '#808000'
|
9
|
+
Attribute.set :blue, 34, color8: '#000080'
|
10
|
+
Attribute.set :magenta, 35, color8: '#800080'
|
11
|
+
Attribute.set :cyan, 36, color8: '#008080'
|
12
|
+
Attribute.set :white, 37, color8: '#c0c0c0'
|
13
13
|
|
14
|
-
Attribute.set :on_black, 40
|
15
|
-
Attribute.set :on_red, 41
|
16
|
-
Attribute.set :on_green, 42
|
17
|
-
Attribute.set :on_yellow, 43
|
18
|
-
Attribute.set :on_blue, 44
|
19
|
-
Attribute.set :on_magenta, 45
|
20
|
-
Attribute.set :on_cyan, 46
|
21
|
-
Attribute.set :on_white, 47
|
14
|
+
Attribute.set :on_black, 40, color8: '#000000'
|
15
|
+
Attribute.set :on_red, 41, color8: '#800000'
|
16
|
+
Attribute.set :on_green, 42, color8: '#008000'
|
17
|
+
Attribute.set :on_yellow, 43, color8: '#808000'
|
18
|
+
Attribute.set :on_blue, 44, color8: '#000080'
|
19
|
+
Attribute.set :on_magenta, 45, color8: '#800080'
|
20
|
+
Attribute.set :on_cyan, 46, color8: '#008080'
|
21
|
+
Attribute.set :on_white, 47, color8: '#808080'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,22 +1,25 @@
|
|
1
|
+
require 'term/ansicolor/attribute/underline'
|
2
|
+
|
1
3
|
module Term
|
2
4
|
module ANSIColor
|
3
5
|
class Attribute
|
4
6
|
class Text
|
5
|
-
Attribute.set :clear,
|
6
|
-
Attribute.set :reset,
|
7
|
-
Attribute.set :bold,
|
8
|
-
Attribute.set :dark,
|
9
|
-
Attribute.set :faint,
|
10
|
-
Attribute.set :italic,
|
11
|
-
Attribute.set :
|
12
|
-
Attribute.set :
|
13
|
-
Attribute.set :
|
14
|
-
Attribute.set :
|
15
|
-
Attribute.set :
|
16
|
-
Attribute.set :
|
17
|
-
Attribute.set :
|
18
|
-
Attribute.set :
|
19
|
-
|
7
|
+
Attribute.set :clear, 0 # String#clear already used in String
|
8
|
+
Attribute.set :reset, 0 # synonym for :clear
|
9
|
+
Attribute.set :bold, 1
|
10
|
+
Attribute.set :dark, 2
|
11
|
+
Attribute.set :faint, 2
|
12
|
+
Attribute.set :italic, 3 # not widely implemented
|
13
|
+
Attribute.set :blink, 5
|
14
|
+
Attribute.set :rapid_blink, 6 # not widely implemented
|
15
|
+
Attribute.set :reverse, 7 # String#reverse already used in String
|
16
|
+
Attribute.set :negative, 7 # synonym for :reverse
|
17
|
+
Attribute.set :concealed, 8
|
18
|
+
Attribute.set :conceal, 8 # synonym for :concealed
|
19
|
+
Attribute.set :strikethrough, 9 # not widely implemented
|
20
|
+
Attribute.set :overline, 53
|
21
|
+
|
22
|
+
include Term::ANSIColor::Attribute::Underline
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Term
|
2
|
+
module ANSIColor
|
3
|
+
class Attribute
|
4
|
+
module Underline
|
5
|
+
Attribute.set :underline, 4, skip_definition: true
|
6
|
+
Attribute.set :underscore, 4, skip_definition: true # synonym for :underline
|
7
|
+
|
8
|
+
def underline(string = nil, color: nil, type: nil, &block)
|
9
|
+
code = {
|
10
|
+
nil => 4,
|
11
|
+
default: '4:1',
|
12
|
+
double: '4:2',
|
13
|
+
curly: '4:3',
|
14
|
+
dotted: '4:4',
|
15
|
+
dashed: '4:5',
|
16
|
+
}.fetch(type) { raise ArgumentError, "invalid line type" }
|
17
|
+
if color
|
18
|
+
a = Term::ANSIColor::Attribute[color]
|
19
|
+
color_code =
|
20
|
+
if a.true_color? || a.rgb_color? || a.color8?
|
21
|
+
color_code = "\e[58;2;#{a.rgb.to_a * ?;}"
|
22
|
+
else
|
23
|
+
raise ArgumentError, "invalid color #{a.name.inspect}"
|
24
|
+
end
|
25
|
+
code = "#{code}m#{color_code}"
|
26
|
+
end
|
27
|
+
apply_code(code, string, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
alias underscore underline
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,42 +3,45 @@ module Term
|
|
3
3
|
class Attribute
|
4
4
|
@__store__ = {}
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.attributes(&block)
|
18
|
-
@__order__.map { |name| @__store__[name] }
|
19
|
-
end
|
20
|
-
else
|
21
|
-
def self.set(name, code, options = {})
|
22
|
-
name = name.to_sym
|
23
|
-
result = @__store__[name] = new(name, code, options)
|
24
|
-
@rgb_colors = nil
|
25
|
-
result
|
6
|
+
def self.set(name, code, **options)
|
7
|
+
name = name.to_sym
|
8
|
+
result = @__store__[name] = new(name, code, options)
|
9
|
+
unless options[:skip_definition]
|
10
|
+
::Term::ANSIColor.class_eval do
|
11
|
+
define_method(name) do |string = nil, &block|
|
12
|
+
apply_attribute(name, string, &block)
|
13
|
+
end
|
14
|
+
end
|
26
15
|
end
|
16
|
+
result
|
17
|
+
end
|
27
18
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
19
|
+
def self.attributes(&block)
|
20
|
+
@__store__.each_value(&block)
|
31
21
|
end
|
32
22
|
|
33
|
-
def self.[](name)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
23
|
+
def self.[](name, true_coloring: false)
|
24
|
+
true_coloring ||= Term::ANSIColor.true_coloring?
|
25
|
+
if true_coloring
|
26
|
+
case
|
27
|
+
when self === name then name
|
28
|
+
when Array === name then true_color name
|
29
|
+
when name.respond_to?(:to_rgb_triple) then true_color(name.to_rgb_triple.to_a)
|
30
|
+
when name.to_s =~ /\A(on_)?(\d+)\z/ then get "#$1color#$2"
|
31
|
+
when name.to_s =~ /\A#([0-9a-f]{3}){1,2}\z/i then true_color name
|
32
|
+
when name.to_s =~ /\Aon_#([0-9a-f]{3}){1,2}\z/i then on_true_color name
|
33
|
+
else get name
|
34
|
+
end
|
35
|
+
else
|
36
|
+
case
|
37
|
+
when self === name then name
|
38
|
+
when Array === name then nearest_rgb_color name
|
39
|
+
when name.respond_to?(:to_rgb_triple) then nearest_rgb_color(name.to_rgb_triple.to_a)
|
40
|
+
when name.to_s =~ /\A(on_)?(\d+)\z/ then get "#$1color#$2"
|
41
|
+
when name.to_s =~ /\A#([0-9a-f]{3}){1,2}\z/i then nearest_rgb_color name
|
42
|
+
when name.to_s =~ /\Aon_#([0-9a-f]{3}){1,2}\z/i then nearest_rgb_on_color name
|
43
|
+
else get name
|
44
|
+
end
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
@@ -47,7 +50,7 @@ module Term
|
|
47
50
|
end
|
48
51
|
|
49
52
|
def self.rgb_colors(options = {}, &block)
|
50
|
-
colors =
|
53
|
+
colors = attributes.select(&:rgb_color?)
|
51
54
|
if options.key?(:gray) && !options[:gray]
|
52
55
|
colors = colors.reject(&:gray?)
|
53
56
|
end
|
@@ -70,12 +73,30 @@ module Term
|
|
70
73
|
colors.select(&:background?).min_by { |c| c.distance_to(rgb, options) }
|
71
74
|
end
|
72
75
|
|
76
|
+
def self.true_color(color, options = {})
|
77
|
+
rgb = RGBTriple[color]
|
78
|
+
new(:true, "", { true_color: rgb, background: false })
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.on_true_color(color, options = {})
|
82
|
+
rgb = RGBTriple[color]
|
83
|
+
new(:on_true, "", { true_color: rgb, background: true })
|
84
|
+
end
|
85
|
+
|
73
86
|
def initialize(name, code, options = {})
|
74
|
-
@name
|
75
|
-
@
|
76
|
-
|
87
|
+
@name = name.to_sym
|
88
|
+
@background = !!options[:background]
|
89
|
+
@code = code.to_s
|
90
|
+
@true_color = false
|
91
|
+
if rgb = options[:true_color]
|
92
|
+
@true_color = true
|
93
|
+
@rgb = rgb
|
94
|
+
elsif rgb = options[:color8]
|
95
|
+
@color8 = true
|
96
|
+
@rgb = RGBTriple.from_html(rgb)
|
97
|
+
elsif html = options[:html]
|
77
98
|
@rgb = RGBTriple.from_html(html)
|
78
|
-
elsif
|
99
|
+
elsif options.slice(:red, :green, :blue).size == 3
|
79
100
|
@rgb = RGBTriple.from_hash(options)
|
80
101
|
else
|
81
102
|
@rgb = nil # prevent instance variable not initialized warnings
|
@@ -85,25 +106,39 @@ module Term
|
|
85
106
|
attr_reader :name
|
86
107
|
|
87
108
|
def code
|
88
|
-
if
|
109
|
+
if true_color?
|
110
|
+
background? ? "48;2;#{@rgb.to_a * ?;}" : "38;2;#{@rgb.to_a * ?;}"
|
111
|
+
elsif rgb_color?
|
89
112
|
background? ? "48;5;#{@code}" : "38;5;#{@code}"
|
113
|
+
elsif color8?
|
114
|
+
background? ? (@code.to_i + 10).to_s : @code
|
90
115
|
else
|
91
116
|
@code
|
92
117
|
end
|
93
118
|
end
|
94
119
|
|
95
120
|
def apply(string = nil, &block)
|
96
|
-
::Term::ANSIColor.
|
121
|
+
::Term::ANSIColor.apply_attribute(self, string, &block)
|
97
122
|
end
|
98
123
|
|
99
124
|
def background?
|
100
|
-
|
125
|
+
!!@background
|
101
126
|
end
|
102
127
|
|
128
|
+
def color8?
|
129
|
+
!!@color8
|
130
|
+
end
|
131
|
+
|
132
|
+
attr_writer :background
|
133
|
+
|
103
134
|
attr_reader :rgb
|
104
135
|
|
105
136
|
def rgb_color?
|
106
|
-
!!@rgb
|
137
|
+
!!@rgb && !@true_color && !@color8
|
138
|
+
end
|
139
|
+
|
140
|
+
def true_color?
|
141
|
+
!!(@rgb && @true_color)
|
107
142
|
end
|
108
143
|
|
109
144
|
def gray?
|
@@ -127,11 +162,16 @@ module Term
|
|
127
162
|
|
128
163
|
def gradient_to(other, options = {})
|
129
164
|
if our_rgb = to_rgb_triple and
|
130
|
-
|
131
|
-
|
132
|
-
|
165
|
+
other.respond_to?(:to_rgb_triple) and
|
166
|
+
other_rgb = other.to_rgb_triple
|
167
|
+
then
|
168
|
+
true_coloring = options[:true_coloring] || Term::ANSIColor.true_coloring?
|
133
169
|
our_rgb.gradient_to(other_rgb, options).map do |rgb_triple|
|
134
|
-
|
170
|
+
if true_coloring
|
171
|
+
self.class.true_color(rgb_triple, options)
|
172
|
+
else
|
173
|
+
self.class.nearest_rgb_color(rgb_triple, options)
|
174
|
+
end
|
135
175
|
end
|
136
176
|
else
|
137
177
|
[]
|
@@ -4,9 +4,10 @@ module Term
|
|
4
4
|
include Term::ANSIColor
|
5
5
|
|
6
6
|
def initialize(io, options = {})
|
7
|
-
@io
|
8
|
-
@options
|
9
|
-
@buffer
|
7
|
+
@io = io
|
8
|
+
@options = options
|
9
|
+
@buffer = ''
|
10
|
+
@true_coloring = options[:true_coloring]
|
10
11
|
end
|
11
12
|
|
12
13
|
def reset_io
|
@@ -34,7 +35,11 @@ module Term
|
|
34
35
|
last_pixel = nil
|
35
36
|
for pixel in row
|
36
37
|
if pixel != last_pixel
|
37
|
-
color =
|
38
|
+
color = if @true_coloring
|
39
|
+
Attribute.true_color(pixel, @options)
|
40
|
+
else
|
41
|
+
Attribute.nearest_rgb_color(pixel, @options)
|
42
|
+
end
|
38
43
|
result << on_color(color)
|
39
44
|
last_pixel = pixel
|
40
45
|
end
|
data/lib/term/ansicolor.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'tins/xt/full'
|
2
|
+
require 'mize'
|
2
3
|
|
3
4
|
module Term
|
4
5
|
|
@@ -18,23 +19,8 @@ module Term
|
|
18
19
|
include Term::ANSIColor::Movement
|
19
20
|
require 'term/ansicolor/hyperlink'
|
20
21
|
include Term::ANSIColor::Hyperlink
|
22
|
+
include Term::ANSIColor::Attribute::Underline
|
21
23
|
|
22
|
-
# :stopdoc:
|
23
|
-
ATTRIBUTE_NAMES = Attribute.named_attributes.map(&:name)
|
24
|
-
# :startdoc:
|
25
|
-
|
26
|
-
# Returns true if Term::ANSIColor supports the +feature+.
|
27
|
-
#
|
28
|
-
# The feature :clear, that is mixing the clear color attribute into String,
|
29
|
-
# is only supported on ruby implementations, that do *not* already
|
30
|
-
# implement the String#clear method. It's better to use the reset color
|
31
|
-
# attribute instead.
|
32
|
-
def support?(feature)
|
33
|
-
case feature
|
34
|
-
when :clear
|
35
|
-
!String.instance_methods(false).map(&:to_sym).include?(:clear)
|
36
|
-
end
|
37
|
-
end
|
38
24
|
# Returns true, if the coloring function of this module
|
39
25
|
# is switched on, false otherwise.
|
40
26
|
def self.coloring?
|
@@ -43,31 +29,32 @@ module Term
|
|
43
29
|
|
44
30
|
# Turns the coloring on or off globally, so you can easily do
|
45
31
|
# this for example:
|
46
|
-
#
|
32
|
+
# Term::ANSIColor::coloring = STDOUT.isatty
|
47
33
|
def self.coloring=(val)
|
48
|
-
@coloring = val
|
34
|
+
@coloring = !!val
|
49
35
|
end
|
50
36
|
self.coloring = true
|
51
37
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
EOT
|
58
|
-
self
|
38
|
+
# Returns true, if the tue coloring mode of this module is switched on,
|
39
|
+
# false otherwise.
|
40
|
+
def self.true_coloring?
|
41
|
+
@true_coloring
|
59
42
|
end
|
60
43
|
|
61
|
-
|
62
|
-
|
44
|
+
# Turns the true coloring mode on or off globally, that will display 24-bit
|
45
|
+
# colors if your terminal supports it:
|
46
|
+
# Term::ANSIColor::true_coloring = ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/
|
47
|
+
def self.true_coloring=(val)
|
48
|
+
@true_coloring = !!val
|
63
49
|
end
|
50
|
+
self.true_coloring = false
|
64
51
|
|
65
52
|
# Regular expression that is used to scan for ANSI-Attributes while
|
66
53
|
# uncoloring strings.
|
67
|
-
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9]|[34]8;5;\d{1,3})?m/
|
54
|
+
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9]|[34]8;(5;\d{1,3}|2;\d{1,3}(;\d{1,3}){2})|4:\d|53)?m/
|
68
55
|
|
69
|
-
# Returns an uncolored version of the string, that is all
|
70
|
-
#
|
56
|
+
# Returns an uncolored version of the string, that is all ANSI-Attributes
|
57
|
+
# are stripped from the string.
|
71
58
|
def uncolor(string = nil) # :yields:
|
72
59
|
if block_given?
|
73
60
|
yield.to_str.gsub(COLORED_REGEXP, '')
|
@@ -82,13 +69,9 @@ module Term
|
|
82
69
|
|
83
70
|
alias uncolored uncolor
|
84
71
|
|
85
|
-
|
86
|
-
# color +name+. If string isn't a string only the escape sequence to switch
|
87
|
-
# on the color +name+ is returned.
|
88
|
-
def color(name, string = nil, &block)
|
89
|
-
attribute = Attribute[name] or raise ArgumentError, "unknown attribute #{name.inspect}"
|
72
|
+
def apply_code(code, string = nil, &block)
|
90
73
|
result = ''
|
91
|
-
result << "\e[#{
|
74
|
+
result << "\e[#{code}m" if Term::ANSIColor.coloring?
|
92
75
|
if block_given?
|
93
76
|
result << yield.to_s
|
94
77
|
elsif string.respond_to?(:to_str)
|
@@ -102,15 +85,34 @@ module Term
|
|
102
85
|
result.extend(Term::ANSIColor)
|
103
86
|
end
|
104
87
|
|
88
|
+
def apply_attribute(name, string = nil, &block)
|
89
|
+
attribute = Attribute[name] or
|
90
|
+
raise ArgumentError, "unknown attribute #{name.inspect}"
|
91
|
+
apply_code(attribute.code, string, &block)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return +string+ or the result string of the given +block+ colored with
|
95
|
+
# color +name+. If string isn't a string only the escape sequence to switch
|
96
|
+
# on the color +name+ is returned.
|
97
|
+
def color(name, string = nil, &block)
|
98
|
+
apply_attribute(name, string, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return +string+ or the result string of the given +block+ with a
|
102
|
+
# background colored with color +name+. If string isn't a string only the
|
103
|
+
# escape sequence to switch on the color +name+ is returned.
|
105
104
|
def on_color(name, string = nil, &block)
|
106
|
-
attribute = Attribute[name] or
|
107
|
-
|
105
|
+
attribute = Attribute[name] or
|
106
|
+
raise ArgumentError, "unknown attribute #{name.inspect}"
|
107
|
+
attribute = attribute.dup
|
108
|
+
attribute.background = true
|
109
|
+
apply_attribute(attribute, string, &block)
|
108
110
|
end
|
109
111
|
|
110
112
|
class << self
|
111
113
|
# Returns an array of all Term::ANSIColor attributes as symbols.
|
112
|
-
def term_ansicolor_attributes
|
113
|
-
::Term::ANSIColor::
|
114
|
+
memoize method: def term_ansicolor_attributes
|
115
|
+
::Term::ANSIColor::Attribute.attributes.map(&:name)
|
114
116
|
end
|
115
117
|
|
116
118
|
alias attributes term_ansicolor_attributes
|
data/term-ansicolor.gemspec
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: term-ansicolor 1.
|
2
|
+
# stub: term-ansicolor 1.10.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "term-ansicolor".freeze
|
6
|
-
s.version = "1.
|
6
|
+
s.version = "1.10.0".freeze
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Florian Frank".freeze]
|
11
|
-
s.date = "2024-
|
11
|
+
s.date = "2024-06-21"
|
12
12
|
s.description = "This library uses ANSI escape sequences to control the attributes of terminal output".freeze
|
13
13
|
s.email = "flori@ping.de".freeze
|
14
14
|
s.executables = ["term_cdiff".freeze, "term_colortab".freeze, "term_decolor".freeze, "term_display".freeze, "term_mandel".freeze, "term_snow".freeze]
|
15
|
-
s.extra_rdoc_files = ["README.md".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze]
|
16
|
-
s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".
|
15
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/attribute/underline.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze]
|
16
|
+
s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".utilsrc".freeze, "CHANGES".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/term_cdiff".freeze, "bin/term_colortab".freeze, "bin/term_decolor".freeze, "bin/term_display".freeze, "bin/term_mandel".freeze, "bin/term_snow".freeze, "examples/example.rb".freeze, "examples/lambda-red-plain.ppm".freeze, "examples/lambda-red.png".freeze, "examples/lambda-red.ppm".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/.keep".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/attribute/underline.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze, "term-ansicolor.gemspec".freeze, "tests/ansicolor_test.rb".freeze, "tests/attribute_test.rb".freeze, "tests/hsl_triple_test.rb".freeze, "tests/hyperlink_test.rb".freeze, "tests/ppm_reader_test.rb".freeze, "tests/rgb_color_metrics_test.rb".freeze, "tests/rgb_triple_test.rb".freeze, "tests/test_helper.rb".freeze]
|
17
17
|
s.homepage = "https://github.com/flori/term-ansicolor".freeze
|
18
18
|
s.licenses = ["Apache-2.0".freeze]
|
19
19
|
s.rdoc_options = ["--title".freeze, "Term-ansicolor - Ruby library that colors strings using ANSI escape sequences".freeze, "--main".freeze, "README.md".freeze]
|
20
|
-
s.rubygems_version = "3.5.
|
20
|
+
s.rubygems_version = "3.5.11".freeze
|
21
21
|
s.summary = "Ruby library that colors strings using ANSI escape sequences".freeze
|
22
22
|
s.test_files = ["tests/ansicolor_test.rb".freeze, "tests/attribute_test.rb".freeze, "tests/hsl_triple_test.rb".freeze, "tests/hyperlink_test.rb".freeze, "tests/ppm_reader_test.rb".freeze, "tests/rgb_color_metrics_test.rb".freeze, "tests/rgb_triple_test.rb".freeze, "tests/test_helper.rb".freeze]
|
23
23
|
|
@@ -28,4 +28,5 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_development_dependency(%q<test-unit>.freeze, [">= 0".freeze])
|
29
29
|
s.add_development_dependency(%q<utils>.freeze, [">= 0".freeze])
|
30
30
|
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0".freeze])
|
31
|
+
s.add_runtime_dependency(%q<mize>.freeze, [">= 0".freeze])
|
31
32
|
end
|
data/tests/ansicolor_test.rb
CHANGED
@@ -103,9 +103,22 @@ class ANSIColorTest < Test::Unit::TestCase
|
|
103
103
|
|
104
104
|
def test_attributes
|
105
105
|
foo = 'foo'
|
106
|
-
|
106
|
+
attributes = %i[
|
107
|
+
clear reset bold dark faint italic underline underscore
|
108
|
+
blink rapid_blink reverse negative concealed conceal strikethrough black
|
109
|
+
red green yellow blue magenta cyan white on_black on_red on_green on_yellow
|
110
|
+
on_blue on_magenta on_cyan on_white intense_black bright_black intense_red
|
111
|
+
bright_red intense_green bright_green intense_yellow bright_yellow
|
112
|
+
intense_blue bright_blue intense_magenta bright_magenta intense_cyan
|
113
|
+
bright_cyan intense_white bright_white on_intense_black on_bright_black
|
114
|
+
on_intense_red on_bright_red on_intense_green on_bright_green
|
115
|
+
on_intense_yellow on_bright_yellow on_intense_blue on_bright_blue
|
116
|
+
on_intense_magenta on_bright_magenta on_intense_cyan on_bright_cyan
|
117
|
+
on_intense_white on_bright_white
|
118
|
+
]
|
119
|
+
for a in attributes
|
107
120
|
# skip :clear and :reverse b/c Ruby implements them on string
|
108
|
-
if a != :clear && a != :reverse
|
121
|
+
if a != :clear && a != :reverse
|
109
122
|
refute_equal foo, foo_colored = foo.__send__(a)
|
110
123
|
assert_equal foo, foo_colored.uncolor
|
111
124
|
end
|
@@ -121,6 +134,36 @@ class ANSIColorTest < Test::Unit::TestCase
|
|
121
134
|
assert_equal Term::ANSIColor.attributes, 'foo'.attributes
|
122
135
|
end
|
123
136
|
|
137
|
+
def test_underline
|
138
|
+
foo = 'foo'
|
139
|
+
assert_equal "\e[4mfoo\e[0m", Term::ANSIColor.underline { foo }
|
140
|
+
assert_equal "\e[4m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(color: '#ff8040') { foo }
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_underline_double
|
144
|
+
foo = 'foo'
|
145
|
+
assert_equal "\e[4:2mfoo\e[0m", Term::ANSIColor.underline(type: :double) { foo }
|
146
|
+
assert_equal "\e[4:2m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :double, color: '#ff8040') { foo }
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_underline_curly
|
150
|
+
foo = 'foo'
|
151
|
+
assert_equal "\e[4:3mfoo\e[0m", Term::ANSIColor.underline(type: :curly) { foo }
|
152
|
+
assert_equal "\e[4:3m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :curly, color: '#ff8040') { foo }
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_underline_dotted
|
156
|
+
foo = 'foo'
|
157
|
+
assert_equal "\e[4:4mfoo\e[0m", Term::ANSIColor.underline(type: :dotted) { foo }
|
158
|
+
assert_equal "\e[4:4m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :dotted, color: '#ff8040') { foo }
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_underline_dashed
|
162
|
+
foo = 'foo'
|
163
|
+
assert_equal "\e[4:5mfoo\e[0m", Term::ANSIColor.underline(type: :dashed) { foo }
|
164
|
+
assert_equal "\e[4:5m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :dashed, color: '#ff8040') { foo }
|
165
|
+
end
|
166
|
+
|
124
167
|
def test_move_to
|
125
168
|
string_23_23 = "\e[23;23Hred"
|
126
169
|
assert_equal string_23_23, string.move_to(23, 23)
|
@@ -157,4 +200,20 @@ class ANSIColorTest < Test::Unit::TestCase
|
|
157
200
|
string = Color.red(string)
|
158
201
|
assert_kind_of Term::ANSIColor, 'new'
|
159
202
|
end
|
203
|
+
|
204
|
+
def test_coloring
|
205
|
+
assert Term::ANSIColor.coloring?
|
206
|
+
Term::ANSIColor.coloring = false
|
207
|
+
assert_false Term::ANSIColor.coloring?
|
208
|
+
ensure
|
209
|
+
Term::ANSIColor.coloring = true
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_true_coloring
|
213
|
+
assert_false Term::ANSIColor.true_coloring?
|
214
|
+
Term::ANSIColor.true_coloring = true
|
215
|
+
assert Term::ANSIColor.true_coloring?
|
216
|
+
ensure
|
217
|
+
Term::ANSIColor.true_coloring = false
|
218
|
+
end
|
160
219
|
end
|
data/tests/attribute_test.rb
CHANGED
@@ -32,7 +32,7 @@ class AttributeTest < Test::Unit::TestCase
|
|
32
32
|
assert_in_delta 250.954, Attribute.get(:color0).distance_to(color), 1e-3
|
33
33
|
color = Attribute.nearest_rgb_color('#0f0')
|
34
34
|
assert_in_delta 255, Attribute.get(:color0).distance_to(color,
|
35
|
-
:
|
35
|
+
metric: RGBColorMetrics::Euclidean), 1e-3
|
36
36
|
assert_equal 1 / 0.0, Attribute.get(:color0).distance_to(nil)
|
37
37
|
end
|
38
38
|
|
@@ -40,14 +40,14 @@ class AttributeTest < Test::Unit::TestCase
|
|
40
40
|
assert_equal Attribute.get(:color0).rgb, Attribute.nearest_rgb_color('#000').rgb
|
41
41
|
assert_equal Attribute.get(:color15).rgb, Attribute.nearest_rgb_color('#ffffff').rgb
|
42
42
|
assert_equal :color248, Attribute.nearest_rgb_color('#aaa').name
|
43
|
-
assert_equal :color109, Attribute.nearest_rgb_color('#aaa', :
|
43
|
+
assert_equal :color109, Attribute.nearest_rgb_color('#aaa', gray: false).name
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_nearest_rgb_on_color
|
47
47
|
assert_equal Attribute.get(:on_color0).rgb, Attribute.nearest_rgb_on_color('#000').rgb
|
48
48
|
assert_equal Attribute.get(:on_color15).rgb, Attribute.nearest_rgb_on_color('#ffffff').rgb
|
49
49
|
assert_equal :on_color248, Attribute.nearest_rgb_on_color('#aaa').name
|
50
|
-
assert_equal :on_color109, Attribute.nearest_rgb_on_color('#aaa', :
|
50
|
+
assert_equal :on_color109, Attribute.nearest_rgb_on_color('#aaa', gray: false).name
|
51
51
|
end
|
52
52
|
|
53
53
|
def test_apply
|
@@ -59,15 +59,54 @@ class AttributeTest < Test::Unit::TestCase
|
|
59
59
|
def test_gradient
|
60
60
|
g0 = Attribute[:blink].gradient_to Attribute['#30ffaa']
|
61
61
|
assert_equal [], g0
|
62
|
-
g1 = Attribute['#30ffaa'].gradient_to(Attribute['#ff507f'], :
|
62
|
+
g1 = Attribute['#30ffaa'].gradient_to(Attribute['#ff507f'], steps: 9)
|
63
63
|
assert_equal [ :color49, :color49, :color43, :color79, :color108,
|
64
64
|
:color247, :color138, :color168, :color204 ], g1.map(&:name)
|
65
65
|
g2 = Attribute['#30ffaa'].gradient_to(
|
66
66
|
Attribute['#ff507f'],
|
67
|
-
:
|
68
|
-
:
|
67
|
+
steps: 9,
|
68
|
+
metric: RGBColorMetrics::Euclidean
|
69
69
|
)
|
70
70
|
assert_equal [ :color49, :color43, :color79, :color73, :color108,
|
71
71
|
:color247, :color138, :color168, :color204 ], g2.map(&:name)
|
72
72
|
end
|
73
|
+
|
74
|
+
def test_true_color
|
75
|
+
pinkish = Attribute['#f050a0', true_coloring: true]
|
76
|
+
assert_equal [ 240, 80, 160 ], pinkish.to_rgb_triple.to_a
|
77
|
+
on_pinkish = Attribute['on_#f050a0', true_coloring: true]
|
78
|
+
assert_equal [ 240, 80, 160 ], on_pinkish.to_rgb_triple.to_a
|
79
|
+
red = Attribute['9', true_coloring: true]
|
80
|
+
assert_equal [ 255, 0, 0 ], red.to_rgb_triple.to_a
|
81
|
+
red = Attribute['red', true_coloring: true]
|
82
|
+
assert_equal :red, red.name
|
83
|
+
pinkish_pinkish = Attribute[pinkish, true_coloring: true]
|
84
|
+
assert_equal pinkish, pinkish_pinkish
|
85
|
+
pinkish_pinkish = Attribute[pinkish.to_rgb_triple, true_coloring: true]
|
86
|
+
assert_equal pinkish.to_rgb_triple, pinkish_pinkish.to_rgb_triple
|
87
|
+
pinkish_pinkish = Attribute[pinkish.to_rgb_triple.to_a, true_coloring: true]
|
88
|
+
assert_equal pinkish.to_rgb_triple, pinkish_pinkish.to_rgb_triple
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_true_color_gradient
|
92
|
+
g0 = Attribute[:blink].gradient_to Attribute['#30ffaa']
|
93
|
+
assert_equal [], g0
|
94
|
+
g1 = Attribute['#30ffaa'].gradient_to(
|
95
|
+
Attribute['#ff507f'],
|
96
|
+
steps: 9,
|
97
|
+
true_coloring: true
|
98
|
+
)
|
99
|
+
assert_equal %w[
|
100
|
+
#00ffaf #1febaa #3ed7a5 #5dc3a0 #7caf9b #9b9b96 #ba8791 #d9738c #ff5f87
|
101
|
+
], g1.map { _1.rgb.html }
|
102
|
+
g2 = Attribute['#30ffaa'].gradient_to(
|
103
|
+
Attribute['#ff507f'],
|
104
|
+
steps: 9,
|
105
|
+
true_coloring: true,
|
106
|
+
metric: RGBColorMetrics::Euclidean
|
107
|
+
)
|
108
|
+
assert_equal %w[
|
109
|
+
#00ffaf #1febaa #3ed7a5 #5dc3a0 #7caf9b #9b9b96 #ba8791 #d9738c #ff5f87
|
110
|
+
], g2.map { _1.rgb.html }
|
111
|
+
end
|
73
112
|
end
|
data/tests/hsl_triple_test.rb
CHANGED
@@ -13,7 +13,7 @@ class HSLTripleTest < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def test_hsl_cast
|
15
15
|
assert_equal '#85e085', HSLTriple[ @pastel_green_hsl ].html
|
16
|
-
assert_equal '#85e085', HSLTriple[ :
|
16
|
+
assert_equal '#85e085', HSLTriple[ hue: 120, saturation: 59.4, lightness: 70 ].html
|
17
17
|
assert_equal '#11ddff', HSLTriple[ '#1df' ].html
|
18
18
|
assert_equal '#8000ff', HSLTriple[ 'rgb(128,0,255)' ].html
|
19
19
|
assert_equal '#85e085', HSLTriple[ 'hsl(120.0,59.4%,70.0%)' ].html
|
data/tests/hyperlink_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
1
3
|
class HyperlinkTest < Test::Unit::TestCase
|
2
4
|
include Term::ANSIColor
|
3
5
|
|
@@ -49,6 +51,8 @@ class HyperlinkTest < Test::Unit::TestCase
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def test_with_stringy_self
|
52
|
-
|
54
|
+
string = 'foo'
|
55
|
+
string.extend Term::ANSIColor
|
56
|
+
assert_equal "\e]8;;#@link\e\\foo\e]8;;\e\\", string.hyperlink(@link)
|
53
57
|
end
|
54
58
|
end
|
data/tests/ppm_reader_test.rb
CHANGED
@@ -28,6 +28,14 @@ class PPMReaderTest < Test::Unit::TestCase
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_rendering_ppm_with_true_colors
|
32
|
+
File.open(example_path('lambda-red.ppm')) do |ppm6|
|
33
|
+
ppm_reader = PPMReader.new(ppm6, :true_coloring => true)
|
34
|
+
assert_equal '5faa2b046cc3e030f86588e472683834',
|
35
|
+
Digest::MD5.hexdigest(ppm_reader.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
31
39
|
def test_to_a
|
32
40
|
File.open(example_path('lambda-red.ppm')) do |ppm6|
|
33
41
|
ppm_reader = PPMReader.new(ppm6, :gray => false)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: term-ansicolor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mize
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: This library uses ANSI escape sequences to control the attributes of
|
84
98
|
terminal output
|
85
99
|
email: flori@ping.de
|
@@ -99,6 +113,7 @@ extra_rdoc_files:
|
|
99
113
|
- lib/term/ansicolor/attribute/color8.rb
|
100
114
|
- lib/term/ansicolor/attribute/intense_color8.rb
|
101
115
|
- lib/term/ansicolor/attribute/text.rb
|
116
|
+
- lib/term/ansicolor/attribute/underline.rb
|
102
117
|
- lib/term/ansicolor/hsl_triple.rb
|
103
118
|
- lib/term/ansicolor/hyperlink.rb
|
104
119
|
- lib/term/ansicolor/movement.rb
|
@@ -109,7 +124,7 @@ extra_rdoc_files:
|
|
109
124
|
files:
|
110
125
|
- ".all_images.yml"
|
111
126
|
- ".gitignore"
|
112
|
-
- ".
|
127
|
+
- ".utilsrc"
|
113
128
|
- CHANGES
|
114
129
|
- COPYING
|
115
130
|
- Gemfile
|
@@ -133,6 +148,7 @@ files:
|
|
133
148
|
- lib/term/ansicolor/attribute/color8.rb
|
134
149
|
- lib/term/ansicolor/attribute/intense_color8.rb
|
135
150
|
- lib/term/ansicolor/attribute/text.rb
|
151
|
+
- lib/term/ansicolor/attribute/underline.rb
|
136
152
|
- lib/term/ansicolor/hsl_triple.rb
|
137
153
|
- lib/term/ansicolor/hyperlink.rb
|
138
154
|
- lib/term/ansicolor/movement.rb
|
@@ -172,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
188
|
- !ruby/object:Gem::Version
|
173
189
|
version: '0'
|
174
190
|
requirements: []
|
175
|
-
rubygems_version: 3.5.
|
191
|
+
rubygems_version: 3.5.11
|
176
192
|
signing_key:
|
177
193
|
specification_version: 4
|
178
194
|
summary: Ruby library that colors strings using ANSI escape sequences
|
data/.tool-versions
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby 3.3.0
|