llt-form_builder 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +8 -0
- data/lib/llt/form/adjective.rb +19 -0
- data/lib/llt/form/adverb.rb +13 -0
- data/lib/llt/form/cardinal.rb +31 -0
- data/lib/llt/form/conjunction.rb +7 -0
- data/lib/llt/form/declinable.rb +23 -0
- data/lib/llt/form/demonstrative_pronoun.rb +7 -0
- data/lib/llt/form/ethnic.rb +6 -0
- data/lib/llt/form/fp.rb +6 -0
- data/lib/llt/form/gerund.rb +9 -0
- data/lib/llt/form/gerundive.rb +12 -0
- data/lib/llt/form/indefinite_pronoun.rb +7 -0
- data/lib/llt/form/infinitive.rb +13 -0
- data/lib/llt/form/interrogative_pronoun.rb +7 -0
- data/lib/llt/form/noun.rb +17 -0
- data/lib/llt/form/participle.rb +9 -0
- data/lib/llt/form/personal_pronoun.rb +13 -0
- data/lib/llt/form/ppa.rb +6 -0
- data/lib/llt/form/ppp.rb +6 -0
- data/lib/llt/form/preposition.rb +32 -0
- data/lib/llt/form/pronoun.rb +17 -0
- data/lib/llt/form/relative_pronoun.rb +7 -0
- data/lib/llt/form/subjunction.rb +7 -0
- data/lib/llt/form/supinum.rb +6 -0
- data/lib/llt/form/uninflectable.rb +22 -0
- data/lib/llt/form/verb.rb +28 -0
- data/lib/llt/form/verbal_noun.rb +18 -0
- data/lib/llt/form.rb +80 -0
- data/lib/llt/form_builder/adjective_builder.rb +86 -0
- data/lib/llt/form_builder/adverb_builder.rb +25 -0
- data/lib/llt/form_builder/declinable_builder.rb +164 -0
- data/lib/llt/form_builder/ethnic_builder.rb +17 -0
- data/lib/llt/form_builder/fp_builder.rb +13 -0
- data/lib/llt/form_builder/gerund_builder.rb +37 -0
- data/lib/llt/form_builder/gerundive_builder.rb +24 -0
- data/lib/llt/form_builder/helpers/adjective_like_building.rb +29 -0
- data/lib/llt/form_builder/helpers/pronoun_segments.rb +226 -0
- data/lib/llt/form_builder/helpers/stem_hash_parser.rb +263 -0
- data/lib/llt/form_builder/helpers/verb_segments.rb +562 -0
- data/lib/llt/form_builder/infinitivum_builder.rb +19 -0
- data/lib/llt/form_builder/irregular_gerund_builder.rb +7 -0
- data/lib/llt/form_builder/irregular_gerundive_builder.rb +7 -0
- data/lib/llt/form_builder/irregular_ppa_builder.rb +7 -0
- data/lib/llt/form_builder/irregular_praesens_builder.rb +5 -0
- data/lib/llt/form_builder/irregular_praesens_infinitivum_builder.rb +5 -0
- data/lib/llt/form_builder/noun_builder.rb +24 -0
- data/lib/llt/form_builder/perfectum_builder.rb +14 -0
- data/lib/llt/form_builder/perfectum_infinitivum_builder.rb +7 -0
- data/lib/llt/form_builder/personal_pronoun_builder.rb +107 -0
- data/lib/llt/form_builder/ppa_builder.rb +20 -0
- data/lib/llt/form_builder/ppp_builder.rb +10 -0
- data/lib/llt/form_builder/praesens_builder.rb +41 -0
- data/lib/llt/form_builder/praesens_infinitivum_builder.rb +9 -0
- data/lib/llt/form_builder/pronoun_builder.rb +106 -0
- data/lib/llt/form_builder/supinum_builder.rb +23 -0
- data/lib/llt/form_builder/verb_builder.rb +37 -0
- data/lib/llt/form_builder/version.rb +5 -0
- data/lib/llt/form_builder.rb +370 -0
- data/lib/llt/stem/adjective_pack.rb +122 -0
- data/lib/llt/stem/adjective_stem.rb +23 -0
- data/lib/llt/stem/ethnic_stem.rb +9 -0
- data/lib/llt/stem/noun_pack.rb +14 -0
- data/lib/llt/stem/noun_stem.rb +26 -0
- data/lib/llt/stem/pack.rb +46 -0
- data/lib/llt/stem/verb_pack.rb +53 -0
- data/lib/llt/stem/verb_stem.rb +18 -0
- data/lib/llt/stem.rb +145 -0
- data/lib/llt/stem_builder.rb +53 -0
- data/llt-form_builder.gemspec +30 -0
- data/spec/lib/llt/form/adjective_spec.rb +10 -0
- data/spec/lib/llt/form/adverb_spec.rb +17 -0
- data/spec/lib/llt/form/conjunction_spec.rb +23 -0
- data/spec/lib/llt/form/demonstrative_pronoun_spec.rb +14 -0
- data/spec/lib/llt/form/fp_spec.rb +12 -0
- data/spec/lib/llt/form/functions_spec.rb +13 -0
- data/spec/lib/llt/form/gerund_spec.rb +10 -0
- data/spec/lib/llt/form/gerundive_spec.rb +13 -0
- data/spec/lib/llt/form/noun_spec.rb +18 -0
- data/spec/lib/llt/form/ppa_spec.rb +12 -0
- data/spec/lib/llt/form/ppp_spec.rb +12 -0
- data/spec/lib/llt/form/preposition_spec.rb +43 -0
- data/spec/lib/llt/form/supinum_spec.rb +9 -0
- data/spec/lib/llt/form/verb_spec.rb +14 -0
- data/spec/lib/llt/form_builder/adjective_builder_spec.rb +182 -0
- data/spec/lib/llt/form_builder/adverb_builder_spec.rb +27 -0
- data/spec/lib/llt/form_builder/ethnic_builder_spec.rb +17 -0
- data/spec/lib/llt/form_builder/form_builder_spec.rb +16 -0
- data/spec/lib/llt/form_builder/fp_builder_spec.rb +42 -0
- data/spec/lib/llt/form_builder/gerund_builder_spec.rb +80 -0
- data/spec/lib/llt/form_builder/gerundive_builder_spec.rb +102 -0
- data/spec/lib/llt/form_builder/helpers/stem_hash_parser_spec.rb +197 -0
- data/spec/lib/llt/form_builder/irregular_gerund_builder_spec.rb +22 -0
- data/spec/lib/llt/form_builder/irregular_gerundive_builder_spec.rb +21 -0
- data/spec/lib/llt/form_builder/irregular_praesens_builder_spec.rb +14 -0
- data/spec/lib/llt/form_builder/irregular_praesens_infinitivum_builder_spec.rb +32 -0
- data/spec/lib/llt/form_builder/noun_builder_spec.rb +245 -0
- data/spec/lib/llt/form_builder/personal_pronoun_builder_spec.rb +49 -0
- data/spec/lib/llt/form_builder/ppa_builder_spec.rb +137 -0
- data/spec/lib/llt/form_builder/ppp_builder_spec.rb +45 -0
- data/spec/lib/llt/form_builder/pronoun_builder_spec.rb +203 -0
- data/spec/lib/llt/form_builder/supinum_builder_spec.rb +24 -0
- data/spec/lib/llt/form_builder/verb_builder_spec.rb +557 -0
- data/spec/lib/llt/form_spec.rb +27 -0
- data/spec/lib/llt/stem/adjective_pack_spec.rb +78 -0
- data/spec/lib/llt/stem/adjective_stem_spec.rb +15 -0
- data/spec/lib/llt/stem/noun_pack_spec.rb +20 -0
- data/spec/lib/llt/stem/noun_stem_spec.rb +14 -0
- data/spec/lib/llt/stem/verb_pack_spec.rb +56 -0
- data/spec/lib/llt/stem_builder_spec.rb +20 -0
- data/spec/spec_helper.rb +21 -0
- metadata +330 -0
@@ -0,0 +1,370 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'llt/helpers'
|
4
|
+
require 'llt/constants'
|
5
|
+
require 'llt/core_extensions/array'
|
6
|
+
|
7
|
+
require 'llt/form'
|
8
|
+
require 'llt/form_builder/version'
|
9
|
+
require 'llt/form_builder/helpers/adjective_like_building'
|
10
|
+
require 'llt/form_builder/helpers/pronoun_segments'
|
11
|
+
require 'llt/form_builder/helpers/stem_hash_parser'
|
12
|
+
require 'llt/form_builder/helpers/verb_segments'
|
13
|
+
|
14
|
+
require 'llt/stem'
|
15
|
+
|
16
|
+
module LLT
|
17
|
+
class FormBuilder
|
18
|
+
|
19
|
+
include Helpers::Constantize
|
20
|
+
include Helpers::Initialize
|
21
|
+
include Helpers::Metrical
|
22
|
+
include Helpers::Normalizer
|
23
|
+
|
24
|
+
extend Helpers::Normalizer
|
25
|
+
extend Helpers::Constantize
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def build(*stem_hashes)
|
29
|
+
stem_hashes = StemHashParser.new(stem_hashes).parse
|
30
|
+
stem_hashes.flat_map do |stem|
|
31
|
+
builder_kl = constant_by_type(stem[:type], suffix: "builder")
|
32
|
+
builder_kl.new(stem).compute
|
33
|
+
end.compact # adverb might return nil forms
|
34
|
+
end
|
35
|
+
|
36
|
+
# Defines the class to use for obtaining additional build information
|
37
|
+
# like thematic vowels or stem extension (e.g. an Imperfectum -ba-).
|
38
|
+
# Defaults to VerbSegments, most commonly used.
|
39
|
+
#
|
40
|
+
# The argument should be a Class name.
|
41
|
+
def lookup_class(arg = nil)
|
42
|
+
arg ? @lookup_class = arg : @lookup_class ||= VerbSegments
|
43
|
+
end
|
44
|
+
|
45
|
+
# Holds a list of attributes, that will be validated.
|
46
|
+
def validations
|
47
|
+
@validations ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Defines the class of the outputted forms. Defaults to the
|
53
|
+
# stem type, # e.g. a :noun stem will build Noun objects.
|
54
|
+
#
|
55
|
+
# Takes a symbol as argument.
|
56
|
+
def form_class(arg)
|
57
|
+
define_method(:form_class) do
|
58
|
+
constant_by_type(arg, namespace: LLT::Form)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Defines which information is needed to obtain the proper set of
|
63
|
+
# endings for a stem. E.g. a noun uses its inflection_class and sexus.
|
64
|
+
def endings_defined_through(*args)
|
65
|
+
define_method(:endings_attributes) do
|
66
|
+
args.map { |arg| instance_variable_get("@#{arg}") }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Defines which endings shall be used, defaults to the stem's type,
|
71
|
+
# a noun stem uses noun endings.
|
72
|
+
# Used by irregular_ppa stems - they use the regular ppa endings.
|
73
|
+
def uses_endings_of(val)
|
74
|
+
define_method(:endings_container) { val }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Defines additional attributes that shall be passed
|
78
|
+
# to the newly built Form object. Cf. #default_args
|
79
|
+
def builds_with(*args)
|
80
|
+
anonymous = Module.new do
|
81
|
+
define_method(:default_args) do
|
82
|
+
# [:a, :b] to { a: a, b: b }, where a and b are method calls,
|
83
|
+
# evaluated in the instance's scope.
|
84
|
+
hsh = Hash[ args.map { |arg| [arg, send(arg)] } ]
|
85
|
+
|
86
|
+
# Mind the empty brackets, super throws an exception
|
87
|
+
# inside of define_method otherwise
|
88
|
+
super().merge(hsh)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
include anonymous
|
93
|
+
end
|
94
|
+
|
95
|
+
# Defines which attributes shall be looked up in the lookup_class.
|
96
|
+
# Such values are automatically included in the validation process.
|
97
|
+
def look_up(*vars)
|
98
|
+
vars.each do |arg|
|
99
|
+
anon = Module.new do
|
100
|
+
define_method(:extensions_and_other_signs) do |args|
|
101
|
+
kl = self.class.lookup_class
|
102
|
+
val = kl.get(arg, args.merge(default_args))
|
103
|
+
args[arg] = val unless val.empty?
|
104
|
+
super(args)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
include anon
|
109
|
+
end
|
110
|
+
|
111
|
+
validate(vars)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Defines arguments that need to be validated.
|
115
|
+
def validate(*args)
|
116
|
+
validations << args
|
117
|
+
validations.flatten!
|
118
|
+
end
|
119
|
+
|
120
|
+
# Responds to has_*** methods and takes one argument.
|
121
|
+
# Defines default values for certain attributes,
|
122
|
+
# e.g. a Gerund's stem always has_extension "nd".
|
123
|
+
def method_missing(meth, *args, &blk)
|
124
|
+
if meth.to_s.match(/^has_(.*)/)
|
125
|
+
define_method($1) { args.first }
|
126
|
+
else
|
127
|
+
super
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Syntactic sugar to include modules with special behavior.
|
132
|
+
def builds_like_an(arg)
|
133
|
+
include FormBuilder.const_get("#{arg.capitalize}LikeBuilding")
|
134
|
+
end
|
135
|
+
alias :builds_like_a :builds_like_an
|
136
|
+
end
|
137
|
+
|
138
|
+
files = %w{ declinable noun ppp adjective ethnic
|
139
|
+
pronoun personal_pronoun
|
140
|
+
verb praesens perfectum ppa fp gerund gerundive supinum
|
141
|
+
infinitivum praesens_infinitivum perfectum_infinitivum
|
142
|
+
irregular_praesens irregular_ppa
|
143
|
+
irregular_gerundive irregular_gerund
|
144
|
+
irregular_praesens_infinitivum
|
145
|
+
adverb }
|
146
|
+
files.each do |file|
|
147
|
+
require "llt/form_builder/#{file}_builder"
|
148
|
+
end
|
149
|
+
|
150
|
+
attr_reader :impersonalium
|
151
|
+
|
152
|
+
def initialize(stem)
|
153
|
+
extract_normalized_args!(stem)
|
154
|
+
|
155
|
+
# Used to evaluate if metrical endings and extensions shall be used
|
156
|
+
evaluate_metrical_presence(@stem) if @stem # pronouns come without their stem
|
157
|
+
|
158
|
+
@options = stem[:options] || {}
|
159
|
+
@validate = @options[:validate] if @options
|
160
|
+
@lookup_indices = lookup_indices
|
161
|
+
|
162
|
+
# Use only downcased stem string in the following events,
|
163
|
+
# only persons and places are allowed to be capitalized.
|
164
|
+
downcase_all_stems unless stays_capitalized
|
165
|
+
end
|
166
|
+
|
167
|
+
def init_keys
|
168
|
+
# normalized values need to be used here!
|
169
|
+
# call a normalize method on this array, which needs to be built
|
170
|
+
%i{ type stem inflection_class nom deponens sexus impersonalium persona place }
|
171
|
+
end
|
172
|
+
|
173
|
+
# The method called by FormBuilder.build to run the building process.
|
174
|
+
# Subclasses overwrite this for more complex computations.
|
175
|
+
def compute
|
176
|
+
regular_forms
|
177
|
+
end
|
178
|
+
|
179
|
+
# Computes a one-dimensional array of indices.
|
180
|
+
#
|
181
|
+
# LLT::Constants::Endings provides endings for all valid
|
182
|
+
# Latin forms. Their index defines additional attributes.
|
183
|
+
#
|
184
|
+
# Contrived Example:
|
185
|
+
# The row %w{ o s t mus tis nt } presents personal endings
|
186
|
+
# for verbs. Index 0 (o) maps to persona: 1, numerus: 1,
|
187
|
+
# index 3 (mus) maps to persona: 1, numerus: 2.
|
188
|
+
#
|
189
|
+
# All FormBuilder subclasses need to implement #indices, consisting
|
190
|
+
# of a hash that reveals the meaning of an index.
|
191
|
+
#
|
192
|
+
# An implementation for the personal endings presented above would be
|
193
|
+
# { persona: [0, 1, 2], numerus: [0, 3] }
|
194
|
+
#
|
195
|
+
# This tells us that there are 3 different values for persona - changing
|
196
|
+
# on every first, second and third position - and 2 values for numerus -
|
197
|
+
# changing on every fourth position in the endings array.
|
198
|
+
#
|
199
|
+
# Depending on the presence of options in the given stem_hash, only
|
200
|
+
# selected indices are returned.
|
201
|
+
def lookup_indices
|
202
|
+
if ending = @options[:ending]
|
203
|
+
indices_by_ending(ending)
|
204
|
+
else
|
205
|
+
arr = indices.map do |attr, index_values|
|
206
|
+
if opt_val = @options[attr]
|
207
|
+
index = value_as_index(opt_val)
|
208
|
+
[index_values[index - 1]].compact
|
209
|
+
else
|
210
|
+
index_values.compact
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
cross_indices(arr)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def indices_by_ending(ending)
|
219
|
+
endings.select_indices { |x| endings_lookup(ending, x) }
|
220
|
+
end
|
221
|
+
|
222
|
+
# Can be overwritten by subclasses if special rules are needed.
|
223
|
+
def endings_lookup(ending, x)
|
224
|
+
x.to_s == ending
|
225
|
+
end
|
226
|
+
|
227
|
+
# LLT::Constants::Terminology provides a numeric representation of
|
228
|
+
# every valid value, e.g. tempus: :praesens == tempus: 1
|
229
|
+
def value_as_index(val)
|
230
|
+
if val.kind_of?(Fixnum)
|
231
|
+
val
|
232
|
+
else
|
233
|
+
t.send(val, :numeric)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def cross_indices(arr)
|
238
|
+
arr.inject(:product).map(&:flatten).map { |a| a.inject(:+) }.sort
|
239
|
+
end
|
240
|
+
|
241
|
+
# General purpose method to map indices to attributes using the
|
242
|
+
# #indices hash.
|
243
|
+
# Several subclasses use an easier algorithm due to computational
|
244
|
+
# efficiency.
|
245
|
+
def attributes_by_index(index)
|
246
|
+
attrs = {}
|
247
|
+
indices.to_a.reverse.each do |type, indices|
|
248
|
+
indices.reverse.each_with_index do |ind, i|
|
249
|
+
if (index - ind) >= 0
|
250
|
+
index -= ind
|
251
|
+
attrs[type] = reverse_lookup[type][i]
|
252
|
+
break
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
attrs.values.reverse
|
257
|
+
end
|
258
|
+
|
259
|
+
def reverse_lookup
|
260
|
+
@rl ||= indices.each_with_object({}) do |(type, values), h|
|
261
|
+
h[type] = t.norm_values_for(type).take(values.size).reverse
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def new_form(args)
|
266
|
+
args = args.merge(default_args)
|
267
|
+
extensions_and_other_signs(args)
|
268
|
+
corrections(args)
|
269
|
+
form_class.new(args) if valid?(args)
|
270
|
+
end
|
271
|
+
|
272
|
+
def corrections(args)
|
273
|
+
end
|
274
|
+
|
275
|
+
def extensions_and_other_signs(args)
|
276
|
+
end
|
277
|
+
|
278
|
+
def validations
|
279
|
+
self.class.validations
|
280
|
+
end
|
281
|
+
|
282
|
+
# used by VerbBuilder, PppBuilder (for irregulars)
|
283
|
+
# GerundiveBuilder and GerundBuilder
|
284
|
+
def prefix
|
285
|
+
p = @options[:prefix].to_s
|
286
|
+
p unless p.empty?
|
287
|
+
end
|
288
|
+
|
289
|
+
def valid?(args)
|
290
|
+
if needs_validation?
|
291
|
+
validations.all? do |validator|
|
292
|
+
validation_rule(args, validator)
|
293
|
+
end
|
294
|
+
else
|
295
|
+
true
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def needs_validation?
|
300
|
+
@validate && validations.any?
|
301
|
+
end
|
302
|
+
|
303
|
+
def validation_rule(args, validator)
|
304
|
+
args[validator].to_s == @options[validator].to_s
|
305
|
+
end
|
306
|
+
|
307
|
+
# Used especially with archaic forms, where a special validation rule
|
308
|
+
# is present, like audiundi. It enters the FB process with thematic u
|
309
|
+
# (archaic) which is looked up as e but passes the validation. Still
|
310
|
+
# we want to present the new forms like they were requested, with their
|
311
|
+
# archaic appearance.
|
312
|
+
# Only call this after you pass validation!
|
313
|
+
# @param args [Hash] - arguments used for form building
|
314
|
+
# @param validator [Symbol] - key that is used for validation
|
315
|
+
# @param classification [Symbol] - adds info why this value should be kept,
|
316
|
+
# e.g. an archaic form
|
317
|
+
# @return [true]
|
318
|
+
def keep_given_value(args, validator, classification = nil)
|
319
|
+
# work in the classification first, as it might be nil
|
320
|
+
# and we want the method to return true, as it will get
|
321
|
+
# most frequently called at the end of a passing validation!
|
322
|
+
args[:classification] = classification
|
323
|
+
args[validator] = @options[validator]
|
324
|
+
end
|
325
|
+
|
326
|
+
def default_args
|
327
|
+
{ stem: stem_copy, inflection_class: @inflection_class }
|
328
|
+
end
|
329
|
+
|
330
|
+
def stem_copy
|
331
|
+
# solely needed for irregular verbs, they might come without
|
332
|
+
# a stem value, which will be set in the course of events
|
333
|
+
@stem ? @stem.clone : ""
|
334
|
+
end
|
335
|
+
|
336
|
+
def form_class
|
337
|
+
constant_by_type(namespace: LLT::Form)
|
338
|
+
end
|
339
|
+
|
340
|
+
def endings
|
341
|
+
endings_path.get(*endings_attributes)
|
342
|
+
end
|
343
|
+
|
344
|
+
def endings_attributes
|
345
|
+
[]
|
346
|
+
end
|
347
|
+
|
348
|
+
def endings_container
|
349
|
+
@type
|
350
|
+
end
|
351
|
+
|
352
|
+
def endings_path
|
353
|
+
path = constant_by_type(endings_container, namespace: endings_namespace)
|
354
|
+
metrical? ? path::Metrical : path
|
355
|
+
end
|
356
|
+
|
357
|
+
def endings_namespace
|
358
|
+
LLT::Constants::Endings
|
359
|
+
end
|
360
|
+
|
361
|
+
def downcase_all_stems
|
362
|
+
@stem.downcase! if @stem
|
363
|
+
@options[:stem].downcase! if @options[:stem]
|
364
|
+
end
|
365
|
+
|
366
|
+
def stays_capitalized
|
367
|
+
false
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class AdjectivePack < Pack
|
4
|
+
def initialize(type, args, source, extension = true)
|
5
|
+
# always extend
|
6
|
+
super
|
7
|
+
@lemma = @stems.first.nominative
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_hash(use = nil, options = {})
|
11
|
+
selector = case options[:comparison_sign].to_s
|
12
|
+
when /^(|i?t?er)$/ then :positivus # regular pos or adverbs
|
13
|
+
when /(ior|ius)/ then :comparativus
|
14
|
+
else :superlativus
|
15
|
+
end
|
16
|
+
|
17
|
+
stem = @stems.find { |st| st.comparatio == selector }
|
18
|
+
stem.to_hash.merge(options: options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def third_decl_with_possible_ne_abl?
|
22
|
+
super do
|
23
|
+
st = @stems.find { |stem| stem.comparatio == :positivus }
|
24
|
+
st ? st.third_decl_with_possible_ne_abl? : false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def extended_stems(args)
|
31
|
+
@stems = []
|
32
|
+
@args = args
|
33
|
+
|
34
|
+
compute_comparatio_stems
|
35
|
+
|
36
|
+
@stems
|
37
|
+
end
|
38
|
+
|
39
|
+
STEMS = %i{ positivus comparativus superlativus }
|
40
|
+
def compute_comparatio_stems
|
41
|
+
STEMS.each do |level|
|
42
|
+
sc = (level != :positivus)
|
43
|
+
build_as(level, sc)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_as(level, stem_change = false)
|
48
|
+
new_args = @args.merge(comparatio: level)
|
49
|
+
|
50
|
+
if stem_change
|
51
|
+
new_stem = send("#{level}_sign")
|
52
|
+
new_args[:stem] = new_stem
|
53
|
+
new_args.delete(:nom)
|
54
|
+
end
|
55
|
+
|
56
|
+
check_irregularities(new_args)
|
57
|
+
|
58
|
+
add(create_stem(new_args))
|
59
|
+
end
|
60
|
+
|
61
|
+
# Creates Irregular Adverb stems like of bonus.
|
62
|
+
# If none such is built, later stages will just use
|
63
|
+
# the usual positivus stem.
|
64
|
+
def check_irregularities(args)
|
65
|
+
stem = args[:stem]
|
66
|
+
if stem.match(irregular_adverbs)
|
67
|
+
args[:irregular_adverb] = true
|
68
|
+
new_stem = select_adverb_stem($1)
|
69
|
+
add(create_stem(:adverb, args.merge(stem: new_stem)))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def select_adverb_stem(match)
|
74
|
+
case match
|
75
|
+
when "bon" then "ben"
|
76
|
+
when "difficil" then "difficul"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def irregular_adverbs
|
81
|
+
/^(bon|difficil)$/
|
82
|
+
end
|
83
|
+
|
84
|
+
def comparativus_sign
|
85
|
+
old_stem = @args[:stem].clone
|
86
|
+
old_stem << "ior"
|
87
|
+
end
|
88
|
+
|
89
|
+
def superlativus_sign
|
90
|
+
old_stem = @args[:stem].clone
|
91
|
+
ext = case old_stem
|
92
|
+
when /l$/ then "lim"
|
93
|
+
when /r$/ then "rim"
|
94
|
+
else "issim"
|
95
|
+
end
|
96
|
+
|
97
|
+
new_stem = send("#{ext}_sup_rules", old_stem)
|
98
|
+
new_stem << ext
|
99
|
+
end
|
100
|
+
|
101
|
+
def rim_sup_rules(stem)
|
102
|
+
if stem =~ /^(veter)$/
|
103
|
+
stem
|
104
|
+
else
|
105
|
+
@args[:nom].clone
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def lim_sup_rules(stem)
|
110
|
+
stem
|
111
|
+
end
|
112
|
+
|
113
|
+
def issim_sup_rules(stem)
|
114
|
+
stem
|
115
|
+
end
|
116
|
+
|
117
|
+
def add(stem)
|
118
|
+
@stems << stem
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class AdjectiveStem < Stem
|
4
|
+
attr_reader :comparatio, :nom
|
5
|
+
|
6
|
+
def init_keys
|
7
|
+
%i{ nom stem inflection_class comparatio number_of_endings }
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"#{t.send(@type, :abbr)}#{@inflection_class} #{@stem}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def nominative
|
15
|
+
@nom
|
16
|
+
end
|
17
|
+
|
18
|
+
def third_decl_with_possible_ne_abl?
|
19
|
+
@inflection_class == 3 && @nom.match(/nis$/) && @stem.match(/n$/)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class NounPack < Pack
|
4
|
+
def initialize(*args)
|
5
|
+
super(*args)
|
6
|
+
@lemma = @stems.first.nominative
|
7
|
+
end
|
8
|
+
|
9
|
+
def third_decl_with_possible_ne_abl?
|
10
|
+
super { @stems.any?(&:third_decl_with_possible_ne_abl?) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class NounStem < Stem
|
4
|
+
attr_reader :nom
|
5
|
+
|
6
|
+
def init_keys
|
7
|
+
%i{ nom stem inflection_class sexus persona place }
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"#{t.send(@type, :abbr)}#{@inflection_class} #{@stem}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def nominative
|
15
|
+
@nom
|
16
|
+
end
|
17
|
+
|
18
|
+
def third_decl_with_possible_ne_abl?
|
19
|
+
if @inflection_class == 3
|
20
|
+
@nom.match(/[id]?on?$/) && @stem.match(/d?in$|i?on$/) ||
|
21
|
+
@nom.match(/men$/) && @stem.match(/min$/)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'llt/helpers'
|
2
|
+
|
3
|
+
module LLT
|
4
|
+
class Stem
|
5
|
+
class Pack
|
6
|
+
include Helpers::Transformer
|
7
|
+
include Helpers::Constantize
|
8
|
+
include Helpers::Normalizer
|
9
|
+
|
10
|
+
attr_reader :stems, :type, :lemma_key, :lemma
|
11
|
+
|
12
|
+
def initialize(type, args, source, extension = false)
|
13
|
+
@type = type
|
14
|
+
@source = source
|
15
|
+
@lemma_key = args[:lemma_key]
|
16
|
+
@stems = (extension ? extended_stems(args) : default_stem(args))
|
17
|
+
end
|
18
|
+
|
19
|
+
def lemma_with_key
|
20
|
+
"#{@lemma}##{@lemma_key}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash(use = nil, options = {})
|
24
|
+
@stems.first.to_hash.merge(options: options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
@stems.map(&:to_s) * ", "
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def create_stem(stem_type = @type, args)
|
34
|
+
constant_by_type(suffix: "stem", namespace: LLT::Stem).new(stem_type, args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def default_stem(args)
|
38
|
+
[create_stem(args)]
|
39
|
+
end
|
40
|
+
|
41
|
+
def third_decl_with_possible_ne_abl?
|
42
|
+
block_given? ? yield : false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class VerbPack < Pack
|
4
|
+
attr_reader :direct_objects, :indirect_objects
|
5
|
+
|
6
|
+
def initialize(type, args, source, extension = true)
|
7
|
+
super
|
8
|
+
extract_valencies(args)
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash(use = nil, options = {})
|
13
|
+
if use
|
14
|
+
stem = @stems.find { |st| st.type == use }
|
15
|
+
stem.to_hash.merge(options: options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def extract_valencies(args)
|
20
|
+
d = args[:dir_objs]
|
21
|
+
i = args[:indir_objs]
|
22
|
+
|
23
|
+
@direct_objects, @indirect_objects = parse_valencies(d, i)
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_valencies(d, i)
|
27
|
+
if d.nil? || d == "not_set"
|
28
|
+
[[4, :aci, :infinitive], [3]]
|
29
|
+
else
|
30
|
+
[d, i].map { |val| convert_valencies(val)}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def convert_valencies(val)
|
35
|
+
val.split.map do |val_string|
|
36
|
+
meth = (val_string.match(/^\d$/) ? :to_i : :to_sym)
|
37
|
+
val_string.send(meth)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
STEMS = %i{ praesens perfectum ppp }
|
42
|
+
def extended_stems(args)
|
43
|
+
STEMS.map do |type|
|
44
|
+
new_type = args[t.send(type, :abbr)]
|
45
|
+
next unless new_type
|
46
|
+
args[:stem] = new_type
|
47
|
+
create_stem(type, args)
|
48
|
+
end.compact
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module LLT
|
2
|
+
class Stem
|
3
|
+
class VerbStem < Stem
|
4
|
+
def init_keys
|
5
|
+
%i{ stem inflection_class deponens pf_composition }
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
"#{@type}#{@inflection_class}#{dep_state.magenta} #{@stem}"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def dep_state
|
14
|
+
@deponens ? " dep" : ""
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|