glossa 1.0.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.
- checksums.yaml +7 -0
- data/glossa.rb +571 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 692941c14d218ff50b931d210bd75aa17f12e322
|
4
|
+
data.tar.gz: 5e421adb5e9e08d1bfb4187973665da6daff4000
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 41274201912b958cfd6c68ea4770c1d944298ddf17ab8beb516135bb7327100cc500dd6940c9e9f97fb100082dc8d904773b903ddc8f30dfb0763e272c10c625
|
7
|
+
data.tar.gz: 5df005c86110b66b589599b7ffe23513fadb3421d5724aa439b418bd898c27f52ba6571b4033cd13cbd5ea00842130d5b018fb5e4c9f02afb1c5d8a00ac00aef
|
data/glossa.rb
ADDED
@@ -0,0 +1,571 @@
|
|
1
|
+
# TODO: Import and export as json methods for a language
|
2
|
+
module Glossa
|
3
|
+
DEFAULT_ORTHO = {
|
4
|
+
'ʃ' => 'sh',
|
5
|
+
'ʒ' => 'zh',
|
6
|
+
'ʧ' => 'ch',
|
7
|
+
'ʤ' => 'j',
|
8
|
+
'ŋ' => 'ng',
|
9
|
+
'j' => 'y',
|
10
|
+
'x' => 'kh',
|
11
|
+
'ɣ' => 'gh',
|
12
|
+
'ʔ' => '‘',
|
13
|
+
'A' => "á",
|
14
|
+
'E' => "é",
|
15
|
+
'I' => "í",
|
16
|
+
'O' => "ó",
|
17
|
+
'U' => "ú"
|
18
|
+
}
|
19
|
+
|
20
|
+
C_ORTH_SETS = [
|
21
|
+
{
|
22
|
+
:name => "Default",
|
23
|
+
:orth => {}
|
24
|
+
},
|
25
|
+
{
|
26
|
+
:name => "Slavic",
|
27
|
+
:orth => {
|
28
|
+
'ʃ' => 'š',
|
29
|
+
'ʒ' => 'ž',
|
30
|
+
'ʧ' => 'č',
|
31
|
+
'ʤ' => 'ǧ',
|
32
|
+
'j' => 'j'
|
33
|
+
}
|
34
|
+
},
|
35
|
+
{
|
36
|
+
:name => "German",
|
37
|
+
:orth => {
|
38
|
+
'ʃ' => 'sch',
|
39
|
+
'ʒ' => 'zh',
|
40
|
+
'ʧ' => 'tsch',
|
41
|
+
'ʤ' => 'dz',
|
42
|
+
'j' => 'j',
|
43
|
+
'x' => 'ch'
|
44
|
+
}
|
45
|
+
},
|
46
|
+
{
|
47
|
+
:name => "French",
|
48
|
+
:orth => {
|
49
|
+
'ʃ' => 'ch',
|
50
|
+
'ʒ' => 'j',
|
51
|
+
'ʧ' => 'tch',
|
52
|
+
'ʤ' => 'dj',
|
53
|
+
'x' => 'kh'
|
54
|
+
}
|
55
|
+
},
|
56
|
+
{
|
57
|
+
:name => "Chinese (pinyin)",
|
58
|
+
:orth => {
|
59
|
+
'ʃ' => 'x',
|
60
|
+
'ʧ' => 'q',
|
61
|
+
'ʤ' => 'j',
|
62
|
+
}
|
63
|
+
}
|
64
|
+
]
|
65
|
+
|
66
|
+
V_ORTH_SETS = [
|
67
|
+
{
|
68
|
+
:name => "Ácutes",
|
69
|
+
:orth => {}
|
70
|
+
},
|
71
|
+
{
|
72
|
+
:name => "Ümlauts",
|
73
|
+
:orth => {
|
74
|
+
"A" => "ä",
|
75
|
+
"E" => "ë",
|
76
|
+
"I" => "ï",
|
77
|
+
"O" => "ö",
|
78
|
+
"U" => "ü"
|
79
|
+
}
|
80
|
+
},
|
81
|
+
{
|
82
|
+
:name => "Welsh",
|
83
|
+
:orth => {
|
84
|
+
"A" => "â",
|
85
|
+
"E" => "ê",
|
86
|
+
"I" => "y",
|
87
|
+
"O" => "ô",
|
88
|
+
"U" => "w"
|
89
|
+
}
|
90
|
+
},
|
91
|
+
{
|
92
|
+
:name => "Diphthongs",
|
93
|
+
:orth => {
|
94
|
+
"A" => "au",
|
95
|
+
"E" => "ei",
|
96
|
+
"I" => "ie",
|
97
|
+
"O" => "ou",
|
98
|
+
"U" => "oo"
|
99
|
+
}
|
100
|
+
},
|
101
|
+
{
|
102
|
+
:name => "Doubles",
|
103
|
+
:orth => {
|
104
|
+
"A" => "aa",
|
105
|
+
"E" => "ee",
|
106
|
+
"I" => "ii",
|
107
|
+
"O" => "oo",
|
108
|
+
"U" => "uu"
|
109
|
+
}
|
110
|
+
}
|
111
|
+
]
|
112
|
+
|
113
|
+
CON_SETS = [
|
114
|
+
{
|
115
|
+
:name => "Minimal",
|
116
|
+
:C => "ptkmnls"
|
117
|
+
},
|
118
|
+
{
|
119
|
+
:name => "English-ish",
|
120
|
+
:C => "ptkbdgmnlrsʃzʒʧ"
|
121
|
+
},
|
122
|
+
{
|
123
|
+
:name => "Pirahã (very simple)",
|
124
|
+
:C => "ptkmnh"
|
125
|
+
},
|
126
|
+
{
|
127
|
+
:name => "Hawaiian-ish",
|
128
|
+
:C => "hklmnpwʔ"
|
129
|
+
},
|
130
|
+
{
|
131
|
+
:name => "Greenlandic-ish",
|
132
|
+
:C => "ptkqvsgrmnŋlj"
|
133
|
+
},
|
134
|
+
{
|
135
|
+
:name => "Arabic-ish",
|
136
|
+
:C => "tksʃdbqɣxmnlrwj"
|
137
|
+
},
|
138
|
+
{
|
139
|
+
:name => "Arabic-lite",
|
140
|
+
:C => "tkdgmnsʃ"
|
141
|
+
},
|
142
|
+
{
|
143
|
+
:name => "English-lite",
|
144
|
+
:C => "ptkbdgmnszʒʧhjw"
|
145
|
+
}
|
146
|
+
]
|
147
|
+
|
148
|
+
S_SETS = [
|
149
|
+
{
|
150
|
+
:name => "Just s",
|
151
|
+
:S => "s"
|
152
|
+
},
|
153
|
+
{
|
154
|
+
:name => "s ʃ",
|
155
|
+
:S => "sʃ"
|
156
|
+
},
|
157
|
+
{
|
158
|
+
:name => "s ʃ f",
|
159
|
+
:S => "sʃf"
|
160
|
+
}
|
161
|
+
]
|
162
|
+
|
163
|
+
L_SETS = [
|
164
|
+
{
|
165
|
+
:name => "r l",
|
166
|
+
:L => "rl"
|
167
|
+
},
|
168
|
+
{
|
169
|
+
:name => "Just r",
|
170
|
+
:L => "r"
|
171
|
+
},
|
172
|
+
{
|
173
|
+
:name => "Just l",
|
174
|
+
:L => "l"
|
175
|
+
},
|
176
|
+
{
|
177
|
+
:name => "w j",
|
178
|
+
:L => "wj"
|
179
|
+
},
|
180
|
+
{
|
181
|
+
:name => "r l w j",
|
182
|
+
:L => "rlwj"
|
183
|
+
}
|
184
|
+
]
|
185
|
+
|
186
|
+
F_SETS = [
|
187
|
+
{
|
188
|
+
:name => "m n",
|
189
|
+
:F => "mn"
|
190
|
+
},
|
191
|
+
{
|
192
|
+
:name => "s k",
|
193
|
+
:F => "sk"
|
194
|
+
},
|
195
|
+
{
|
196
|
+
:name => "m n ŋ",
|
197
|
+
:F => "mnŋ"
|
198
|
+
},
|
199
|
+
{
|
200
|
+
:name => "s ʃ z ʒ",
|
201
|
+
:F => "sʃzʒ"
|
202
|
+
}
|
203
|
+
]
|
204
|
+
|
205
|
+
VOW_SETS = [
|
206
|
+
{
|
207
|
+
:name => "Standard 5-vowel",
|
208
|
+
:V => "aeiou"
|
209
|
+
},
|
210
|
+
{
|
211
|
+
:name => "3-vowel a i u",
|
212
|
+
:V => "aiu"
|
213
|
+
},
|
214
|
+
{
|
215
|
+
:name => "Extra A E I",
|
216
|
+
:V => "aeiouAEI"
|
217
|
+
},
|
218
|
+
{
|
219
|
+
:name => "Extra U",
|
220
|
+
:V => "aeiouU"
|
221
|
+
},
|
222
|
+
{
|
223
|
+
:name => "5-vowel a i u A I",
|
224
|
+
:V => "aiuAI"
|
225
|
+
},
|
226
|
+
{
|
227
|
+
:name => "3-vowel e o u",
|
228
|
+
:V => "eou"
|
229
|
+
},
|
230
|
+
{
|
231
|
+
:name => "Extra A O U",
|
232
|
+
:V => "aeiouAOU"
|
233
|
+
}
|
234
|
+
]
|
235
|
+
|
236
|
+
SYLL_STRUCTS = [
|
237
|
+
"CVC",
|
238
|
+
"CVV?C",
|
239
|
+
"CVVC?", "CVC?", "CV", "VC", "CVF", "C?VC", "CVF?",
|
240
|
+
"CL?VC", "CL?VF", "S?CVC", "S?CVF", "S?CVC?",
|
241
|
+
"C?VF", "C?VC?", "C?VF?", "C?L?VC", "VC",
|
242
|
+
"CVL?C?", "C?VL?C", "C?VLC?"
|
243
|
+
]
|
244
|
+
|
245
|
+
RESTRICT_SETS = [
|
246
|
+
{
|
247
|
+
:name => "None",
|
248
|
+
:res => []
|
249
|
+
},
|
250
|
+
{
|
251
|
+
:name => "Double sounds",
|
252
|
+
:res => [/(.)\1/]
|
253
|
+
},
|
254
|
+
{
|
255
|
+
:name => "Doubles and hard clusters",
|
256
|
+
:res => [/[sʃf][sʃ]/, /(.)\1/, /[rl][rl]/]
|
257
|
+
}
|
258
|
+
]
|
259
|
+
|
260
|
+
class Language
|
261
|
+
attr_accessor :phonemes, :structure, :exponent, :restricts, :cortho, :vortho, :noortho, :nomorph, :nowordpool, :minsyll, :maxsyll, :morphemes, :words, :names, :genitive, :definitive, :joiner, :maxchar, :minchar
|
262
|
+
|
263
|
+
def initialize(random = false, options = nil)
|
264
|
+
if random
|
265
|
+
@phonemes = {
|
266
|
+
"C" => shuffle(choose(CON_SETS, 2)[:C]),
|
267
|
+
"V" => shuffle(choose(VOW_SETS, 2)[:V]),
|
268
|
+
"L" => shuffle(choose(L_SETS, 2)[:L]),
|
269
|
+
"S" => shuffle(choose(S_SETS, 2)[:S]),
|
270
|
+
"F" => shuffle(choose(F_SETS, 2)[:F])
|
271
|
+
}
|
272
|
+
@noortho = false
|
273
|
+
@nomorph = false
|
274
|
+
@nowordpool = false
|
275
|
+
@structure = choose(SYLL_STRUCTS)
|
276
|
+
@exponent = rand(1..3)
|
277
|
+
@restricts = RESTRICT_SETS[2][:res]
|
278
|
+
@cortho = choose(C_ORTH_SETS, 2)[:orth]
|
279
|
+
@vortho = choose(V_ORTH_SETS, 2)[:orth]
|
280
|
+
@morphemes = {}
|
281
|
+
@words = {}
|
282
|
+
@names = []
|
283
|
+
@joiner = choose(' -')
|
284
|
+
@maxchar = rand(10...15)
|
285
|
+
@minchar = rand(3...5)
|
286
|
+
@minsyll = rand(1...3)
|
287
|
+
@maxsyll = rand(@minsyll + 1...7)
|
288
|
+
|
289
|
+
if @structure.length < 3
|
290
|
+
@minsyll += 1;
|
291
|
+
end
|
292
|
+
else
|
293
|
+
options ||= {}
|
294
|
+
@phonemes = options[:phonemes] || {
|
295
|
+
"C" => "ptkmnls",
|
296
|
+
"V" => "aeiou",
|
297
|
+
"S" => "s",
|
298
|
+
"F" => "mn",
|
299
|
+
"L" => "rl"
|
300
|
+
}
|
301
|
+
@structure = options[:structure] || "CVC"
|
302
|
+
@exponent = options[:exponent] || 2
|
303
|
+
@restricts = options[:restricts] || []
|
304
|
+
@cortho = options[:cortho] || {}
|
305
|
+
@vortho = options[:vortho] || {}
|
306
|
+
@noortho = options[:noortho] || true
|
307
|
+
@nomorph = options[:nomorph] || true
|
308
|
+
@nowordpool = options[:nowordpool] || true
|
309
|
+
@minsyll = options[:minsyll] || 1
|
310
|
+
@maxsyll = options[:maxsyll] || 1
|
311
|
+
@morphemes = options[:morphemes] || {}
|
312
|
+
@words = options[:words] || {}
|
313
|
+
@names = options[:names] || []
|
314
|
+
@joiner = options[:joiner] || ' '
|
315
|
+
@maxchar = options[:maxchar] || 12
|
316
|
+
@minchar = options[:minchar] || 5
|
317
|
+
end
|
318
|
+
|
319
|
+
@genitive = get_morpheme('of')
|
320
|
+
@definitive = get_morpheme('the')
|
321
|
+
end
|
322
|
+
|
323
|
+
##
|
324
|
+
# Takes an array and picks a semi-random element, with the first
|
325
|
+
# elements weighted more frequently the the last elements by using
|
326
|
+
# the power of a given exponent.
|
327
|
+
def choose(list, exponent = 1)
|
328
|
+
listIndex = ((rand ** exponent) * list.length).floor
|
329
|
+
|
330
|
+
list[listIndex]
|
331
|
+
end
|
332
|
+
|
333
|
+
##
|
334
|
+
# This is already how rand works? Need to verify
|
335
|
+
def rand_range(lo, hi = nil)
|
336
|
+
if hi.nil?
|
337
|
+
hi = lo
|
338
|
+
lo = 0
|
339
|
+
end
|
340
|
+
|
341
|
+
(rand * (hi - lo) + lo).floor
|
342
|
+
end
|
343
|
+
|
344
|
+
##
|
345
|
+
# Takes an array or string and shuffles it into a random order.
|
346
|
+
def shuffle(list)
|
347
|
+
is_string = list.is_a? String
|
348
|
+
l = is_string ? list.chars : list
|
349
|
+
new_list = l.dup
|
350
|
+
|
351
|
+
i = 0;
|
352
|
+
l.each do |item|
|
353
|
+
tmp = item
|
354
|
+
rand_index = rand(i)
|
355
|
+
new_list[i] = new_list[rand_index]
|
356
|
+
new_list[rand_index] = tmp
|
357
|
+
i += 1;
|
358
|
+
end
|
359
|
+
|
360
|
+
if is_string
|
361
|
+
return new_list.join
|
362
|
+
else
|
363
|
+
return new_list
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
##
|
368
|
+
# Takes an array of strings and an optional joiner string
|
369
|
+
# and concatenates them into a single string
|
370
|
+
def join(list, sep = '')
|
371
|
+
return '' if list.length == 0
|
372
|
+
first_word = list.shift
|
373
|
+
list.each do |item|
|
374
|
+
first_word << sep << item
|
375
|
+
end
|
376
|
+
|
377
|
+
first_word
|
378
|
+
end
|
379
|
+
|
380
|
+
##
|
381
|
+
# Takes an array of phonetic syllables, and spells it using the languages orthography
|
382
|
+
def spell(syllables)
|
383
|
+
return syllables if self.noortho
|
384
|
+
s = syllables.chars
|
385
|
+
word = ''
|
386
|
+
s.each do |syllable|
|
387
|
+
if self.cortho[syllable]
|
388
|
+
word << self.cortho[syllable]
|
389
|
+
elsif self.vortho[syllable]
|
390
|
+
word << self.vortho[syllable]
|
391
|
+
elsif DEFAULT_ORTHO[syllable]
|
392
|
+
word << DEFAULT_ORTHO[syllable]
|
393
|
+
else
|
394
|
+
word << syllable
|
395
|
+
end
|
396
|
+
end
|
397
|
+
word
|
398
|
+
end
|
399
|
+
|
400
|
+
##
|
401
|
+
# Creates a spelled (see the spell() method) syllable, according to
|
402
|
+
# the language's syllable structure. It does this by selecting a semi-random
|
403
|
+
# phonetic letter for the appropriate phoneme type in the structure, making sure
|
404
|
+
# that it doesn't conflict with a restricted pattern, and then spells the
|
405
|
+
# phonetic word according to the language's orthography.
|
406
|
+
def make_syllable
|
407
|
+
structure = self.structure.chars
|
408
|
+
while true
|
409
|
+
syll = ''
|
410
|
+
structure.each do |ptype|
|
411
|
+
# If the char is '?', skip with 50% chance to remove last character
|
412
|
+
if ptype == '?'
|
413
|
+
if rand < 0.5
|
414
|
+
syll = syll[0...syll.length - 1]
|
415
|
+
end
|
416
|
+
next
|
417
|
+
end
|
418
|
+
|
419
|
+
syll << choose(self.phonemes[ptype], self.exponent)
|
420
|
+
end
|
421
|
+
bad = false
|
422
|
+
self.restricts.each do |regex|
|
423
|
+
if regex =~ syll
|
424
|
+
bad = true
|
425
|
+
break
|
426
|
+
end
|
427
|
+
end
|
428
|
+
next if bad
|
429
|
+
|
430
|
+
return spell(syll)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
##
|
435
|
+
# The lowest common-denominator "word" that we will store for our language.
|
436
|
+
# Morphemes are the smallest unit of language that has a meaning.
|
437
|
+
# A "morpheme," in this sense, is a unique syllable (spelled according to our orthography)
|
438
|
+
# with a type (key). Whenever a morpheme is created, we store it in the class instance,
|
439
|
+
# so as to make sure we don't create duplicates. Morphemes comprise words.
|
440
|
+
def get_morpheme(key = '')
|
441
|
+
return make_syllable if self.nomorph
|
442
|
+
|
443
|
+
# Use the morphemes we've already made for this kind of word if possible
|
444
|
+
list = self.morphemes[key] || []
|
445
|
+
|
446
|
+
# If a key is not specified, make 10 generic morphemes
|
447
|
+
# otherwise, just make one new one
|
448
|
+
extras = key == '' ? 10 : 1
|
449
|
+
|
450
|
+
while true
|
451
|
+
# As more morphemes are created, there is a
|
452
|
+
# diminishing chance that a new one will be created.
|
453
|
+
n = rand_range(list.length + extras)
|
454
|
+
return list[n] if list[n]
|
455
|
+
|
456
|
+
morph = make_syllable
|
457
|
+
|
458
|
+
# No duplicates!
|
459
|
+
bad = false
|
460
|
+
self.morphemes.each do |k|
|
461
|
+
next if self.morphemes[k].nil?
|
462
|
+
if self.morphemes[k].include? morph
|
463
|
+
bad = true
|
464
|
+
break
|
465
|
+
end
|
466
|
+
end
|
467
|
+
next if bad
|
468
|
+
list << morph
|
469
|
+
self.morphemes[key] = list
|
470
|
+
|
471
|
+
return morph
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
##
|
476
|
+
# Given the min- and max-syllables for our language, create a new
|
477
|
+
# word out of a random number of morphemes.
|
478
|
+
def make_word(key)
|
479
|
+
num_sylls = rand_range(self.minsyll, self.maxsyll + 1)
|
480
|
+
word = ''
|
481
|
+
keys = []
|
482
|
+
|
483
|
+
# If a key is defined, then select one of the syllables
|
484
|
+
# to have a morpheme of that type.
|
485
|
+
keys[rand_range(num_sylls)] = key
|
486
|
+
num_sylls.times { |i| word << get_morpheme(keys[i]) }
|
487
|
+
|
488
|
+
word
|
489
|
+
end
|
490
|
+
|
491
|
+
##
|
492
|
+
# This method has a chance to use an existing word, or create a new
|
493
|
+
# one of the type (key) specified using the make_word method. If a
|
494
|
+
# new word is created, it will make sure that it is not duplicating
|
495
|
+
# an existing word, and then add it to the list of stored words.
|
496
|
+
def get_word(key = '')
|
497
|
+
words = self.words[key] || []
|
498
|
+
extras = key == '' ? 2 : 3
|
499
|
+
|
500
|
+
while true
|
501
|
+
n = rand_range(words.length + extras)
|
502
|
+
existing_word = words[n]
|
503
|
+
return existing_word if existing_word
|
504
|
+
|
505
|
+
new_word = make_word(key)
|
506
|
+
bad = false
|
507
|
+
self.words.each do |word|
|
508
|
+
if word.include? new_word
|
509
|
+
bad = true
|
510
|
+
break
|
511
|
+
end
|
512
|
+
end
|
513
|
+
next if bad
|
514
|
+
words << new_word
|
515
|
+
self.words[key] = words
|
516
|
+
|
517
|
+
return new_word
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
##
|
522
|
+
# A wrapper with some additional logic around the get_word method.
|
523
|
+
# make_name will create a name, using get_word (so the words created
|
524
|
+
# to make up the name will be saved by the specified key), and have
|
525
|
+
# a 50% chance to add an additional word, and potentially the genitive
|
526
|
+
# and definitive words. After checking to make sure that it's an ok size
|
527
|
+
# and isn't already used, it saves and returns the name
|
528
|
+
def make_name(key = '')
|
529
|
+
## If you don't dup these, words will get concatenated onto them during the join process
|
530
|
+
genitive = self.genitive.dup
|
531
|
+
definitive = self.definitive.dup
|
532
|
+
puts self.definitive
|
533
|
+
while true
|
534
|
+
# 50% chance that the name will be a single word, 50% chance that it will be two words combined somehow
|
535
|
+
name = rand < 0.5 ? get_word(key) : nil
|
536
|
+
if name.nil?
|
537
|
+
# 60% chance that each word will use the same key as invoked
|
538
|
+
w1_key = rand < 0.6 ? key : ''
|
539
|
+
w1 = get_word(w1_key).capitalize
|
540
|
+
w2_key = rand < 0.6 ? key : ''
|
541
|
+
w2 = get_word(w2_key).capitalize
|
542
|
+
|
543
|
+
# 50% chance to be joined without the lang's genitive word
|
544
|
+
if rand > 0.5
|
545
|
+
name = join([w1, w2], self.joiner)
|
546
|
+
else
|
547
|
+
name = join([w1, genitive, w2], self.joiner)
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
# 10% to prefix with definitive
|
552
|
+
name = join([definitive, name], self.joiner) if rand < 0.1
|
553
|
+
puts self.definitive
|
554
|
+
next if (name.length < self.minchar) || (name.length > self.maxchar)
|
555
|
+
|
556
|
+
used = false
|
557
|
+
self.names.each do |lang_name|
|
558
|
+
if (name.include? lang_name) || (lang_name.include? name)
|
559
|
+
used = true
|
560
|
+
break
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
next if used
|
565
|
+
|
566
|
+
self.names << name.capitalize
|
567
|
+
return name.capitalize
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: glossa
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jake Franklin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: glossa is a tool for creating simple naming language generators (which
|
14
|
+
can in turn generate names)
|
15
|
+
email: jacob.d.franklin@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- glossa.rb
|
21
|
+
homepage: http://rubygems.org/gems/glossa
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 2.6.8
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: A random naming language generator generator
|
45
|
+
test_files: []
|