term-ansicolor 1.8.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9718f060556740778ada5aec7993d0ed9e4b61548b037f437255c2b01697dafa
4
- data.tar.gz: 2f8eebac308b3c1d46436916c4dd7e37d71bfce3bb4376ed0b88027da1a1af9e
3
+ metadata.gz: 1b4b022358ec0c08c813fd02b38a04f434d49fcd75db660e25b8fe99a7b1e847
4
+ data.tar.gz: a829c2406f9a20c5738297253bcf3e3dc46f497fbb0c3433bef01fa488cd9c10
5
5
  SHA512:
6
- metadata.gz: 3a59e5c5c1ba7d9ece81227fc207be44959ac5c6f9d2b6c89c35a16563217f0f36c70c1ea33fa8a7ed89fc9e47e0a3ebf9827401e08b89b770b2f9a1c28c9701
7
- data.tar.gz: a842928574662464fd5ad2bbd18bb9bcf0a45b1bd354e674462004ca07f60d3f36ef8b18bccb60faeba08f416f19652be501e51f17b216fce96f8068d7efdec5
6
+ metadata.gz: 1ee33e17663543ec540ae88b5e84ff8ea6651394d62fe71086258f1294e556180c3255a3f2615dba39f54ab712927b5d862607995e41e7a86cbd43e3ffc89230
7
+ data.tar.gz: b17b3b732562f3132f478d01c6ba8b96ae9c158d50ad0ca147c722ddc232125301d911574996e023a4e25696ef574bfce986df05b5a487bd43fb5d82fb6ba4ae
data/.gitignore CHANGED
@@ -4,5 +4,6 @@
4
4
  .rvmrc
5
5
  Gemfile.lock
6
6
  coverage
7
+ errors.lst
7
8
  pkg
8
9
  tags
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.8.0
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 => metric,
88
- :gray => 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 = Term::ANSIColor
19
- color =
20
- ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
21
- ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
22
- ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
23
- ac::Attribute[ color_random ].gradient_to(ac::Attribute[ color_random ], :steps => 16) +
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
- rx = opts['x'].full? { |r| Range.new(*(r.split('..', 2).map(&:to_f))) } || (-2.0..1.0)
50
- ry = opts['y'].full? { |r| Range.new(*(r.split('..', 2).map(&:to_f))) } || (-1.0..1.0)
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
- @x, @y, @shape = x, y, Array(shape).sample
13
- @shape.size != 1 and raise ArgumentError, "#@shape needs to be a character"
14
- end
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
- attr_accessor :x
16
+ attr_accessor :x
17
17
 
18
- attr_accessor :y
18
+ attr_accessor :y
19
19
 
20
- attr_accessor :shape
20
+ attr_accessor :shape
21
21
 
22
- def to_s
23
- move_to(y, x) { white on_black @shape }
24
- end
22
+ def to_s
23
+ move_to(y, x) { white on_black @shape }
24
+ end
25
25
  end
26
26
 
27
- opts = go 'n:s:'
28
- new_snowflakes = (opts[?n] || 3).to_i
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 == 1
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 *flakes
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) } * ', ', "\n\n"
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, :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'
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, :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'
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, :red => red, :green => green, :blue => blue
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, :red => grey, :green => grey, :blue => grey
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, :html => '#000000'
37
- Attribute.set :on_color1, 1, :html => '#800000'
38
- Attribute.set :on_color2, 2, :html => '#808000'
39
- Attribute.set :on_color3, 3, :html => '#808000'
40
- Attribute.set :on_color4, 4, :html => '#000080'
41
- Attribute.set :on_color5, 5, :html => '#800080'
42
- Attribute.set :on_color6, 6, :html => '#008080'
43
- Attribute.set :on_color7, 7, :html => '#c0c0c0'
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, :html => '#808080'
46
- Attribute.set :on_color9, 9, :html => '#ff0000'
47
- Attribute.set :on_color10, 10, :html => '#00ff00'
48
- Attribute.set :on_color11, 11, :html => '#ffff00'
49
- Attribute.set :on_color12, 12, :html => '#0000ff'
50
- Attribute.set :on_color13, 13, :html => '#ff00ff'
51
- Attribute.set :on_color14, 14, :html => '#00ffff'
52
- Attribute.set :on_color15, 15, :html => '#ffffff'
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, :red => red, :green => green, :blue => blue
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, :red => grey, :green => grey, :blue => grey
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, 0 # String#clear already used in String
6
- Attribute.set :reset, 0 # synonym for :clear
7
- Attribute.set :bold, 1
8
- Attribute.set :dark, 2
9
- Attribute.set :faint, 2
10
- Attribute.set :italic, 3 # not widely implemented
11
- Attribute.set :underline, 4
12
- Attribute.set :underscore, 4 # synonym for :underline
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
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
- if RUBY_VERSION < '1.9'
7
- @__order__ = []
8
-
9
- def self.set(name, code, options = {})
10
- name = name.to_sym
11
- result = @__store__[name] = new(name, code, options)
12
- @__order__ << name
13
- @rgb_colors = nil
14
- result
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
- def self.attributes(&block)
29
- @__store__.each_value(&block)
30
- end
19
+ def self.attributes(&block)
20
+ @__store__.each_value(&block)
31
21
  end
32
22
 
33
- def self.[](name)
34
- case
35
- when self === name then name
36
- when Array === name then nearest_rgb_color name
37
- when name.respond_to?(:to_rgb_triple) then nearest_rgb_color(name.to_rgb_triple.to_a)
38
- when name.to_s =~ /\A(on_)?(\d+)\z/ then get "#$1color#$2"
39
- when name.to_s =~ /\A#([0-9a-f]{3}){1,2}\z/i then nearest_rgb_color name
40
- when name.to_s =~ /\Aon_#([0-9a-f]{3}){1,2}\z/i then nearest_rgb_on_color name
41
- else get name
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 = @rgb_colors ||= attributes.select(&:rgb_color?)
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 = name.to_sym
75
- @code = code.to_s
76
- if html = options[:html]
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 !options.empty?
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 rgb_color?
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.color(self, string, &block)
121
+ ::Term::ANSIColor.apply_attribute(self, string, &block)
97
122
  end
98
123
 
99
124
  def background?
100
- @name.to_s.start_with?('on_')
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
- other.respond_to?(:to_rgb_triple) and
131
- other_rgb = other.to_rgb_triple
132
- then
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
- self.class.nearest_rgb_color(rgb_triple, options)
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 = io
8
- @options = 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 = Attribute.nearest_rgb_color(pixel, @options)
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
@@ -1,6 +1,6 @@
1
1
  module Term::ANSIColor
2
2
  # Term::ANSIColor version
3
- VERSION = '1.8.0'
3
+ VERSION = '1.10.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -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
- # Term::ANSIColor::coloring = STDOUT.isatty
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
- def self.create_color_method(color_name, color_value)
53
- module_eval <<-EOT
54
- def #{color_name}(string = nil, &block)
55
- color(:#{color_name}, string, &block)
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
- for attribute in Attribute.named_attributes
62
- create_color_method(attribute.name, attribute.code)
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
- # ANSI-Attributes are stripped from the string.
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
- # Return +string+ or the result string of the given +block+ colored with
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[#{attribute.code}m" if Term::ANSIColor.coloring?
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 raise ArgumentError, "unknown attribute #{name.inspect}"
107
- color("on_#{attribute.name}", string, &block)
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::ATTRIBUTE_NAMES
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
@@ -1,23 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: term-ansicolor 1.8.0 ruby lib
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.8.0".freeze
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-04-13"
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, ".tool-versions".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/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]
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.3".freeze
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
@@ -103,9 +103,22 @@ class ANSIColorTest < Test::Unit::TestCase
103
103
 
104
104
  def test_attributes
105
105
  foo = 'foo'
106
- for a in Term::ANSIColor.attributes
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 || Term::ANSIColor.support?(:clear)
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
@@ -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
- :metric => RGBColorMetrics::Euclidean), 1e-3
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', :gray => false).name
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', :gray => false).name
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'], :steps => 9)
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
- :steps => 9,
68
- :metric => RGBColorMetrics::Euclidean
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
@@ -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[ :hue => 120, :saturation => 59.4, :lightness => 70 ].html
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
@@ -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
- assert_equal "\e]8;;#@link\e\\foo\e]8;;\e\\", "foo".hyperlink(@link)
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
@@ -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.8.0
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-04-13 00:00:00.000000000 Z
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
- - ".tool-versions"
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.3
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