latinverb 0.2.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +0 -1
  2. data/Gemfile +1 -2
  3. data/README.markdown +54 -240
  4. data/etc/irreg_skel.json +104 -0
  5. data/{latinirb.gemspec → latinverb.gemspec} +4 -4
  6. data/lib/latinverb/chart.rb +94 -0
  7. data/lib/latinverb/version.rb +10 -0
  8. data/lib/latinverb.rb +710 -0
  9. data/lib/linguistics/latin/verb/classification_types.rb +59 -0
  10. data/lib/linguistics/latin/verb/constants.rb +201 -0
  11. data/lib/linguistics/latin/verb/deponent_tense_methods.rb +98 -0
  12. data/lib/linguistics/latin/verb/infinitives.rb +212 -0
  13. data/lib/linguistics/latin/verb/irregulars.rb +4393 -0
  14. data/lib/linguistics/latin/verb/latinverb/auxiliary_classes.rb +208 -0
  15. data/lib/linguistics/latin/verb/latinverb/classmethods.rb +215 -0
  16. data/lib/linguistics/latin/verb/latinverb/data.rb +90 -0
  17. data/lib/linguistics/latin/verb/latinverb/display.rb +23 -0
  18. data/lib/linguistics/latin/verb/latinverb/metaprogramming.rb +79 -0
  19. data/lib/linguistics/latin/verb/latinverb/validation.rb +66 -0
  20. data/lib/linguistics/latin/verb/participles.rb +202 -0
  21. data/lib/linguistics/latin/verb/phonographia.rb +109 -0
  22. data/lib/linguistics/latin/verb/supine.rb +42 -0
  23. data/lib/linguistics/latin/verb/tense_methods.rb +950 -0
  24. data/test/testAmbiguousLookups.rb +30 -0
  25. data/test/testClusterResolution.rb +20 -0
  26. data/test/testDataStructures.rb +29 -0
  27. data/test/testDefectSemiImp.rb +111 -0
  28. data/test/testDeponentFirstConjugation.rb +64 -0
  29. data/test/testDeponentFourthConjugation.rb +64 -0
  30. data/test/testDeponentSecondConjugation.rb +64 -0
  31. data/test/testDeponentThirdConjugation.rb +64 -0
  32. data/test/testDeponentThirdIOConjugation.rb +64 -0
  33. data/test/testDeserializeInfinitives.rb +38 -0
  34. data/test/testFirstConjugation.rb +388 -0
  35. data/test/testFourthConjugation.rb +190 -0
  36. data/test/testFreakishVerbs.rb +93 -0
  37. data/test/testImperativeBlock.rb +27 -0
  38. data/test/testIrregularSum.rb +22 -0
  39. data/test/testIrregulars.rb +652 -0
  40. data/test/testLatinVerb.rb +195 -0
  41. data/test/testMacronRules.rb +19 -0
  42. data/test/testSecondConjugation.rb +189 -0
  43. data/test/testThirdConjugation.rb +190 -0
  44. data/test/testThirdIOConjugation.rb +190 -0
  45. metadata +70 -18
  46. data/bin/latinirb.rb +0 -7
  47. data/latinverb.rb +0 -544
  48. data/lib/LatinIRB.rb +0 -172
  49. data/lib/latinirb/paradigmatic_verbs.rb +0 -17
  50. data/lib/latinirb/version.rb +0 -10
  51. 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
+