greek_stemmer 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,263 @@
1
+ step_1_exceptions:
2
+ ΦΑΓΙΑ: ΦΑ
3
+ ΦΑΓΙΟΥ: ΦΑ
4
+ ΦΑΓΙΩΝ: ΦΑ
5
+ ΣΚΑΓΙΑ: ΣΚΑ
6
+ ΣΚΑΓΙΟΥ: ΣΚΑ
7
+ ΣΚΑΓΙΩΝ: ΣΚΑ
8
+ #ΟΛΟΓΙΟΥ: ΟΛΟ
9
+ #ΟΛΟΓΙΑ: ΟΛΟ
10
+ #ΟΛΟΓΙΩΝ: ΟΛΟ
11
+ ΣΟΓΙΟΥ: ΣΟ
12
+ ΣΟΓΙΑ: ΣΟ
13
+ ΣΟΓΙΩΝ: ΣΟ
14
+ ΤΑΤΟΓΙΑ: ΤΑΤΟ
15
+ ΤΑΤΟΓΙΟΥ: ΤΑΤΟ
16
+ ΤΑΤΟΓΙΩΝ: ΤΑΤΟ
17
+ ΚΡΕΑΣ: ΚΡΕ
18
+ ΚΡΕΑΤΟΣ: ΚΡΕ
19
+ ΚΡΕΑΤΑ: ΚΡΕ
20
+ ΚΡΕΑΤΩΝ: ΚΡΕ
21
+ ΠΕΡΑΣ: ΠΕΡ
22
+ ΠΕΡΑΤΟΣ: ΠΕΡ
23
+ ΠΕΡΑΤΑ: ΠΕΡ
24
+ ΠΕΡΑΤΩΝ: ΠΕΡ
25
+ ΤΕΡΑΣ: ΤΕΡ
26
+ ΤΕΡΑΤΟΣ: ΤΕΡ
27
+ ΤΕΡΑΤΑ: ΤΕΡ
28
+ ΤΕΡΑΤΩΝ: ΤΕΡ
29
+ ΦΩΣ: ΦΩ
30
+ ΦΩΤΟΣ: ΦΩ
31
+ ΦΩΤΑ: ΦΩ
32
+ ΦΩΤΩΝ: ΦΩ
33
+ ΚΑΘΕΣΤΩΣ: ΚΑΘΕΣΤ
34
+ ΚΑΘΕΣΤΩΤΟΣ: ΚΑΘΕΣΤ
35
+ ΚΑΘΕΣΤΩΤΑ: ΚΑΘΕΣΤ
36
+ ΚΑΘΕΣΤΩΤΩΝ: ΚΑΘΕΣΤ
37
+ ΓΕΓΟΝΟΣ: ΓΕΓΟΝ
38
+ ΓΕΓΟΝΟΤΟΣ: ΓΕΓΟΝ
39
+ ΓΕΓΟΝΟΤΑ: ΓΕΓΟΝ
40
+ ΓΕΓΟΝΟΤΩΝ: ΓΕΓΟΝ
41
+
42
+ protected_words:
43
+ - ΑΚΡΙΒΩΣ
44
+ - ΑΛΑ
45
+ - ΑΛΛΑ
46
+ - ΑΛΛΙΩΣ
47
+ - ΑΛΛΟΤΕ
48
+ - ΑΜΑ
49
+ - ΑΝΩ
50
+ - ΑΝΑ
51
+ - ΑΝΑΜΕΣΑ
52
+ - ΑΝΑΜΕΤΑΞΥ
53
+ - ΑΝΕΥ
54
+ - ΑΝΤΙ
55
+ - ΑΝΤΙΠΕΡΑ
56
+ - ΑΝΤΙΟ
57
+ - ΑΞΑΦΝΑ
58
+ - ΑΠΟ
59
+ - ΑΠΟΨΕ
60
+ - ΑΡΑ
61
+ - ΑΡΑΓΕ
62
+ - ΑΥΡΙΟ
63
+ - ΑΦΟΙ
64
+ - ΑΦΟΥ
65
+ - ΑΦΟΤΟΥ
66
+ - ΒΡΕ
67
+ - ΓΕΙΑ
68
+ - ΓΙΑ
69
+ - ΓΙΑΤΙ
70
+ - ΓΡΑΜΜΑ
71
+ - ΔΕΗ
72
+ - ΔΕΝ
73
+ - ΔΗΛΑΔΗ
74
+ - ΔΙΧΩΣ
75
+ - ΔΥΟ
76
+ - ΕΑΝ
77
+ - ΕΓΩ
78
+ - ΕΔΩ
79
+ - ΕΔΑ
80
+ - ΕΙΘΕ
81
+ - ΕΙΜΑΙ
82
+ - ΕΙΜΑΣΤΕ
83
+ - ΕΙΣΑΙ
84
+ - ΕΙΣΑΣΤΕ
85
+ - ΕΙΝΑΙ
86
+ - ΕΙΣΤΕ
87
+ - ΕΙΤΕ
88
+ - ΕΚΕΙ
89
+ - ΕΚΟ
90
+ - ΕΛΑ
91
+ - ΕΜΑΣ
92
+ - ΕΜΕΙΣ
93
+ - ΕΝΤΕΛΩΣ
94
+ - ΕΝΤΟΣ
95
+ - ΕΝΤΩΜΕΤΑΞΥ
96
+ - ΕΝΩ
97
+ - ΕΞΙ
98
+ - ΕΞΙΣΟΥ
99
+ - ΕΞΗΣ
100
+ - ΕΞΩ
101
+ - ΕΟΚ
102
+ - ΕΠΑΝΩ
103
+ - ΕΠΕΙΔΗ
104
+ - ΕΠΕΙΤΑ
105
+ - ΕΠΙ
106
+ - ΕΠΙΣΗΣ
107
+ - ΕΠΟΜΕΝΩΣ
108
+ - ΕΠΤΑ
109
+ - ΕΣΑΣ
110
+ - ΕΣΕΙΣ
111
+ - ΕΣΤΩ
112
+ - ΕΣΥ
113
+ - ΕΣΩ
114
+ - ΕΤΣΙ
115
+ - ΕΥΓΕ
116
+ - ΕΦΕ
117
+ - ΕΦΕΞΗΣ
118
+ - ΕΧΤΕΣ
119
+ - ΕΩΣ
120
+ - ΗΔΗ
121
+ - ΗΜΙ
122
+ - ΗΠΑ
123
+ - ΗΤΟΙ
124
+ - ΘΕΣ
125
+ - ΙΔΙΩΣ
126
+ - ΙΔΗ
127
+ - ΙΚΑ
128
+ - ΙΣΩΣ
129
+ - ΚΑΘΕ
130
+ - ΚΑΘΕΤΙ
131
+ - ΚΑΘΟΛΟΥ
132
+ - ΚΑΘΩΣ
133
+ - ΚΑΙ
134
+ - ΚΑΝ
135
+ - ΚΑΠΟΤΕ
136
+ - ΚΑΠΟΥ
137
+ - ΚΑΤΑ
138
+ - ΚΑΤΙ
139
+ - ΚΑΤΟΠΙΝ
140
+ - ΚΑΤΩ
141
+ - ΚΕΙ
142
+ - ΚΙΧ
143
+ - ΚΚΕ
144
+ - ΚΟΛΑΝ
145
+ - ΚΥΡΙΩΣ
146
+ - ΚΩΣ
147
+ - ΜΑΚΑΡΙ
148
+ - ΜΑΛΙΣΤΑ
149
+ - ΜΑΛΛΟΝ
150
+ - ΜΑΙ
151
+ - ΜΑΟ
152
+ - ΜΑΟΥΣ
153
+ - ΜΑΣ
154
+ - ΜΕΘΑΥΡΙΟ
155
+ - ΜΕΣ
156
+ - ΜΕΣΑ
157
+ - ΜΕΤΑ
158
+ - ΜΕΤΑΞΥ
159
+ - ΜΕΧΡΙ
160
+ - ΜΗΔΕ
161
+ - ΜΗΝ
162
+ - ΜΗΠΩΣ
163
+ - ΜΗΤΕ
164
+ - ΜΙΑ
165
+ - ΜΙΑΣ
166
+ - ΜΙΣ
167
+ - ΜΜΕ
168
+ - ΜΟΛΟΝΟΤΙ
169
+ - ΜΟΥ
170
+ - ΜΠΑ
171
+ - ΜΠΑΣ
172
+ - ΜΠΟΥΦΑΝ
173
+ - ΜΠΡΟΣ
174
+ - ΝΑΙ
175
+ - ΝΕΣ
176
+ - ΝΤΑ
177
+ - ΝΤΕ
178
+ - ΞΑΝΑ
179
+ - ΟΗΕ
180
+ - ΟΚΤΩ
181
+ - ΟΜΩΣ
182
+ - ΟΝΕ
183
+ - ΟΠΑ
184
+ - ΟΠΟΥ
185
+ - ΟΠΩΣ
186
+ - ΟΣΟ
187
+ - ΟΤΑΝ
188
+ - ΟΤΕ
189
+ - ΟΤΙ
190
+ - ΟΥΤΕ
191
+ - ΟΧΙ
192
+ - ΠΑΛΙ
193
+ - ΠΑΝ
194
+ - ΠΑΝΟ
195
+ - ΠΑΝΤΟΤΕ
196
+ - ΠΑΝΤΟΥ
197
+ - ΠΑΝΤΩΣ
198
+ - ΠΑΝΩ
199
+ - ΠΑΡΑ
200
+ - ΠΕΡΑ
201
+ - ΠΕΡΙ
202
+ - ΠΕΡΙΠΟΥ
203
+ - ΠΙΑ
204
+ - ΠΙΟ
205
+ - ΠΙΣΩ
206
+ - ΠΛΑΙ
207
+ - ΠΛΕΟΝ
208
+ - ΠΛΗΝ
209
+ - ΠΟΤΕ
210
+ - ΠΟΥ
211
+ - ΠΡΟ
212
+ - ΠΡΟΣ
213
+ - ΠΡΟΧΤΕΣ
214
+ - ΠΡΟΧΘΕΣ
215
+ - ΡΟΔΙ
216
+ - ΠΩΣ
217
+ - ΣΑΙ
218
+ - ΣΑΣ
219
+ - ΣΑΝ
220
+ - ΣΕΙΣ
221
+ - ΣΙΑ
222
+ - ΣΚΙ
223
+ - ΣΟΙ
224
+ - ΣΟΥ
225
+ - ΣΡΙ
226
+ - ΣΥΝ
227
+ - ΣΥΝΑΜΑ
228
+ - ΣΧΕΔΟΝ
229
+ - ΤΑΔΕ
230
+ - ΤΑΞΙ
231
+ - ΤΑΧΑ
232
+ - ΤΕΙ
233
+ - ΤΗΝ
234
+ - ΤΗΣ
235
+ - ΤΙΠΟΤΑ
236
+ - ΤΙΠΟΤΕ
237
+ - ΤΙΣ
238
+ - ΤΟΝ
239
+ - ΤΟΤΕ
240
+ - ΤΟΥ
241
+ - ΤΟΥΣ
242
+ - ΤΣΑ
243
+ - ΤΣΕ
244
+ - ΤΣΙ
245
+ - ΤΣΟΥ
246
+ - ΤΩΝ
247
+ - ΥΠΟ
248
+ - ΥΠΟΨΗ
249
+ - ΥΠΟΨΙΝ
250
+ - ΥΣΤΕΡΑ
251
+ - ΦΕΤΟΣ
252
+ - ΦΙΣ
253
+ - ΦΠΑ
254
+ - ΧΑΦ
255
+ - ΧΘΕΣ
256
+ - ΧΤΕΣ
257
+ - ΧΩΡΙΣ
258
+ - ΩΣ
259
+ - ΩΣΑΝ
260
+ - ΩΣΟΤΟΥ
261
+ - ΩΣΠΟΥ
262
+ - ΩΣΤΕ
263
+ - ΩΣΤΟΣΟ
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'greek_stemmer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "greek_stemmer"
8
+ spec.version = GreekStemmer::VERSION
9
+ spec.authors = ["Tasos Stathopoulos", "Giorgos Tsiftsis"]
10
+ spec.email = ["stathopa@skroutz.gr", "giorgos.tsiftsis@skroutz.gr"]
11
+ spec.summary = %q{A simple Greek stemmer}
12
+ spec.description = %q{A simple Greek stemmer}
13
+ spec.homepage = "https://github.com/skroutz/greek_stemmer"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ # spec.files.reject! { Dir['benchmarks'] }
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+
26
+ if RUBY_VERSION >= "2.0.0"
27
+ spec.add_development_dependency "pry-byebug"
28
+ else
29
+ spec.add_development_dependency "pry"
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module GreekStemmer
2
+ VERSION = "1.0.4"
3
+ end
@@ -0,0 +1,276 @@
1
+ # coding: utf-8
2
+ require "greek_stemmer/version"
3
+ require "yaml"
4
+
5
+ # Please note that we use only upcase letters for all methods. One should
6
+ # normalize input streams before using the `stem` method. Normalization means
7
+ # detone and upcase.
8
+ module GreekStemmer
9
+ extend self
10
+
11
+ # Helper method for loading settings
12
+ #
13
+ # @param key [String] the key
14
+ def load_settings(key)
15
+ config_path = File.expand_path("../../config/stemmer.yml", __FILE__)
16
+
17
+ begin
18
+ YAML.load_file(config_path)[key]
19
+ rescue => e
20
+ raise "Please provide a valid config/stemmer.yml file, #{e}"
21
+ end
22
+ end
23
+
24
+ # Transformations for step 1 words
25
+ STEP_1_EXCEPTIONS = load_settings("step_1_exceptions")
26
+
27
+ # Protected words
28
+ PROTECTED_WORDS = load_settings("protected_words")
29
+
30
+ # Regular expression that checks if the word contains only Greek characters
31
+ ALPHABET = Regexp.new("^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]+$").freeze
32
+
33
+ # Stems Greek words
34
+ #
35
+ # @param word [String] the word to be stemmed
36
+ # @return [String] the stemmed word
37
+ def stem(word)
38
+ return word if word.length < 3
39
+ stem = word.dup
40
+ return stem if PROTECTED_WORDS.include?(stem) || !greek?(word)
41
+
42
+ step_1_regexp = /(.*)(#{STEP_1_EXCEPTIONS.keys.join("|")})$/u
43
+
44
+ # step 1
45
+ stem.scan(step_1_regexp) do |st, suffix|
46
+ stem = st + STEP_1_EXCEPTIONS[suffix]
47
+ end
48
+
49
+ # step 2a
50
+ stem.scan(/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/u) do |st, suffix|
51
+ stem = st
52
+ stem << "ΑΔ" unless st =~ /(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|
53
+ ΠΕΘΕΡ|ΜΟΥΣΑΜ|ΚΑΠΛΑΜ|ΠΑΡ|ΨΑΡ|ΤΖΟΥΡ|ΤΑΜΠΟΥΡ)$/ux
54
+ end
55
+
56
+ # step 2b
57
+ stem.scan(/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/u) do |st, suffix|
58
+ stem = st
59
+ stem << "ΕΔ" if st =~ /(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/u
60
+ end
61
+
62
+ # step 2c
63
+ stem.scan(/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/u) do |st, suffix|
64
+ stem = st
65
+ stem << "ΟΥΔ" if st =~ /(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|
66
+ ΣΠ|ΤΡΑΓ|ΦΕ)$/ux
67
+ end
68
+
69
+ # step 2d
70
+ stem.scan(/^(.+?)(ΕΩΣ|ΕΩΝ|ΕΑΣ|ΕΑ)$/u) do |st, suffix|
71
+ stem = st
72
+ stem << "Ε" if st =~ /^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ|ΣΤΕΡ|ΟΡΦ|ΑΝΔΡ|ΑΝΤΡ)$/u
73
+ end
74
+
75
+ # step 3
76
+ stem.scan(/^(.+?)(ΙΟΥΣ|ΙΑΣ|ΙΕΣ|ΙΟΣ|ΙΟΥ|ΙΟΙ|ΙΩΝ|ΙΟΝ|ΙΑ|ΙΟ)$/u) do |st, suffix|
77
+ stem = st
78
+ stem << "Ι" if ends_on_vowel?(st) || st.length < 2 || st=~ /^(ΑΓ|ΑΓΓΕΛ|ΑΓΡ|
79
+ ΑΕΡ|ΑΘΛ|ΑΚΟΥΣ|ΑΞ|ΑΣ|Β|ΒΙΒΛ|ΒΥΤ|Γ|ΓΙΑΓ|ΓΩΝ|Δ|ΔΑΝ|ΔΗΛ|ΔΗΜ|
80
+ ΔΟΚΙΜ|ΕΛ|ΖΑΧΑΡ|ΗΛ|ΗΠ|ΙΔ|ΙΣΚ|ΙΣΤ|ΙΟΝ|ΙΩΝ|ΚΙΜΩΛ|ΚΟΛΟΝ|ΚΟΡ|
81
+ ΚΤΗΡ|ΚΥΡ|ΛΑΓ|ΛΟΓ|ΜΑΓ|ΜΠΑΝ|ΜΠΡ|ΝΑΥΤ|ΝΟΤ|ΟΠΑΛ|ΟΞ|ΟΡ|ΟΣ|ΠΑΝΑΓ|
82
+ ΠΑΤΡ|ΠΗΛ|ΠΗΝ|ΠΛΑΙΣ|ΠΟΝΤ|ΡΑΔ|ΡΟΔ|ΣΚ|ΣΚΟΡΠ|ΣΟΥΝ|ΣΠΑΝ|ΣΤΑΔ|
83
+ ΣΥΡ|ΤΗΛ|ΤΙΜ|ΤΟΚ|ΤΟΠ|ΤΡΟΧ|ΦΙΛ|ΦΩΤ|Χ|ΧΙΛ|ΧΡΩΜ|ΧΩΡ)$/ux
84
+ stem << "ΑΙ" if st =~ /^(ΠΑΛ)$/u
85
+ end
86
+
87
+ # step 4
88
+ stem.scan(/^(.+?)(ΙΚΟΣ|ΙΚΟΝ|ΙΚΕΙΣ|ΙΚΟΙ|ΙΚΕΣ|ΙΚΟΥΣ|ΙΚΗ|ΙΚΗΣ|ΙΚΟ|ΙΚΑ|ΙΚΟΥ|ΙΚΩΝ|ΙΚΩΣ)$/u) do |st, suffix|
89
+ stem = st
90
+ stem << "ΙΚ" if ends_on_vowel?(st) || st =~ /^(ΑΔ|ΑΛ|ΑΜΑΝ|ΑΜΕΡ|ΑΜΜΟΧΑΛ|
91
+ ΑΝΗΘ|ΑΝΤΙΔ|ΑΠΛ|ΑΤΤ|ΑΦΡ|ΒΑΣ|ΒΡΩΜ|ΓΕΝ|ΓΕΡ|Δ|ΔΥΤ|ΕΙΔ|ΕΝΔ|
92
+ ΕΞΩΔ|ΗΘ|ΘΕΤ|ΚΑΛΛΙΝ|ΚΑΛΠ|ΚΑΤΑΔ|ΚΡ|ΚΩΔ|ΛΟΓ|Μ|ΜΕΡ|ΜΟΝΑΔ|ΜΟΥΛ|
93
+ ΜΟΥΣ|ΜΠΑΓΙΑΤ|ΜΠΑΝ|ΜΠΟΛ|ΜΠΟΣ|ΜΥΣΤ|Ν|ΝΙΤ|ΞΙΚ|ΟΠΤ|ΠΑΝ|ΠΕΤΣ|
94
+ ΠΙΚΑΝΤ|ΠΙΤΣ|ΠΛΑΣΤ|ΠΛΙΑΤΣ|ΠΟΝΤ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΗΜΑΝΤ|
95
+ ΣΤΑΤ|ΣΥΝΑΔ|ΣΥΝΟΜΗΛ|ΤΕΛ|ΤΕΧΝ|ΤΡΟΠ|ΤΣΑΜ|ΥΠΟΔ|Φ|ΦΙΛΟΝ|ΦΥΛΟΔ|
96
+ ΦΥΣ|ΧΑΣ)$/ux || st =~ /(ΦΟΙΝ)$/u
97
+ end
98
+
99
+ # step 5a
100
+ stem = "ΑΓΑΜ" if word == 'ΑΓΑΜΕ'
101
+
102
+ stem.scan(/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/u) do |st, suffix|
103
+ stem = st
104
+ end
105
+
106
+ stem.scan(/^(.+?)(ΑΜΕ)$/u) do |st, suffix|
107
+ stem = st
108
+ stem << "ΑΜ" if st =~ /^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|
109
+ ΣΙΧ|Χ)$/ux
110
+ end
111
+
112
+ # step 5b
113
+ stem.scan(/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|
114
+ ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/ux) do |st, suffix|
115
+ stem = st
116
+ stem << "ΑΓΑΝ" if st =~ /^(ΤΡ|ΤΣ)$/u
117
+ end
118
+
119
+ stem.scan(/^(.+?)(ΑΝΕ)$/u) do |st, suffix|
120
+ stem = st
121
+ stem << "ΑΝ" if st =~ /^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|
122
+ ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜ|Ν|ΟΥΛ|Π|ΠΕΛΕΚ|
123
+ ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|
124
+ ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|
125
+ ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|
126
+ ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|
127
+ ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|
128
+ ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|
129
+ ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|
130
+ ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|
131
+ ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|
132
+ ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/ux || ends_on_vowel2?(st)
133
+ end
134
+
135
+ # step 5c
136
+ stem.scan(/^(.+?)(ΗΣΕΤΕ)$/u) do |st, suffix|
137
+ stem = st
138
+ end
139
+
140
+ stem.scan(/^(.+?)(ΕΤΕ)$/u) do |st, suffix|
141
+ stem = st
142
+ stem << "ΕΤ" if ends_on_vowel2?(st) || st =~ /(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|
143
+ ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|
144
+ ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/ux ||
145
+ st =~ /^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|
146
+ ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/ux
147
+ end
148
+
149
+ # step 5d
150
+ stem.scan(/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/u) do |st, suffix|
151
+ stem = st
152
+ stem << "ΟΝΤ" if st =~ /^ΑΡΧ$/u
153
+ stem << "ΩΝΤ" if st =~ /ΚΡΕ$/u
154
+ end
155
+
156
+ # step 5e
157
+ stem.scan(/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/u) do |st, suffix|
158
+ stem = st
159
+ stem << "ΟΜΑΣΤ" if st =~ /^ΟΝ$/u
160
+ end
161
+
162
+ # step 5f
163
+ stem.scan(/^(.+?)(ΙΕΣΤΕ)$/u) do |st, suffix|
164
+ stem = st
165
+ stem << "ΙΕΣΤ" if st =~ /^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/u
166
+ end
167
+
168
+ stem.scan(/^(.+?)(ΕΣΤΕ)$/u) do |st, suffix|
169
+ stem = st
170
+ stem << "ΕΣΤ" if st =~ /^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΑΡ|ΠΡΟ|ΝΙΣ)$/u
171
+ end
172
+
173
+ # step 5g
174
+ stem.scan(/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/u) do |st, suffix|
175
+ stem = st
176
+ end
177
+
178
+ stem.scan(/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/u) do |st, suffix|
179
+ stem = st
180
+ stem << "ΗΚ" if st =~ /(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/u || st =~ /^(ΔΙΑΘ|Θ|
181
+ ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ|)$/ux
182
+ end
183
+
184
+ # step 5h
185
+ stem.scan(/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/u) do |st, suffix|
186
+ stem = st
187
+ stem << "ΟΥΣ" if st =~ /^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|
188
+ ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ|ΔΕ|ΔΕΥΤΕΡΕΥ|
189
+ ΚΑΘΑΡΕΥ|ΠΛΕ|ΤΣΑ)$/ux || st =~ /(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|
190
+ ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/ux || ends_on_vowel?(st)
191
+ end
192
+
193
+ # step 5i
194
+ stem.scan(/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/u) do |st, suffix|
195
+ stem = st
196
+ stem << "ΑΓ" if (st =~ /^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|
197
+ ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|
198
+ ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|
199
+ ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/ux || st =~ /(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|
200
+ ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/ux) && !(st =~ /^(ΨΟΦ|ΝΑΥΛΟΧ)$/u || st =~ /(ΚΟΛΛ)$/u)
201
+ end
202
+
203
+ # step 5j
204
+ stem.scan(/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/u) do |st, suffix|
205
+ stem = st
206
+ stem << "ΗΣ" if st =~ /^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ|Ι)$/u
207
+ end
208
+
209
+ # step 5k
210
+ stem.scan(/^(.+?)(ΗΣΤΕ)$/u) do |st, suffix|
211
+ stem = st
212
+ stem << "ΗΣΤ" if st =~ /^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|
213
+ ΠΑΛΙΜΨ)$/ux
214
+ end
215
+
216
+ # step 5l
217
+ stem.scan(/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/u) do |st, suffix|
218
+ stem = st
219
+ stem << "ΟΥΝ" if st =~ /^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/u
220
+ end
221
+
222
+ # step 5m
223
+ stem.scan(/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/u) do |st, suffix|
224
+ stem = st
225
+ stem << "ΟΥΜ" if st =~ /^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/u
226
+ end
227
+
228
+ # step 6a
229
+ stem.scan(/^(.+?)(ΜΑΤΟΙ|ΜΑΤΟΥΣ|ΜΑΤΟ|ΜΑΤΑ|ΜΑΤΩΣ|ΜΑΤΩΝ|ΜΑΤΟΣ|ΜΑΤΕΣ|ΜΑΤΗ|
230
+ ΜΑΤΗΣ|ΜΑΤΟΥ)$/ux) do |st, suffix|
231
+ stem = st + "Μ"
232
+ if st =~ /^(ΓΡΑΜ)$/u
233
+ stem << "Α"
234
+ elsif st =~ /^(ΓΕ|ΣΤΑ)$/u
235
+ stem << "ΑΤ"
236
+ end
237
+ end
238
+
239
+ stem = long_stem_list(stem) if stem.length == word.length
240
+
241
+ stem.scan(/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/u) do |st, suffix|
242
+ stem = st unless st =~ /^(ΕΞ|ΕΣ|ΑΝ|ΚΑΤ|Κ|ΠΡ)$/u
243
+
244
+ stem = st + "ΥΤ" if st =~ /^(ΚΑ|Μ|ΕΛΕ|ΛΕ|ΔΕ)$/u
245
+ end
246
+
247
+ stem
248
+ end
249
+
250
+ private
251
+
252
+ def ends_on_vowel?(word)
253
+ word =~ /[ΑΕΗΙΟΥΩ]$/u
254
+ end
255
+
256
+ def ends_on_vowel2?(word)
257
+ word =~ /[ΑΕΗΙΟΩ]$/u
258
+ end
259
+
260
+ def long_stem_list(word)
261
+ word.scan(/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|
262
+ ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|
263
+ ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|
264
+ ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|
265
+ ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|
266
+ ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|
267
+ ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ|ΥΣ|Ω|ΩΝ|ΟΙΣ)$/ux) do |st, suffix|
268
+ word = st
269
+ end
270
+ word
271
+ end
272
+
273
+ def greek?(word)
274
+ !! word.match(ALPHABET)
275
+ end
276
+ end
@@ -0,0 +1,115 @@
1
+ # step 1
2
+ ΚΡΕΑΣ: ΚΡΕ
3
+ ΠΑΝΓΚΡΕΑΣ: ΠΑΝΓΚΡΕ
4
+ ΗΜΙΦΩΣ: ΗΜΙΦΩ
5
+ ΚΟΜΠΟΛΟΓΙΑ: ΚΟΜΠΟΛΟΓ
6
+ ΠΑΤΕΡΑΣ: ΠΑΤΕΡ
7
+
8
+ # step 2a
9
+ ΓΙΑΓΙΑΔΩΝ: ΓΙΑΓΙ
10
+ ΟΜΑΔΕΣ: ΟΜΑΔ
11
+
12
+ # step 2b
13
+ ΚΑΦΕΔΩΝ: ΚΑΦ
14
+ ΓΗΠΕΔΩΝ: ΓΗΠΕΔ
15
+
16
+ # step 2c
17
+ ΠΑΠΠΟΥΔΩΝ: ΠΑΠΠ
18
+ ΑΡΚΟΥΔΕΣ: ΑΡΚΟΥΔ
19
+
20
+ # step 2d
21
+ ΥΠΟΘΕΣΕΩΣ: ΥΠΟΘΕΣ
22
+ ΥΠΟΘΕΣΕΩΝ: ΥΠΟΘΕΣ
23
+ ΘΕΩΝ: ΘΕ
24
+
25
+ # step 3
26
+ ΠΑΙΔΙΑ: ΠΑΙΔ
27
+ ΤΕΛΕΙΟΥ: ΤΕΛΕΙ
28
+ ΤΕΛΕΙΩΝ: ΤΕΛΕΙ
29
+
30
+ # step 4
31
+ ΖΗΛΙΑΡΙΚΟ: ΖΗΛΙΑΡ
32
+ ΑΓΡΟΙΚΟΥ: ΑΓΡΟΙΚ
33
+
34
+ # step 5
35
+ ΑΓΑΠΑΜΕ: ΑΓΑΠ
36
+ ΑΓΑΠΗΣΑΜΕ: ΑΓΑΠ
37
+ ΑΝΑΠΑΜΕ: ΑΝΑΠΑΜ
38
+
39
+ # step 5b
40
+ ΑΓΑΠΗΣΑΝΕ: ΑΓΑΠ
41
+ ΤΡΑΓΑΝΕ: ΤΡΑΓΑΝ
42
+ ΒΡΑΧΜΑΝΕ: ΒΡΑΧΜΑΝ
43
+ ΣΑΡΑΚΑΤΣΑΝΕ: ΣΑΡΑΚΑΤΣΑΝ
44
+
45
+ # step 5c
46
+ ΑΓΑΠΗΣΕΤΕ: ΑΓΑΠ
47
+ ΒΕΝΕΤΕ: ΒΕΝΕΤ
48
+
49
+ # step 5d
50
+ ΑΓΑΠΩΝΤΑΣ: ΑΓΑΠ
51
+ ΑΡΧΟΝΤΑΣ: ΑΡΧΟΝΤ
52
+ ΚΡΕΩΝΤΑΣ: ΚΡΕΩΝΤ
53
+
54
+ # step 5e
55
+ ΑΓΑΠΙΟΜΑΣΤΕ: ΑΓΑΠ
56
+ ΟΝΟΜΑΣΤΕ: ΟΝΟΜΑΣΤ
57
+
58
+ # step 5f
59
+ ΑΓΑΠΙΕΣΤΕ: ΑΓΑΠ
60
+ ΠΙΕΣΤΕ: ΠΙΕΣΤ
61
+ ΕΚΤΕΛΕΣΤΕ: ΕΚΤΕΛΕΣΤ
62
+
63
+ # step 5g
64
+ ΧΤΙΣΤΗΚΕ: ΧΤΙΣΤ
65
+ ΔΙΑΘΗΚΗ: ΔΙΑΘΗΚ
66
+ ΔΙΑΘΗΚΕΣ: ΔΙΑΘΗΚ
67
+ ΚΑΤΑΚΤΗΘΗΚΕ: ΚΑΤΑΚΤ
68
+ ΠΟΛΕΜΗΘΗΚΕ: ΠΟΛΕΜ
69
+
70
+ # step 5h
71
+ ΧΤΥΠΩ: ΧΤΥΠ
72
+ ΧΤΥΠΟΥΣΕΣ: ΧΤΥΠ
73
+ ΜΕΔΟΥΣΑ: ΜΕΔΟΥΣ
74
+ ΜΕΔΟΥΣΕΣ: ΜΕΔΟΥΣ
75
+
76
+ # step 5i
77
+ ΚΟΛΛΑΩ: ΚΟΛΛ
78
+ ΚΟΛΛΑΓΕΣ: ΚΟΛΛ
79
+ ΑΒΑΣΤΑΓΟ: ΑΒΑΣΤΑΓ
80
+ ΑΒΑΣΤΑΓΑ: ΑΒΑΣΤΑΓ
81
+
82
+ # step 5j
83
+ ΑΓΑΠΩ: ΑΓΑΠ
84
+ ΑΓΑΠΗΣΕ: ΑΓΑΠ
85
+ ΝΗΣΟΣ: ΝΗΣ
86
+ ΝΗΣΟΥ: ΝΗΣ
87
+
88
+ # step 5k
89
+ ΑΓΑΠΩ: ΑΓΑΠ
90
+ ΑΓΑΠΗΣΤΕ: ΑΓΑΠ
91
+ ΣΒΗΣΤΟΣ: ΣΒΗΣΤ
92
+ ΣΒΗΣΤΕ: ΣΒΗΣΤ
93
+
94
+ # step 5l
95
+ ΑΓΑΠΩ: ΑΓΑΠ
96
+ ΑΓΑΠΟΥΝΕ: ΑΓΑΠ
97
+ ΝΟΥΝΟΣ: ΝΟΥΝ
98
+ ΝΟΥΝΕ: ΝΟΥΝ
99
+
100
+ # step 5m
101
+ ΑΓΑΠΩ: ΑΓΑΠ
102
+ ΑΓΑΠΟΥΜΕ: ΑΓΑΠ
103
+ ΦΟΥΜΟΣ: ΦΟΥΜ
104
+ ΦΟΥΜΕ: ΦΟΥΜ
105
+
106
+ # step 6a
107
+ ΚΥΜΑ: ΚΥΜ
108
+ ΚΥΜΑΤΑ: ΚΥΜ
109
+ ΧΩΡΑΤΟ: ΧΩΡΑΤ
110
+ ΧΩΡΑΤΑ: ΧΩΡΑΤ
111
+
112
+ # step 7
113
+ ΠΛΗΣΙΕΣΤΑΤΟΣ: ΠΛΗΣΙ
114
+ ΜΕΓΑΛΥΤΕΡΗ: ΜΕΓΑΛ
115
+ ΚΟΝΤΟΤΕΡΟ: ΚΟΝΤ
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+ require "yaml"
4
+
5
+ describe GreekStemmer do
6
+ describe "#stem" do
7
+ let(:words) { YAML.load_file('spec/fixtures/examples.yml') }
8
+ it "stems words correctly" do
9
+ words.each_pair do |word, stem|
10
+ expect(described_class.stem(word)).to eq(stem)
11
+ end
12
+ end
13
+
14
+ context "when a non-greek word is used" do
15
+ it "does not stem it" do
16
+ expect(described_class.stem("englishΟΣ")).to eq("englishΟΣ")
17
+ end
18
+ end
19
+ end
20
+ end