treat 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/INSTALL +0 -0
  2. data/LICENSE +28 -0
  3. data/README +0 -0
  4. data/TODO +67 -0
  5. data/bin/INFO +1 -0
  6. data/examples/benchmark.rb +81 -0
  7. data/examples/keywords.rb +60 -0
  8. data/examples/texts/bugged_out.txt +26 -0
  9. data/examples/texts/half_cocked_basel.txt +16 -0
  10. data/examples/texts/hedge_funds.txt +24 -0
  11. data/examples/texts/hose_and_dry.txt +19 -0
  12. data/examples/texts/hungarys_troubles.txt +46 -0
  13. data/examples/texts/indias_slowdown.txt +15 -0
  14. data/examples/texts/merkozy_rides_again.txt +24 -0
  15. data/examples/texts/prada_is_not_walmart.txt +9 -0
  16. data/examples/texts/republican_nomination.txt +26 -0
  17. data/examples/texts/to_infinity_and_beyond.txt +15 -0
  18. data/lib/treat.rb +91 -0
  19. data/lib/treat/buildable.rb +115 -0
  20. data/lib/treat/categories.rb +29 -0
  21. data/lib/treat/category.rb +28 -0
  22. data/lib/treat/delegatable.rb +90 -0
  23. data/lib/treat/detectors.rb +28 -0
  24. data/lib/treat/detectors/encoding/native.rb +12 -0
  25. data/lib/treat/detectors/encoding/r_chardet19.rb +24 -0
  26. data/lib/treat/detectors/format/file.rb +36 -0
  27. data/lib/treat/detectors/language/language_detector.rb +19 -0
  28. data/lib/treat/detectors/language/what_language.rb +29 -0
  29. data/lib/treat/entities.rb +52 -0
  30. data/lib/treat/entities/collection.rb +19 -0
  31. data/lib/treat/entities/constituents.rb +15 -0
  32. data/lib/treat/entities/document.rb +11 -0
  33. data/lib/treat/entities/entity.rb +242 -0
  34. data/lib/treat/entities/sentence.rb +8 -0
  35. data/lib/treat/entities/text.rb +7 -0
  36. data/lib/treat/entities/tokens.rb +37 -0
  37. data/lib/treat/entities/zones.rb +17 -0
  38. data/lib/treat/exception.rb +5 -0
  39. data/lib/treat/extractors.rb +41 -0
  40. data/lib/treat/extractors/key_sentences/topics_frequency.rb +49 -0
  41. data/lib/treat/extractors/named_entity/abner.rb +20 -0
  42. data/lib/treat/extractors/named_entity/stanford.rb +174 -0
  43. data/lib/treat/extractors/statistics/frequency.rb +22 -0
  44. data/lib/treat/extractors/statistics/frequency_of.rb +17 -0
  45. data/lib/treat/extractors/statistics/position_in.rb +13 -0
  46. data/lib/treat/extractors/statistics/transition_matrix.rb +105 -0
  47. data/lib/treat/extractors/statistics/transition_probability.rb +53 -0
  48. data/lib/treat/extractors/time/chronic.rb +12 -0
  49. data/lib/treat/extractors/time/native.rb +12 -0
  50. data/lib/treat/extractors/time/nickel.rb +45 -0
  51. data/lib/treat/extractors/topic_words/lda.rb +71 -0
  52. data/lib/treat/extractors/topic_words/lda/data.dat +46 -0
  53. data/lib/treat/extractors/topic_words/lda/wiki.yml +121 -0
  54. data/lib/treat/extractors/topics/reuters.rb +91 -0
  55. data/lib/treat/extractors/topics/reuters/industry.xml +2717 -0
  56. data/lib/treat/extractors/topics/reuters/region.xml +13585 -0
  57. data/lib/treat/extractors/topics/reuters/topics.xml +17977 -0
  58. data/lib/treat/feature.rb +53 -0
  59. data/lib/treat/formatters.rb +44 -0
  60. data/lib/treat/formatters/cleaners/html.rb +17 -0
  61. data/lib/treat/formatters/readers/autoselect.rb +35 -0
  62. data/lib/treat/formatters/readers/gocr.rb +24 -0
  63. data/lib/treat/formatters/readers/html.rb +13 -0
  64. data/lib/treat/formatters/readers/ocropus.rb +31 -0
  65. data/lib/treat/formatters/readers/pdf.rb +17 -0
  66. data/lib/treat/formatters/readers/txt.rb +15 -0
  67. data/lib/treat/formatters/serializers/xml.rb +48 -0
  68. data/lib/treat/formatters/serializers/yaml.rb +15 -0
  69. data/lib/treat/formatters/serializers/yaml/helper.rb +96 -0
  70. data/lib/treat/formatters/unserializers/autoselect.rb +19 -0
  71. data/lib/treat/formatters/unserializers/xml.rb +79 -0
  72. data/lib/treat/formatters/unserializers/yaml.rb +15 -0
  73. data/lib/treat/formatters/visualizers/dot.rb +73 -0
  74. data/lib/treat/formatters/visualizers/html.rb +12 -0
  75. data/lib/treat/formatters/visualizers/inspect.rb +16 -0
  76. data/lib/treat/formatters/visualizers/short_value.rb +14 -0
  77. data/lib/treat/formatters/visualizers/standoff.rb +41 -0
  78. data/lib/treat/formatters/visualizers/tree.rb +28 -0
  79. data/lib/treat/formatters/visualizers/txt.rb +31 -0
  80. data/lib/treat/group.rb +96 -0
  81. data/lib/treat/inflectors.rb +50 -0
  82. data/lib/treat/inflectors/cardinal_words/linguistics.rb +45 -0
  83. data/lib/treat/inflectors/conjugators/linguistics.rb +30 -0
  84. data/lib/treat/inflectors/declensors/en.rb +18 -0
  85. data/lib/treat/inflectors/declensors/linguistics.rb +30 -0
  86. data/lib/treat/inflectors/lemmatizers/e_lemma.rb +12 -0
  87. data/lib/treat/inflectors/lemmatizers/e_lemma/Makefile +213 -0
  88. data/lib/treat/inflectors/lemmatizers/e_lemma/elemma.c +68 -0
  89. data/lib/treat/inflectors/lemmatizers/e_lemma/extconf.rb +6 -0
  90. data/lib/treat/inflectors/ordinal_words/linguistics.rb +21 -0
  91. data/lib/treat/inflectors/stemmers/porter.rb +158 -0
  92. data/lib/treat/inflectors/stemmers/porter_c.rb +23 -0
  93. data/lib/treat/inflectors/stemmers/uea.rb +30 -0
  94. data/lib/treat/lexicalizers.rb +49 -0
  95. data/lib/treat/lexicalizers/category/from_tag.rb +30 -0
  96. data/lib/treat/lexicalizers/linkages/naive.rb +63 -0
  97. data/lib/treat/lexicalizers/synsets/rita_wn.rb +23 -0
  98. data/lib/treat/lexicalizers/synsets/wordnet.rb +72 -0
  99. data/lib/treat/lexicalizers/tag/brill.rb +101 -0
  100. data/lib/treat/lexicalizers/tag/lingua.rb +114 -0
  101. data/lib/treat/lexicalizers/tag/stanford.rb +86 -0
  102. data/lib/treat/processors.rb +45 -0
  103. data/lib/treat/processors/chunkers/txt.rb +27 -0
  104. data/lib/treat/processors/parsers/enju.rb +214 -0
  105. data/lib/treat/processors/parsers/stanford.rb +60 -0
  106. data/lib/treat/processors/segmenters/punkt.rb +48 -0
  107. data/lib/treat/processors/segmenters/stanford.rb +45 -0
  108. data/lib/treat/processors/segmenters/tactful.rb +34 -0
  109. data/lib/treat/processors/tokenizers/macintyre.rb +76 -0
  110. data/lib/treat/processors/tokenizers/multilingual.rb +31 -0
  111. data/lib/treat/processors/tokenizers/perl.rb +96 -0
  112. data/lib/treat/processors/tokenizers/punkt.rb +42 -0
  113. data/lib/treat/processors/tokenizers/stanford.rb +33 -0
  114. data/lib/treat/processors/tokenizers/tactful.rb +59 -0
  115. data/lib/treat/proxies.rb +66 -0
  116. data/lib/treat/registrable.rb +26 -0
  117. data/lib/treat/resources.rb +10 -0
  118. data/lib/treat/resources/categories.rb +18 -0
  119. data/lib/treat/resources/delegates.rb +96 -0
  120. data/lib/treat/resources/dependencies.rb +0 -0
  121. data/lib/treat/resources/edges.rb +8 -0
  122. data/lib/treat/resources/formats.rb +23 -0
  123. data/lib/treat/resources/languages.rb +86 -0
  124. data/lib/treat/resources/languages.txt +504 -0
  125. data/lib/treat/resources/tags.rb +393 -0
  126. data/lib/treat/sugar.rb +43 -0
  127. data/lib/treat/tree.rb +174 -0
  128. data/lib/treat/utilities.rb +127 -0
  129. data/lib/treat/visitable.rb +27 -0
  130. data/test/profile.rb +2 -0
  131. data/test/tc_detectors.rb +27 -0
  132. data/test/tc_entity.rb +105 -0
  133. data/test/tc_extractors.rb +48 -0
  134. data/test/tc_formatters.rb +46 -0
  135. data/test/tc_inflectors.rb +39 -0
  136. data/test/tc_lexicalizers.rb +39 -0
  137. data/test/tc_processors.rb +36 -0
  138. data/test/tc_resources.rb +27 -0
  139. data/test/tc_treat.rb +64 -0
  140. data/test/tc_tree.rb +60 -0
  141. data/test/tests.rb +19 -0
  142. data/test/texts.rb +20 -0
  143. data/test/texts/english/long.html +24 -0
  144. data/test/texts/english/long.txt +22 -0
  145. data/test/texts/english/medium.txt +5 -0
  146. data/test/texts/english/short.txt +3 -0
  147. metadata +412 -0
@@ -0,0 +1,15 @@
1
+ module Treat
2
+ module Formatters
3
+ module Unserializers
4
+ class YAML
5
+ # Require the Psych YAML parser.
6
+ require 'psych'
7
+ # Unserialize a YAML file representing an entity.
8
+ def self.unserialize(document, options = {})
9
+ document << ::Psych.load(File.read(document.file))
10
+ document
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,73 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ class Dot
5
+ # Border colors to use for different POS tags.
6
+ BorderColors = {
7
+ :verb => "#00AABB",
8
+ :noun => "#FAD4A7",
9
+ :adverb => '#103585',
10
+ :adjective => '#D21D54'
11
+ }
12
+ # Create the top-most graph structure
13
+ # and delegate the creation of the graph
14
+ # nodes to to_dot.
15
+ def self.visualize(entity, options = {})
16
+ string = "graph {"
17
+ string << self.to_dot(entity)
18
+ string << "\n}"
19
+ end
20
+ # dot -Tpdf test4.dot > test4.pdf
21
+ def self.to_dot(entity)
22
+ string = ''
23
+ if entity.is_leaf?
24
+ if entity.is_a?(Treat::Entities::Word)
25
+ label = "label=\"#{entity.value} (#{entity.tag})\","
26
+ label << "color=\"#{BorderColors[entity.cat]}\","
27
+ else
28
+ label = "label=\"#{entity.value.inspect[1..-2]}\","
29
+ end
30
+ else
31
+ if entity.class < Entities::Constituent
32
+ label = "label=\"#{entity.tag}\","
33
+ # label << "color=\"#{BorderColors[entity.tag]}\","
34
+ else
35
+ label = "label=\"#{cc(cl(entity.class))}\","
36
+ end
37
+ end
38
+ string << "\n#{entity.id} ["
39
+ if entity.has_features?
40
+ string << label
41
+ entity.features.each_pair do |feature, value|
42
+ if value.is_a?(Treat::Entities::Entity)
43
+ string << "#{feature}=\"#{value.id}\","
44
+ else
45
+ string << "#{feature}=\"#{value}\","
46
+ end
47
+ end
48
+ string = string[0..-2]
49
+ string << "]"
50
+ else
51
+ string << "#{label[0..-2]}]"
52
+ end
53
+ if entity.has_parent?
54
+ string << "\n#{entity.parent.id} -- #{entity.id};"
55
+ end
56
+ if entity.has_children?
57
+ entity.each do |child|
58
+ string << self.to_dot(child)
59
+ end
60
+ end
61
+ if entity.has_edges?
62
+ entity.edges.each_pair do |target, type|
63
+ string << "\n#{entity.id} -- #{target}"
64
+ string << "[label=#{type},dir=forward,"
65
+ string << "arrowhead=\"odiamond\"]"
66
+ end
67
+ end
68
+ string
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,12 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ # This class is not implemented yet.
5
+ class HTML
6
+ # Not implemented yet.
7
+ def self.visualize(entity, options = {})
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ class Inspect
5
+ def self.visualize(entity, options = {})
6
+ s = "#{entity.class.to_s.split('::')[-1]} (#{entity.id.to_s})"
7
+ unless caller_method == :inspect
8
+ s += " | #{entity.short_value.inspect} | #{entity.features.inspect}" +
9
+ " | #{entity.edges.inspect}"
10
+ end
11
+ s
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ class ShortValue
5
+ def self.visualize(entity, options = {})
6
+ options[:max_length] ||= 6
7
+ words = entity.to_s.split(' ')
8
+ return entity.to_s if words.size < options[:max_length]
9
+ words[0..2].join(' ') + ' [...] ' + words[-3..-1].join(' ')
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ # This class allows the visualization of
5
+ # an entity in standoff format; for example:
6
+ # (S (NP John) (VP has (VP come))).
7
+ class Standoff
8
+ Recurse = Proc.new do |entity, options|
9
+ v = ''
10
+ entity.each { |child| v += visualize(child, options) }
11
+ v
12
+ end
13
+ # Visualize the entity using standoff notation.
14
+ # This can only be called on sentences, as it
15
+ # is not a suitable format to represent larger
16
+ # entity.
17
+ def self.visualize(entity, options = {})
18
+ options = {:indent => 0} if options.empty?
19
+ value = ''; spaces = ''
20
+ options[:indent].times { spaces << ' '}
21
+ options[:indent] += 1
22
+ if entity.is_a?(Treat::Entities::Token)
23
+ value += "#{spaces}(#{entity.tag} #{entity.value})"
24
+ elsif entity.is_a?(Treat::Entities::Constituent)
25
+ value += ("#{spaces}(#{entity.tag}\n" +
26
+ "#{Recurse.call(entity, options)})\n")
27
+ elsif entity.is_a?(Treat::Entities::Sentence)
28
+ value += ("#{spaces}(S\n" +
29
+ "#{Recurse.call(entity, options)})\n")
30
+ else
31
+ raise 'Standoff format is unsuitable to represent' +
32
+ ' entities larger than sentences.'
33
+ end
34
+ options[:indent] -= 1
35
+ value.gsub!(")\n)", "))")
36
+ value
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ class Tree
5
+ # Obtain a plain text tree representation
6
+ # of the entity.
7
+ def self.visualize(entity, options = {})
8
+ options = {:indent => 0} if options.empty?
9
+ string = ''
10
+ if entity.has_children?
11
+ spacer = '--'
12
+ spaces = ''
13
+ options[:indent].times { spaces << ' '}
14
+ string << "+ #{entity.inspect}\n#{spaces}|"
15
+ options[:indent] += 1
16
+ entity.children.each do |child|
17
+ string = string + "\n" + spaces + '+' +
18
+ spacer + self.visualize(child, options)
19
+ end
20
+ options[:indent] -= 1
21
+ return string
22
+ end
23
+ '> ' + entity.inspect
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ module Treat
2
+ module Formatters
3
+ module Visualizers
4
+ # Creates a plain text visualization of an entity.
5
+ class Txt
6
+ # Obtain a plain text visualization of the entity,
7
+ # with no additional information.
8
+ def self.visualize(entity, options = {})
9
+ options[:sep] = ' '
10
+ return entity.value if !entity.has_children?
11
+ value = ''
12
+ entity.each do |child|
13
+ if child.is_a?(Treat::Entities::Token) || child.value != ''
14
+ # Remove the trailing space for tokens that
15
+ # 'stick' to the previous one, such
16
+ # as punctuation symbols and clitics.
17
+ if child.is_a?(Treat::Entities::Punctuation) ||
18
+ child.is_a?(Treat::Entities::Clitic)
19
+ value.strip!
20
+ end
21
+ value += child.value + options[:sep]
22
+ else
23
+ value += visualize(child, options)
24
+ end
25
+ end
26
+ value
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ module Treat
2
+ module Group
3
+ def self.extended(group)
4
+ group.module_eval do
5
+ class << self
6
+ attr_accessor :type, :default, :targets
7
+ end
8
+ # Return the method corresponding to the group.
9
+ # This method resolves the name of the method
10
+ # that a group should provide based on the name
11
+ # of the group. Basically, if the group ends in
12
+ # -ers, the verb corresponding to the group is
13
+ # returned (tokenizers -> tokenize, inflectors ->
14
+ # inflect). Otherwise, the name of the method
15
+ # is the same as that of the group (encoding ->
16
+ # encoding, tag -> tag).
17
+ @method = nil
18
+ def self.method
19
+ return @method if @method
20
+ m = ucc(cl(self))
21
+ if m[-3..-1] == 'ers'
22
+ if ['k', 't', 'm', 'd', 'g', 'n'].include? m[-4]
23
+ n = m[0..-4]
24
+ n = n[0..-2] if n[-1] == n[-2]
25
+ else
26
+ n = m[0..-3]
27
+ end
28
+ elsif m[-3..-1] == 'ors'
29
+ n = m[0..-4] + 'e'
30
+ else
31
+ n = m
32
+ end
33
+ @method = :"#{n}"
34
+ end
35
+ end
36
+ end
37
+ # Create a new algorithm within the group. Once
38
+ # the algorithm is added, it will be automatically
39
+ # installed on all the targets of the group.
40
+ def add(class_name, &block)
41
+ class_name = :"#{cc(class_name)}"
42
+ klass = self.const_set(class_name, Class.new)
43
+ method = self.method
44
+ klass.class_eval do
45
+ @@block = block
46
+ eval "def #{method}(entity);" +
47
+ "@@block.call(entity); end"
48
+ end
49
+ end
50
+ # Boolean - does the group have the supplied class
51
+ # included in its targets?
52
+ def has_target?(target, strict = false)
53
+ is_target = false
54
+ self.targets.each do |entity_type|
55
+ entity_type = Entities.const_get(cc(entity_type))
56
+ if target < entity_type || entity_type == target
57
+
58
+ is_target = true; break
59
+ end
60
+ end
61
+ is_target
62
+ end
63
+ # Populates once the list of the adaptors in the group
64
+ # by crawling the filesystem.
65
+ @@list = {}
66
+ def list
67
+ mod = ucc(cl(self))
68
+ if @@list[mod].nil?
69
+ @@list[mod] = []
70
+ dirs = Dir["#{File.dirname(__FILE__)}/*/#{mod}/*.rb"] # Fix
71
+ dirs.each do |file|
72
+ @@list[mod] <<
73
+ :"#{file.split('/')[-1][0..-4]}"
74
+ end
75
+ end
76
+ @@list[mod]
77
+ end
78
+ # Set inherit to false by default.
79
+ def const_get(const)
80
+ super(const, false)
81
+ end
82
+ # Autoload the algorithms.
83
+ def const_missing(const)
84
+ bits = self.ancestors[0].to_s.split('::')
85
+ bits.collect! { |bit| ucc(bit) }
86
+ file = bits.join('/') + "/#{ucc(const)}" # Fix
87
+ #if not File.readable?(file + '.rb')
88
+ # raise Treat::Exception,
89
+ # "File '#{file}.rb' corresponding to requested delegate "+
90
+ # "#{self}::#{const} does not exist."
91
+ require file
92
+ const_get(const)
93
+ #end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,50 @@
1
+ module Treat
2
+ # Algorithms to retrieve the inflections of a word.
3
+ # Stemmers return the stem (not root form) of a word.
4
+ # Taggers return the part of speech tag of a word.
5
+ # Inflectors allow to retrieve the different inflections of a
6
+ # noun (declensions), a verb (conjugations). Lexicons return,
7
+ # among other things, the gloss or synset of a word.
8
+ module Inflectors
9
+ # Lemmatizers return the root form of a word.
10
+ module Lemmatizers
11
+ extend Group
12
+ self.type = :annotator
13
+ self.targets = [:word]
14
+ end
15
+ # Stemmers return the stem (*not root form*) of a word.
16
+ module Stemmers
17
+ extend Group
18
+ self.type = :annotator
19
+ self.targets = [:word]
20
+ end
21
+ # Declensors allow to retrieve the different declensions of a
22
+ # noun (singular, plural).
23
+ module Declensors
24
+ extend Group
25
+ self.type = :annotator
26
+ self.targets = [:word]
27
+ end
28
+ # Conjugators allow to retrieve the different conjugations of
29
+ # a word.
30
+ module Conjugators
31
+ extend Group
32
+ self.type = :annotator
33
+ self.targets = [:word]
34
+ end
35
+ # Cardinal retrieve the full text description of a number.
36
+ module CardinalWords
37
+ extend Group
38
+ self.type = :annotator
39
+ self.targets = [:number]
40
+ end
41
+ # Ordinal retrieve the ordinal form of numbers.
42
+ module OrdinalWords
43
+ extend Group
44
+ self.type = :annotator
45
+ self.targets = [:number]
46
+ end
47
+ extend Treat::Category
48
+ end
49
+ end
50
+
@@ -0,0 +1,45 @@
1
+ module Treat
2
+ module Inflectors
3
+ module CardinalWords
4
+ class Linguistics
5
+ silently { require 'linguistics' }
6
+ #
7
+ # Options:
8
+ #
9
+ # :group => Controls how many numbers at a time are
10
+ # grouped together. Valid values are 0 (normal grouping),
11
+ # 1 (single-digit grouping, e.g., “one, two, three, four”),
12
+ # 2 (double-digit grouping, e.g., “twelve, thirty-four”, or
13
+ # 3 (triple-digit grouping, e.g., “one twenty-three, four”).
14
+ # :comma => Set the character/s used to separate word groups.
15
+ # Defaults to ", ".
16
+ # :and => Set the word and/or characters used where ' and '
17
+ # (the default) is normally used. Setting :and to ' ', for
18
+ # example, will cause 2556 to be returned as “two-thousand,
19
+ # five hundred fifty-six” instead of “two-thousand, five
20
+ # hundred and fifty-six”.
21
+ # :zero => Set the word used to represent the numeral 0 in
22
+ # the result. 'zero' is the default.
23
+ # :decimal => Set the translation of any decimal points in
24
+ # the number; the default is 'point'.
25
+ # :asArray If set to a true value, the number will be returned
26
+ # as an array of word groups instead of a String.
27
+ #
28
+ # More specific options when using :type => :ordinal:
29
+ #
30
+ #
31
+ def self.cardinal_words(entity, options = {})
32
+ begin
33
+ l = entity.language.to_s.upcase
34
+ delegate = nil
35
+ silently { delegate = ::Linguistics.const_get(l) }
36
+ rescue RuntimeError
37
+ raise "Ruby Linguistics does not have a module " +
38
+ " installed for the #{entity.language} language."
39
+ end
40
+ silently { delegate.numwords(entity.to_s, options) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ module Treat
2
+ module Inflectors
3
+ module Conjugators
4
+ class Linguistics
5
+ silently { require 'linguistics' }
6
+ def self.conjugate(entity, parameters)
7
+ begin
8
+ l = entity.language.to_s.upcase
9
+ delegate = nil
10
+ silently { delegate = ::Linguistics.const_get(l) }
11
+ rescue RuntimeError
12
+ raise "Ruby Linguistics does not have a module " +
13
+ " installed for the #{entity.language} language."
14
+ end
15
+ if parameters[:mode] == :infinitive
16
+ silently { delegate.infinitive(entity.to_s) }
17
+ elsif parameters[:mode] == :participle && parameters[:tense] == :present
18
+ silently { delegate.present_participle(entity.to_s) }
19
+ elsif parameters[:count] == :plural && parameters.size == 1
20
+ silently { delegate.plural_verb(entity.to_s) }
21
+ else
22
+ raise Treat::Exception,
23
+ 'This combination of modes, tenses, persons ' +
24
+ 'and/or counts is not presently supported.'
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end