latinverb 0.2.0 → 0.9.2
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.
- data/.gitignore +0 -1
- data/Gemfile +1 -2
- data/README.markdown +54 -240
- data/etc/irreg_skel.json +104 -0
- data/{latinirb.gemspec → latinverb.gemspec} +4 -4
- data/lib/latinverb/chart.rb +94 -0
- data/lib/latinverb/version.rb +10 -0
- data/lib/latinverb.rb +710 -0
- data/lib/linguistics/latin/verb/classification_types.rb +59 -0
- data/lib/linguistics/latin/verb/constants.rb +201 -0
- data/lib/linguistics/latin/verb/deponent_tense_methods.rb +98 -0
- data/lib/linguistics/latin/verb/infinitives.rb +212 -0
- data/lib/linguistics/latin/verb/irregulars.rb +4393 -0
- data/lib/linguistics/latin/verb/latinverb/auxiliary_classes.rb +208 -0
- data/lib/linguistics/latin/verb/latinverb/classmethods.rb +215 -0
- data/lib/linguistics/latin/verb/latinverb/data.rb +90 -0
- data/lib/linguistics/latin/verb/latinverb/display.rb +23 -0
- data/lib/linguistics/latin/verb/latinverb/metaprogramming.rb +79 -0
- data/lib/linguistics/latin/verb/latinverb/validation.rb +66 -0
- data/lib/linguistics/latin/verb/participles.rb +202 -0
- data/lib/linguistics/latin/verb/phonographia.rb +109 -0
- data/lib/linguistics/latin/verb/supine.rb +42 -0
- data/lib/linguistics/latin/verb/tense_methods.rb +950 -0
- data/test/testAmbiguousLookups.rb +30 -0
- data/test/testClusterResolution.rb +20 -0
- data/test/testDataStructures.rb +29 -0
- data/test/testDefectSemiImp.rb +111 -0
- data/test/testDeponentFirstConjugation.rb +64 -0
- data/test/testDeponentFourthConjugation.rb +64 -0
- data/test/testDeponentSecondConjugation.rb +64 -0
- data/test/testDeponentThirdConjugation.rb +64 -0
- data/test/testDeponentThirdIOConjugation.rb +64 -0
- data/test/testDeserializeInfinitives.rb +38 -0
- data/test/testFirstConjugation.rb +388 -0
- data/test/testFourthConjugation.rb +190 -0
- data/test/testFreakishVerbs.rb +93 -0
- data/test/testImperativeBlock.rb +27 -0
- data/test/testIrregularSum.rb +22 -0
- data/test/testIrregulars.rb +652 -0
- data/test/testLatinVerb.rb +195 -0
- data/test/testMacronRules.rb +19 -0
- data/test/testSecondConjugation.rb +189 -0
- data/test/testThirdConjugation.rb +190 -0
- data/test/testThirdIOConjugation.rb +190 -0
- metadata +70 -18
- data/bin/latinirb.rb +0 -7
- data/latinverb.rb +0 -544
- data/lib/LatinIRB.rb +0 -172
- data/lib/latinirb/paradigmatic_verbs.rb +0 -17
- data/lib/latinirb/version.rb +0 -10
- data/lib/latirb.rb +0 -20
@@ -0,0 +1,950 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'linguistics/latin/verb/phonographia'
|
4
|
+
require 'linguistics/latin/verb/latinverb/auxiliary_classes'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module Linguistics
|
8
|
+
module Latin
|
9
|
+
module Verb
|
10
|
+
##
|
11
|
+
# == NAME
|
12
|
+
#
|
13
|
+
# TenseBlock
|
14
|
+
#
|
15
|
+
# == DESCRIPTION
|
16
|
+
#
|
17
|
+
# As per the LatinVerb documentation, LatinVerbs decorate themselves with
|
18
|
+
# the method which loads up a voice/tense/mood black box. That black box
|
19
|
+
# is a TenseBlock. The TenseBlock, in turn, responds to getting the final
|
20
|
+
# two components of the fully-qualified vector back (person and number).
|
21
|
+
# It also has Array-like behaviors (e.g. +[]+) based on the 2 * 3 matrix.
|
22
|
+
#
|
23
|
+
# == INTERNALS
|
24
|
+
#
|
25
|
+
# Internally, a Tenseblock is effectively an Array of the arguments passed
|
26
|
+
# in during TenseBlock.initialize. These are assumed to be
|
27
|
+
# first/singular, second/singular, third/singular and then
|
28
|
+
# first/plural, second/plural, third/plural.
|
29
|
+
#
|
30
|
+
# Syntactic sugar methods are added to access this array. Thus, in a
|
31
|
+
# LatinVerb a fully-qualified vectors first 3/5 data resolve to a
|
32
|
+
# TenseBlock. The last 2/5 of resolution occurs within the TenseBlock
|
33
|
+
# (effectively pulling the contents of the Array). Therefore, when a
|
34
|
+
# LatinVerb is accessed with the quinpartite fully-qualified vector it can
|
35
|
+
# return the unique value. The mechanics of this hook through (surprise!)
|
36
|
+
# method_missing.
|
37
|
+
#
|
38
|
+
#
|
39
|
+
##
|
40
|
+
|
41
|
+
class TenseBlock
|
42
|
+
include Linguistics::Latin::Phonographia
|
43
|
+
|
44
|
+
# Idea from Mike Perham (6/1/2011): Add a way to leave a note that
|
45
|
+
# describes, in English, the signification of the given tense. Good
|
46
|
+
# idea.
|
47
|
+
|
48
|
+
attr_reader :meaning
|
49
|
+
|
50
|
+
# === ARGUMENTS
|
51
|
+
#
|
52
|
+
# *r:* :: An Array (or something that can respond to to_a) containing 0-6
|
53
|
+
# elements that will be mapped into the 2*3 matrix of Latin verb person /
|
54
|
+
# number specifications.
|
55
|
+
# === RETURNS
|
56
|
+
#
|
57
|
+
# Nothing
|
58
|
+
##
|
59
|
+
def initialize(r, opts={})
|
60
|
+
begin
|
61
|
+
if r.class != Array
|
62
|
+
raise if r.nil?
|
63
|
+
r = r.to_a
|
64
|
+
end
|
65
|
+
@results = r.map{|v| Linguistics::Latin::Phonographia.fix_macrons v}
|
66
|
+
@meaning = opts[:meaning] if opts[:meaning]
|
67
|
+
rescue => e
|
68
|
+
raise e, "TenseBlock failed to initialize correctly. passed #{r.nil?}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
#
|
74
|
+
# Required for serialization
|
75
|
+
#
|
76
|
+
##
|
77
|
+
def to_json(*a)
|
78
|
+
{
|
79
|
+
'json_class' => self.class.name,
|
80
|
+
'data' => @results.map{|i| i.to_json}
|
81
|
+
}.to_json(*a)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
#
|
86
|
+
# Required for deserialization
|
87
|
+
#
|
88
|
+
##
|
89
|
+
def TenseBlock.json_create(o)
|
90
|
+
new(o['data'])
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
#
|
95
|
+
# Provides Array-like interface to the collection of results.
|
96
|
+
#
|
97
|
+
##
|
98
|
+
def [](arg)
|
99
|
+
@results[arg]
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
#
|
104
|
+
# To Array, useful in serialization
|
105
|
+
#
|
106
|
+
##
|
107
|
+
def to_a
|
108
|
+
return @results
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
#
|
113
|
+
# Add array compatibility support
|
114
|
+
#
|
115
|
+
##
|
116
|
+
def length; return @results.length; end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Add array empty? compatibility
|
120
|
+
#
|
121
|
+
##
|
122
|
+
def empty?; return @results.empty?; end
|
123
|
+
|
124
|
+
##
|
125
|
+
#
|
126
|
+
# Add a sensible string display
|
127
|
+
#
|
128
|
+
##
|
129
|
+
def to_s; return self.to_a.to_s; end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Return whether the result arrays is empty of words
|
133
|
+
##
|
134
|
+
def wordless?
|
135
|
+
@results.map do |r|
|
136
|
+
return false if r =~ /\w/
|
137
|
+
end
|
138
|
+
true
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
#
|
143
|
+
# Provide a method_missing so that ambiguous cases can be resolves
|
144
|
+
#
|
145
|
+
##
|
146
|
+
def method_missing(symbol, *args)
|
147
|
+
begin
|
148
|
+
returnArray = []
|
149
|
+
methods.grep(/#{symbol.to_s}/) do |s|
|
150
|
+
returnArray.push(send s)
|
151
|
+
end
|
152
|
+
return returnArray unless returnArray.empty?
|
153
|
+
rescue Exception
|
154
|
+
end
|
155
|
+
super
|
156
|
+
end
|
157
|
+
|
158
|
+
##
|
159
|
+
#--
|
160
|
+
# TODO: I dream of this being generated dynamically through the
|
161
|
+
# VerbvectorGenerator for more dynamicity. This would require a richer DSL in
|
162
|
+
# VerbvectorGenerator, but would be totally awesome if we could describe this
|
163
|
+
# language in a DSL.
|
164
|
+
#++
|
165
|
+
##
|
166
|
+
|
167
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
168
|
+
def first_person_singular_number; return @results[0]; end
|
169
|
+
|
170
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
171
|
+
def second_person_singular_number; return @results[1]; end
|
172
|
+
|
173
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
174
|
+
def third_person_singular_number; return @results[2]; end
|
175
|
+
|
176
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
177
|
+
def first_person_plural_number; return @results[3]; end
|
178
|
+
|
179
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
180
|
+
def second_person_plural_number; return @results[4]; end
|
181
|
+
|
182
|
+
# Syntactic sugar for accessing the final coordinates in the TenseBlock
|
183
|
+
def third_person_plural_number; return @results[5]; end
|
184
|
+
end
|
185
|
+
|
186
|
+
class LatinVerb
|
187
|
+
|
188
|
+
|
189
|
+
##
|
190
|
+
#
|
191
|
+
# === GRAMMATICAL FUNCTION
|
192
|
+
#
|
193
|
+
# Commands for immediate action. Always second person.
|
194
|
+
#
|
195
|
+
# === ARGUMENTS
|
196
|
+
#
|
197
|
+
# None
|
198
|
+
#
|
199
|
+
# === RETURNS
|
200
|
+
#
|
201
|
+
# TenseBlock
|
202
|
+
#
|
203
|
+
###
|
204
|
+
def active_voice_imperative_mood_present_tense
|
205
|
+
imp = imperatives
|
206
|
+
TenseBlock.new( [ '', imp.present_tense_singular_number, '',
|
207
|
+
'', imp.present_tense_plural_number, ''
|
208
|
+
],
|
209
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_imperative_mood_present_tense] }
|
210
|
+
)
|
211
|
+
end
|
212
|
+
|
213
|
+
##
|
214
|
+
#
|
215
|
+
# === GRAMMATICAL FUNCTION
|
216
|
+
#
|
217
|
+
# Commands for immediate action. Only supports second or third
|
218
|
+
# person.
|
219
|
+
#
|
220
|
+
# === ARGUMENTS
|
221
|
+
#
|
222
|
+
# None
|
223
|
+
#
|
224
|
+
# === RETURNS
|
225
|
+
#
|
226
|
+
# TenseBlock
|
227
|
+
#
|
228
|
+
###
|
229
|
+
def active_voice_imperative_mood_future_tense
|
230
|
+
f = imperatives.future
|
231
|
+
return TenseBlock.new( [ '', f[0], f[2],
|
232
|
+
'', f[1], f[3]
|
233
|
+
],
|
234
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_imperative_mood_future_tense] }
|
235
|
+
)
|
236
|
+
end
|
237
|
+
##
|
238
|
+
#
|
239
|
+
# === GRAMMATICAL FUNCTION
|
240
|
+
#
|
241
|
+
# Action to be completed in the future. A&G,160,a,3.
|
242
|
+
#
|
243
|
+
# === ARGUMENTS
|
244
|
+
#
|
245
|
+
# None
|
246
|
+
#
|
247
|
+
# === RETURNS
|
248
|
+
#
|
249
|
+
# TenseBlock
|
250
|
+
#
|
251
|
+
###
|
252
|
+
def active_voice_indicative_mood_future_tense
|
253
|
+
return TenseBlock.new(
|
254
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
255
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
256
|
+
[AF_ONE_TWO_ENDINGS.collect{|x| stem + x}].flatten
|
257
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
258
|
+
[AF_OTHER_ENDINGS.collect{|x| stem + x}].flatten
|
259
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO or
|
260
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
261
|
+
[AF_OTHER_ENDINGS.collect{|x| stem + "i" + x}].flatten
|
262
|
+
end,
|
263
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_future_tense] }
|
264
|
+
)
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
#
|
269
|
+
# === GRAMMATICAL FUNCTION
|
270
|
+
#
|
271
|
+
# Action completed in the future.
|
272
|
+
# A&G,160,b,3.
|
273
|
+
#
|
274
|
+
# === ARGUMENTS
|
275
|
+
#
|
276
|
+
# None
|
277
|
+
#
|
278
|
+
# === RETURNS
|
279
|
+
#
|
280
|
+
# TenseBlock
|
281
|
+
#
|
282
|
+
###
|
283
|
+
def active_voice_indicative_mood_futureperfect_tense
|
284
|
+
substem = @first_pers_perf[0..-2]
|
285
|
+
return TenseBlock.new [APERF_FUTURE_ENDINGS.collect{|x| substem+x}].flatten,
|
286
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_futureperfect_tense] }
|
287
|
+
end
|
288
|
+
|
289
|
+
##
|
290
|
+
#
|
291
|
+
# === GRAMMATICAL FUNCTION
|
292
|
+
#
|
293
|
+
# Habitual action in the past. A&G,160,a,2.
|
294
|
+
#
|
295
|
+
# === ARGUMENTS
|
296
|
+
#
|
297
|
+
# None
|
298
|
+
#
|
299
|
+
# === RETURNS
|
300
|
+
#
|
301
|
+
# TenseBlock
|
302
|
+
#
|
303
|
+
###
|
304
|
+
def active_voice_indicative_mood_imperfect_tense
|
305
|
+
return TenseBlock.new(
|
306
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
307
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
308
|
+
[AI_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS.collect{|x| stem + x}].flatten
|
309
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
310
|
+
[AI_THIRD_CONJUG_PERS_ENDINGS.collect{|x| stem + x}].flatten
|
311
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO or
|
312
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
313
|
+
[AI_THIRD_CONJUG_PERS_ENDINGS.collect do |x|
|
314
|
+
stem + "i" + x end ].flatten!
|
315
|
+
end,
|
316
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_imperfect_tense] }
|
317
|
+
)
|
318
|
+
end
|
319
|
+
|
320
|
+
##
|
321
|
+
#
|
322
|
+
# === GRAMMATICAL FUNCTION
|
323
|
+
#
|
324
|
+
# Action completed in the past prior to an event in the past.
|
325
|
+
# A&G,160,b,3.
|
326
|
+
#
|
327
|
+
# === ARGUMENTS
|
328
|
+
#
|
329
|
+
# None
|
330
|
+
#
|
331
|
+
# === RETURNS
|
332
|
+
#
|
333
|
+
# TenseBlock
|
334
|
+
#
|
335
|
+
###
|
336
|
+
def active_voice_indicative_mood_pastperfect_tense
|
337
|
+
substem = @first_pers_perf[0..-2]
|
338
|
+
return TenseBlock.new [APERF_PAST_ENDINGS.collect{|x| substem+x}].flatten,
|
339
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_pastperfect_tense] }
|
340
|
+
end
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
##
|
345
|
+
#
|
346
|
+
# === GRAMMATICAL FUNCTION
|
347
|
+
#
|
348
|
+
# Action completed in the past. A&G,160,b,1.
|
349
|
+
#
|
350
|
+
# === ARGUMENTS
|
351
|
+
#
|
352
|
+
# None
|
353
|
+
#
|
354
|
+
# === RETURNS
|
355
|
+
#
|
356
|
+
# TenseBlock
|
357
|
+
#
|
358
|
+
###
|
359
|
+
def active_voice_indicative_mood_perfect_tense
|
360
|
+
substem = @first_pers_perf[0..-2]
|
361
|
+
return TenseBlock.new [@first_pers_perf.to_s, APERF_ENDINGS.collect{|x| substem+x.to_s}].flatten,
|
362
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_perfect_tense] }
|
363
|
+
end
|
364
|
+
|
365
|
+
##
|
366
|
+
#
|
367
|
+
# === GRAMMATICAL FUNCTION
|
368
|
+
#
|
369
|
+
# The canonical building block of learning to conjugate verbs in
|
370
|
+
# Latin. Take the present active infinitive, chop off the ending, and
|
371
|
+
# add the classic o,s,t,mus,tis,nt
|
372
|
+
#
|
373
|
+
# Wheelock Reference, p. 4.
|
374
|
+
# A&G, 160,a,1.
|
375
|
+
#
|
376
|
+
# === ARGUMENTS
|
377
|
+
#
|
378
|
+
# None
|
379
|
+
#
|
380
|
+
# === RETURNS
|
381
|
+
#
|
382
|
+
# TenseBlock
|
383
|
+
#
|
384
|
+
###
|
385
|
+
def active_voice_indicative_mood_present_tense
|
386
|
+
return TenseBlock.new(
|
387
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
388
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
389
|
+
[ @first_pers_singular,
|
390
|
+
AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS.collect{ |ending| stem + ending}
|
391
|
+
].flatten!
|
392
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
393
|
+
[ AP_THIRD_CONJUG_PERS_ENDINGS.collect{ |ending| stem + ending } ].flatten!
|
394
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO or
|
395
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
396
|
+
[ @first_pers_singular,
|
397
|
+
AP_THIRDIO_CONJG_PERS_ENDINGS.collect{ |ending| stem + ending }
|
398
|
+
].flatten!
|
399
|
+
end,
|
400
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_indicative_mood_present_tense] }
|
401
|
+
)
|
402
|
+
end
|
403
|
+
|
404
|
+
##
|
405
|
+
#
|
406
|
+
# === GRAMMATICAL FUNCTION
|
407
|
+
#
|
408
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
409
|
+
# the verb in context.</em>
|
410
|
+
#
|
411
|
+
# === ARGUMENTS
|
412
|
+
#
|
413
|
+
# None
|
414
|
+
#
|
415
|
+
# === RETURNS
|
416
|
+
#
|
417
|
+
# TenseBlock
|
418
|
+
#
|
419
|
+
###
|
420
|
+
def active_voice_subjunctive_mood_imperfect_tense
|
421
|
+
TenseBlock.new(
|
422
|
+
['m', AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
423
|
+
@pres_act_inf.sub(/e$/,'ē') + ending
|
424
|
+
end,
|
425
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_subjunctive_mood_imperfect_tense] }
|
426
|
+
)
|
427
|
+
end
|
428
|
+
|
429
|
+
##
|
430
|
+
#
|
431
|
+
# === GRAMMATICAL FUNCTION
|
432
|
+
#
|
433
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
434
|
+
# the verb in context.</em>
|
435
|
+
#
|
436
|
+
# === ARGUMENTS
|
437
|
+
#
|
438
|
+
# None
|
439
|
+
#
|
440
|
+
# === RETURNS
|
441
|
+
#
|
442
|
+
# TenseBlock
|
443
|
+
#
|
444
|
+
###
|
445
|
+
def active_voice_subjunctive_mood_pastperfect_tense
|
446
|
+
asp_base = @first_pers_perf[0..@first_pers_perf.length-2] + "issē"
|
447
|
+
TenseBlock.new( ['m', AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
448
|
+
asp_base + ending
|
449
|
+
end,
|
450
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_subjunctive_mood_pastperfect_tense] }
|
451
|
+
)
|
452
|
+
end
|
453
|
+
|
454
|
+
##
|
455
|
+
#
|
456
|
+
# === GRAMMATICAL FUNCTION
|
457
|
+
#
|
458
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
459
|
+
# the verb in context.</em>
|
460
|
+
#
|
461
|
+
# === ARGUMENTS
|
462
|
+
#
|
463
|
+
# None
|
464
|
+
#
|
465
|
+
# === RETURNS
|
466
|
+
#
|
467
|
+
# TenseBlock
|
468
|
+
#
|
469
|
+
###
|
470
|
+
def active_voice_subjunctive_mood_perfect_tense
|
471
|
+
asp_base =
|
472
|
+
@first_pers_perf[0..@first_pers_perf.length-2] +
|
473
|
+
"erī"
|
474
|
+
TenseBlock.new(
|
475
|
+
['m', AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
476
|
+
asp_base + ending
|
477
|
+
end,
|
478
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_subjunctive_mood_perfect_tense] }
|
479
|
+
)
|
480
|
+
end
|
481
|
+
|
482
|
+
##
|
483
|
+
#
|
484
|
+
# === GRAMMATICAL FUNCTION
|
485
|
+
#
|
486
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
487
|
+
# the verb in context.</em>
|
488
|
+
#
|
489
|
+
# === ARGUMENTS
|
490
|
+
#
|
491
|
+
# None
|
492
|
+
#
|
493
|
+
# === RETURNS
|
494
|
+
#
|
495
|
+
# TenseBlock
|
496
|
+
#
|
497
|
+
###
|
498
|
+
def active_voice_subjunctive_mood_present_tense
|
499
|
+
key = lambda do
|
500
|
+
conjugation.to_s.split(/::/).last.to_sym
|
501
|
+
end
|
502
|
+
|
503
|
+
TenseBlock.new(
|
504
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
505
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
506
|
+
asp_base = ACTIVE_PRESENT_SUBJUNCTIVE_ENDINGS[key.call].call(stem[0..-2])
|
507
|
+
['m',
|
508
|
+
AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
509
|
+
asp_base + ending
|
510
|
+
end
|
511
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third or
|
512
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
513
|
+
asp_base = ACTIVE_PRESENT_SUBJUNCTIVE_ENDINGS[key.call].call(stem[0..-1])
|
514
|
+
['m',
|
515
|
+
AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
516
|
+
asp_base + ending
|
517
|
+
end
|
518
|
+
else
|
519
|
+
base =
|
520
|
+
['m',
|
521
|
+
AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS].flatten!.map do |ending|
|
522
|
+
ACTIVE_PRESENT_SUBJUNCTIVE_ENDINGS[key.call].call(@stem) + ending
|
523
|
+
end
|
524
|
+
end,
|
525
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:active_voice_subjunctive_mood_present_tense] }
|
526
|
+
)
|
527
|
+
end
|
528
|
+
|
529
|
+
##
|
530
|
+
#
|
531
|
+
# === GRAMMATICAL FUNCTION
|
532
|
+
#
|
533
|
+
# <em>Refer to "Voice" section in reference, for function consult
|
534
|
+
# active-voice counterpart.</em>
|
535
|
+
#
|
536
|
+
# === ARGUMENTS
|
537
|
+
#
|
538
|
+
# None
|
539
|
+
#
|
540
|
+
# === RETURNS
|
541
|
+
#
|
542
|
+
# TenseBlock
|
543
|
+
#
|
544
|
+
###
|
545
|
+
def passive_voice_indicative_mood_future_tense
|
546
|
+
TenseBlock.new(
|
547
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
548
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
549
|
+
fp_stem=stem+"bi"
|
550
|
+
standards = PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG[2..-1].map{|x| fp_stem + x}
|
551
|
+
standards.pop
|
552
|
+
fp_stem.sub!(/.$/,'u')
|
553
|
+
[stem + "b\xc5\x8dr",
|
554
|
+
stem + "beris", standards, fp_stem+PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.last].flatten!
|
555
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
556
|
+
fp_stem=stem+"ē"
|
557
|
+
standards = PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG[1..-1].map{|x| fp_stem + x}
|
558
|
+
[stem + "ar", standards].flatten!
|
559
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO or
|
560
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
561
|
+
ie_base=stem+"iē"
|
562
|
+
[stem+"ia"+PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG[0],
|
563
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG[1..-1].map{|x| ie_base + x}].flatten!
|
564
|
+
end,
|
565
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_future_tense] }
|
566
|
+
)
|
567
|
+
end
|
568
|
+
|
569
|
+
##
|
570
|
+
#
|
571
|
+
# === GRAMMATICAL FUNCTION
|
572
|
+
#
|
573
|
+
# <em>Refer to "Voice" section in reference, for function consult
|
574
|
+
# active-voice counterpart.</em>
|
575
|
+
# Wheelock, 122
|
576
|
+
#
|
577
|
+
# === ARGUMENTS
|
578
|
+
#
|
579
|
+
# None
|
580
|
+
#
|
581
|
+
# === RETURNS
|
582
|
+
#
|
583
|
+
# TenseBlock
|
584
|
+
#
|
585
|
+
###
|
586
|
+
def passive_voice_indicative_mood_futureperfect_tense
|
587
|
+
return TenseBlock.new(
|
588
|
+
PASS_PERF_FUTURE_ENDINGS.map{ |helping_verb| "#{@pass_perf_part} #{helping_verb}" },
|
589
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_futureperfect_tense] }
|
590
|
+
)
|
591
|
+
end
|
592
|
+
|
593
|
+
|
594
|
+
##
|
595
|
+
#
|
596
|
+
# === GRAMMATICAL FUNCTION
|
597
|
+
#
|
598
|
+
# <em>Refer to "Voice" section in reference, for function consult
|
599
|
+
# active-voice counterpart.</em>
|
600
|
+
# Wheelock, 117
|
601
|
+
#
|
602
|
+
# === ARGUMENTS
|
603
|
+
#
|
604
|
+
# None
|
605
|
+
#
|
606
|
+
# === RETURNS
|
607
|
+
#
|
608
|
+
# TenseBlock
|
609
|
+
#
|
610
|
+
###
|
611
|
+
def passive_voice_indicative_mood_imperfect_tense
|
612
|
+
return TenseBlock.new(
|
613
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
614
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
615
|
+
imperfect_stem = stem + "b\xc4\x81"
|
616
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map{|x| imperfect_stem+x}
|
617
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
618
|
+
ministem=stem + "ēbā"
|
619
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map{|x| ministem + x}
|
620
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO or
|
621
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
622
|
+
base=stem+"iēbā"
|
623
|
+
[PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map{|x| base + x}].flatten!
|
624
|
+
end,
|
625
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_imperfect_tense] }
|
626
|
+
)
|
627
|
+
end
|
628
|
+
|
629
|
+
|
630
|
+
##
|
631
|
+
#
|
632
|
+
# === GRAMMATICAL FUNCTION
|
633
|
+
#
|
634
|
+
# <em>Refer to "Voice" section in reference, for function consult
|
635
|
+
# active-voice counterpart.</em>
|
636
|
+
# Wheelock, 117
|
637
|
+
#
|
638
|
+
# === ARGUMENTS
|
639
|
+
#
|
640
|
+
# None
|
641
|
+
#
|
642
|
+
# === RETURNS
|
643
|
+
#
|
644
|
+
# TenseBlock
|
645
|
+
#
|
646
|
+
###
|
647
|
+
def passive_voice_indicative_mood_pastperfect_tense
|
648
|
+
TenseBlock.new(
|
649
|
+
PASS_PERF_PAST_ENDINGS.map{ |helping_verb| "#{@pass_perf_part} #{helping_verb}" },
|
650
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_pastperfect_tense]}
|
651
|
+
)
|
652
|
+
end
|
653
|
+
|
654
|
+
|
655
|
+
##
|
656
|
+
#
|
657
|
+
# === GRAMMATICAL FUNCTION
|
658
|
+
#
|
659
|
+
# Wheelock, 122
|
660
|
+
#
|
661
|
+
# === ARGUMENTS
|
662
|
+
#
|
663
|
+
# None
|
664
|
+
#
|
665
|
+
# === RETURNS
|
666
|
+
#
|
667
|
+
# TenseBlock
|
668
|
+
#
|
669
|
+
###
|
670
|
+
def passive_voice_indicative_mood_perfect_tense
|
671
|
+
TenseBlock.new(
|
672
|
+
PASS_PERF_PRESENT_ENDINGS.map{ |helping_verb| "#{@pass_perf_part} #{helping_verb}" },
|
673
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_perfect_tense] }
|
674
|
+
)
|
675
|
+
end
|
676
|
+
|
677
|
+
|
678
|
+
##
|
679
|
+
#
|
680
|
+
# === GRAMMATICAL FUNCTION
|
681
|
+
#
|
682
|
+
# <em>Refer to "Voice" section in reference, for function consult
|
683
|
+
# active-voice counterpart.</em>
|
684
|
+
# Wheelock, 117
|
685
|
+
#
|
686
|
+
# === ARGUMENTS
|
687
|
+
#
|
688
|
+
# None
|
689
|
+
#
|
690
|
+
# === RETURNS
|
691
|
+
#
|
692
|
+
# TenseBlock
|
693
|
+
#
|
694
|
+
###
|
695
|
+
def passive_voice_indicative_mood_present_tense
|
696
|
+
return TenseBlock.new(
|
697
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
698
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
699
|
+
local_pe=PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.clone
|
700
|
+
[@first_pers_singular.to_s + "r",
|
701
|
+
local_pe[1..-1].map{|x| @stem + x}].flatten!
|
702
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third
|
703
|
+
[@first_pers_singular+"r",
|
704
|
+
PASSIVE_ENDINGS_OTHER[1..-1].map{|x| stem + x}].flatten!
|
705
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO
|
706
|
+
base=stem+"i"
|
707
|
+
[@first_pers_singular+"r",
|
708
|
+
PASSIVE_ENDINGS_OTHER[1..-2].map{|x| stem + x},
|
709
|
+
base+PASSIVE_ENDINGS_OTHER[-1]].flatten!
|
710
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
711
|
+
base=@stem+"ī"
|
712
|
+
[@first_pers_singular+"r",
|
713
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG[1..-2].map{|x| base + x},
|
714
|
+
base+PASSIVE_ENDINGS_OTHER[-1]].flatten!
|
715
|
+
end,
|
716
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_indicative_mood_present_tense] }
|
717
|
+
)
|
718
|
+
end
|
719
|
+
|
720
|
+
##
|
721
|
+
#
|
722
|
+
# === GRAMMATICAL FUNCTION
|
723
|
+
#
|
724
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
725
|
+
# the verb in context.</em>
|
726
|
+
#
|
727
|
+
# === ARGUMENTS
|
728
|
+
#
|
729
|
+
# None
|
730
|
+
#
|
731
|
+
# === RETURNS
|
732
|
+
#
|
733
|
+
# TenseBlock
|
734
|
+
#
|
735
|
+
###
|
736
|
+
def passive_voice_subjunctive_mood_imperfect_tense
|
737
|
+
base = @pres_act_inf.gsub(/(.*)(.)$/,"\\1" + 'ē')
|
738
|
+
TenseBlock.new(
|
739
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map do |ending|
|
740
|
+
base + ending
|
741
|
+
end,
|
742
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_subjunctive_mood_imperfect_tense] }
|
743
|
+
)
|
744
|
+
end
|
745
|
+
|
746
|
+
##
|
747
|
+
#
|
748
|
+
# === GRAMMATICAL FUNCTION
|
749
|
+
#
|
750
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
751
|
+
# the verb in context.</em>
|
752
|
+
#
|
753
|
+
# === ARGUMENTS
|
754
|
+
#
|
755
|
+
# None
|
756
|
+
#
|
757
|
+
# === RETURNS
|
758
|
+
#
|
759
|
+
# TenseBlock
|
760
|
+
#
|
761
|
+
###
|
762
|
+
def passive_voice_subjunctive_mood_pastperfect_tense
|
763
|
+
count = -1
|
764
|
+
TenseBlock.new(PASS_PLUPERF_PAST_ENDINGS.map do |ending|
|
765
|
+
count += 1
|
766
|
+
(count <= 2 ?
|
767
|
+
"[ #{triplicate_and_genderize @pass_perf_part} ]" :
|
768
|
+
"[ #{pluralize_participial_listing(triplicate_and_genderize(@pass_perf_part))} ]" )+ " " + ending
|
769
|
+
end,
|
770
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_subjunctive_mood_pastperfect_tense] }
|
771
|
+
)
|
772
|
+
end
|
773
|
+
|
774
|
+
##
|
775
|
+
#
|
776
|
+
# === GRAMMATICAL FUNCTION
|
777
|
+
#
|
778
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
779
|
+
# the verb in context.</em>
|
780
|
+
#
|
781
|
+
# === ARGUMENTS
|
782
|
+
#
|
783
|
+
# None
|
784
|
+
#
|
785
|
+
# === RETURNS
|
786
|
+
#
|
787
|
+
# TenseBlock
|
788
|
+
#
|
789
|
+
###
|
790
|
+
def passive_voice_subjunctive_mood_perfect_tense
|
791
|
+
counter = -1
|
792
|
+
TenseBlock.new(PASS_PERF_SUBJ_ENDINGS.map do |ending|
|
793
|
+
counter += 1
|
794
|
+
(counter <=2 ?
|
795
|
+
"[ #{triplicate_and_genderize @pass_perf_part} ]" :
|
796
|
+
"[ #{pluralize_participial_listing(triplicate_and_genderize(@pass_perf_part))} ]" )+ " " + ending
|
797
|
+
end,
|
798
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_subjunctive_mood_perfect_tense] }
|
799
|
+
)
|
800
|
+
end
|
801
|
+
|
802
|
+
##
|
803
|
+
#
|
804
|
+
# === GRAMMATICAL FUNCTION
|
805
|
+
#
|
806
|
+
# <em>Refer to "Moods," above. Tense is constrained by function of
|
807
|
+
# the verb in context.</em>
|
808
|
+
#
|
809
|
+
# === ARGUMENTS
|
810
|
+
#
|
811
|
+
# None
|
812
|
+
#
|
813
|
+
# === RETURNS
|
814
|
+
#
|
815
|
+
# TenseBlock
|
816
|
+
#
|
817
|
+
###
|
818
|
+
def passive_voice_subjunctive_mood_present_tense
|
819
|
+
key = lambda do
|
820
|
+
conjugation.to_s.split(/::/).last.to_sym
|
821
|
+
end
|
822
|
+
TenseBlock.new(
|
823
|
+
if conjugation == Linguistics::Latin::Verb::VerbTypes::First or
|
824
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::Second
|
825
|
+
short_base =
|
826
|
+
ACTIVE_PRESENT_SUBJUNCTIVE_ENDINGS[key.call].call(stem[0..-2])
|
827
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map do |ending|
|
828
|
+
short_base + ending
|
829
|
+
end
|
830
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Third or
|
831
|
+
conjugation == Linguistics::Latin::Verb::VerbTypes::ThirdIO
|
832
|
+
subjunctive_stem = conjugation.to_s =~ /O$/i ? stem + "iā" : stem + "ā"
|
833
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map do |ending|
|
834
|
+
subjunctive_stem + ending
|
835
|
+
end
|
836
|
+
elsif conjugation == Linguistics::Latin::Verb::VerbTypes::Fourth
|
837
|
+
subjunctive_stem = stem + "iā"
|
838
|
+
PASSIVE_ENDINGS_FIRST_AND_SECOND_CONJG.map do |ending|
|
839
|
+
subjunctive_stem + ending
|
840
|
+
end
|
841
|
+
end,
|
842
|
+
{ :meaning => Linguistics::Latin::Verb::LatinVerb::MEANINGS[:passive_voice_subjunctive_mood_present_tense] }
|
843
|
+
)
|
844
|
+
end
|
845
|
+
|
846
|
+
##
|
847
|
+
#
|
848
|
+
# === GRAMMATICAL FUNCTION
|
849
|
+
#
|
850
|
+
# Used to express command. As A&G notes, oftentimes the Subjunctive
|
851
|
+
# is the correct mood for exhortation.
|
852
|
+
#
|
853
|
+
# === ARGUMENTS
|
854
|
+
#
|
855
|
+
# None
|
856
|
+
#
|
857
|
+
# === RETURNS
|
858
|
+
#
|
859
|
+
# TenseBlock
|
860
|
+
#
|
861
|
+
###
|
862
|
+
def imperatives
|
863
|
+
@imperatives ||= form_imperatives
|
864
|
+
end
|
865
|
+
|
866
|
+
private
|
867
|
+
|
868
|
+
def form_imperatives
|
869
|
+
|
870
|
+
imperative_exceptions = {
|
871
|
+
"ducere" => %w(duc ducite),
|
872
|
+
"dicere" => %w(dic dicite),
|
873
|
+
"facere" => %w(fac facite),
|
874
|
+
"ferre" => %w(fer ferte),
|
875
|
+
"nolere" => %w(nolo nolite)
|
876
|
+
}
|
877
|
+
|
878
|
+
# Exceptional imperatives. If we have one, return it straight away.
|
879
|
+
if imperative_exceptions.has_key?(@pres_act_inf)
|
880
|
+
return Linguistics::Latin::Verb::ImperativeBlock.new(
|
881
|
+
imperative_exceptions[@pres_act_inf])
|
882
|
+
end
|
883
|
+
|
884
|
+
# Therefore, let us assume that we are dealing with a standard verb
|
885
|
+
# with standard imperatives. Accordingly, we will create an
|
886
|
+
# ImperativeBlock.
|
887
|
+
|
888
|
+
return Linguistics::Latin::Verb::ImperativeBlock.new @stem, @pres_act_inf
|
889
|
+
end
|
890
|
+
|
891
|
+
##
|
892
|
+
#
|
893
|
+
# === DESCRIPTION
|
894
|
+
#
|
895
|
+
# Used for handling verb states that are compounds like _amatus,
|
896
|
+
# amata, amatum sum_ and converting them to amati, amatae, amata,
|
897
|
+
# (sumus|estis|sunt).
|
898
|
+
#
|
899
|
+
# === ARGUMENTS
|
900
|
+
#
|
901
|
+
# +x:+ :: A string that looks like --us, --a, --um
|
902
|
+
# This method mutates those singular endings to plural forms
|
903
|
+
#
|
904
|
+
# === RETURNS
|
905
|
+
#
|
906
|
+
# Altered string
|
907
|
+
#
|
908
|
+
# === EXAMPLE
|
909
|
+
#
|
910
|
+
# pluralize_participial_listing(qq/amatus, amata, amatum/) #=>
|
911
|
+
# amatī, amatae, amata
|
912
|
+
#
|
913
|
+
##
|
914
|
+
def pluralize_participial_listing(x)
|
915
|
+
x.sub!(/us,/, 'ī,' )
|
916
|
+
x.sub!(/a,/, 'ae,')
|
917
|
+
x.sub!(/um.*$/, 'a' )
|
918
|
+
end
|
919
|
+
|
920
|
+
##
|
921
|
+
#
|
922
|
+
# === DESCRIPTION
|
923
|
+
#
|
924
|
+
# Used for turning a participial form --um into --us, --a, --um
|
925
|
+
#
|
926
|
+
# === ARGUMENTS
|
927
|
+
#
|
928
|
+
# +s:+ :: --um
|
929
|
+
#
|
930
|
+
# === RETURNS
|
931
|
+
#
|
932
|
+
# Altered string
|
933
|
+
#
|
934
|
+
# === EXAMPLE
|
935
|
+
#
|
936
|
+
# triplicate_and_genderize("amatum") #=> amatus, amata, amatum
|
937
|
+
#
|
938
|
+
##
|
939
|
+
def triplicate_and_genderize(s)
|
940
|
+
stem = s.sub(/^(.*)um$/,"\\1")
|
941
|
+
[ stem + 'us',
|
942
|
+
stem + 'a',
|
943
|
+
s
|
944
|
+
].join(', ')
|
945
|
+
end
|
946
|
+
end
|
947
|
+
end
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|