string_dot_gradient 0.1.9 → 0.4.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: 229c7c52d938962d064671617bd9c8ae622df4a52fa5dd7df0b4485ec14e55a1
4
- data.tar.gz: 0d926f9ed11056c3870c3964a7497c345b890582e8816296baa2c38eaa07836d
3
+ metadata.gz: edc1903ceea6827357c02ef0efdea7dcf1de66b9e6487f61b43ab01932eae822
4
+ data.tar.gz: 561e461b724a013786533e03ce752756f224cc8d6aaee6f064ace18ccf7a1e11
5
5
  SHA512:
6
- metadata.gz: 9baf8ae5b7a5e0285db981cc3d4426493cd44864f40a44cbefecde30b7742602f5424275bfe676a330dd9a8eb5c9117c4c50b055811c76d072c2f9c632ab7e07
7
- data.tar.gz: 3186f138e9036fc98801a0810913524c16508a2468126c41a9482d3043b0accaf41bbcbf9aa2c6600365e30d043e6b311aaec8db6b43d83eea6cfe3e75f47565
6
+ metadata.gz: c072842423ac1aadda79d3c445c6a0e7b347b5ddc67c62ee2a6a9195571e6c23b82485014e514af9d8fb363ad82ab411dd7d71568744cc90463845968f407874
7
+ data.tar.gz: c302d7acbfca9b35d182fe8b2a0406d6882487cc242b18c2d050b600ea9d087a49f2c9bb85db580c5d91b7207e6f193c4543e142a8700596c099888395353f22
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "string_dot_gradient/version"
3
+ require_relative 'string_dot_gradient/version'
4
+ require 'string_dot_gradient/hex_to_rgb.rb'
4
5
  require 'string_dot_gradient/gradient.rb'
@@ -46,15 +46,50 @@ class String
46
46
  #
47
47
  # The option blink makes the texts blink on supported terminals.
48
48
  # Set blink to anything truthy or falsey, but better just go with true and false or nil
49
- def gradient(*arg_colours, bg: false, exclude_spaces: true, bold: false, blink: false)
49
+ def gradient(*arg_colours,
50
+ exclude_spaces: true,
51
+ bg: false,
52
+ bold: false,
53
+ italic: false,
54
+ underline: false,
55
+ blink: false,
56
+ strikethrough: false,
57
+ double_underline: false,
58
+ overline: false
59
+ )
60
+
61
+ space, tab = ?\s.freeze, ?\t.freeze
62
+
63
+ block_given = block_given?
50
64
  temp = ''
51
65
  flatten_colours = arg_colours.flatten
52
66
 
67
+ # Create the styling here rather than creating it in the each_line loop
68
+ # We also make it a bit different, rather than using \e[1m\e[5m, we will do
69
+ # \e[1;5m to save the number of characters spit out by this method
70
+ style = nil
71
+
72
+ if bold || italic || underline || blink || strikethrough || double_underline || overline
73
+ style = "\e["
74
+
75
+ style << '1;'.freeze if bold
76
+ style << '3;'.freeze if italic
77
+ style << '4;'.freeze if underline
78
+ style << '5;'.freeze if blink
79
+ style << '9;'.freeze if strikethrough
80
+ style << '21;'.freeze if double_underline
81
+ style << '53;'.freeze if overline
82
+
83
+ style.chop!
84
+ style << ?m.freeze
85
+ end
86
+
53
87
  raise ArgumentError, "Wrong numeber of colours (given #{flatten_colours.length}, expected minimum 2)" if flatten_colours.length < 2
54
88
  raise ArgumentError, "Given argument for colour is neither a String nor an Integer" if flatten_colours.any? { |x| !(x.is_a?(String) || x.is_a?(Integer)) }
55
89
 
56
90
  all_rgbs = flatten_colours.map!(&method(:hex_to_rgb))
57
- block_given = block_given?
91
+
92
+ yield style if block_given && style
58
93
 
59
94
  # r, g, b => starting r, g, b
60
95
  # r2, g2, b2 => stopping r, g, b
@@ -65,8 +100,7 @@ class String
65
100
  init = bg ? 48 : 38
66
101
 
67
102
  each_line do |c|
68
- temp << "\e[1m".freeze if bold
69
- temp << "\e[5m".freeze if blink
103
+ temp << style if style
70
104
 
71
105
  _r, _g, _b = r, g, b
72
106
  chomped = !!c.chomp!(''.freeze)
@@ -77,6 +111,11 @@ class String
77
111
  n_variable = 1 if n_variable < 1
78
112
 
79
113
  # colour operator, colour value
114
+ #
115
+ # r_op, g_op, b_op are also flags to determine
116
+ # if the r, g, and b values respectively should change or not
117
+ # For example, if the given blues are equal, the b_op is nil
118
+ # So it won't change the colour in the ouput
80
119
  r_op = r_val = nil
81
120
  g_op = g_val = nil
82
121
  b_op = b_val = nil
@@ -108,7 +147,7 @@ class String
108
147
  while (i += 1) < len
109
148
  _c = c[i]
110
149
 
111
- if !exclude_spaces || (exclude_spaces && !(_c == ?\s.freeze || _c == ?\t.freeze))
150
+ if !exclude_spaces || (_c != space && _c != tab)
112
151
  _r = _r.send(r_op, r_val) if r_op
113
152
  _g = _g.send(g_op, g_val) if g_op
114
153
  _b = _b.send(b_op, b_val) if b_op
@@ -118,11 +157,11 @@ class String
118
157
  g_to_i = _g.to_i
119
158
  b_to_i = _b.to_i
120
159
 
121
- f_r = r_to_i < 0 ? 0 : r_to_i > 255 ? 255 : r_to_i
122
- f_g = g_to_i < 0 ? 0 : g_to_i > 255 ? 255 : g_to_i
123
- f_b = b_to_i < 0 ? 0 : b_to_i > 255 ? 255 : b_to_i
160
+ clamped_r = r_to_i < 0 ? 0 : r_to_i > 255 ? 255 : r_to_i
161
+ clamped_g = g_to_i < 0 ? 0 : g_to_i > 255 ? 255 : g_to_i
162
+ clamped_b = b_to_i < 0 ? 0 : b_to_i > 255 ? 255 : b_to_i
124
163
 
125
- ret = "\e[#{init};2;#{f_r};#{f_g};#{f_b}m#{_c}"
164
+ ret = "\e[#{init};2;#{clamped_r};#{clamped_g};#{clamped_b}m#{_c}"
126
165
 
127
166
  if block_given
128
167
  yield ret
@@ -153,36 +192,83 @@ class String
153
192
  block_given ? nil : temp
154
193
  end
155
194
 
156
- private
157
- def hex_to_rgb(hex)
158
- # Duplicate colour, even if colour is nil
159
- # This workaround is for Ruby 2.0 to Ruby 2.2
160
- # Which won't allow duplicate nil.
161
- colour = hex && hex.dup.to_s || ''
162
- colour.strip!
163
- colour.downcase!
164
- colour[0] = ''.freeze if colour[0] == ?#.freeze
165
-
166
- # out of range
167
- oor = colour.scan(/[^a-f0-9]/)
168
-
169
- unless oor.empty?
170
- invalids = colour.chars.map { |x|
171
- oor.include?(x) ? "\e[1;31m#{x}\e[0m" : x
172
- }.join
173
-
174
- puts "Hex Colour ##{invalids} is Out of Range"
175
- raise ArgumentError
176
- end
195
+ ##
196
+ # = multi_gradient(*n_arg_colours, bg: false, exclude_spaces: true, bold: false, blink: false) # => string or nil
197
+ #
198
+ # Accepts n number of colours. Example:
199
+ # 'Hello world this is multi_gradient()'.multi_gradient('3eb', '55f', 'f55', 'fa0')
200
+ #
201
+ # In this example, multi_gradient() paints the string with 4 colours in one line.
202
+ #
203
+ # It Splits up a string with the Calls String#gradient() with the given number of colours
204
+ # So each call to multi_gradient() involves many calls to String#gradient().
205
+ # Hence it's slower than String#gradient()
206
+ def multi_gradient(*colours,
207
+ exclude_spaces: true,
208
+ bg: false,
209
+ bold: false,
210
+ italic: false,
211
+ underline: false,
212
+ blink: false,
213
+ strikethrough: false,
214
+ double_underline: false,
215
+ overline: false,
216
+ &block
217
+ )
177
218
 
178
- clen = colour.length
179
- if clen == 3
180
- colour.chars.map { |x| x.<<(x).to_i(16) }
181
- elsif clen == 6
182
- colour.chars.each_slice(2).map { |x| x.join.to_i(16) }
183
- else
184
- sli = clen > 6 ? 'too long'.freeze : clen < 3 ? 'too short'.freeze : 'invalid'.freeze
185
- raise ArgumentError, "Invalid Hex Colour ##{colour} (length #{sli})"
186
- end
219
+ len = colours.length
220
+ raise ArgumentError, "Minimum two colours are required, given #{len}" if len < 2
221
+
222
+ div = len - 1
223
+ div_1 = div - 1
224
+ ret = ''
225
+ block_given = block_given?
226
+
227
+ params = {
228
+ exclude_spaces: exclude_spaces,
229
+ bg: bg,
230
+ bold: bold,
231
+ italic: italic,
232
+ underline: underline,
233
+ blink: blink,
234
+ strikethrough: strikethrough,
235
+ double_underline: double_underline,
236
+ overline: overline,
237
+ }
238
+
239
+ each_line { |l|
240
+ _len = l.length
241
+
242
+ len, c = _len.fdiv(div).round, colours.dup
243
+ counter, i, j = -1, -1, 0
244
+ ch = ''
245
+
246
+ while x = l[i += 1] do
247
+ counter += 1
248
+
249
+ # colour % len == 0 is very slow approach
250
+ if counter == len && j < div_1
251
+ counter, j = 0, j + 1
252
+ if block_given
253
+ ch.gradient(c[0], c[1], **params, &block)
254
+ else
255
+ ret << ch.gradient(c[0], c[1], **params)
256
+ end
257
+
258
+ c.rotate!
259
+ ch.clear
260
+ end
261
+
262
+ ch << x
263
+ end
264
+
265
+ if block_given
266
+ ch.gradient(c[0], c[1], **params, &block)
267
+ else
268
+ ret << ch.gradient(c[0], c[1], **params)
269
+ end
270
+ }
271
+
272
+ block_given ? nil : ret
187
273
  end
188
274
  end
@@ -0,0 +1,53 @@
1
+ class String
2
+ # Fast conversion to RGB when Integer is passed.
3
+ # For example: 0xffffff for white,
4
+ # 0x000000 or 0x0 for black, 0x00aa00 for deep green
5
+ # 0xff50a6 for pink, 0xff5555 for light red, etc.
6
+ #
7
+ # Similarly:
8
+ # (255 * 256 * 256) + (255 * 256) + (255) => 0xffffff
9
+ # (0 * 256 * 256) + (0 * 256) + 0 => 0x0
10
+ # (255 * 256 * 256) + (85 * 256) + 85 => #ff5555
11
+ # (85 * 256 * 256) + (85 * 256) + 255 => #5555ff
12
+ # (255 * 256 * 256) + (170 * 256) + 0 => 0xffaa00
13
+ # (0 * 256 * 256) + (170 * 256) + 0 => 0x00aa00
14
+ def hex_to_rgb(hex)
15
+ return [
16
+ 255 & hex >> 16,
17
+ 255 & hex >> 8,
18
+ 255 & hex
19
+ ] if hex.is_a?(Integer)
20
+
21
+ # Duplicate colour, even if colour is nil
22
+ # This workaround is for Ruby 2.0 to Ruby 2.2
23
+ # Which won't allow duplicate nil.
24
+ colour = hex && hex.dup.to_s || ''
25
+ colour.strip!
26
+ colour.downcase!
27
+ colour[0] = ''.freeze if colour[0] == ?#.freeze
28
+
29
+ # out of range
30
+ oor = colour.scan(/[^a-f0-9]/)
31
+
32
+ unless oor.empty?
33
+ invalids = colour.chars.map { |x|
34
+ oor.include?(x) ? "\e[1;31m#{x}\e[0m" : x
35
+ }.join
36
+
37
+ raise ArgumentError, "\e[0mHex Colour \e[1m##{invalids} is Out of Range\e[0m"
38
+ end
39
+
40
+ clen = colour.length
41
+
42
+ if clen == 3
43
+ colour.chars.map { |x| x.<<(x).to_i(16) }
44
+ elsif clen == 6
45
+ colour.chars.each_slice(2).map { |x| x.join.to_i(16) }
46
+ else
47
+ sli = clen > 6 ? 'too long'.freeze : clen < 3 ? 'too short'.freeze : 'invalid'.freeze
48
+ raise ArgumentError, "Invalid Hex Colour ##{colour} (length #{sli})"
49
+ end
50
+ end
51
+
52
+ private(:hex_to_rgb)
53
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StringDotGradient
4
- VERSION = "0.1.9"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: string_dot_gradient
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sourav Goswami
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-14 00:00:00.000000000 Z
11
+ date: 2021-06-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: An itty-bitty extension that adds gradient method to String class that
14
- supports any hex colour, for Linux | Unix terminals only
13
+ description: An itty-bitty extension that adds "gradient" method to String class that
14
+ supports any hex colour, for Linux terminals
15
15
  email:
16
16
  - souravgoswami@protonmail.com
17
17
  executables: []
@@ -20,6 +20,7 @@ extra_rdoc_files: []
20
20
  files:
21
21
  - lib/string_dot_gradient.rb
22
22
  - lib/string_dot_gradient/gradient.rb
23
+ - lib/string_dot_gradient/hex_to_rgb.rb
23
24
  - lib/string_dot_gradient/version.rb
24
25
  homepage: https://github.com/Souravgoswami/string_dot_gradient
25
26
  licenses:
@@ -40,9 +41,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
41
  - !ruby/object:Gem::Version
41
42
  version: '0'
42
43
  requirements: []
43
- rubygems_version: 3.1.4
44
+ rubygems_version: 3.2.19
44
45
  signing_key:
45
46
  specification_version: 4
46
- summary: An itty-bitty extension that adds gradient method to String class that supports
47
- any hex colour, for Linux | Unix terminals only
47
+ summary: An itty-bitty extension that adds "gradient" method to String class that
48
+ supports any hex colour, for Linux terminals
48
49
  test_files: []