term-ansicolor 1.7.1 → 1.10.4

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.
@@ -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 rgb = a.ask_and_send(:to_rgb_triple).full?(:to_a)
21
+ "\e[58;2;#{rgb * ?;}"
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,31 @@ 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
+ @direct = false
91
+ @true_color = false
92
+ if rgb = options[:true_color]
93
+ @true_color = true
94
+ @rgb = rgb
95
+ elsif rgb = options[:direct]
96
+ @direct = true
97
+ @rgb = RGBTriple.from_html(rgb)
98
+ elsif html = options[:html]
77
99
  @rgb = RGBTriple.from_html(html)
78
- elsif !options.empty?
100
+ elsif options.slice(:red, :green, :blue).size == 3
79
101
  @rgb = RGBTriple.from_hash(options)
80
102
  else
81
103
  @rgb = nil # prevent instance variable not initialized warnings
@@ -85,25 +107,39 @@ module Term
85
107
  attr_reader :name
86
108
 
87
109
  def code
88
- if rgb_color?
110
+ if true_color?
111
+ background? ? "48;2;#{@rgb.to_a * ?;}" : "38;2;#{@rgb.to_a * ?;}"
112
+ elsif rgb_color?
89
113
  background? ? "48;5;#{@code}" : "38;5;#{@code}"
114
+ elsif direct?
115
+ background? ? (@code.to_i + 10).to_s : @code
90
116
  else
91
117
  @code
92
118
  end
93
119
  end
94
120
 
95
121
  def apply(string = nil, &block)
96
- ::Term::ANSIColor.color(self, string, &block)
122
+ ::Term::ANSIColor.apply_attribute(self, string, &block)
97
123
  end
98
124
 
99
125
  def background?
100
- @name.to_s.start_with?('on_')
126
+ !!@background
101
127
  end
102
128
 
129
+ def direct?
130
+ !!@direct
131
+ end
132
+
133
+ attr_writer :background
134
+
103
135
  attr_reader :rgb
104
136
 
105
137
  def rgb_color?
106
- !!@rgb
138
+ !!@rgb && !@true_color && !@direct
139
+ end
140
+
141
+ def true_color?
142
+ !!(@rgb && @true_color)
107
143
  end
108
144
 
109
145
  def gray?
@@ -127,11 +163,16 @@ module Term
127
163
 
128
164
  def gradient_to(other, options = {})
129
165
  if our_rgb = to_rgb_triple and
130
- other.respond_to?(:to_rgb_triple) and
131
- other_rgb = other.to_rgb_triple
132
- then
166
+ other.respond_to?(:to_rgb_triple) and
167
+ other_rgb = other.to_rgb_triple
168
+ then
169
+ true_coloring = options[:true_coloring] || Term::ANSIColor.true_coloring?
133
170
  our_rgb.gradient_to(other_rgb, options).map do |rgb_triple|
134
- self.class.nearest_rgb_color(rgb_triple, options)
171
+ if true_coloring
172
+ self.class.true_color(rgb_triple, options)
173
+ else
174
+ self.class.nearest_rgb_color(rgb_triple, options)
175
+ end
135
176
  end
136
177
  else
137
178
  []
@@ -72,8 +72,8 @@ module Term
72
72
 
73
73
  def initialize(hue, saturation, lightness)
74
74
  @hue = Float(hue) % 360
75
- @saturation = [ [ Float(saturation), 0 ].max, 100 ].min
76
- @lightness = [ [ Float(lightness), 0 ].max, 100 ].min
75
+ @saturation = Float(saturation).clamp(0, 100)
76
+ @lightness = Float(lightness).clamp(0, 100)
77
77
  end
78
78
 
79
79
  attr_reader :hue
@@ -0,0 +1,34 @@
1
+ require 'tins/terminal'
2
+
3
+ module Term
4
+ module ANSIColor
5
+ module Hyperlink
6
+ def hyperlink(link, string = nil, id: nil, as_link: false)
7
+ block_given? && string != nil && !respond_to?(:to_str) and
8
+ raise ArgumentError,
9
+ "Require either the string argument or a block argument"
10
+ if link.nil?
11
+ link = ''
12
+ end
13
+ if as_link && !link.empty?
14
+ string ||= link
15
+ end
16
+ result = ''
17
+ if Term::ANSIColor.coloring?
18
+ result = "\e]8;#{"id=#{id}" unless id.nil?};" << link.to_str << "\e\\"
19
+ end
20
+ if block_given?
21
+ result << yield.to_s
22
+ elsif string.respond_to?(:to_str)
23
+ result << string.to_str
24
+ elsif respond_to?(:to_str)
25
+ result << to_str
26
+ else
27
+ return result # only switch on
28
+ end
29
+ result << "\e]8;;\e\\" if Term::ANSIColor.coloring?
30
+ result
31
+ end
32
+ end
33
+ end
34
+ end
@@ -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
@@ -59,9 +59,7 @@ module Term
59
59
  end
60
60
 
61
61
  def initialize(red, green, blue)
62
- @values = [ red, green, blue ].map { |v|
63
- [ [ Integer(v), 0 ].max, 0xff ].min
64
- }
62
+ @values = [ red, green, blue ].map! { |v| v.clamp(0, 0xff) }
65
63
  end
66
64
 
67
65
  def red
@@ -1,6 +1,6 @@
1
1
  module Term::ANSIColor
2
2
  # Term::ANSIColor version
3
- VERSION = '1.7.1'
3
+ VERSION = '1.10.4'
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,6 @@
1
1
  require 'tins/xt/full'
2
+ require 'tins/xt/ask_and_send'
3
+ require 'mize'
2
4
 
3
5
  module Term
4
6
 
@@ -15,25 +17,11 @@ module Term
15
17
  require 'term/ansicolor/attribute/intense_color8'
16
18
  require 'term/ansicolor/attribute/color256'
17
19
  require 'term/ansicolor/movement'
18
-
19
20
  include Term::ANSIColor::Movement
21
+ require 'term/ansicolor/hyperlink'
22
+ include Term::ANSIColor::Hyperlink
23
+ include Term::ANSIColor::Attribute::Underline
20
24
 
21
- # :stopdoc:
22
- ATTRIBUTE_NAMES = Attribute.named_attributes.map(&:name)
23
- # :startdoc:
24
-
25
- # Returns true if Term::ANSIColor supports the +feature+.
26
- #
27
- # The feature :clear, that is mixing the clear color attribute into String,
28
- # is only supported on ruby implementations, that do *not* already
29
- # implement the String#clear method. It's better to use the reset color
30
- # attribute instead.
31
- def support?(feature)
32
- case feature
33
- when :clear
34
- !String.instance_methods(false).map(&:to_sym).include?(:clear)
35
- end
36
- end
37
25
  # Returns true, if the coloring function of this module
38
26
  # is switched on, false otherwise.
39
27
  def self.coloring?
@@ -42,31 +30,32 @@ module Term
42
30
 
43
31
  # Turns the coloring on or off globally, so you can easily do
44
32
  # this for example:
45
- # Term::ANSIColor::coloring = STDOUT.isatty
33
+ # Term::ANSIColor::coloring = STDOUT.isatty
46
34
  def self.coloring=(val)
47
- @coloring = val
35
+ @coloring = !!val
48
36
  end
49
37
  self.coloring = true
50
38
 
51
- def self.create_color_method(color_name, color_value)
52
- module_eval <<-EOT
53
- def #{color_name}(string = nil, &block)
54
- color(:#{color_name}, string, &block)
55
- end
56
- EOT
57
- self
39
+ # Returns true, if the tue coloring mode of this module is switched on,
40
+ # false otherwise.
41
+ def self.true_coloring?
42
+ @true_coloring
58
43
  end
59
44
 
60
- for attribute in Attribute.named_attributes
61
- create_color_method(attribute.name, attribute.code)
45
+ # Turns the true coloring mode on or off globally, that will display 24-bit
46
+ # colors if your terminal supports it:
47
+ # Term::ANSIColor::true_coloring = ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/
48
+ def self.true_coloring=(val)
49
+ @true_coloring = !!val
62
50
  end
51
+ self.true_coloring = false
63
52
 
64
53
  # Regular expression that is used to scan for ANSI-Attributes while
65
54
  # uncoloring strings.
66
- COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9]|[34]8;5;\d{1,3})?m/
55
+ 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/
67
56
 
68
- # Returns an uncolored version of the string, that is all
69
- # ANSI-Attributes are stripped from the string.
57
+ # Returns an uncolored version of the string, that is all ANSI-Attributes
58
+ # are stripped from the string.
70
59
  def uncolor(string = nil) # :yields:
71
60
  if block_given?
72
61
  yield.to_str.gsub(COLORED_REGEXP, '')
@@ -81,13 +70,9 @@ module Term
81
70
 
82
71
  alias uncolored uncolor
83
72
 
84
- # Return +string+ or the result string of the given +block+ colored with
85
- # color +name+. If string isn't a string only the escape sequence to switch
86
- # on the color +name+ is returned.
87
- def color(name, string = nil, &block)
88
- attribute = Attribute[name] or raise ArgumentError, "unknown attribute #{name.inspect}"
73
+ def apply_code(code, string = nil, &block)
89
74
  result = ''
90
- result << "\e[#{attribute.code}m" if Term::ANSIColor.coloring?
75
+ result << "\e[#{code}m" if Term::ANSIColor.coloring?
91
76
  if block_given?
92
77
  result << yield.to_s
93
78
  elsif string.respond_to?(:to_str)
@@ -95,21 +80,40 @@ module Term
95
80
  elsif respond_to?(:to_str)
96
81
  result << to_str
97
82
  else
98
- return result #only switch on
83
+ return result # only switch on
99
84
  end
100
85
  result << "\e[0m" if Term::ANSIColor.coloring?
101
86
  result.extend(Term::ANSIColor)
102
87
  end
103
88
 
89
+ def apply_attribute(name, string = nil, &block)
90
+ attribute = Attribute[name] or
91
+ raise ArgumentError, "unknown attribute #{name.inspect}"
92
+ apply_code(attribute.code, string, &block)
93
+ end
94
+
95
+ # Return +string+ or the result string of the given +block+ colored with
96
+ # color +name+. If string isn't a string only the escape sequence to switch
97
+ # on the color +name+ is returned.
98
+ def color(name, string = nil, &block)
99
+ apply_attribute(name, string, &block)
100
+ end
101
+
102
+ # Return +string+ or the result string of the given +block+ with a
103
+ # background colored with color +name+. If string isn't a string only the
104
+ # escape sequence to switch on the color +name+ is returned.
104
105
  def on_color(name, string = nil, &block)
105
- attribute = Attribute[name] or raise ArgumentError, "unknown attribute #{name.inspect}"
106
- color("on_#{attribute.name}", string, &block)
106
+ attribute = Attribute[name] or
107
+ raise ArgumentError, "unknown attribute #{name.inspect}"
108
+ attribute = attribute.dup
109
+ attribute.background = true
110
+ apply_attribute(attribute, string, &block)
107
111
  end
108
112
 
109
113
  class << self
110
114
  # Returns an array of all Term::ANSIColor attributes as symbols.
111
- def term_ansicolor_attributes
112
- ::Term::ANSIColor::ATTRIBUTE_NAMES
115
+ memoize method: def term_ansicolor_attributes
116
+ ::Term::ANSIColor::Attribute.attributes.map(&:name)
113
117
  end
114
118
 
115
119
  alias attributes term_ansicolor_attributes
@@ -1,45 +1,32 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: term-ansicolor 1.7.1 ruby lib
2
+ # stub: term-ansicolor 1.10.4 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "term-ansicolor".freeze
6
- s.version = "1.7.1"
6
+ s.version = "1.10.4".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 = "2019-01-18"
11
+ s.date = "2024-07-15"
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
- s.executables = ["term_snow".freeze, "term_display".freeze, "term_decolor".freeze, "term_cdiff".freeze, "term_mandel".freeze, "term_colortab".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/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 = [".gitignore".freeze, ".travis.yml".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/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/ppm_reader_test.rb".freeze, "tests/rgb_color_metrics_test.rb".freeze, "tests/rgb_triple_test.rb".freeze, "tests/test_helper.rb".freeze]
17
- s.homepage = "http://flori.github.com/term-ansicolor".freeze
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/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
+ 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.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
21
- s.rubygems_version = "3.0.1".freeze
20
+ s.rubygems_version = "3.5.11".freeze
22
21
  s.summary = "Ruby library that colors strings using ANSI escape sequences".freeze
23
- s.test_files = ["tests/ansicolor_test.rb".freeze, "tests/attribute_test.rb".freeze, "tests/hsl_triple_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]
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]
24
23
 
25
- if s.respond_to? :specification_version then
26
- s.specification_version = 4
24
+ s.specification_version = 4
27
25
 
28
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
30
- s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
31
- s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
32
- s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0"])
33
- else
34
- s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
35
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
36
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
37
- s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
38
- end
39
- else
40
- s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
41
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
42
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
43
- s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
44
- end
26
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.16.0".freeze])
27
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
28
+ s.add_development_dependency(%q<test-unit>.freeze, [">= 0".freeze])
29
+ s.add_development_dependency(%q<utils>.freeze, [">= 0".freeze])
30
+ s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0".freeze])
31
+ s.add_runtime_dependency(%q<mize>.freeze, ["~> 0.5".freeze])
45
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,44 @@ class ANSIColorTest < Test::Unit::TestCase
121
134
  assert_equal Term::ANSIColor.attributes, 'foo'.attributes
122
135
  end
123
136
 
137
+ def test_underline_invalid_type
138
+ assert_raises(ArgumentError) { Term::ANSIColor.underline(type: :nix) { 'foo' } }
139
+ end
140
+
141
+ def test_underline_invalid_color
142
+ assert_raises(ArgumentError) { Term::ANSIColor.underline(color: :nix) { 'foo' } }
143
+ end
144
+
145
+ def test_underline
146
+ foo = 'foo'
147
+ assert_equal "\e[4mfoo\e[0m", Term::ANSIColor.underline { foo }
148
+ assert_equal "\e[4m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(color: '#ff8040') { foo }
149
+ end
150
+
151
+ def test_underline_double
152
+ foo = 'foo'
153
+ assert_equal "\e[4:2mfoo\e[0m", Term::ANSIColor.underline(type: :double) { foo }
154
+ assert_equal "\e[4:2m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :double, color: '#ff8040') { foo }
155
+ end
156
+
157
+ def test_underline_curly
158
+ foo = 'foo'
159
+ assert_equal "\e[4:3mfoo\e[0m", Term::ANSIColor.underline(type: :curly) { foo }
160
+ assert_equal "\e[4:3m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :curly, color: '#ff8040') { foo }
161
+ end
162
+
163
+ def test_underline_dotted
164
+ foo = 'foo'
165
+ assert_equal "\e[4:4mfoo\e[0m", Term::ANSIColor.underline(type: :dotted) { foo }
166
+ assert_equal "\e[4:4m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :dotted, color: '#ff8040') { foo }
167
+ end
168
+
169
+ def test_underline_dashed
170
+ foo = 'foo'
171
+ assert_equal "\e[4:5mfoo\e[0m", Term::ANSIColor.underline(type: :dashed) { foo }
172
+ assert_equal "\e[4:5m\e[58;2;255;135;95mfoo\e[0m", Term::ANSIColor.underline(type: :dashed, color: '#ff8040') { foo }
173
+ end
174
+
124
175
  def test_move_to
125
176
  string_23_23 = "\e[23;23Hred"
126
177
  assert_equal string_23_23, string.move_to(23, 23)
@@ -157,4 +208,20 @@ class ANSIColorTest < Test::Unit::TestCase
157
208
  string = Color.red(string)
158
209
  assert_kind_of Term::ANSIColor, 'new'
159
210
  end
211
+
212
+ def test_coloring
213
+ assert Term::ANSIColor.coloring?
214
+ Term::ANSIColor.coloring = false
215
+ assert_false Term::ANSIColor.coloring?
216
+ ensure
217
+ Term::ANSIColor.coloring = true
218
+ end
219
+
220
+ def test_true_coloring
221
+ assert_false Term::ANSIColor.true_coloring?
222
+ Term::ANSIColor.true_coloring = true
223
+ assert Term::ANSIColor.true_coloring?
224
+ ensure
225
+ Term::ANSIColor.true_coloring = false
226
+ end
160
227
  end