Class: Odyssey::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/odyssey/engine.rb

Constant Summary collapse

LETTER_REGEX =

regex

/[A-z]/
WORD_REGEX =
/[^\W][A-z\-']*/
SENTENCE_REGEX =
/[^\.!?\s][^\.!?]*(?:[\.!?](?!['"]?\s|$)[^\.!?]*)*[\.!?]?['"]?(?=\s|$)/
PROBLEM_WORDS =

words that cause the syllable analyzer to fail word => syllables

{
  'ion'    => 2
}

Instance Method Summary collapse

Constructor Details

#initialize(formula_name) ⇒ Engine

Returns a new instance of Engine.


23
24
25
26
27
28
29
# File 'lib/odyssey/engine.rb', line 23

def initialize(formula_name)
  reset
  klass = Module.const_get formula_name
  @formula = klass.new
rescue
  @formula = Formula.new
end

Instance Method Details

#analyze_syllables(_word) ⇒ Object


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/odyssey/engine.rb', line 102

def analyze_syllables(_word)
  #remove non-alpha characters
  word = _word.gsub(/[^A-z]/, '')
  count = 0

  if PROBLEM_WORDS.has_key?(word)
    count = PROBLEM_WORDS[word]
  else
    #this is an approximation, but it is fairly close
    word.downcase!
    return 1 if word.length <= 3
    word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '')
    word.sub!(/^y/, '')
    count = word.scan(/[aeiouy]{1,2}/).size
  end

  count
end

#average_syllables_per_word(text) ⇒ Object


92
93
94
# File 'lib/odyssey/engine.rb', line 92

def average_syllables_per_word(text)
  @stats['syllable_count'].to_f / @stats['word_count'].to_f
end

#average_words_per_sentence(text) ⇒ Object


88
89
90
# File 'lib/odyssey/engine.rb', line 88

def average_words_per_sentence(text)
  @stats['word_count'].to_f / @stats['sentence_count'].to_f
end

#get_statsObject


121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/odyssey/engine.rb', line 121

def get_stats
  { 
    'name'           => @formula.name,
    'formula'        => @formula,
    'score'          => @score,
    'string_length'  => @stats['string_length'],
    'letter_count'   => @stats['letter_count'],
    'syllable_count' => @stats['syllable_count'],
    'word_count'     => @stats['word_count'],
    'sentence_count' => @stats['sentence_count'],
    'average_words_per_sentence' => @stats['average_words_per_sentence'],
    'average_syllables_per_word' => @stats['average_syllables_per_word']
  }
end

#letter_count(text) ⇒ Object


63
64
65
66
# File 'lib/odyssey/engine.rb', line 63

def letter_count(text)
  matches = text.scan LETTER_REGEX
  matches.size
end

#resetObject


136
137
138
139
140
141
142
143
# File 'lib/odyssey/engine.rb', line 136

def reset
  @formula = nil
  @score = 0
  @stats = {}
  @words = nil
  @sentences = nil
  @syllables = []
end

#sanitize(text) ⇒ Object

for now this just removes html tags but it could do more in the future


98
99
100
# File 'lib/odyssey/engine.rb', line 98

def sanitize(text)
  output = text.gsub(/<\/?[^>]+>/, '')
end

#score(_text) ⇒ Object


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/odyssey/engine.rb', line 31

def score(_text)
  #sanitize the text
  text = sanitize(_text)

  #first get all the statistics
  @stats = {
    'string_length' => string_length(text),
    'letter_count' => letter_count(text),
    'word_count' => word_count(text),
    'syllable_count' => syllable_count(text),
    'sentence_count' => sentence_count(text),
  }
  
  @stats['average_words_per_sentence'] = average_words_per_sentence(text)
  @stats['average_syllables_per_word'] = average_syllables_per_word(text)

  #prepare the parameter to the score method
  data = {
    'raw' => text,
    'words' => @words,
    'sentences' => @sentences,
    'syllables' => @syllables
  }

  #now run all that through the formula
  @score = @formula.score(data, @stats)
end

#sentence_count(text) ⇒ Object


83
84
85
86
# File 'lib/odyssey/engine.rb', line 83

def sentence_count(text)
  @sentences = text.scan SENTENCE_REGEX
  @sentences.size
end

#string_length(text) ⇒ Object


59
60
61
# File 'lib/odyssey/engine.rb', line 59

def string_length(text)
  text.length
end

#syllable_count(text) ⇒ Object


68
69
70
71
72
73
74
75
76
# File 'lib/odyssey/engine.rb', line 68

def syllable_count(text)
  count = 0
  @words.each do |w|
    num = analyze_syllables(w)
    count += num
    @syllables << num
  end
  count
end

#word_count(text) ⇒ Object


78
79
80
81
# File 'lib/odyssey/engine.rb', line 78

def word_count(text)
  @words = text.scan WORD_REGEX
  @words.size
end