Class: String

Inherits:
Object
  • Object
show all
Defined in:
lib/fat_core/string.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.random(size = 8) ⇒ Object


124
125
126
# File 'lib/fat_core/string.rb', line 124

def self.random(size = 8)
  ('a'..'z').cycle.take(size).shuffle.join
end

Instance Method Details

#as_stringObject


80
81
82
# File 'lib/fat_core/string.rb', line 80

def as_string
  self
end

#as_symObject

Convert to symbol “Hello World” -> :hello_world


75
76
77
78
# File 'lib/fat_core/string.rb', line 75

def as_sym
  strip.squeeze(' ').gsub(/\s+/, '_')
    .gsub(/[^_A-Za-z0-9]/, '').downcase.to_sym
end

#cleanObject

Remove leading and trailing white space and compress internal runs of white space to a single space.


6
7
8
# File 'lib/fat_core/string.rb', line 6

def clean
  strip.squeeze(' ')
end

#colorize(text, color_code) ⇒ Object


249
250
251
# File 'lib/fat_core/string.rb', line 249

def colorize(text, color_code)
  "#{color_code}#{text}\001\e[0m\002"
end

245
246
247
# File 'lib/fat_core/string.rb', line 245

def console_blink
  colorize(self, "\001\e[5m\002")
end

#console_blueObject


225
226
227
# File 'lib/fat_core/string.rb', line 225

def console_blue
  colorize(self, "\001\e[1m\e[34m\002")
end

#console_boldObject


241
242
243
# File 'lib/fat_core/string.rb', line 241

def console_bold
  colorize(self, "\001\e[1m\002")
end

#console_dark_blueObject


229
230
231
# File 'lib/fat_core/string.rb', line 229

def console_dark_blue
  colorize(self, "\001\e[34m\002")
end

#console_dark_greenObject


213
214
215
# File 'lib/fat_core/string.rb', line 213

def console_dark_green
  colorize(self, "\001\e[32m\002")
end

#console_dark_redObject


205
206
207
# File 'lib/fat_core/string.rb', line 205

def console_dark_red
  colorize(self, "\001\e[31m\002")
end

#console_dark_yellowObject


221
222
223
# File 'lib/fat_core/string.rb', line 221

def console_dark_yellow
  colorize(self, "\001\e[33m\002")
end

#console_defObject


237
238
239
# File 'lib/fat_core/string.rb', line 237

def console_def
  colorize(self, "\001\e[1m\002")
end

#console_greenObject


209
210
211
# File 'lib/fat_core/string.rb', line 209

def console_green
  colorize(self, "\001\e[1m\e[32m\002")
end

#console_purpleObject


233
234
235
# File 'lib/fat_core/string.rb', line 233

def console_purple
  colorize(self, "\001\e[1m\e[35m\002")
end

#console_redObject

Thanks to Eugene at stackoverflow for the following. stackoverflow.com/questions/8806643/

colorized-output-breaks-linewrapping-with-readline

These color strings without confusing readline about the length of the prompt string in the shell. (Unlike the rainbow routines)


201
202
203
# File 'lib/fat_core/string.rb', line 201

def console_red
  colorize(self, "\001\e[1m\e[31m\002")
end

#console_yellowObject


217
218
219
# File 'lib/fat_core/string.rb', line 217

def console_yellow
  colorize(self, "\001\e[1m\e[33m\002")
end

#digdate2isoObject

Convert a string with an all-digit date to an iso string E.g., “20090923” -> “2009-09-23”


130
131
132
# File 'lib/fat_core/string.rb', line 130

def digdate2iso
  sub(/(\d\d\d\d)(\d\d)(\d\d)/, '\1-\2-\3')
end

#distance(other, block_size: 1, max_distance: 10) ⇒ Object


10
11
12
13
14
15
16
17
# File 'lib/fat_core/string.rb', line 10

def distance(other, block_size: 1, max_distance: 10)
  dl = DamerauLevenshtein
  # NOTE: DL 'gives up after' max_distance, so the distance function
  # will return max_distance+1 if the distance is bigger than that.
  # Here we subtract 1 so the max_distance also becomes the max
  # return value.
  dl.distance(self, other, block_size, max_distance - 1)
end

#entitleObject


182
183
184
# File 'lib/fat_core/string.rb', line 182

def entitle
  dup.entitle!
end

#entitle!Object


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
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/fat_core/string.rb', line 134

def entitle!
  little_words = %w(a an the and or in on under of from as by to)
  newwords = []
  words = split(/\s+/)
  first_word = true
  num_words = words.length
  words.each_with_index do |w, k|
    last_word = (k + 1 == num_words)
    if w =~ %r{c/o}i
      # Care of
      newwords.push('c/o')
    elsif w =~ /^p\.?o\.?$/i
      # Post office
      newwords.push('P.O.')
    elsif w =~ /^[0-9]+(st|nd|rd|th)$/i
      # Ordinals
      newwords.push(w.downcase)
    elsif w =~ /^(cr|dr|st|rd|ave|pk|cir)$/i
      # Common abbrs to capitalize
      newwords.push(w.capitalize)
    elsif w =~ /^(us|ne|se|rr)$/i
      # Common 2-letter abbrs to upcase
      newwords.push(w.upcase)
    elsif w =~ /^[0-9].*$/i
      # Other runs starting with numbers,
      # like 3-A
      newwords.push(w.upcase)
    elsif w =~ /^(N|S|E|W|NE|NW|SE|SW)$/i
      # Compass directions all caps
      newwords.push(w.upcase)
    elsif w =~ /^[^aeiouy]*$/i && w.size > 2
      # All consonants and at least 3 chars, probably abbr
      newwords.push(w.upcase)
    elsif w =~ /^(\w+)-(\w+)$/i
      # Hyphenated double word
      newwords.push($1.capitalize + '-' + $2.capitalize)
    elsif little_words.include?(w.downcase)
      # Only capitalize at beginning or end
      newwords.push(first_word || last_word ? w.capitalize : w.downcase)
    else
      # All else
      newwords.push(w.capitalize)
    end
    first_word = false
  end
  self[0..-1] = newwords.join(' ')
end

#format_by(fmt) ⇒ Object

Format the string according to the given sprintf format.


187
188
189
190
191
192
193
194
# File 'lib/fat_core/string.rb', line 187

def format_by(fmt)
  return self unless fmt
  begin
    format fmt, self
  rescue ArgumentError
    return self
  end
end

#fuzzy_match(other) ⇒ Object

See if self contains colon- or space-separated words that include the colon- or space-separated words of other. Return the matched portion of self. Other cannot be a regex embedded in a string.


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/fat_core/string.rb', line 22

def fuzzy_match(other)
  # Remove periods, commas, and apostrophes
  other = other.gsub(/[\*.,']/, '')
  target = gsub(/[\*.,']/, '')
  matchers = other.split(/[: ]+/)
  regexp_string = matchers.map { |m| ".*?#{Regexp.escape(m)}.*?" }.join('[: ]')
  regexp_string.sub!(/^\.\*\?/, '')
  regexp_string.sub!(/\.\*\?$/, '')
  regexp = /#{regexp_string}/i
  matched_text =
    if (match = regexp.match(target))
      match[0]
    end
  matched_text
end

#matches_with(str) ⇒ Object

Here are instance methods for the class that includes Matchable This tries to convert the receiver object into a string, then matches against the given matcher, either via regex or a fuzzy string matcher.


42
43
44
45
46
47
48
49
50
51
# File 'lib/fat_core/string.rb', line 42

def matches_with(str)
  if str.nil?
    nil
  elsif str =~ %r{^\s*/}
    re = str.to_regexp
    $& if to_s =~ re
  else
    to_s.fuzzy_match(str)
  end
end

#number?Boolean

Returns:

  • (Boolean)

84
85
86
87
88
89
# File 'lib/fat_core/string.rb', line 84

def number?
  Float(self)
  true
rescue ArgumentError
  return false
end

#tex_quoteObject


109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/fat_core/string.rb', line 109

def tex_quote
  r = dup
  r = r.gsub(/[{]/, 'XzXzXobXzXzX')
  r = r.gsub(/[}]/, 'XzXzXcbXzXzX')
  r = r.gsub(/\\/, '\textbackslash{}')
  r = r.gsub(/\^/, '\textasciicircum{}')
  r = r.gsub(/~/, '\textasciitilde{}')
  r = r.gsub(/\|/, '\textbar{}')
  r = r.gsub(/\</, '\textless{}')
  r = r.gsub(/\>/, '\textgreater{}')
  r = r.gsub(/([_$&%#])/) { |m| '\\' + m }
  r = r.gsub('XzXzXobXzXzX', '\\{')
  r.gsub('XzXzXcbXzXzX', '\\}')
end

#to_regexpObject

Convert a string of the form ‘/…/Iixm’ to a regular expression. However, make the regular expression case-insensitive by default and extend the modifier syntax to allow ‘/I’ to indicate case-sensitive.


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/fat_core/string.rb', line 56

def to_regexp
  if self =~ %r{^\s*/([^/]*)/([Iixm]*)\s*$}
    body = $1
    opts = $2
    flags = Regexp::IGNORECASE
    unless opts.blank?
      flags = 0 if opts.include?('I')
      flags |= Regexp::IGNORECASE if opts.include?('i')
      flags |= Regexp::EXTENDED if opts.include?('x')
      flags |= Regexp::MULTILINE if opts.include?('m')
    end
    flags = nil if flags.zero?
    Regexp.new(body, flags)
  else
    Regexp.new(self)
  end
end

#wrap(width = 70, hang = 0) ⇒ Object


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/fat_core/string.rb', line 91

def wrap(width = 70, hang = 0)
  offset = 0
  trip = 1
  result = ''
  while (s = slice(offset, width))
    offset += width
    if trip == 1
      width -= hang
    else
      s = (' ' * hang) + s
    end
    result << s + "\n"
    trip += 1
  end
  # Remove the final newline before exiting
  result.strip
end