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 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