class Plasper::Plasper
Constants
- SENTENCE_DELIMITER
Attributes
Public Class Methods
Prepares selectors and weights storage
# File lib/Plasper/plasper.rb, line 11 def initialize @weights = { count: {}, first: {}, next: {}, last: {} } end
Public Instance Methods
Analyze input and add appropriate part
Determines if input is word, sentence or passage and adds it
@param [String] input
# File lib/Plasper/plasper.rb, line 20 def <<(input) if input.index(/\s+/).nil? word = normalize_word input self.word = word unless word == '' elsif input.scan(SENTENCE_DELIMITER).length < 2 self.sentence = input.gsub(SENTENCE_DELIMITER, '') else self.passage = input end end
Add weight
Used for adding weights for counters, first, next and last letter. Valid types are :count, :first, :next and :last (@see initialize) Group is either symbol (e.g. :letters, :words, :sentences, :letter), or string representing letter Item is integer (letter, word and sentence count) or string representing letter Weight is used for weighted-select in generation methods
@param [Symbol] type @param [Symbol|String] group @param [String|Integer] item @param [Integer] weight
# File lib/Plasper/plasper.rb, line 110 def add_weight(type, group, item, weight = 1) @weights[type][group] ||= Hash.new(0) @weights[type][group][item] += Integer weight end
Generate passage
@return [String]
# File lib/Plasper/plasper.rb, line 94 def passage sentence_count.times.map { sentence }.join('. ') + '.' end
Analyze passage
Splits passage with sentence-ending punctuation, adds sentence count weight and analyzes each sentence
@param [String] passage
# File lib/Plasper/plasper.rb, line 85 def passage=(passage) sentences = passage.split(SENTENCE_DELIMITER).select { |sentence| sentence.chomp != '' } sentences.each { |sentence| self.sentence = sentence } add_weight :count, :sentence, sentences.count end
Generate sentence
@return [String]
# File lib/Plasper/plasper.rb, line 74 def sentence string = word_count.times.map { word }.join(' ') string[0] = Unicode.upcase(string[0]) unless string.to_s == '' string end
Analyze sentence
Splits sentence with whitespace delimiter, adds weight for word count and analyzes each word
@param [String] sentence
# File lib/Plasper/plasper.rb, line 62 def sentence=(sentence) words = sentence.split(/\s+/) add_weight :count, :word, words.length unless words.length < 1 words.each do |word| normalized_word = normalize_word word self.word = normalized_word unless normalized_word == '' end end
Generate word
@return [String]
# File lib/Plasper/plasper.rb, line 46 def word letter_count = weighted(:count, :letter).to_i if letter_count == 1 last_letter! nil elsif letter_count > 0 result = first_letter (letter_count - 2).times { result += next_letter!(result[-1]) } result + last_letter!(result[-1]) end end
Analyze word
Adds weights for first, next and last letters and letter count
@param [String] word
# File lib/Plasper/plasper.rb, line 36 def word=(word) add_weight :count, :letter, word.length add_weight :first, :letter, word[0] (word.length - 1).times { |l| add_weight :next, word[l], word[l.succ] } add_weight :last, word[-2], word[-1] end
Private Instance Methods
Generate first letter
@return [String]
# File lib/Plasper/plasper.rb, line 139 def first_letter weighted :first, :letter end
Generate last letter after penultimate letter
@param [String] penultimate_letter @return [String]
# File lib/Plasper/plasper.rb, line 166 def last_letter(penultimate_letter) weighted :last, penultimate_letter end
Generate last letter with fallback to next_letter!
If there are no weights for last letter after given one, try to fall back to next_letter
@param [String] penultimate_letter @return [String]
# File lib/Plasper/plasper.rb, line 176 def last_letter!(penultimate_letter) last_letter(penultimate_letter) || next_letter!(penultimate_letter) end
Generate next letter for current one
@param [String] current_letter @return [String]
# File lib/Plasper/plasper.rb, line 147 def next_letter(current_letter) weighted :next, current_letter end
Generate next letter with fallback
If there are no weights with next letters for current_letter, try to generate another first letter instead and use it
@param [String] current_letter @return [String]
# File lib/Plasper/plasper.rb, line 158 def next_letter!(current_letter) next_letter(current_letter) || first_letter.to_s end
# File lib/Plasper/plasper.rb, line 118 def normalize_word(word) Unicode.downcase word.gsub(/[^[:word:]'-]/u, '') end
Weighted-randomly select sentence count
Used when generating passage
@return [Integer]
# File lib/Plasper/plasper.rb, line 194 def sentence_count weighted(:count, :sentence).to_i end
Generate weighted-random value
Type is :count, :first, :next or :last Group is symbol (for member count or first letter) or string representing letter
@param [Symbol] type @param [Symbol|String] group
# File lib/Plasper/plasper.rb, line 129 def weighted(type, group) if @weights[type].has_key?(group) selector = WeightedSelect::Selector.new @weights[type][group] selector.select end end
Weighted-randomly select word count
Used when generating sentence
@return [Integer]
# File lib/Plasper/plasper.rb, line 185 def word_count weighted(:count, :word).to_i end