latinverb 0.2.0
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 +11 -0
- data/Gemfile +6 -0
- data/README.markdown +249 -0
- data/Rakefile +14 -0
- data/bin/latinirb.rb +7 -0
- data/latinirb.gemspec +22 -0
- data/latinverb.rb +544 -0
- data/lib/LatinIRB.rb +172 -0
- data/lib/latinirb/paradigmatic_verbs.rb +17 -0
- data/lib/latinirb/version.rb +10 -0
- data/lib/latirb.rb +20 -0
- metadata +67 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,249 @@
|
|
1
|
+
# LatinIRB
|
2
|
+
|
3
|
+
## DESCRIPTION
|
4
|
+
|
5
|
+
LatinIRB is an IRB session in which a user can interact with paradigmatic
|
6
|
+
Latin verbs (`@aFirst`, `@aSecond`, `@aThird`, `@aThirdIO`, `@aFourth`) as
|
7
|
+
calculated heuristically by the LatinVerb library.
|
8
|
+
|
9
|
+
The methods of chief interest will be those that are _vectors_ within the
|
10
|
+
LatinVerb parlance i.e. methods that uniquely identify a specific conjugated
|
11
|
+
form of a verb.
|
12
|
+
|
13
|
+
An primary use case would be:
|
14
|
+
|
15
|
+
@aFirst.active\_voice\_indicative\_mood\_present\_tense\_first\_person\_singular\_number #=> amō
|
16
|
+
|
17
|
+
Upon opening the script, the student may play with verbs offered for
|
18
|
+
exploration. These are the standard paradigmatics verbs presented in
|
19
|
+
Wheelock:
|
20
|
+
|
21
|
+
<table>
|
22
|
+
<tr><th>Varible </th> <th>Parts </th> <th> Meaning</th></tr>
|
23
|
+
<tr><td>@aFirst </td> <td>amō amāre amāvī amatum </td> <td> to love / like</td></tr>
|
24
|
+
<tr><td>@aSecond </td> <td>moneō monēre monvī monitum</td> <td> to warn / advise</td></tr>
|
25
|
+
<tr><td>@aThird </td> <td>agō agere ēgī actum </td> <td> to do / lead / undertake</td></tr>
|
26
|
+
<tr><td>@aThirdIO</td> <td>capiō capere cēpī captum </td> <td> to grab / seize</td></tr>
|
27
|
+
<tr><td>@aFourth </td> <td>audiō audīre audīvī auditum</td> <td> to hear</td></tr>
|
28
|
+
</table>
|
29
|
+
|
30
|
+
## INSTANTIATING
|
31
|
+
|
32
|
+
Because LatinVerb attempts to preserve the phonographic data of a Latin verb,
|
33
|
+
the quantity of the vowels, the LatinVerb-definining string _must_ contain the
|
34
|
+
macron data so that the heuristics work. To this end, you may use
|
35
|
+
MacronConversions to convert ASCII TeX-style transliterations of macronized
|
36
|
+
vowels to produce the correct string:
|
37
|
+
|
38
|
+
lv = LatinVerb.new(Text::Latex::Util::Macronconversions.convert('am\={o} am\={a}re am\={a}v\={i} amatum', :mc))
|
39
|
+
lv.active\_voice\_indicative\_mood\_present\_tense\_first\_person\_singular\_number #=> amō
|
40
|
+
|
41
|
+
## VIEWING
|
42
|
+
|
43
|
+
The environment takes advantage of Ruby's UTF-8 support to display the verbs
|
44
|
+
with macrons (notation representing the quantity of the vowels). I recommend
|
45
|
+
that you use urxvt or Apple's Terminal.app for viewing these entries.
|
46
|
+
|
47
|
+
## GENERATING VERBS
|
48
|
+
|
49
|
+
Typically, in the code I have used the macron-ized character because Textmate and my Terminal of choice
|
50
|
+
both understand it.
|
51
|
+
|
52
|
+
LatinVerb.new %w(amō amāre amāvī amatum)
|
53
|
+
|
54
|
+
## EXECUTING METHODS
|
55
|
+
|
56
|
+
Every verb in latin is a "vector" comprised of the voice / mood / tense /
|
57
|
+
number / and person
|
58
|
+
|
59
|
+
### CHART VIEW
|
60
|
+
|
61
|
+
*Currently Unimplemented: 1 June 2011: Implementation underway*
|
62
|
+
|
63
|
+
To view the chart of a verb, use LatinVerb.chart\_display. This is a basic
|
64
|
+
chart that will look familiar to students.
|
65
|
+
|
66
|
+
### SINGULAR VECTOR
|
67
|
+
|
68
|
+
As such methods are of the form
|
69
|
+
|
70
|
+
(active|passive)\_voice\_(indicative|subjunctive)\_mood\_(present|imperfect|perfect|pastperfect|futureperfect|etc.)tense\_first\_person\_singular\_number
|
71
|
+
|
72
|
+
This will return a single value. Where the result is ambiguous (e.g. 'number' is not provided) multiple values are returned.
|
73
|
+
an exhaustive list of options follows below.
|
74
|
+
|
75
|
+
### MULTIPLEX VECTORS
|
76
|
+
|
77
|
+
Several convenience methods exist which load multiple tenses at the same time such as "present system" or "perfect system". These
|
78
|
+
methods load the tenses into the @collections iVar associated with the LatinVerb. This value can be accessed as @collections
|
79
|
+
is shared per attr\_reader
|
80
|
+
|
81
|
+
|
82
|
+
### Comprehensive List of Singular Vectors
|
83
|
+
|
84
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_first\_person\_singular\_number
|
85
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_second\_person\_singular\_number
|
86
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_third\_person\_singular\_number
|
87
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_first\_person\_plural\_number
|
88
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_second\_person\_plural\_number
|
89
|
+
* LatinVerb.active\_voice\_indicative\_mood\_present\_tense\_third\_person\_plural\_number
|
90
|
+
|
91
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_first\_person\_singular\_number
|
92
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_second\_person\_singular\_number
|
93
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_third\_person\_singular\_number
|
94
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_first\_person\_plural\_number
|
95
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_second\_person\_plural\_number
|
96
|
+
* LatinVerb.active\_voice\_indicative\_mood\_imperfect\_tense\_third\_person\_plural\_number
|
97
|
+
|
98
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_first\_person\_singular\_number
|
99
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_second\_person\_singular\_number
|
100
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_third\_person\_singular\_number
|
101
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_first\_person\_plural\_number
|
102
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_second\_person\_plural\_number
|
103
|
+
* LatinVerb.active\_voice\_indicative\_mood\_future\_tense\_third\_person\_plural\_number
|
104
|
+
|
105
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_first\_person\_singular\_number
|
106
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_second\_person\_singular\_number
|
107
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_third\_person\_singular\_number
|
108
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_first\_person\_plural\_number
|
109
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_second\_person\_plural\_number
|
110
|
+
* LatinVerb.active\_voice\_indicative\_mood\_perfect\_tense\_third\_person\_plural\_number
|
111
|
+
|
112
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_first\_person\_singular\_number
|
113
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_second\_person\_singular\_number
|
114
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_third\_person\_singular\_number
|
115
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_first\_person\_plural\_number
|
116
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_second\_person\_plural\_number
|
117
|
+
* LatinVerb.active\_voice\_indicative\_mood\_pastperfect\_tense\_third\_person\_plural\_number
|
118
|
+
|
119
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_first\_person\_singular\_number
|
120
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_second\_person\_singular\_number
|
121
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_third\_person\_singular\_number
|
122
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_first\_person\_plural\_number
|
123
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_second\_person\_plural\_number
|
124
|
+
* LatinVerb.active\_voice\_indicative\_mood\_futureperfect\_tense\_third\_person\_plural\_number
|
125
|
+
|
126
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_first\_person\_singular\_number
|
127
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_second\_person\_singular\_number
|
128
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_third\_person\_singular\_number
|
129
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_first\_person\_plural\_number
|
130
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_second\_person\_plural\_number
|
131
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_present\_tense\_third\_person\_plural\_number
|
132
|
+
|
133
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_first\_person\_singular\_number
|
134
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_second\_person\_singular\_number
|
135
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_third\_person\_singular\_number
|
136
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_first\_person\_plural\_number
|
137
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_second\_person\_plural\_number
|
138
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_imperfect\_tense\_third\_person\_plural\_number
|
139
|
+
|
140
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_first\_person\_singular\_number
|
141
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_second\_person\_singular\_number
|
142
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_third\_person\_singular\_number
|
143
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_first\_person\_plural\_number
|
144
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_second\_person\_plural\_number
|
145
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_future\_tense\_third\_person\_plural\_number
|
146
|
+
|
147
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_first\_person\_singular\_number
|
148
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_second\_person\_singular\_number
|
149
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_third\_person\_singular\_number
|
150
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_first\_person\_plural\_number
|
151
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_second\_person\_plural\_number
|
152
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_perfect\_tense\_third\_person\_plural\_number.to\_s)
|
153
|
+
|
154
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_first\_person\_singular\_number
|
155
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_second\_person\_singular\_number
|
156
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_third\_person\_singular\_number
|
157
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_first\_person\_plural\_number
|
158
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_second\_person\_plural\_number
|
159
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_pastperfect\_tense\_third\_person\_plural\_number.to\_s)
|
160
|
+
|
161
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_first\_person\_singular\_number
|
162
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_second\_person\_singular\_number
|
163
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_third\_person\_singular\_number
|
164
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_first\_person\_plural\_number
|
165
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_second\_person\_plural\_number
|
166
|
+
* LatinVerb.passive\_voice\_indicative\_mood\_futureperfect\_tense\_third\_person\_plural\_number
|
167
|
+
|
168
|
+
|
169
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_first\_person\_singular\_number
|
170
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_second\_person\_singular\_number
|
171
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_third\_person\_singular\_number
|
172
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_first\_person\_plural\_number
|
173
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_second\_person\_plural\_number
|
174
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_present\_tense\_third\_person\_plural\_number
|
175
|
+
|
176
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_first\_person\_singular\_number
|
177
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_second\_person\_singular\_number
|
178
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_third\_person\_singular\_number
|
179
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_first\_person\_plural\_number
|
180
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_second\_person\_plural\_number
|
181
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_imperfect\_tense\_third\_person\_plural\_number
|
182
|
+
|
183
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_first\_person\_singular\_number
|
184
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_second\_person\_singular\_number
|
185
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_third\_person\_singular\_number
|
186
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_first\_person\_plural\_number
|
187
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_second\_person\_plural\_number
|
188
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_perfect\_tense\_third\_person\_plural\_number
|
189
|
+
|
190
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_first\_person\_singular\_number
|
191
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_second\_person\_singular\_number
|
192
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_third\_person\_singular\_number
|
193
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_first\_person\_plural\_number
|
194
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_second\_person\_plural\_number
|
195
|
+
* LatinVerb.active\_voice\_subjunctive\_mood\_pastperfect\_tense\_third\_person\_plural\_number
|
196
|
+
|
197
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_first\_person\_singular\_number
|
198
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_second\_person\_singular\_number
|
199
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_third\_person\_singular\_number
|
200
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_first\_person\_plural\_number
|
201
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_second\_person\_plural\_number
|
202
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_present\_tense\_third\_person\_plural\_number
|
203
|
+
|
204
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_first\_person\_singular\_number
|
205
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_second\_person\_singular\_number
|
206
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_third\_person\_singular\_number
|
207
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_first\_person\_plural\_number
|
208
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_second\_person\_plural\_number
|
209
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_imperfect\_tense\_third\_person\_plural\_number
|
210
|
+
|
211
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_first\_person\_singular\_number
|
212
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_second\_person\_singular\_number
|
213
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_third\_person\_singular\_number
|
214
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_first\_person\_plural\_number
|
215
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_second\_person\_plural\_number
|
216
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_perfect\_tense\_third\_person\_plural\_number
|
217
|
+
|
218
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_first\_person\_singular\_number
|
219
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_second\_person\_singular\_number
|
220
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_third\_person\_singular\_number
|
221
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_first\_person\_plural\_number
|
222
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_second\_person\_plural\_number
|
223
|
+
* LatinVerb.passive\_voice\_subjunctive\_mood\_pastperfect\_tense\_third\_person\_plural\_number
|
224
|
+
|
225
|
+
* LatinVerb.imperatives[0]
|
226
|
+
* LatinVerb.imperatives[1]
|
227
|
+
|
228
|
+
* LatinVerb.present\_active\_participle
|
229
|
+
* LatinVerb.future\_active\_participle
|
230
|
+
* LatinVerb.perfect\_passive\_participle
|
231
|
+
* LatinVerb.future\_passive\_participle
|
232
|
+
|
233
|
+
* LatinVerb.present\_active\_infinitive
|
234
|
+
* LatinVerb.perfect\_active\_infinitive
|
235
|
+
* LatinVerb.future\_active\_infinitive
|
236
|
+
* LatinVerb.present\_passive\_infinitive
|
237
|
+
* LatinVerb.perfect\_passive\_infinitive)
|
238
|
+
|
239
|
+
## AUTHOR
|
240
|
+
|
241
|
+
Steven G. Harms (http://stevengharms.com)
|
242
|
+
|
243
|
+
## THANKS
|
244
|
+
|
245
|
+
Thanks to the Austin Ruby coders group who answered questions that helped me put this all together. Thanks also
|
246
|
+
to the Reject^{2} conference at the Lone Star Ruby Conference 2008 who helped me think through some of the
|
247
|
+
metaprogrammatic approaches. Thanks to Professor James Burleson of Austin Community College who insisted,
|
248
|
+
old-style, of a mastery of the rote basics of Latin. Thanks also to Lauren Roth ( http://www.laurennroth.com)
|
249
|
+
for her support and encouragement and understanding of my pre-dawn hack sessions.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require "rake/rdoctask"
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
# Generate documentation
|
7
|
+
Rake::RDocTask.new do |rd|
|
8
|
+
rd.rdoc_files.include("lib/**/*.rb")
|
9
|
+
rd.rdoc_dir = "rdoc"
|
10
|
+
end
|
11
|
+
|
12
|
+
#Added to get testing working
|
13
|
+
require 'rake/testtask'
|
14
|
+
Rake::TestTask.new(:test)
|
data/bin/latinirb.rb
ADDED
data/latinirb.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "latinirb/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "latinverb"
|
7
|
+
s.version = Linguistics::Latin::Util::LatinIRB::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Steven G. Harms"]
|
10
|
+
s.email = ["steven.harms@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/latinverb"
|
12
|
+
s.summary = %q{Gem designed to explore verbs created by LatinVerb}
|
13
|
+
s.description = %q{This gem takes initial data describing a LatinVerb and allows this is be instantiated into an IRB session. Here the verb can be queried or displayed.}
|
14
|
+
|
15
|
+
|
16
|
+
s.rubyforge_project = "latinverb"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
data/latinverb.rb
ADDED
@@ -0,0 +1,544 @@
|
|
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
ADDED
@@ -0,0 +1,172 @@
|
|
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
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'macronconversions'
|
4
|
+
|
5
|
+
module Linguistics
|
6
|
+
module Latin
|
7
|
+
module Util
|
8
|
+
class LatinIRB
|
9
|
+
@aFirst = Linguistics::Latin::Verb::LatinVerb.new Text::Latex::Util::Macronconversions.convert('am\={o} am\={a}re am\={a}v\={\i} amatum', 'mc')
|
10
|
+
@aSecond = Linguistics::Latin::Verb::LatinVerb.new %q(moneō monēre monvī monitum)
|
11
|
+
@aThird = Linguistics::Latin::Verb::LatinVerb.new %q(agō agere ēgī actum)
|
12
|
+
@aThirdIO = Linguistics::Latin::Verb::LatinVerb.new %q(capiō capere cēpī captum)
|
13
|
+
@aFourth = Linguistics::Latin::Verb::LatinVerb.new %q(audiō audīre audīvī auditum)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/latirb.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# Basic definitions
|
3
|
+
@aFirst = Linguistics::Latin::Verb::LatinVerb.new %q(amō amāre amāvī amatum)
|
4
|
+
@aSecond = Linguistics::Latin::Verb::LatinVerb.new %q(moneō monēre monvī monitum)
|
5
|
+
@aThird = Linguistics::Latin::Verb::LatinVerb.new %q(agō agere ēgī actum)
|
6
|
+
@aThirdIO = Linguistics::Latin::Verb::LatinVerb.new %q(capiō capere cēpī captum)
|
7
|
+
@aFourth = Linguistics::Latin::Verb::LatinVerb.new %q(audiō audīre audīvī auditum)
|
8
|
+
|
9
|
+
# It's handy to have these two methods defined here for simple tests of the
|
10
|
+
# code and demonstrations.
|
11
|
+
|
12
|
+
def j
|
13
|
+
puts @aFirst.active_voice_indicative_mood_present_tense_first_person_singular_number
|
14
|
+
end
|
15
|
+
def b(f)
|
16
|
+
puts f.active_voice_indicative_mood_present_tense_first_person_singular_number
|
17
|
+
end
|
18
|
+
|
19
|
+
# Start up the REPL
|
20
|
+
irb
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: latinverb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Steven G. Harms
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-06-01 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: This gem takes initial data describing a LatinVerb and allows this is be instantiated into an IRB session. Here the verb can be queried or displayed.
|
18
|
+
email:
|
19
|
+
- steven.harms@gmail.com
|
20
|
+
executables:
|
21
|
+
- latinirb.rb
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- Gemfile
|
29
|
+
- README.markdown
|
30
|
+
- Rakefile
|
31
|
+
- bin/latinirb.rb
|
32
|
+
- latinirb.gemspec
|
33
|
+
- latinverb.rb
|
34
|
+
- lib/LatinIRB.rb
|
35
|
+
- lib/latinirb/paradigmatic_verbs.rb
|
36
|
+
- lib/latinirb/version.rb
|
37
|
+
- lib/latirb.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://rubygems.org/gems/latinverb
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: latinverb
|
62
|
+
rubygems_version: 1.6.2
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Gem designed to explore verbs created by LatinVerb
|
66
|
+
test_files: []
|
67
|
+
|