class RubyMarkovify::Text

Constants

DEFAULT_MAX_OVERLAP_RATIO
DEFAULT_MAX_OVERLAP_TOTAL
DEFAULT_TRIES
REJECT_PATTERN
WORD_SPLIT_PATTERN

Public Class Methods

new(input_text, state_size = nil, chain = nil) click to toggle source
# File lib/ruby_markovify/text.rb, line 7
def initialize(input_text, state_size = nil, chain = nil)
  runs = generate_corpus(input_text)
  @rejoined_text = sentence_join(runs.map { |e| word_join(e) })
  state_size ||= 2
  @chain = chain || Chain.new(runs, state_size)
end

Public Instance Methods

generate_corpus(text) click to toggle source
# File lib/ruby_markovify/text.rb, line 38
def generate_corpus(text)
  sentences = sentence_split text
  sentences.reject! { |e| test_sentence_input(e) }
  sentences.map { |e| word_split(e) }
end
make_sentence(init_state = nil, options = {}) click to toggle source
# File lib/ruby_markovify/text.rb, line 63
def make_sentence(init_state = nil, options = {})
  tries = options[:tries] || DEFAULT_TRIES
  mor = options[:max_overlap_ratio] || DEFAULT_MAX_OVERLAP_RATIO
  mot = options[:max_overlap_total] || DEFAULT_MAX_OVERLAP_TOTAL

  tries.times do
    words = @chain.walk(init_state)
    return word_join(words) if test_sentence_output(words, mor, mot)
  end
  nil
end
make_sentence_with_start(beginning, options = {}) click to toggle source
# File lib/ruby_markovify/text.rb, line 82
def make_sentence_with_start(beginning, options = {})
  make_sentence(word_split(beginning), options)
end
make_short_sentence(char_limit, options = {}) click to toggle source
# File lib/ruby_markovify/text.rb, line 75
def make_short_sentence(char_limit, options = {})
  loop do
    sentence = make_sentence(nil, options)
    return sentence if sentence && sentence.length < char_limit
  end
end
sentence_join(sentences) click to toggle source
# File lib/ruby_markovify/text.rb, line 19
def sentence_join(sentences)
  sentences.join ' '
end
sentence_split(text) click to toggle source
# File lib/ruby_markovify/text.rb, line 15
def sentence_split(text)
  split_into_sentences(text)
end
test_sentence_input(sentence) click to toggle source
# File lib/ruby_markovify/text.rb, line 34
def test_sentence_input(sentence)
  !!(sentence.to_ascii =~ REJECT_PATTERN)
end
test_sentence_output(words, max_overlap_ratio, max_overlap_total) click to toggle source
# File lib/ruby_markovify/text.rb, line 44
def test_sentence_output(words, max_overlap_ratio, max_overlap_total)
  overlap_ratio = (max_overlap_ratio * words.length).round
  overlap_max = [max_overlap_total, overlap_ratio].min
  overlap_over = overlap_max + 1
  gram_count = [words.length - overlap_max, 1].max

  grams = [*0..gram_count].map { |i| words[i..i+overlap_over] }
  grams.each do |g|
    gram_joined = word_join(g)
    return false if @rejoined_text.include? gram_joined
  end

  true
end
word_join(words) click to toggle source
# File lib/ruby_markovify/text.rb, line 28
def word_join(words)
  words.join ' '
end
word_split(sentence) click to toggle source
# File lib/ruby_markovify/text.rb, line 24
def word_split(sentence)
  sentence.split(WORD_SPLIT_PATTERN)
end