module Poefy::StringManipulation

Private Instance Methods

bracketed?(string) click to toggle source

Is the string enclosed in brackets?

# File lib/poefy/string_manipulation.rb, line 143
def bracketed? string
  square = (string[0] == '[' and string[-1] == ']')
  curly  = (string[0] == '{' and string[-1] == '}')
  square or curly
end
capitalize_first(text) click to toggle source

Capitalise the first character of a string

# File lib/poefy/string_manipulation.rb, line 112
def capitalize_first text
  text[0] = text[0].upcase
  text
end
end_the_sentence(text) click to toggle source

Final line must close with sentence-end punctuation.

# File lib/poefy/string_manipulation.rb, line 95
def end_the_sentence text
  if find = text.scan(/[[:punct:]]+$/).first
    swap = find.tr(',:;-', '.').delete('—–-')
    text.reverse.sub(find.reverse, swap.reverse).reverse
  else
    text += '.'
  end
end
fill_hash(value, key_range) click to toggle source

Fill a hash with a single value. Keys are integers in a range.

# File lib/poefy/string_manipulation.rb, line 134
def fill_hash value, key_range
  output = {}
  key_range.each do |i|
    output[i] = value
  end
  output
end
first_word(text) click to toggle source

The first word in a text string. Relies on space for whitespace. Discards any punctuation.

# File lib/poefy/string_manipulation.rb, line 27
def first_word text
  (text.gsub(/[[:punct:]]/,'').scan(/^[^ ]+/).first rescue '') || ''
end
has_stop_punctuation?(text) click to toggle source

Does the sentence end with a .!?

# File lib/poefy/string_manipulation.rb, line 105
def has_stop_punctuation? text
  return false if text.nil?
  punct = text.scan(/[[:punct:]]+$/).first
  !!(punct.match(/[\.!?]/) if punct)
end
humanize_instr(text) click to toggle source

Humanize every number in the text. This will not work for floats. It will also break emoticons, but GIGO.

# File lib/poefy/string_manipulation.rb, line 47
def humanize_instr text
  output = text.dup
  loop do
    num = output[/\d+/]
    break if not num
    output.sub!(num, num.to_i.humanize)
  end
  output
end
merge_hashes(one, two) click to toggle source

Combine two hashes together, transforming all values to array. These arrays are then flattened.

# File lib/poefy/string_manipulation.rb, line 119
def merge_hashes one, two
  one ||= {}
  two ||= {}
  new_hash = Hash.new { |h,k| h[k] = [] }
  keys = (one.keys + two.keys).sort.uniq
  keys.each do |key|
    new_hash[key] << one[key] if one[key]
    new_hash[key] << two[key] if two[key]
    new_hash[key].flatten!
  end
  new_hash
end
numeric?(text) click to toggle source

True if the whole text string can be expressed as Float.

# File lib/poefy/string_manipulation.rb, line 21
def numeric? text
  Float(text) != nil rescue false
end
phrase_info(text) click to toggle source

Return info that is returned using 'ruby_rhymes' '#to_phrase' But also account for numbers and initialisms.

# File lib/poefy/string_manipulation.rb, line 33
def phrase_info text
  input = humanize_instr text
  phrase = input.to_phrase rescue nil
  return { rhymes: [], syllables: 0, last_word: '' } if phrase.nil?
  last_word = phrase.last_word.downcase rescue ''
  rhy = phrase.rhymes.keys rescue []
  rhy = rhyme_initialism(input) if rhy.empty?
  syl = syllables_correct text rescue 0
  { rhymes: rhy, syllables: syl, last_word: last_word }
end
rhyme_initialism(text) click to toggle source

We will only call this method if there are no dictionary rhymes. If the last word is uppercase, then assume it's an initialism. Get the last letter and rhyme that. Else, return an empty array, as normal.

# File lib/poefy/string_manipulation.rb, line 61
def rhyme_initialism text
  output = []
  last_word = text.split.last
  if last_word and last_word == last_word.upcase
    letter = last_word.scan(/[A-Z]/).last
    output = letter.to_phrase.rhymes.keys rescue []
  end
  output
end
syllables_correct(text) click to toggle source

Get the correct syllable count, even for initialisms. e.g. “Flew in from Miami Beach BOAC”

"I'm back in the U.S.S.R"
# File lib/poefy/string_manipulation.rb, line 74
def syllables_correct text
  syll_count = 0

  # This is similar to how 'ruby_rhymes' splits to word.
  # But that gem ignores case, which we need.
  text.gsub(/[^A-Z ']/i,'').split.each do |word|

    # If the word has no rhymes, and it is uppercase, then assume
    #   it's an initialism and count each letter's syllables.
    if word.to_phrase.rhyme_keys.empty? and word == word.upcase
      word.gsub(/[^A-Z]/,'').split('').each do |i|
        syll_count += i.to_phrase.syllables
      end
    else
      syll_count += word.to_phrase.syllables
    end
  end
  syll_count
end