hilighter 1.5.2

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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 12de20d926f333f17c63422220db0c8c5baf18e7870127de78e8ad55cf4598d6
4
+ data.tar.gz: 23057327a183158182505494e5943733c8da2ab55995af832d363c315dd61b1f
5
+ SHA512:
6
+ metadata.gz: fd5a67726beb497ed99e5357275fe6cabb23ca575152172010fab86873faa40039db76050dad00bcafa987df923dbca75ff12024adfd0ddb4e0f6aa1bf74cf0b
7
+ data.tar.gz: e139afef30ae8387e7e9dde274a48b907f41d62df8c091a1c2f9eed8eb34c4e3f870c9ce4bcf4a20e23f0f33ff9084dcd8cb705878f90dbcb5829d41baff95ff
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "hilighter"
4
+ require "io/wait"
5
+ require "optparse"
6
+
7
+ ### Helpers begin
8
+ def err(msg)
9
+ puts("[!] #{msg}".red)
10
+ end
11
+ def errx(msg)
12
+ raise Exception.new(msg)
13
+ end
14
+ def good(msg)
15
+ puts("[+] #{msg}".green)
16
+ end
17
+ def info(msg)
18
+ puts("[*] #{msg}".white)
19
+ end
20
+ def subinfo(msg)
21
+ puts("[=] #{msg}".cyan)
22
+ end
23
+ def warn(msg)
24
+ puts("[-] #{msg}".yellow)
25
+ end
26
+ ### Helpers end
27
+
28
+ class HilighterExit
29
+ GOOD = 0
30
+ INVALID_OPTION = 1
31
+ INVALID_ARGUMENT = 2
32
+ MISSING_ARGUMENT = 3
33
+ EXTRA_ARGUMENTS = 4
34
+ EXCEPTION = 5
35
+ AMBIGUOUS_ARGUMENT = 6
36
+ end
37
+
38
+ def parse(args)
39
+ options = Hash.new
40
+ options["action"] = "default"
41
+ options["verbose"] = false
42
+
43
+ info = [
44
+ "Hilights the text from stdin using the methods passed on",
45
+ "the CLI."
46
+ ].join(" ")
47
+
48
+ parser = OptionParser.new do |opts|
49
+ opts.summary_width = 19
50
+
51
+ opts.banner = [
52
+ "Usage: #{File.basename($0)} [OPTIONS] [color1]...",
53
+ "[colorN]"
54
+ ].join(" ")
55
+
56
+ opts.on("", "DESCRIPTION")
57
+
58
+ info.wrap(76).each_line do |line|
59
+ opts.on(" #{line.chomp}")
60
+ end
61
+
62
+ opts.on("", "OPTIONS")
63
+
64
+ opts.on("-h", "--help", "Display this help message") do
65
+ puts(opts)
66
+ exit HilighterExit::GOOD
67
+ end
68
+
69
+ opts.on("--[no-]color", "Disable colorized output") do |c|
70
+ Hilighter.disable if (!c)
71
+ end
72
+
73
+ opts.on(
74
+ "-s",
75
+ "--sample",
76
+ "Show sample foreground/background colors"
77
+ ) do
78
+ options["action"] = "sample"
79
+ end
80
+
81
+ opts.on("-t", "--table", "Show the color table") do
82
+ options["action"] = "table"
83
+ end
84
+
85
+ opts.on(
86
+ "-v",
87
+ "--verbose",
88
+ "Show backtrace when error occurs"
89
+ ) do
90
+ options["verbose"] = true
91
+ end
92
+
93
+ opts.on("-V", "--version", "Show version") do
94
+ __FILE__.match(/hilighter-(\d+\.\d+\.\d+)/) do |m|
95
+ puts(m[1])
96
+ end
97
+ exit HilighterExit::GOOD
98
+ end
99
+ end
100
+
101
+ begin
102
+ parser.parse!
103
+ rescue OptionParser::InvalidOption => e
104
+ puts(e.message)
105
+ puts(parser)
106
+ exit HilighterExit::INVALID_OPTION
107
+ rescue OptionParser::InvalidArgument => e
108
+ puts(e.message)
109
+ puts(parser)
110
+ exit HilighterExit::INVALID_ARGUMENT
111
+ rescue OptionParser::MissingArgument => e
112
+ puts(e.message)
113
+ puts(parser)
114
+ exit HilighterExit::MISSING_ARGUMENT
115
+ rescue OptionParser::AmbiguousOption => e
116
+ puts(e.message)
117
+ puts(parser)
118
+ exit Exit::AMBIGUOUS_ARGUMENT
119
+ end
120
+
121
+ return options
122
+ end
123
+
124
+ begin
125
+ options = parse(ARGV)
126
+ rescue Interrupt
127
+ # Exit gracefully on ^C
128
+ exit HilighterExit::GOOD
129
+ end
130
+
131
+ begin
132
+ case options["action"]
133
+ when "sample"
134
+ Hilighter.sample
135
+ when "table"
136
+ Hilighter.table
137
+ else
138
+ bad = Array.new
139
+ loop do
140
+ # Get input
141
+ input = STDIN.gets
142
+
143
+ # Break if EOF, otherwise remove existing color codes
144
+ break if (input.nil?)
145
+
146
+ # Apply all requested color codes
147
+ ARGV.each do |color|
148
+ begin
149
+ input = input.send(color)
150
+ rescue NoMethodError
151
+ bad.push(color)
152
+ end
153
+ end
154
+ break if (!bad.empty?)
155
+
156
+ # Output
157
+ puts(input)
158
+ end
159
+ puts("Invalid colors: #{bad.join(", ")}") if (!bad.empty?)
160
+ end
161
+ rescue Interrupt
162
+ # Exit gracefully on ^C
163
+ rescue Errno::EPIPE
164
+ # Do nothing. This can happen if piping to another program such as
165
+ # less. Usually if less is closed before we're done with STDOUT.
166
+ rescue Exception => e
167
+ $stderr.puts(
168
+ [
169
+ "Oops! Looks like an error has occured! If the error",
170
+ "persists, file a bug at:"
171
+ ].join(" ").wrap
172
+ )
173
+ $stderr.puts
174
+ $stderr.puts(" https://gitlab.com/mjwhitta/hilighter/issues")
175
+ $stderr.puts
176
+ $stderr.puts(
177
+ [
178
+ "Maybe the message below will help. If not, you can use",
179
+ "the --verbose flag to get a backtrace."
180
+ ].join(" ").wrap
181
+ )
182
+ $stderr.puts
183
+
184
+ $stderr.puts(e.message.white.on_red)
185
+ if (options["verbose"])
186
+ e.backtrace.each do |line|
187
+ $stderr.puts(line.light_yellow)
188
+ end
189
+ end
190
+ exit HilighterExit::EXCEPTION
191
+ end
192
+ exit HilighterExit::GOOD
data/bin/hl ADDED
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "hilighter"
4
+ require "io/wait"
5
+ require "optparse"
6
+
7
+ ### Helpers begin
8
+ def err(msg)
9
+ puts("[!] #{msg}".red)
10
+ end
11
+ def errx(msg)
12
+ raise Exception.new(msg)
13
+ end
14
+ def good(msg)
15
+ puts("[+] #{msg}".green)
16
+ end
17
+ def info(msg)
18
+ puts("[*] #{msg}".white)
19
+ end
20
+ def subinfo(msg)
21
+ puts("[=] #{msg}".cyan)
22
+ end
23
+ def warn(msg)
24
+ puts("[-] #{msg}".yellow)
25
+ end
26
+ ### Helpers end
27
+
28
+ class HilighterExit
29
+ GOOD = 0
30
+ INVALID_OPTION = 1
31
+ INVALID_ARGUMENT = 2
32
+ MISSING_ARGUMENT = 3
33
+ EXTRA_ARGUMENTS = 4
34
+ EXCEPTION = 5
35
+ AMBIGUOUS_ARGUMENT = 6
36
+ end
37
+
38
+ def parse(args)
39
+ options = Hash.new
40
+ options["action"] = "default"
41
+ options["verbose"] = false
42
+
43
+ info = [
44
+ "Hilights the text from stdin using the methods passed on",
45
+ "the CLI."
46
+ ].join(" ")
47
+
48
+ parser = OptionParser.new do |opts|
49
+ opts.summary_width = 19
50
+
51
+ opts.banner = [
52
+ "Usage: #{File.basename($0)} [OPTIONS] [color1]...",
53
+ "[colorN]"
54
+ ].join(" ")
55
+
56
+ opts.on("", "DESCRIPTION")
57
+
58
+ info.wrap(76).each_line do |line|
59
+ opts.on(" #{line.chomp}")
60
+ end
61
+
62
+ opts.on("", "OPTIONS")
63
+
64
+ opts.on("-h", "--help", "Display this help message") do
65
+ puts(opts)
66
+ exit HilighterExit::GOOD
67
+ end
68
+
69
+ opts.on("--[no-]color", "Disable colorized output") do |c|
70
+ Hilighter.disable if (!c)
71
+ end
72
+
73
+ opts.on(
74
+ "-s",
75
+ "--sample",
76
+ "Show sample foreground/background colors"
77
+ ) do
78
+ options["action"] = "sample"
79
+ end
80
+
81
+ opts.on("-t", "--table", "Show the color table") do
82
+ options["action"] = "table"
83
+ end
84
+
85
+ opts.on(
86
+ "-v",
87
+ "--verbose",
88
+ "Show backtrace when error occurs"
89
+ ) do
90
+ options["verbose"] = true
91
+ end
92
+
93
+ opts.on("-V", "--version", "Show version") do
94
+ __FILE__.match(/hilighter-(\d+\.\d+\.\d+)/) do |m|
95
+ puts(m[1])
96
+ end
97
+ exit HilighterExit::GOOD
98
+ end
99
+ end
100
+
101
+ begin
102
+ parser.parse!
103
+ rescue OptionParser::InvalidOption => e
104
+ puts(e.message)
105
+ puts(parser)
106
+ exit HilighterExit::INVALID_OPTION
107
+ rescue OptionParser::InvalidArgument => e
108
+ puts(e.message)
109
+ puts(parser)
110
+ exit HilighterExit::INVALID_ARGUMENT
111
+ rescue OptionParser::MissingArgument => e
112
+ puts(e.message)
113
+ puts(parser)
114
+ exit HilighterExit::MISSING_ARGUMENT
115
+ rescue OptionParser::AmbiguousOption => e
116
+ puts(e.message)
117
+ puts(parser)
118
+ exit Exit::AMBIGUOUS_ARGUMENT
119
+ end
120
+
121
+ return options
122
+ end
123
+
124
+ begin
125
+ options = parse(ARGV)
126
+ rescue Interrupt
127
+ # Exit gracefully on ^C
128
+ exit HilighterExit::GOOD
129
+ end
130
+
131
+ begin
132
+ case options["action"]
133
+ when "sample"
134
+ Hilighter.sample
135
+ when "table"
136
+ Hilighter.table
137
+ else
138
+ bad = Array.new
139
+ loop do
140
+ # Get input
141
+ input = STDIN.gets
142
+
143
+ # Break if EOF, otherwise remove existing color codes
144
+ break if (input.nil?)
145
+
146
+ # Apply all requested color codes
147
+ ARGV.each do |color|
148
+ begin
149
+ input = input.send(color)
150
+ rescue NoMethodError
151
+ bad.push(color)
152
+ end
153
+ end
154
+ break if (!bad.empty?)
155
+
156
+ # Output
157
+ puts(input)
158
+ end
159
+ puts("Invalid colors: #{bad.join(", ")}") if (!bad.empty?)
160
+ end
161
+ rescue Interrupt
162
+ # Exit gracefully on ^C
163
+ rescue Errno::EPIPE
164
+ # Do nothing. This can happen if piping to another program such as
165
+ # less. Usually if less is closed before we're done with STDOUT.
166
+ rescue Exception => e
167
+ $stderr.puts(
168
+ [
169
+ "Oops! Looks like an error has occured! If the error",
170
+ "persists, file a bug at:"
171
+ ].join(" ").wrap
172
+ )
173
+ $stderr.puts
174
+ $stderr.puts(" https://gitlab.com/mjwhitta/hilighter/issues")
175
+ $stderr.puts
176
+ $stderr.puts(
177
+ [
178
+ "Maybe the message below will help. If not, you can use",
179
+ "the --verbose flag to get a backtrace."
180
+ ].join(" ").wrap
181
+ )
182
+ $stderr.puts
183
+
184
+ $stderr.puts(e.message.white.on_red)
185
+ if (options["verbose"])
186
+ e.backtrace.each do |line|
187
+ $stderr.puts(line.light_yellow)
188
+ end
189
+ end
190
+ exit HilighterExit::EXCEPTION
191
+ end
192
+ exit HilighterExit::GOOD
@@ -0,0 +1,109 @@
1
+ class Hilighter
2
+ def self.disable(val = true)
3
+ @@disable = val
4
+ end
5
+
6
+ def self.disable?
7
+ @@disable ||= false
8
+ return @@disable
9
+ end
10
+
11
+ # Convert hex to xterm-256 8-bit value
12
+ # https://stackoverflow.com/questions/11765623/convert-hex-hex_to_256bitto-closest-x11-color-number
13
+ def self.hex_to_x256(hex)
14
+ @@cached_codes ||= Hash.new
15
+ cache = @@cached_codes[hex]
16
+ return "color_#{cache}" if (!cache.nil?)
17
+
18
+ # For simplicity, assume RGB space is perceptually uniform.
19
+ # There are 5 places where one of two outputs needs to be
20
+ # chosen when the input is the exact middle:
21
+ # - The r/g/b channels and the gray value:
22
+ # - the higher value output is chosen
23
+ # - If the gray and color values have same distance from the
24
+ # input
25
+ # - color is chosen
26
+
27
+ # Calculate the nearest 0-based color index at 16..231
28
+ r = g = b = 0
29
+ x = "[A-Fa-f0-9]{2}"
30
+ hex.match(/^#?(#{x})(#{x})(#{x})(#{x})?$/) do |m|
31
+ r = m[1].to_i(16)
32
+ g = m[2].to_i(16)
33
+ b = m[3].to_i(16)
34
+ end
35
+
36
+ # 0..5 each
37
+ ir = (r < 48) ? 0 : (r < 115) ? 1 : ((r - 35) / 40)
38
+ ig = (g < 48) ? 0 : (g < 115) ? 1 : ((g - 35) / 40)
39
+ ib = (b < 48) ? 0 : (b < 115) ? 1 : ((b - 35) / 40)
40
+
41
+ # 0..215 lazy evaluation
42
+ cidx = (36 * ir) + (6 * ig) + ib + 16
43
+
44
+ # Calculate the nearest 0-based gray index at 232..255
45
+ average = (r + g + b) / 3
46
+
47
+ # 0..23
48
+ gidx = (average > 238) ? 23 : (average - 3) / 10
49
+
50
+ # Calculate the represented colors back from the index
51
+ i2cv = [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
52
+
53
+ # r/g/b 0..255 each
54
+ cr = i2cv[ir]
55
+ cg = i2cv[ig]
56
+ cb = i2cv[ib]
57
+
58
+ # same value for r/g/b 0..255
59
+ gv = (10 * gidx) + 8
60
+
61
+ # Return the one which is nearer to the original rgb
62
+ # values
63
+ clr_err = ((cr - r) ** 2 + (cg - g) ** 2 + (cb - b) ** 2)
64
+ gray_err = ((gv - r) ** 2 + (gv - g) ** 2 + (gv - b) ** 2)
65
+
66
+ if (clr_err <= gray_err)
67
+ @@cached_codes[hex] = cidx.to_s.rjust(3, "0")
68
+ else
69
+ @@cached_codes[hex] = (gidx + 232).to_s.rjust(3, "0")
70
+ end
71
+
72
+ return "color_#{@@cached_codes[hex]}"
73
+ end
74
+
75
+ def self.sample
76
+ String.colors.keys[0..15].each do |fg|
77
+ String.colors.keys[16..31].each do |bg|
78
+ print(" mw ".send(fg).send(bg))
79
+ end
80
+ puts
81
+ end
82
+ end
83
+
84
+ def self.table
85
+ (0..15).each do |i|
86
+ bg = i.to_s.rjust(3, "0")
87
+ print(" ".send("on_color_#{bg}"))
88
+ print(bg.black.send("on_color_#{bg}"))
89
+ print(" ".send("on_color_#{bg}"))
90
+ print(bg.white.send("on_color_#{bg}"))
91
+ print(" ".send("on_color_#{bg}"))
92
+ puts if (((i + 1) % 8) == 0)
93
+ end
94
+
95
+ (16..255).each do |i|
96
+ bg = i.to_s.rjust(3, "0")
97
+ print(" ".send("on_color_#{bg}"))
98
+ print(bg.black.send("on_color_#{bg}"))
99
+ print(" ".send("on_color_#{bg}"))
100
+ print(bg.white.send("on_color_#{bg}"))
101
+ print(" ".send("on_color_#{bg}"))
102
+ puts if (((i - 15) % 6) == 0)
103
+ end
104
+ end
105
+ end
106
+
107
+ require "hilighter/codes"
108
+ require "hilighter/methods"
109
+ require "string"
@@ -0,0 +1,151 @@
1
+ class Hilighter
2
+ module Codes
3
+ def add_methods
4
+ color_regex = /(^|\n)(\e\[([0-9;]+m|K))+(\n|$)/
5
+
6
+ colors.each do |key, val|
7
+ if (key.start_with?("on_"))
8
+ on_default = colors["on_default"]
9
+ define_method key do
10
+ return self.plain if (Hilighter.disable?)
11
+
12
+ return [
13
+ "\e[#{val}m",
14
+ self.plain_bg.gsub(
15
+ /\n/,
16
+ "\e[#{on_default}m\n\e[#{val}m"
17
+ ),
18
+ "\e[#{on_default}m"
19
+ ].join.gsub(color_regex, "\\1\\4")
20
+ end
21
+ else
22
+ default = colors["default"]
23
+ define_method key do
24
+ return self.plain if (Hilighter.disable?)
25
+
26
+ return [
27
+ "\e[#{val}m",
28
+ self.plain_fg.gsub(
29
+ /\n/,
30
+ "\e[#{default}m\n\e[#{val}m"
31
+ ),
32
+ "\e[#{default}m"
33
+ ].join.gsub(color_regex, "\\1\\4")
34
+ end
35
+ end
36
+ end
37
+
38
+ modes.each do |key, val|
39
+ rm = [
40
+ modes[key],
41
+ modes["no_#{key}".gsub(/^no_no_/, "")]
42
+ ].delete_if(&:nil?).uniq.join("|")
43
+
44
+ off = "no_#{key}"
45
+ if modes.has_key?(off)
46
+ off = "\e[#{modes[off]}m"
47
+ else
48
+ off = ""
49
+ end
50
+
51
+ define_method key do
52
+ return self.plain if (Hilighter.disable?)
53
+ self.gsub!(/\e\[(#{rm})m/, "")
54
+ return "\e[#{val}m#{self}#{off}".gsub(
55
+ color_regex,
56
+ "\\1\\4"
57
+ )
58
+ end
59
+ end
60
+ end
61
+
62
+ def colors
63
+ @valid_colors ||= {
64
+ "black" => 30,
65
+ "red" => 31,
66
+ "green" => 32,
67
+ "yellow" => 33,
68
+ "blue" => 34,
69
+ "magenta" => 35,
70
+ "cyan" => 36,
71
+ "white" => 37,
72
+ "light_black" => 90,
73
+ "light_red" => 91,
74
+ "light_green" => 92,
75
+ "light_yellow" => 93,
76
+ "light_blue" => 94,
77
+ "light_magenta" => 95,
78
+ "light_cyan" => 96,
79
+ "light_white" => 97,
80
+
81
+ "on_black" => 40,
82
+ "on_red" => 41,
83
+ "on_green" => 42,
84
+ "on_yellow" => 43,
85
+ "on_blue" => 44,
86
+ "on_magenta" => 45,
87
+ "on_cyan" => 46,
88
+ "on_white" => 47,
89
+ "on_light_black" => 100,
90
+ "on_light_red" => 101,
91
+ "on_light_green" => 102,
92
+ "on_light_yellow" => 103,
93
+ "on_light_blue" => 104,
94
+ "on_light_magenta" => 105,
95
+ "on_light_cyan" => 106,
96
+ "on_light_white" => 107,
97
+
98
+ "default" => 39,
99
+ "on_default" => 49
100
+ }
101
+ if (@valid_colors.length < 256)
102
+ 256.times.each do |i|
103
+ clr = i.to_s.rjust(3, "0")
104
+ @valid_colors["color_#{clr}"] = "38;5;#{clr}"
105
+ @valid_colors["on_color_#{clr}"] = "48;5;#{clr}"
106
+ end
107
+ end
108
+ return @valid_colors
109
+ end
110
+
111
+ def modes
112
+ return {
113
+ "reset" => 0,
114
+ "normal" => 0,
115
+ "bold" => 1,
116
+ "dim" => 2,
117
+ "faint" => 2,
118
+ "italic" => 3,
119
+ "underline" => 4,
120
+ "blink" => 5,
121
+ "blink_slow" => 5,
122
+ "blink_rapid" => 6,
123
+ "inverse" => 7,
124
+ "negative" => 7,
125
+ "swap" => 7,
126
+ "hide" => 8,
127
+ "conceal" => 8,
128
+ "crossed_out" => 9,
129
+ "strikethrough" => 9,
130
+ "fraktur" => 20,
131
+
132
+ "no_bold" => 21,
133
+ "no_dim" => 22,
134
+ "no_faint" => 22,
135
+ "no_italic" => 23,
136
+ "no_fraktur" => 23,
137
+ "no_underline" => 24,
138
+ "no_blink" => 25,
139
+ "no_blink_slow" => 25,
140
+ "no_blink_rapid" => 26,
141
+ "no_inverse" => 27,
142
+ "no_negative" => 27,
143
+ "no_swap" => 27,
144
+ "no_hide" => 28,
145
+ "no_conceal" => 28,
146
+ "no_crossed_out" => 29,
147
+ "no_strikethrough" => 29
148
+ }
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,103 @@
1
+ class Hilighter
2
+ module Methods
3
+ def color_regex
4
+ return /\e\[([0-9;]*m|K)/
5
+ end
6
+ private :color_regex
7
+
8
+ def hex_color(hex)
9
+ return self.send(Hilighter.hex_to_x256(hex))
10
+ end
11
+
12
+ def method_missing(method_name, *args)
13
+ method_name.to_s.match(/^([A-Fa-f0-9]{6})$/) do |m|
14
+ return self.hex_color(m[1])
15
+ end
16
+ method_name.to_s.match(/^on_([A-Fa-f0-9]{6})$/) do |m|
17
+ return self.on_hex_color(m[1])
18
+ end
19
+ method_name.to_s.match(/^wrap(_(\d+))?$/) do |m|
20
+ width = nil
21
+ width = m[2].to_i if (!m[1].nil?)
22
+ return self.wrap(width)
23
+ end
24
+ super
25
+ end
26
+
27
+ def on_hex_color(hex)
28
+ return self.send("on_#{Hilighter.hex_to_x256(hex)}")
29
+ end
30
+
31
+ def on_rainbow
32
+ return self.plain if (Hilighter.disable?)
33
+
34
+ clrs = rainbow_colors
35
+ out = Array.new
36
+
37
+ self.plain_bg.each_line do |line|
38
+ line.chomp!
39
+ colorized = line.scan(
40
+ /((#{color_regex})*[^\e](#{color_regex})*)/
41
+ ).map.with_index do |c, i|
42
+ "\e[#{clrs[i % clrs.length] + 10}m#{c[0]}"
43
+ end.join
44
+ out.push("#{colorized}\e[49m\n")
45
+ end
46
+
47
+ return out.join.gsub(/^(#{color_regex})+$/, "")
48
+ end
49
+
50
+ def plain
51
+ return self.gsub(color_regex, "")
52
+ end
53
+
54
+ def plain_bg
55
+ return self.gsub(/\e\[(4|10)[0-9;]+m/, "")
56
+ end
57
+
58
+ def plain_fg
59
+ return self.gsub(/\e\[[39][0-9;]+m/, "")
60
+ end
61
+
62
+ def rainbow_colors
63
+ return [31, 32, 33, 34, 35, 36, 91, 92, 93, 94, 95, 96]
64
+ end
65
+ private :rainbow_colors
66
+
67
+ def rainbow
68
+ return self.plain if (Hilighter.disable?)
69
+
70
+ clrs = rainbow_colors
71
+ out = Array.new
72
+
73
+ self.plain_fg.each_line do |line|
74
+ line.chomp!
75
+ colorized = line.scan(
76
+ /((#{color_regex})*[^\e](#{color_regex})*)/
77
+ ).map.with_index do |c, i|
78
+ "\e[#{clrs[i % clrs.length]}m#{c[0]}"
79
+ end.join
80
+ out.push("#{colorized}\n")
81
+ end
82
+
83
+ return out.join.gsub(/^(#{color_regex})+$/, "")
84
+ end
85
+
86
+ def wrap(width = 80)
87
+ line = ""
88
+ lines = Array.new
89
+ self.split(/\s+/).each do |word|
90
+ if ((line.plain.size + word.plain.size) > width)
91
+ lines.push("#{line}\n")
92
+ line = word
93
+ elsif (line.empty?)
94
+ line = word
95
+ else
96
+ line += " #{word}"
97
+ end
98
+ end
99
+ lines.push("#{line}\n") if (!line.empty?)
100
+ return lines.join
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ extend Hilighter::Codes
3
+ include Hilighter::Methods
4
+ add_methods
5
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hilighter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.5.2
5
+ platform: ruby
6
+ authors:
7
+ - Miles Whittaker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 13.0.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '13.0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 13.0.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ description: Adds color methods to String class. Also allows for string wrapping that
34
+ accounts for color escape codes.
35
+ email: mj@whitta.dev
36
+ executables:
37
+ - hl
38
+ - hilight
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - bin/hilight
43
+ - bin/hl
44
+ - lib/hilighter.rb
45
+ - lib/hilighter/codes.rb
46
+ - lib/hilighter/methods.rb
47
+ - lib/string.rb
48
+ homepage: https://gitlab.com/mjwhitta/hilighter/tree/ruby
49
+ licenses:
50
+ - GPL-3.0
51
+ metadata:
52
+ source_code_uri: https://gitlab.com/mjwhitta/hilighter/tree/ruby
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.0.6
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Adds color methods to String class
72
+ test_files: []