Class: String
- Defined in:
- lib/epitools/core_ext/string.rb,
lib/epitools/core_ext/truthiness.rb
Constant Summary collapse
- LOWERCASE_WORDS =
For ‘titlecase`
Set.new %w[of to or the and an a at is for from in]
- COLOR_REGEXP =
A Regexp to recognize ANSI escape sequences
/\e\[.*?(\d)+m/- BASE62_DIGITS =
Cached constants for base62 decoding.
- BASE62_BASE =
Integer::BASE62_BASE
Instance Method Summary collapse
-
#amount(n) ⇒ Object
Convert this string into a string describing this many of the string.
-
#any? ⇒ Boolean
(also: #present?)
Is there anything in the string? (ignoring whitespace/newlines).
-
#blank? ⇒ Boolean
‘true’ if the string’s length is 0 (after whitespace has been stripped from the ends).
-
#contains_color? ⇒ Boolean
(also: #contains_colors?, #contains_ansi?)
This string contains ANSI (VT100) control codes.
-
#deflate(level = nil) ⇒ Object
deflate the string.
-
#dewhitespace ⇒ Object
Remove redundant whitespace AND newlines.
-
#each_chomped ⇒ Object
(also: #chomped_lines, #chomp_lines)
Like #each_line, but removes trailing n.
-
#each_slice(slice_width, &block) ⇒ Object
Iterate over slices of the string of size ‘slice_width`.
-
#endswith?(substring) ⇒ Boolean
(also: #endswith)
‘true` if this string ends with the substring.
-
#float? ⇒ Boolean
Could this string be cast to an float?.
-
#from_base62 ⇒ Object
Convert a string encoded in base62 into an integer.
-
#from_base64 ⇒ Object
(also: #decode64)
Decode a mime64/base64 encoded string.
-
#from_hms ⇒ Object
Converts time duration strings (mm:ss, mm:ss.dd, hh:mm:ss, or dd:hh:mm:ss) to seconds.
-
#from_json ⇒ Object
Parse this string as JSON.
-
#from_yaml ⇒ Object
Parse this string as YAML.
-
#gunzip ⇒ Object
gunzip the string.
-
#gzip(level = nil) ⇒ Object
gzip the string.
-
#hexdump ⇒ Object
Print a hexdump of the string to STDOUT (coloured, if the terminal supports it).
-
#indent(prefix = " ") ⇒ Object
Indent all the lines, if “prefix” is a string, prepend that string to each lien.
-
#inflate ⇒ Object
inflate the string.
-
#integer? ⇒ Boolean
Could this string be cast to an integer?.
-
#md5 ⇒ Object
MD5 the string.
-
#nice_html(indent = 2) ⇒ Object
(also: #nicehtml, #indent_html)
Use Nokogiri to parse this string as HTML, and return an indented version.
-
#nice_lines ⇒ Object
(also: #nicelines, #clean_lines)
Like #each_line, but skips empty lines and removes n‘s.
-
#number? ⇒ Boolean
Could this string be cast to an number?.
-
#rot13 ⇒ Object
The Infamous Caesar-Cipher.
-
#sha1 ⇒ Object
SHA1 the string.
-
#startswith?(substring) ⇒ Boolean
(also: #startswith)
‘true` if this string starts with the substring.
-
#strip_color ⇒ Object
(also: #strip_ansi)
Remove ANSI color codes.
-
#tighten ⇒ Object
Remove redundant whitespaces (not including newlines).
-
#titlecase ⇒ Object
Return a new string converted to “Title Case” (first letter of each word capitalized).
-
#titlecase! ⇒ Object
Convert string to “Title Case” (first letter of each word capitalized).
-
#to_base62 ⇒ Object
Convert a string (encoded in base16 “hex” – for example, an MD5 or SHA1 hash) into “base62” format.
-
#to_base64 ⇒ Object
(also: #base64, #encode64)
Encode into a mime64/base64 string.
-
#to_params ⇒ Object
Convert a query string to a hash of params.
-
#to_proc(&block) ⇒ Object
String#to_proc.
-
#to_unix ⇒ Object
Convert rn to n.
-
#truthy? ⇒ Boolean
Does this string contain something that means roughly “true”?.
-
#unmarshal ⇒ Object
(also: #from_marshal)
Unmarshal the string (transform it into Ruby datatypes).
-
#urldecode ⇒ Object
Convert an URI’s %XXes into regular characters.
-
#urlencode ⇒ Object
Convert non-URI characters into %XXes.
-
#wrap(width = nil) ⇒ Object
(also: #word_wrap)
Word-wrap the string so each line is at most ‘width` wide.
-
#wrap_and_indent(prefix, width = nil) ⇒ Object
(also: #wrapdent)
Wrap all lines at window size, and indent.
Instance Method Details
#amount(n) ⇒ Object
Convert this string into a string describing this many of the string. (Note: Doesn’t know anything about proper grammar.)
Example:
"cookie".amount(0) #=> "0 cookies"
"shirt".amount(17) #=> "17 shirts"
"dollar".amount(-10) #=> "-10 dollars"
"love".amount(1) #=> "1 love"
379 380 381 382 383 384 385 386 387 388 |
# File 'lib/epitools/core_ext/string.rb', line 379 def amount(n) case n when 0 "0 #{self}s" when 1, -1 "#{n} #{self}" else "#{n} #{self}s" end end |
#any? ⇒ Boolean Also known as: present?
Is there anything in the string? (ignoring whitespace/newlines)
133 134 135 |
# File 'lib/epitools/core_ext/truthiness.rb', line 133 def any? not blank? end |
#blank? ⇒ Boolean
‘true’ if the string’s length is 0 (after whitespace has been stripped from the ends)
126 127 128 |
# File 'lib/epitools/core_ext/truthiness.rb', line 126 def blank? strip.size == 0 end |
#contains_color? ⇒ Boolean Also known as: contains_colors?, contains_ansi?
This string contains ANSI (VT100) control codes
64 65 66 |
# File 'lib/epitools/core_ext/string.rb', line 64 def contains_color? self[COLOR_REGEXP] end |
#deflate(level = nil) ⇒ Object
deflate the string
321 322 323 |
# File 'lib/epitools/core_ext/string.rb', line 321 def deflate(level=nil) Zlib::Deflate.deflate(self, level) end |
#dewhitespace ⇒ Object
Remove redundant whitespace AND newlines.
24 25 26 |
# File 'lib/epitools/core_ext/string.rb', line 24 def dewhitespace gsub(/\s+/,' ').strip end |
#each_chomped ⇒ Object Also known as: chomped_lines, chomp_lines
Like #each_line, but removes trailing n
92 93 94 |
# File 'lib/epitools/core_ext/string.rb', line 92 def each_chomped each_line { |line| yield line.chomp } end |
#each_slice(slice_width, &block) ⇒ Object
Iterate over slices of the string of size ‘slice_width`.
194 195 196 197 198 199 200 201 |
# File 'lib/epitools/core_ext/string.rb', line 194 def each_slice(slice_width, &block) max = size p = 0 while p < max yield self[p...p+slice_width] p += slice_width end end |
#endswith?(substring) ⇒ Boolean Also known as: endswith
‘true` if this string ends with the substring
342 343 344 |
# File 'lib/epitools/core_ext/string.rb', line 342 def endswith?(substring) self[-substring.size..-1] == substring end |
#float? ⇒ Boolean
Could this string be cast to an float?
112 113 114 |
# File 'lib/epitools/core_ext/truthiness.rb', line 112 def float? !!strip.match(/^-?\d+\.\d+$/) end |
#from_base62 ⇒ Object
Convert a string encoded in base62 into an integer. (See Integer#to_base62 for more info.)
261 262 263 264 265 266 267 268 |
# File 'lib/epitools/core_ext/string.rb', line 261 def from_base62 accumulator = 0 digits = chars.map { |c| BASE62_DIGITS[c] }.reverse digits.each_with_index do |digit, power| accumulator += (BASE62_BASE**power) * digit if digit > 0 end accumulator end |
#from_base64 ⇒ Object Also known as: decode64
Decode a mime64/base64 encoded string
273 274 275 |
# File 'lib/epitools/core_ext/string.rb', line 273 def from_base64 unpack("m").first end |
#from_hms ⇒ Object
Converts time duration strings (mm:ss, mm:ss.dd, hh:mm:ss, or dd:hh:mm:ss) to seconds. (The reverse of Integer#to_hms)
394 395 396 397 398 399 400 401 402 |
# File 'lib/epitools/core_ext/string.rb', line 394 def from_hms nums = split(':') nums[-1] = nums[-1].to_f if nums[-1] =~ /\d+\.\d+/ # convert fractional seconds to a float nums.map! { |n| n.is_a?(String) ? n.to_i : n } # convert the rest to integers nums_and_units = nums.reverse.zip %w[seconds minutes hours days] nums_and_units.map { |num, units| num.send(units) }.sum end |
#from_json ⇒ Object
Parse this string as JSON
350 351 352 |
# File 'lib/epitools/core_ext/string.rb', line 350 def from_json JSON.parse(self) end |
#from_yaml ⇒ Object
Parse this string as YAML
357 358 359 |
# File 'lib/epitools/core_ext/string.rb', line 357 def from_yaml YAML.load(self) end |
#gunzip ⇒ Object
gunzip the string
313 314 315 316 |
# File 'lib/epitools/core_ext/string.rb', line 313 def gunzip data = StringIO.new(self) Zlib::GzipReader.new(data).read end |
#gzip(level = nil) ⇒ Object
gzip the string
304 305 306 307 308 |
# File 'lib/epitools/core_ext/string.rb', line 304 def gzip(level=nil) zipped = StringIO.new Zlib::GzipWriter.wrap(zipped, level) { |io| io.write(self) } zipped.string end |
#hexdump ⇒ Object
Print a hexdump of the string to STDOUT (coloured, if the terminal supports it)
407 408 409 |
# File 'lib/epitools/core_ext/string.rb', line 407 def hexdump Hex.dump(self) end |
#indent(prefix = " ") ⇒ Object
Indent all the lines, if “prefix” is a string, prepend that string to each lien. If it’s an integer, prepend that many spaces.
103 104 105 106 107 108 109 110 111 |
# File 'lib/epitools/core_ext/string.rb', line 103 def indent(prefix=" ") prefix = (" " * prefix) if prefix.is_an? Integer if block_given? lines.each { |line| yield prefix + line } else lines.map { |line| prefix + line }.join('') end end |
#inflate ⇒ Object
inflate the string
328 329 330 |
# File 'lib/epitools/core_ext/string.rb', line 328 def inflate Zlib::Inflate.inflate(self) end |
#integer? ⇒ Boolean
Could this string be cast to an integer?
105 106 107 |
# File 'lib/epitools/core_ext/truthiness.rb', line 105 def integer? !!strip.match(/^-?\d+$/) end |
#md5 ⇒ Object
MD5 the string
290 291 292 |
# File 'lib/epitools/core_ext/string.rb', line 290 def md5 Digest::MD5.hexdigest self end |
#nice_html(indent = 2) ⇒ Object Also known as: nicehtml, indent_html
Use Nokogiri to parse this string as HTML, and return an indented version
116 117 118 |
# File 'lib/epitools/core_ext/string.rb', line 116 def nice_html(indent=2) Nokogiri::HTML.fragment(self).to_xhtml(indent: indent) end |
#nice_lines ⇒ Object Also known as: nicelines, clean_lines
Like #each_line, but skips empty lines and removes n‘s.
81 82 83 84 |
# File 'lib/epitools/core_ext/string.rb', line 81 def nice_lines # note: $/ is the platform's newline separator split($/).select{|l| not l.blank? } end |
#number? ⇒ Boolean
Could this string be cast to an number?
119 120 121 |
# File 'lib/epitools/core_ext/truthiness.rb', line 119 def number? !!strip.match(/^-?\d\.?\d*$/) end |
#rot13 ⇒ Object
The Infamous Caesar-Cipher. Unbreakable to this day.
207 208 209 |
# File 'lib/epitools/core_ext/string.rb', line 207 def rot13 tr('n-za-mN-ZA-M', 'a-zA-Z') end |
#sha1 ⇒ Object
SHA1 the string
297 298 299 |
# File 'lib/epitools/core_ext/string.rb', line 297 def sha1 Digest::SHA1.hexdigest self end |
#startswith?(substring) ⇒ Boolean Also known as: startswith
‘true` if this string starts with the substring
334 335 336 |
# File 'lib/epitools/core_ext/string.rb', line 334 def startswith?(substring) self[0...substring.size] == substring end |
#strip_color ⇒ Object Also known as: strip_ansi
Remove ANSI color codes.
73 74 75 |
# File 'lib/epitools/core_ext/string.rb', line 73 def strip_color gsub(COLOR_REGEXP, '') end |
#tighten ⇒ Object
Remove redundant whitespaces (not including newlines).
17 18 19 |
# File 'lib/epitools/core_ext/string.rb', line 17 def tighten gsub(/[\t ]+/,' ').strip end |
#titlecase ⇒ Object
Return a new string converted to “Title Case” (first letter of each word capitalized)
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/epitools/core_ext/string.rb', line 36 def titlecase first = true words = downcase.split(/(?<!\w')\b/) words.map.with_index do |word,i| if LOWERCASE_WORDS.include?(word) and i > 0 # leave LOWERCASE_WORDS lowercase, unless it's the first word. word else word.gsub(/^\w/) { |c| c.upcase } # capitalize first letter end end.join('') end |
#titlecase! ⇒ Object
Convert string to “Title Case” (first letter of each word capitalized)
52 53 54 |
# File 'lib/epitools/core_ext/string.rb', line 52 def titlecase! replace(titlecase) end |
#to_base62 ⇒ Object
Convert a string (encoded in base16 “hex” – for example, an MD5 or SHA1 hash) into “base62” format. (See Integer#to_base62 for more info.)
253 254 255 |
# File 'lib/epitools/core_ext/string.rb', line 253 def to_base62 to_i(16).to_base62 end |
#to_base64 ⇒ Object Also known as: base64, encode64
Encode into a mime64/base64 string
281 282 283 |
# File 'lib/epitools/core_ext/string.rb', line 281 def to_base64 [self].pack("m") end |
#to_params ⇒ Object
Convert a query string to a hash of params
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/epitools/core_ext/string.rb', line 228 def to_params params = {} split(/[&;]/).each do |pairs| key, value = pairs.split('=',2).collect { |v| CGI.unescape(v) } if key and value params[key] ||= [] params[key] << value end end params.map_values { |v| v.size > 1 ? v : v.first } end |
#to_proc(&block) ⇒ Object
String#to_proc
See weblog.raganwald.com/2007/10/stringtoproc.html
Ported from the String Lambdas in Oliver Steele’s Functional Javascript osteele.com/sources/javascript/functional/
This work is licensed under the MIT License:
© 2007 Reginald Braithwaite Portions Copyright © 2006 Oliver Steele
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
# File 'lib/epitools/core_ext/string.rb', line 446 def to_proc &block params = [] expr = self sections = expr.split(/\s*->\s*/m) if sections.length > 1 then eval_block(sections.reverse!.inject { |e, p| "(Proc.new { |#{p.split(/\s/).join(', ')}| #{e} })" }, block) elsif expr.match(/\b_\b/) eval_block("Proc.new { |_| #{expr} }", block) else leftSection = expr.match(/^\s*(?:[+*\/%&|\^\.=<>\[]|!=)/m) rightSection = expr.match(/[+\-*\/%&|\^\.=<>!]\s*$/m) if leftSection || rightSection then if (leftSection) then params.push('$left') expr = '$left' + expr end if (rightSection) then params.push('$right') expr = expr + '$right' end else self.gsub( /(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|self|arguments|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/, '' ).scan( /([a-z_$][a-z_$\d]*)/i ) do |v| params.push(v) unless params.include?(v) end end eval_block("Proc.new { |#{params.join(', ')}| #{expr} }", block) end end |
#to_unix ⇒ Object
Convert rn to n
10 11 12 |
# File 'lib/epitools/core_ext/string.rb', line 10 def to_unix gsub("\r\n", "\n") end |
#truthy? ⇒ Boolean
Does this string contain something that means roughly “true”?
141 142 143 144 145 146 147 148 |
# File 'lib/epitools/core_ext/truthiness.rb', line 141 def truthy? case strip.downcase when "1", "true", "yes", "on", "enabled", "affirmative" true else false end end |
#unmarshal ⇒ Object Also known as: from_marshal
Unmarshal the string (transform it into Ruby datatypes).
364 365 366 |
# File 'lib/epitools/core_ext/string.rb', line 364 def unmarshal Marshal.restore self end |
#urldecode ⇒ Object
Convert an URI’s %XXes into regular characters.
221 222 223 |
# File 'lib/epitools/core_ext/string.rb', line 221 def urldecode URI.unescape(self) end |
#urlencode ⇒ Object
Convert non-URI characters into %XXes.
214 215 216 |
# File 'lib/epitools/core_ext/string.rb', line 214 def urlencode URI.escape(self) end |
#wrap(width = nil) ⇒ Object Also known as: word_wrap
Word-wrap the string so each line is at most ‘width` wide. Returns a string, or, if a block is given, yields each word-wrapped line to the block.
If ‘width` is nil, find the current width of the terminal and use that. If `width` is negative, subtract `width` from the terminal’s current width.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/epitools/core_ext/string.rb', line 130 def wrap(width=nil) if width.nil? or width < 0 require 'io/console' _, winwidth = STDIN.winsize if width < 0 width = (winwidth - 1) + width else width = winwidth - 1 end end return self if size <= width strings = [] start_pos = 0 end_pos = width loop do split_pos = rindex(/\s/, end_pos) || end_pos strings << self[start_pos...split_pos] start_pos = index(/\S/, split_pos) break if start_pos == nil end_pos = start_pos + width if end_pos > size strings << self[start_pos..-1] break end end if block_given? strings.each { |s| yield s } else strings.join("\n") end end |
#wrap_and_indent(prefix, width = nil) ⇒ Object Also known as: wrapdent
Wrap all lines at window size, and indent
176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/epitools/core_ext/string.rb', line 176 def wrap_and_indent(prefix, width=nil) prefix = " "*prefix if prefix.is_a? Numeric prefix_size = prefix.strip_color.size if width width = width - prefix_size else width = -prefix_size end wrap(width).each_line.map { |line| prefix + line }.join end |