llt-form_builder 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|