string_dot_gradient 0.1.6 → 0.3.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: 705f4872e8c680732b71c8d5e1e70f2287418d4b38278f92bbf801bb3d838f5a
4
- data.tar.gz: bc0c962ecd6615bc40ec1c58f1c90131a752651f1165b6962898e046f38511bf
3
+ metadata.gz: d6fa81c2c57dbe1b9712438b587127627a24f23e7583b1892328412ebc14031a
4
+ data.tar.gz: 2960add227d5e2c678f693da5a6c84269045b286b1d3c37f8426eb66f776f6e0
5
5
  SHA512:
6
- metadata.gz: 234f82023c22e4f0acffc3456eee6080b73cfad4516a34cb645a6a1dcc9a742c743e09368f71e15187721805ada57e3d2fbc892413677eb0daa0889bb98c6cbd
7
- data.tar.gz: '095bc1362d552dae0d1e8e56808fc993a92f47a529ef584fd0fdbbc6705cda1cb40237beb06b64d0ba0f28fe828b3179b76712f652e522658a110104bfbc1d57'
6
+ metadata.gz: 63ffc5173183586621b0b98550651b4049875464aa39aa97f5b926e479cfad1b72ca4f63fb4c959a051a7d9552b1f8bfd5b94454318709986784e1b406ed7e33
7
+ data.tar.gz: 443780070aabb205c759966136b725cd3d7d2ca4e7f1cf2208407d1553db7e95ce6712fbddba594d5e12b218f8dbd10f48c9a5f1a10481d83e97b2bd7f820aad
@@ -1,6 +1,6 @@
1
1
  class String
2
2
  ##
3
- # = gradient(*arg_colours, bg: false, exclude_spaces: true) # => string or nil
3
+ # = gradient(*arg_colours, bg: false, exclude_spaces: true, bold: false, blink: false) # => string or nil
4
4
  #
5
5
  # Prettifies your string by adding gradient colours.
6
6
  #
@@ -40,128 +40,137 @@ class String
40
40
  # This is because \r wipes out the previous characters, and using \u0000 in
41
41
  # a string is uncommon, and developers are requested to delete
42
42
  # \u0000 from string if such situations arise.
43
- def gradient(*arg_colours, bg: false, exclude_spaces: true)
44
- colours, line_length = [], -1
43
+ #
44
+ # The option bold makes texts bold, but it also makes the string bigger.
45
+ # Set bold to anything truthy or falsey, but better just go with true and false or nil
46
+ #
47
+ # The option blink makes the texts blink on supported terminals.
48
+ # Set blink to anything truthy or falsey, but better just go with true and false or nil
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
+
45
61
  temp = ''
46
62
  flatten_colours = arg_colours.flatten
47
63
 
64
+ # Create the styling here rather than creating it in the each_line loop
65
+ # We also make it a bit different, rather than using \e[1m\e[5m, we will do
66
+ # \e[1;5m to save the number of characters spit out by this method
67
+ style = nil
68
+
69
+ if bold || italic || underline || blink || strikethrough || double_underline || overline
70
+ style = "\e["
71
+
72
+ style << '1;'.freeze if bold
73
+ style << '3;'.freeze if italic
74
+ style << '4;'.freeze if underline
75
+ style << '5;'.freeze if blink
76
+ style << '9;'.freeze if strikethrough
77
+ style << '21;'.freeze if double_underline
78
+ style << '53;'.freeze if overline
79
+
80
+ style.chop!
81
+ style << ?m.freeze
82
+ end
83
+
48
84
  raise ArgumentError, "Wrong numeber of colours (given #{flatten_colours.length}, expected minimum 2)" if flatten_colours.length < 2
49
85
  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)) }
50
86
 
51
87
  all_rgbs = flatten_colours.map!(&method(:hex_to_rgb))
52
88
  block_given = block_given?
53
89
 
54
- r, g, b = all_rgbs[0]
55
- r2, g2, b2 = all_rgbs[1]
90
+ # r, g, b => starting r, g, b
91
+ # r2, g2, b2 => stopping r, g, b
92
+ r, g, b = *all_rgbs[0]
93
+ r2, g2, b2 = *all_rgbs[1]
56
94
  rotate = all_rgbs.length > 2
57
95
 
58
96
  init = bg ? 48 : 38
59
97
 
60
98
  each_line do |c|
99
+ temp << style if style
100
+
61
101
  _r, _g, _b = r, g, b
62
102
  chomped = !!c.chomp!(''.freeze)
63
103
 
64
- n = c.length
65
- n_variable = exclude_spaces ? c.delete("\t\s".freeze).length : n
104
+ len = c.length
105
+ n_variable = exclude_spaces ? c.delete("\t\s".freeze).length : len
106
+ n_variable -= 1
107
+ n_variable = 1 if n_variable < 1
66
108
 
67
- r_op = r_val = r_max = r_min = nil
68
- g_op = g_val = g_max = g_min = nil
69
- b_op = b_val = b_max = b_min = nil
70
-
71
- r_comp_op = r_comp_val = nil
72
- g_comp_op = g_comp_val = nil
73
- b_comp_op = b_comp_val = nil
109
+ # colour operator, colour value
110
+ r_op = r_val = nil
111
+ g_op = g_val = nil
112
+ b_op = b_val = nil
74
113
 
75
114
  if r2 > r
76
- r_op, r_val, r_max, r_min = :+, r2.fdiv(n_variable), r2, r
77
- r_comp_op, r_comp_val = :<=, r_max
115
+ r_op, r_val = :+, r2.-(r).fdiv(n_variable)
78
116
  elsif r2 < r
79
- r_op, r_val, r_max, r_min = :-, r.fdiv(n_variable), r, r2
80
- r_comp_op, r_comp_val = :>=, r_min
117
+ r_op, r_val = :-, r.-(r2).fdiv(n_variable)
81
118
  end
82
119
 
83
120
  if g2 > g
84
- g_op, g_val, g_max, g_min = :+, g2.fdiv(n_variable), g2, g
85
- g_comp_op, g_comp_val = :<=, g_max
121
+ g_op, g_val = :+, g2.-(g).fdiv(n_variable)
86
122
  elsif g2 < g
87
- g_op, g_val, g_max, g_min = :-, g.fdiv(n_variable), g, g2
88
- g_comp_op, g_comp_val = :>=, g_min
123
+ g_op, g_val = :-, g.-(g2).fdiv(n_variable)
89
124
  end
90
125
 
91
126
  if b2 > b
92
- b_op, b_val, b_max, b_min = :+, b2.fdiv(n_variable), b2, b
93
- b_comp_op, b_comp_val = :<=, b_max
127
+ b_op, b_val = :+, b2.-(b).fdiv(n_variable)
94
128
  elsif b2 < b
95
- b_op, b_val, b_max, b_min = :-, b.fdiv(n_variable), b, b2
96
- b_comp_op, b_comp_val = :>=, b_min
129
+ b_op, b_val = :-, b.-(b2).fdiv(n_variable)
97
130
  end
98
131
 
99
132
  # To avoid the value getting adding | subtracted from the initial character
100
- # Note that duplication is fine if we don't get a little bit performance loss
101
- _r = _r.send(r_op, r_val * -1) if r_comp_op && _r.send(r_comp_op, r_comp_val)
102
- _g = _g.send(g_op, g_val * -1) if g_comp_op && _g.send(g_comp_op, g_comp_val)
103
- _b = _b.send(b_op, b_val * -1) if b_comp_op && _b.send(b_comp_op, b_comp_val)
104
-
105
- if line_length != n || rotate
106
- line_length = n
107
- colours.clear
108
-
109
- i = -1
110
- while (i += 1) < n
111
- if exclude_spaces
112
- _c = c[i]
113
-
114
- if !(_c == ?\s.freeze || _c == ?\t.freeze)
115
- _r = _r.send(r_op, r_val) if r_comp_op && _r.send(r_comp_op, r_comp_val)
116
- _g = _g.send(g_op, g_val) if g_comp_op && _g.send(g_comp_op, g_comp_val)
117
- _b = _b.send(b_op, b_val) if b_comp_op && _b.send(b_comp_op, b_comp_val)
118
- end
119
- else
120
- # We also have duplication above,
121
- # But we are not going to remove this code unless
122
- # we find some efficient solution. Using a proc or method
123
- # for setting these values and calling that is a way
124
- # to make code slower.
125
- _r = _r.send(r_op, r_val) if r_comp_op && _r.send(r_comp_op, r_comp_val)
126
- _g = _g.send(g_op, g_val) if g_comp_op && _g.send(g_comp_op, g_comp_val)
127
- _b = _b.send(b_op, b_val) if b_comp_op && _b.send(b_comp_op, b_comp_val)
128
- end
129
-
130
- r_to_i = _r.to_i
131
- g_to_i = _g.to_i
132
- b_to_i = _b.to_i
133
-
134
- colours << [
135
- r_to_i < 0 ? 0 : r_to_i > 255 ? 255 : r_to_i,
136
- g_to_i < 0 ? 0 : g_to_i > 255 ? 255 : g_to_i,
137
- b_to_i < 0 ? 0 : b_to_i > 255 ? 255 : b_to_i,
138
- ]
139
- end
140
- end
133
+ _r = _r.send(r_op, r_val * -1) if r_op
134
+ _g = _g.send(g_op, g_val * -1) if g_op
135
+ _b = _b.send(b_op, b_val * -1) if b_op
141
136
 
142
137
  i = -1
143
- while (i += 1) < n
138
+ while (i += 1) < len
139
+ _c = c[i]
140
+
141
+ if !exclude_spaces || (exclude_spaces && !(_c == ?\s.freeze || _c == ?\t.freeze))
142
+ _r = _r.send(r_op, r_val) if r_op
143
+ _g = _g.send(g_op, g_val) if g_op
144
+ _b = _b.send(b_op, b_val) if b_op
145
+ end
146
+
147
+ r_to_i = _r.to_i
148
+ g_to_i = _g.to_i
149
+ b_to_i = _b.to_i
150
+
151
+ f_r = r_to_i < 0 ? 0 : r_to_i > 255 ? 255 : r_to_i
152
+ f_g = g_to_i < 0 ? 0 : g_to_i > 255 ? 255 : g_to_i
153
+ f_b = b_to_i < 0 ? 0 : b_to_i > 255 ? 255 : b_to_i
154
+
155
+ ret = "\e[#{init};2;#{f_r};#{f_g};#{f_b}m#{_c}"
156
+
144
157
  if block_given
145
- yield "\e[#{init};2;#{colours[i][0]};#{colours[i][1]};#{colours[i][2]}m#{c[i]}"
158
+ yield ret
146
159
  else
147
- temp.concat(
148
- "\e[#{init};2;#{colours[i][0]};#{colours[i][1]};#{colours[i][2]}m#{c[i]}"
149
- )
160
+ temp << ret
150
161
  end
151
162
  end
152
163
 
164
+ ret = if !c.empty?
165
+ chomped ? "\e[0m\n".freeze : "\e[0m".freeze
166
+ elsif chomped
167
+ ?\n.freeze
168
+ end
169
+
153
170
  if block_given
154
- if !c.empty?
155
- yield(chomped ? "\e[0m\n".freeze : "\e[0m".freeze)
156
- elsif chomped && c.empty?
157
- yield(?\n.freeze)
158
- end
171
+ yield ret
159
172
  else
160
- if !c.empty?
161
- temp.concat(chomped ? "\e[0m\n".freeze : "\e[0m".freeze)
162
- elsif chomped && c.empty?
163
- temp.concat(?\n.freeze)
164
- end
173
+ temp << ret
165
174
  end
166
175
 
167
176
  if rotate
@@ -174,9 +183,81 @@ class String
174
183
  block_given ? nil : temp
175
184
  end
176
185
 
186
+ ##
187
+ # = multi_gradient(*n_arg_colours, bg: false, exclude_spaces: true, bold: false, blink: false) # => string or nil
188
+ #
189
+ # Accepts n number of colours. Example:
190
+ # 'Hello world this is multi_gradient()'.multi_gradient('3eb', '55f', 'f55', 'fa0')
191
+ #
192
+ # In this example, multi_gradient() paints the string with 4 colours in one line.
193
+ #
194
+ # It Splits up a string with the Calls String#gradient() with the given number of colours
195
+ # So each call to multi_gradient() involves many calls to String#gradient().
196
+ # Hence it's slower than String#gradient()
197
+ def multi_gradient(*colours,
198
+ exclude_spaces: true,
199
+ bg: false,
200
+ bold: false,
201
+ italic: false,
202
+ underline: false,
203
+ blink: false,
204
+ strikethrough: false,
205
+ double_underline: false,
206
+ overline: false
207
+ )
208
+
209
+ len = colours.length
210
+ raise ArgumentError, "Minimum two colours are required, given #{len}" if len < 2
211
+
212
+ div = len - 1
213
+ div_1 = div - 1
214
+ ret = ''
215
+
216
+ params = {
217
+ exclude_spaces: exclude_spaces,
218
+ bg: bg,
219
+ bold: bold,
220
+ italic: italic,
221
+ underline: underline,
222
+ blink: blink,
223
+ strikethrough: strikethrough,
224
+ double_underline: double_underline,
225
+ overline: overline
226
+ }
227
+
228
+ each_line { |l|
229
+ _len = l.length
230
+
231
+ len, c = _len.fdiv(div).round, colours.dup
232
+ counter, i, j = -1, -1, 0
233
+ ch = ''
234
+
235
+ while x = l[i += 1] do
236
+ counter += 1
237
+
238
+ # colour % len == 0 is very slow approach
239
+ if counter == len && j < div_1
240
+ counter, j = 0, j + 1
241
+ ret << ch.gradient(c[0], c[1], **params)
242
+
243
+ c.rotate!
244
+ ch.clear
245
+ end
246
+
247
+ ch << x
248
+ end
249
+
250
+ ret << ch.gradient(c[0], c[1], **params)
251
+ }
252
+
253
+ ret
254
+ end
255
+
177
256
  private
178
257
  def hex_to_rgb(hex)
179
258
  # Duplicate colour, even if colour is nil
259
+ # This workaround is for Ruby 2.0 to Ruby 2.2
260
+ # Which won't allow duplicate nil.
180
261
  colour = hex && hex.dup.to_s || ''
181
262
  colour.strip!
182
263
  colour.downcase!
@@ -190,8 +271,7 @@ class String
190
271
  oor.include?(x) ? "\e[1;31m#{x}\e[0m" : x
191
272
  }.join
192
273
 
193
- puts "Hex Colour ##{invalids} is Out of Range"
194
- raise ArgumentError
274
+ raise ArgumentError, "\e[0mHex Colour \e[1m##{invalids} is Out of Range\e[0m"
195
275
  end
196
276
 
197
277
  clen = colour.length
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StringDotGradient
4
- VERSION = "0.1.6"
4
+ VERSION = "0.3.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.6
4
+ version: 0.3.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-09 00:00:00.000000000 Z
11
+ date: 2021-04-01 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: []
@@ -40,9 +40,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  requirements: []
43
- rubygems_version: 3.1.4
43
+ rubygems_version: 3.2.13
44
44
  signing_key:
45
45
  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
46
+ summary: An itty-bitty extension that adds "gradient" method to String class that
47
+ supports any hex colour, for Linux terminals
48
48
  test_files: []