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
data/latinverb.rb
DELETED
@@ -1,544 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Latin
|
4
|
-
|
5
|
-
=begin rdoc
|
6
|
-
|
7
|
-
== Description
|
8
|
-
|
9
|
-
LatinVerb is a class for turning a given 4-part string of:
|
10
|
-
|
11
|
-
* active voice, present, first person singular: amō, or amo
|
12
|
-
* present, active infinitive: amāre, or amare
|
13
|
-
* present, perfect, first person singular: amāvī, or amavi
|
14
|
-
* perfect passive participle: amatum, or amatus
|
15
|
-
|
16
|
-
Into a fully-exploded, fully conjugated Latin verb ( like you would see in
|
17
|
-
chart forms on Wikipedia et in locis alteriis.
|
18
|
-
|
19
|
-
These are traditionally given in Wheelock as:
|
20
|
-
<tt>amō, amāre, amāvī, amatum</tt>
|
21
|
-
|
22
|
-
Philosophically, in this class, we keep attributes and methods which are
|
23
|
-
used to define the meta-structure of the verb. The specific verb calls
|
24
|
-
("Give me the present active participles" or "Give me the present tense
|
25
|
-
active indicative class") are handled metaprogrammatically and held
|
26
|
-
in Latin::LatinConjugation.
|
27
|
-
|
28
|
-
=end
|
29
|
-
|
30
|
-
|
31
|
-
class LatinVerb < Latin::LatinWord
|
32
|
-
include Latin::Conjugation
|
33
|
-
include Latin::Display
|
34
|
-
=begin
|
35
|
-
|
36
|
-
Scalar, created during initialization
|
37
|
-
These are iVar's pointing to the “four principal parts” of a Latin
|
38
|
-
verb.
|
39
|
-
|
40
|
-
=end
|
41
|
-
|
42
|
-
attr_reader :first_pers_singular, :pres_act_inf,
|
43
|
-
:first_pers_perf, :pass_perf_part, :conjugation
|
44
|
-
|
45
|
-
=begin
|
46
|
-
|
47
|
-
Conjugation state, set by metapgrogrammatically handling the method
|
48
|
-
call. Latin verbs have voice, mood, tense, number, and person. The
|
49
|
-
:voice, :mood, etc. iVars will trap this. The default mode
|
50
|
-
use case is to return all number / person “nodes” in a given
|
51
|
-
tense. As such, the number and person are not stored here as iVars.
|
52
|
-
|
53
|
-
=end
|
54
|
-
|
55
|
-
attr_reader :voice, :mood, :tense, :number, :person
|
56
|
-
|
57
|
-
=begin
|
58
|
-
|
59
|
-
Here are iVars that are used in calculation of nodes.
|
60
|
-
|
61
|
-
Stem is a place to store the verb stem e.g. amare=>ama, dicere => dic
|
62
|
-
Vector is the original method that's passed. As mentioned above, we
|
63
|
-
take a metaprogrammatic approach to handling method calls to the
|
64
|
-
object. @vector records the method call that is trapped by
|
65
|
-
method_missing?(id,*opts)
|
66
|
-
|
67
|
-
Participal stem is used as the base for forming participles.
|
68
|
-
|
69
|
-
Response is stored. It is a hash
|
70
|
-
with only one pair: the name of the collection accessed, and the block
|
71
|
-
of nodes ( or a single node, if it has been defined in such an
|
72
|
-
explicit fashion )
|
73
|
-
|
74
|
-
Collections is is where the displayable payload is stored.
|
75
|
-
|
76
|
-
=end
|
77
|
-
|
78
|
-
attr_reader :stem, :participial_stem, :vector, :response,
|
79
|
-
:collections
|
80
|
-
|
81
|
-
=begin
|
82
|
-
|
83
|
-
Array
|
84
|
-
|
85
|
-
Four_pp is an aray of the four principal parts ( headers on listings)
|
86
|
-
|
87
|
-
=end
|
88
|
-
|
89
|
-
attr_reader :four_pp
|
90
|
-
|
91
|
-
=begin
|
92
|
-
|
93
|
-
##############################################################################
|
94
|
-
METHOD DECLARATION
|
95
|
-
##############################################################################
|
96
|
-
|
97
|
-
=end
|
98
|
-
|
99
|
-
=begin rdoc
|
100
|
-
|
101
|
-
<b>Arguments</b>: Array containing 4 principal parts
|
102
|
-
|
103
|
-
<b>Attribs Used</b>: N/A
|
104
|
-
|
105
|
-
<b>Attribs Set</b>: @four_pp, @first_pers_singular, @pres_act_inf,
|
106
|
-
@first_pers_perf, @pass_perf_part, @four_pp,
|
107
|
-
@voice_mood_matrix, @stem ( via #calculate_stem)
|
108
|
-
|
109
|
-
*Returns*: Instance of LatinVerb
|
110
|
-
|
111
|
-
*Purpose*: A LatinVerb is created by passing an array of the four principal
|
112
|
-
parts that define a Latin Verb. Typically these are: They are defined in an array:
|
113
|
-
<tt>amō amāre amāvī amatum</tt>.
|
114
|
-
|
115
|
-
=end
|
116
|
-
|
117
|
-
def initialize(*params)
|
118
|
-
|
119
|
-
# Creates an array of LatinWords for each of the passed-in parameters
|
120
|
-
# Each principal part is given its own iVar
|
121
|
-
|
122
|
-
@four_pp = params[0].map { |a_principal_part| Latin::LatinWord.new(a_principal_part) }
|
123
|
-
|
124
|
-
if @four_pp.length != 4
|
125
|
-
deponent_handler if @four_pp[2] =~ /sum$/
|
126
|
-
end
|
127
|
-
|
128
|
-
irregular_handler(@four_pp[1])
|
129
|
-
|
130
|
-
|
131
|
-
@first_pers_singular, @pres_act_inf,
|
132
|
-
@first_pers_perf, @pass_perf_part = @four_pp
|
133
|
-
|
134
|
-
# Create a top-level matrix that defines active_indicative /
|
135
|
-
# passive_indicative, etc.
|
136
|
-
#
|
137
|
-
# ____________
|
138
|
-
# | | X | Y |
|
139
|
-
# | 1 | a | b |
|
140
|
-
# | 2 | c | d |
|
141
|
-
# -------------
|
142
|
-
#
|
143
|
-
# In this case we have “voice by mood”
|
144
|
-
|
145
|
-
@voice_mood_matrix = TenseBlock.new( {
|
146
|
-
:boundaries => 'voice by mood',
|
147
|
-
:voice => %w(Active Passive),
|
148
|
-
:mood => %w(Indicative Subjunctive),
|
149
|
-
:tense => nil,
|
150
|
-
:default_p => lambda {
|
151
|
-
|x,y| "#{x.downcase}_voice_#{y.downcase}_mood"
|
152
|
-
}
|
153
|
-
}
|
154
|
-
)
|
155
|
-
|
156
|
-
# Given the 4 PP's, we can now derive the stem
|
157
|
-
@stem = Latin::LatinWord.new(calculate_stem)
|
158
|
-
|
159
|
-
# Set my conjugation
|
160
|
-
@conjugation = evaluate_conjugation
|
161
|
-
|
162
|
-
# Calculate participal stem
|
163
|
-
@participial_stem = Latin::LatinWord.new(calculate_participial_stem)
|
164
|
-
|
165
|
-
# Where to store things to-be displayed
|
166
|
-
@collections = []
|
167
|
-
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
=begin rdoc
|
172
|
-
|
173
|
-
*Arguments*: Unrecognized method call, optional arguments
|
174
|
-
|
175
|
-
<b>Attribs Used</b>: N/A
|
176
|
-
|
177
|
-
<b>Attribs Set</b>: @vector
|
178
|
-
|
179
|
-
*Returns*: Instance of LatinVerb
|
180
|
-
|
181
|
-
*Purpose*: The method calls to a verb object can vary in over 100 ways, as such, coding that many methods seemed painful. Accordingly, we trap the unknown method call, parse it, and set iVars.
|
182
|
-
|
183
|
-
Having identified the iVars, we are able to call a hash structure
|
184
|
-
containing lambdas to do the appropriate processing based on the “vector”
|
185
|
-
of voice, mood, tense, person, etc.
|
186
|
-
|
187
|
-
=end
|
188
|
-
def method_missing(id, *args)
|
189
|
-
# We expect that method calls will be made to the object in the form:
|
190
|
-
# V.active_voice_indicative_mood_present_tense. Instead of having to
|
191
|
-
# create all these methods, we will look for unknown methods containing
|
192
|
-
# the pattern _voice_
|
193
|
-
|
194
|
-
if id.to_s =~ /_voice_/
|
195
|
-
|
196
|
-
@vector = id.to_s
|
197
|
-
|
198
|
-
# This assignation needs to be done each call to the metaprog.
|
199
|
-
# method because of the event that a verb was called for
|
200
|
-
# a tense vector, and then a node vector. The first instance's
|
201
|
-
# filling in of @number, @person will cause the second call to do
|
202
|
-
# the wrong thing
|
203
|
-
|
204
|
-
@number = @person = nil
|
205
|
-
evaluate_method(id)
|
206
|
-
|
207
|
-
# In the case that the instance has been used before to get
|
208
|
-
# a specific vector, then we want to clear it out
|
209
|
-
@collections=[] if not @person.nil? and not @collections.nil?
|
210
|
-
|
211
|
-
generated_method = [@voice,@mood,@tense].join('_').to_sym
|
212
|
-
|
213
|
-
raise("Method #{generated_method.to_} is not responded to!") unless
|
214
|
-
self.respond_to?(generated_method)
|
215
|
-
|
216
|
-
raise ("FLAMING DETH: pass to handler method returned nothing!") if
|
217
|
-
self.send(generated_method.to_sym).nil?
|
218
|
-
|
219
|
-
|
220
|
-
@collections <<
|
221
|
-
conjoin_nodes_with_labels(
|
222
|
-
self.send(generated_method),
|
223
|
-
TenseBlock.new( {
|
224
|
-
:boundaries => 'numbers by persons',
|
225
|
-
:numbers => %w(Singular Plural),
|
226
|
-
:persons => %w(First Second Third),
|
227
|
-
:tense => 'present',
|
228
|
-
}
|
229
|
-
)
|
230
|
-
)
|
231
|
-
else
|
232
|
-
super(id)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
def to_s
|
237
|
-
display!("\n")
|
238
|
-
end
|
239
|
-
|
240
|
-
def definition_string
|
241
|
-
return @four_pp.join(', ').to_s
|
242
|
-
end
|
243
|
-
=begin
|
244
|
-
|
245
|
-
##############################################################################
|
246
|
-
# PRIVATE METHODS BELOW
|
247
|
-
##############################################################################
|
248
|
-
|
249
|
-
=end
|
250
|
-
private
|
251
|
-
|
252
|
-
=begin rdoc
|
253
|
-
|
254
|
-
*Arguments*: None
|
255
|
-
|
256
|
-
*Attribs Used*: @pres_act_inf
|
257
|
-
|
258
|
-
*Attribs Set*: None
|
259
|
-
|
260
|
-
*Returns*: The “stem” of a Latin Verb
|
261
|
-
|
262
|
-
*Purpose*: Based on the present active infinitive, identify the “stem” and set the @stem iVar.
|
263
|
-
The method also returns the stem value.
|
264
|
-
|
265
|
-
=end
|
266
|
-
|
267
|
-
def calculate_stem
|
268
|
-
# For efficiency, if the iVar @stem is defined, don't go through this structure
|
269
|
-
|
270
|
-
pres_act_inf = @pres_act_inf.to_s
|
271
|
-
|
272
|
-
if pres_act_inf =~ /āre$/
|
273
|
-
return pres_act_inf.gsub(/(.*)āre$/,'\\1ā')
|
274
|
-
end
|
275
|
-
if pres_act_inf =~ /ēre$/
|
276
|
-
return pres_act_inf.gsub(/(.*)ēre$/,'\\1ē')
|
277
|
-
end
|
278
|
-
if pres_act_inf =~ /ere$/
|
279
|
-
if @first_pers_singular =~ /io$/
|
280
|
-
return pres_act_inf.gsub(/(.*)ere$/,'\\1')
|
281
|
-
else
|
282
|
-
return pres_act_inf.gsub(/(.*)ere$/,'\\1')
|
283
|
-
end
|
284
|
-
end
|
285
|
-
if pres_act_inf =~ /īre$/
|
286
|
-
return pres_act_inf.gsub(/(.*)īre$/,'\\1')
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
=begin rdoc
|
291
|
-
|
292
|
-
|
293
|
-
*Arguments*: None
|
294
|
-
|
295
|
-
*Attribs Used*: @pres_act_inf
|
296
|
-
|
297
|
-
*Attribs Set*: @conjugation
|
298
|
-
|
299
|
-
*Returns*: The “stem” of a Latin Verb
|
300
|
-
|
301
|
-
*Purpose*: Based on the present, active infinitive, decide on the conjugation. This method requires that the endings be macron-ized in order to differentiate between _ere_ ( 2nd conjugation ) and _ere_ ( 4th conjugation). It returns the value as a String: <tt>1</tt>, <tt>2</tt>, <tt>3</tt>, <tt>4</tt>, or <tt>3IO</tt> (e.g. <i>duco/ducere</i>)
|
302
|
-
|
303
|
-
=end
|
304
|
-
|
305
|
-
def evaluate_conjugation
|
306
|
-
ending = @pres_act_inf.get_last_three_characters
|
307
|
-
returnValue = nil
|
308
|
-
|
309
|
-
if ending =~ /āre$/
|
310
|
-
returnValue = "1"
|
311
|
-
end
|
312
|
-
|
313
|
-
if ending =~ /ēre$/
|
314
|
-
returnValue = "2"
|
315
|
-
end
|
316
|
-
|
317
|
-
if ending =~ /ere$/
|
318
|
-
if @first_pers_singular.get_last_three_characters =~ /iō$/
|
319
|
-
returnValue = "3IO"
|
320
|
-
else
|
321
|
-
returnValue = "3"
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
if ending =~ /īre$/
|
326
|
-
returnValue = "4"
|
327
|
-
end
|
328
|
-
|
329
|
-
return returnValue
|
330
|
-
end
|
331
|
-
|
332
|
-
=begin rdoc
|
333
|
-
|
334
|
-
Calculate the participial stem, used in forming participles.
|
335
|
-
|
336
|
-
=end
|
337
|
-
|
338
|
-
def calculate_participial_stem
|
339
|
-
raise("@pres_act_inf was nil!") if
|
340
|
-
@pres_act_inf.nil? or @first_pers_singular.nil?
|
341
|
-
|
342
|
-
if @pres_act_inf.to_s =~ /(.*ā)re$/
|
343
|
-
return $1
|
344
|
-
end
|
345
|
-
|
346
|
-
if @pres_act_inf.to_s =~ /(.*ē)re$/
|
347
|
-
return $1
|
348
|
-
end
|
349
|
-
|
350
|
-
if @pres_act_inf.to_s =~ /(.*)ere$/
|
351
|
-
match=$1
|
352
|
-
if @first_pers_singular =~ /iō/
|
353
|
-
return match + "iē"
|
354
|
-
else
|
355
|
-
return match + "e"
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
if @pres_act_inf.to_s =~ /(.*)īre$/
|
360
|
-
return $1 + "iē"
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
|
365
|
-
=begin
|
366
|
-
|
367
|
-
This is used to print out a full vector's nodes. The value
|
368
|
-
of @vector is used as a title. The nodes that were produced
|
369
|
-
by means of the lambda are then printed out.
|
370
|
-
|
371
|
-
=end
|
372
|
-
|
373
|
-
def conjoin_nodes_with_labels(nodes,labels)
|
374
|
-
raise "conjoin_nodes failed to receieve a node or label set" if
|
375
|
-
nodes.nil? or labels.nil?
|
376
|
-
paired_node_array=[]
|
377
|
-
|
378
|
-
0.upto(labels.length-1) do |i|
|
379
|
-
paired_node_array.push(Latin::LatinNode.new(labels.matrix[i],
|
380
|
-
nodes[i], {:displayable => 'valuesonly'}) )
|
381
|
-
end
|
382
|
-
|
383
|
-
tense_label = @vector.capitalize!.split(/_/).join(' ')
|
384
|
-
|
385
|
-
full_tense = Latin::LatinTense.new(tense_label, paired_node_array)
|
386
|
-
|
387
|
-
if @person.nil? and @number.nil? # For handling ...present_tense
|
388
|
-
return full_tense
|
389
|
-
elsif @number.nil? and not @person.nil? # number not defined; person yes
|
390
|
-
|
391
|
-
# Find the methods that match the parameter that we were given
|
392
|
-
matching_methods =
|
393
|
-
full_tense.verb_methods.map {|x| x if x =~ /#{@person}/}.compact!
|
394
|
-
|
395
|
-
# Call those methods and store the result to an array
|
396
|
-
ambiguous_results =
|
397
|
-
matching_methods.map{|aMethod| full_tense.send(aMethod.to_sym)}
|
398
|
-
|
399
|
-
# Return it
|
400
|
-
return ambiguous_results.join(", ")
|
401
|
-
elsif not @number.nil? and @person.nil?
|
402
|
-
# This guy is really just the inverse of the above.
|
403
|
-
|
404
|
-
# Find the methods that match the parameter that we were given
|
405
|
-
matching_methods =
|
406
|
-
full_tense.verb_methods.map {|x| x if x =~ /#{@number}/}.compact!
|
407
|
-
|
408
|
-
# Call those methods and store the result to an array
|
409
|
-
ambiguous_results =
|
410
|
-
matching_methods.map{|aMethod| full_tense.send(aMethod.to_sym)}
|
411
|
-
|
412
|
-
# Return it
|
413
|
-
return ambiguous_results.join(", ")
|
414
|
-
|
415
|
-
elsif not @number.nil? and not @person.nil? # fully specified node
|
416
|
-
locate_string = [@number,'number',@person,'person',].join('_')
|
417
|
-
return full_tense.send(locate_string.to_sym)
|
418
|
-
end
|
419
|
-
|
420
|
-
end
|
421
|
-
|
422
|
-
# This method is used internally to evaluate a method call that looks like
|
423
|
-
# a request for a conjugation. The first descriptor pair is chopped off
|
424
|
-
# from the given 'name' and the rest is held. The given is sent through
|
425
|
-
# is recognized? where, if valid, an iVar is set.
|
426
|
-
#
|
427
|
-
# e.g. active_voice performs @voice=active
|
428
|
-
#
|
429
|
-
# Failure to successfully classify raises an exception
|
430
|
-
#
|
431
|
-
# If there is anything left in 'rest', then the function is recursively
|
432
|
-
# called with 'rest'.
|
433
|
-
#
|
434
|
-
|
435
|
-
def evaluate_method(name)
|
436
|
-
command = name.to_s.match(/(\w+?_){2}/).to_s
|
437
|
-
rest = name.to_s[command.to_s.length..name.to_s.length]
|
438
|
-
|
439
|
-
# If you're at the last term, command does not get loaded
|
440
|
-
# but rest stays the same.
|
441
|
-
if command !~ /\w/ and name == rest
|
442
|
-
command = rest
|
443
|
-
rest = nil
|
444
|
-
end
|
445
|
-
|
446
|
-
# We've reached the end
|
447
|
-
return if command !~ /\w/ and rest !~ /\w/
|
448
|
-
|
449
|
-
# Recurse
|
450
|
-
evaluate_method(rest) if is_recognized?(command)
|
451
|
-
|
452
|
-
end
|
453
|
-
|
454
|
-
# Given a string of the form "active_voice" ( or a "value/term" pair )
|
455
|
-
# test its validity by Object.send(term.to_sym, value).
|
456
|
-
|
457
|
-
def is_recognized?(datum)
|
458
|
-
value, term = datum.split(/_/)
|
459
|
-
term = "calculate_" + term
|
460
|
-
send(term.to_sym, value)
|
461
|
-
|
462
|
-
# Return true, because the 'send' call did not throw an exception
|
463
|
-
return true
|
464
|
-
end
|
465
|
-
|
466
|
-
# Used to set the voice iVar OR raise an exception
|
467
|
-
def calculate_voice(param)
|
468
|
-
if param =~ /^(active|passive)$/i
|
469
|
-
@voice = param
|
470
|
-
return
|
471
|
-
end
|
472
|
-
raise "Unknown voice: #{param.to_s}, called."
|
473
|
-
end
|
474
|
-
|
475
|
-
# Used to set the voice iVar OR raise an exception
|
476
|
-
def calculate_mood(param)
|
477
|
-
param.gsub!(/\W/, '')
|
478
|
-
if param =~ /(indicative|subjunctive)/i
|
479
|
-
@mood = param.downcase
|
480
|
-
return
|
481
|
-
end
|
482
|
-
raise "Unknown mood: #{param.to_s}, called"
|
483
|
-
end
|
484
|
-
|
485
|
-
# Used to set the voice iVar OR raise an exception
|
486
|
-
def calculate_tense(param)
|
487
|
-
param.downcase!
|
488
|
-
if @mood == "indicative"
|
489
|
-
# All the legitimate moods in the indicative
|
490
|
-
if param == "present" or
|
491
|
-
param == "imperfect" or
|
492
|
-
param == "future" or
|
493
|
-
param == "perfect" or
|
494
|
-
param == "pluperfect" or
|
495
|
-
param == "pastperfect" or
|
496
|
-
param == "futureperfect"
|
497
|
-
@tense = param
|
498
|
-
end
|
499
|
-
elsif @mood == "subjunctive"
|
500
|
-
# All the legitimate moods in the subjunctive
|
501
|
-
if param == "present" or
|
502
|
-
param == "imperfect" or
|
503
|
-
param == "perfect" or
|
504
|
-
param == "pluperfect" or
|
505
|
-
param == "pastperfect"
|
506
|
-
@tense = param
|
507
|
-
end
|
508
|
-
else
|
509
|
-
raise "Tense [#{param}] was found to be invalid."
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
def calculate_person(param)
|
514
|
-
@person = param.downcase
|
515
|
-
end
|
516
|
-
|
517
|
-
def calculate_number(param)
|
518
|
-
@number = param.downcase
|
519
|
-
end
|
520
|
-
|
521
|
-
def deponent_handler
|
522
|
-
raise "Sorry, we do not handle (semi-) deponent verbs at this time. It's on the TODO list, thought!"
|
523
|
-
end
|
524
|
-
|
525
|
-
def irregular_handler(test_infinitive)
|
526
|
-
if %w(esse nōlle).find{|irregular| test_infinitive.to_s == irregular}
|
527
|
-
raise "Sorry, we do not handle irregular verbs at this time. It's on the TODO list, thought!"
|
528
|
-
end
|
529
|
-
end
|
530
|
-
end # ends the class
|
531
|
-
|
532
|
-
=begin rdoc
|
533
|
-
|
534
|
-
== Dependencies
|
535
|
-
|
536
|
-
None
|
537
|
-
|
538
|
-
== Author
|
539
|
-
|
540
|
-
Steven G. Harms, http://www.stevengharms.com
|
541
|
-
|
542
|
-
=end
|
543
|
-
end
|
544
|
-
|
data/lib/LatinIRB.rb
DELETED
@@ -1,172 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'irb'
|
4
|
-
require 'irb/completion'
|
5
|
-
require 'latinverb'
|
6
|
-
require 'latinirb/paradigmatic_verbs'
|
7
|
-
require 'macronconversions'
|
8
|
-
require 'pp'
|
9
|
-
|
10
|
-
# Monkey-patch to change the gets behavior. In the gem, the FileInputMethod
|
11
|
-
# class's 'gets' method always prints out what was read. This should be
|
12
|
-
# suppressed by the IRB class's Context class's ECHO state, but this is not
|
13
|
-
# used, possibly a bug depending on what the semantics of that @echo variable
|
14
|
-
# are meant to mean.
|
15
|
-
|
16
|
-
module IRB
|
17
|
-
class FileInputMethod < InputMethod
|
18
|
-
def gets
|
19
|
-
@io.gets
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module Linguistics
|
25
|
-
module Latin
|
26
|
-
module Util
|
27
|
-
class LatinIRB
|
28
|
-
def self.begin
|
29
|
-
#---
|
30
|
-
#
|
31
|
-
# This method is taken from irb.rb's IRB.start method. I trimmed
|
32
|
-
# out some of the conditional possibilities that I did not want to
|
33
|
-
# handle here (because they're not necessary).
|
34
|
-
#
|
35
|
-
# Run the basic setup script and pull the configuration object
|
36
|
-
# (IRB::Context) back into the present scope. Then we set that
|
37
|
-
# object's options and proceed.
|
38
|
-
#
|
39
|
-
#+++
|
40
|
-
|
41
|
-
IRB.setup(nil)
|
42
|
-
@CONF = IRB.conf
|
43
|
-
|
44
|
-
# This will be the script IRB sources on execution. You can
|
45
|
-
# pre-define variables (@aFirst, etc.) and convenience methods here.
|
46
|
-
|
47
|
-
@CONF[:SCRIPT]="lib/latirb.rb"
|
48
|
-
|
49
|
-
# No, do not tell me what you read in
|
50
|
-
@CONF[:ECHO]=false
|
51
|
-
|
52
|
-
# Nor tell me how it evaluated
|
53
|
-
@CONF[:VERBOSE]=false
|
54
|
-
|
55
|
-
# We need this module
|
56
|
-
@CONF[:LOAD_MODULES]=["latinverb"]
|
57
|
-
|
58
|
-
# Create an irb object that is programmed to (silently, per above)
|
59
|
-
# source a configuration file that ends with a call to 'irb' itself
|
60
|
-
# after defining several instance variables
|
61
|
-
|
62
|
-
irb = IRB::Irb.new(nil, @CONF[:SCRIPT])
|
63
|
-
|
64
|
-
# Create a LatinIRB prompt
|
65
|
-
@CONF[:PROMPT][:LATINIRB] = {
|
66
|
-
:PROMPT_I => "LatinIRB > ",
|
67
|
-
:PROMPT_S => "LatinIRB%l> ",
|
68
|
-
:PROMPT_C => "LatinIRB > ",
|
69
|
-
:PROMPT_N => "LatinIRB ?> ",
|
70
|
-
:RETURN => " => %s \n",
|
71
|
-
:AUTO_INDENT => true
|
72
|
-
}
|
73
|
-
@CONF[:PROMPT_MODE]=:LATINIRB
|
74
|
-
|
75
|
-
# Unless this is set, eval_input will fail. Make sure this is
|
76
|
-
# set.
|
77
|
-
@CONF[:MAIN_CONTEXT] = irb.context
|
78
|
-
|
79
|
-
# This corrects the tab-completion behavior as provided by
|
80
|
-
# irb/completion.rb. In the even that what's tabbed-after matches
|
81
|
-
# the RegExp, it should invoke this process. If the receiver is a
|
82
|
-
# LatinVerb, the full complement of vectors should be provided as
|
83
|
-
# complet-able. IF NOT, then the pairing is passed to the standard
|
84
|
-
# CompletionProc.
|
85
|
-
|
86
|
-
Readline.completion_proc = calculate_completion_proc
|
87
|
-
|
88
|
-
# We have finished the configuration at this point, so now we need
|
89
|
-
# to kick up the REPL after providing preliminary instruction.
|
90
|
-
puts "Beginning a LatinVerb session."
|
91
|
-
|
92
|
-
puts "The following verbs have been made available to this session via latirb.rb:"
|
93
|
-
|
94
|
-
instance_variables.grep(/[a-z]/).each{|x| puts " * #{x}"}
|
95
|
-
|
96
|
-
puts "Tab-completion of the conjugation \"vectors\" is supported."
|
97
|
-
|
98
|
-
trap("SIGINT") do
|
99
|
-
irb.signal_handle
|
100
|
-
end
|
101
|
-
|
102
|
-
begin
|
103
|
-
catch(:IRB_EXIT) do
|
104
|
-
# Start the REPL
|
105
|
-
irb.eval_input
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
puts "Vale! Come back to LatinIRB soon."
|
110
|
-
end
|
111
|
-
|
112
|
-
##
|
113
|
-
#
|
114
|
-
# Used to override IRB::InputCompletor::select_message for handling
|
115
|
-
# tab-completion of instance variables. Code is largely taken from
|
116
|
-
# that method with the addition of the /^@/ condition. In
|
117
|
-
# IRB::Completor, when an array of matches has been identified, they
|
118
|
-
# are sent as the "candidates" while the "receiver" bears the match
|
119
|
-
# based on the regex of "message."
|
120
|
-
#
|
121
|
-
##
|
122
|
-
|
123
|
-
def self.select_message(receiver, message, candidates)
|
124
|
-
candidates.grep(/^#{message}/).collect do |e|
|
125
|
-
case e
|
126
|
-
when /^[a-zA-Z_]/
|
127
|
-
receiver + "." + e
|
128
|
-
when /^[0-9]/
|
129
|
-
when /^@/
|
130
|
-
e
|
131
|
-
when *Operators
|
132
|
-
#receiver + " " + e
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
##
|
138
|
-
#
|
139
|
-
# As part of the TAB completion, Readline must be provided a
|
140
|
-
# completion proc that will be used to generate the matching results
|
141
|
-
# that will be appended to the line at whose end the TAB key was
|
142
|
-
# struck. This method provides that proc.
|
143
|
-
#
|
144
|
-
##
|
145
|
-
|
146
|
-
def self.calculate_completion_proc
|
147
|
-
proc do |input|
|
148
|
-
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
149
|
-
|
150
|
-
input =~ /^([^."].*)\.([^.]*)$/
|
151
|
-
begin
|
152
|
-
receiver = $1
|
153
|
-
message = Regexp.quote($2)
|
154
|
-
rObj = instance_variable_get(receiver.to_sym)
|
155
|
-
rescue Exception
|
156
|
-
end
|
157
|
-
|
158
|
-
if rObj.class == Linguistics::Latin::Verb::LatinVerb
|
159
|
-
IRB::InputCompletor::select_message(receiver, message, rObj.instance_methods.grep(/^#{message}/))
|
160
|
-
elsif input =~ /^@/
|
161
|
-
# This handles instance variables. input is @someInstanceVariable's @aSomeIn<TAB>
|
162
|
-
self.select_message(input, input, eval("instance_variables", bind).grep(/^@a/))
|
163
|
-
else
|
164
|
-
IRB::InputCompletor::CompletionProc.call input
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|