poefy 0.5.1
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/.gitignore +74 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/LICENSE +13 -0
- data/README.md +522 -0
- data/Rakefile +6 -0
- data/bin/poefy +205 -0
- data/data/emily_dickinson.txt +9942 -0
- data/data/english_as_she_is_spoke.txt +647 -0
- data/data/shakespeare_sonnets.txt +2618 -0
- data/data/spec_test_tiny.txt +12 -0
- data/data/st_therese_of_lisieux.txt +3700 -0
- data/data/whitman_leaves.txt +17815 -0
- data/lib/poefy/conditional_satisfaction.rb +208 -0
- data/lib/poefy/database.rb +252 -0
- data/lib/poefy/generation.rb +268 -0
- data/lib/poefy/handle_error.rb +27 -0
- data/lib/poefy/poefy_gen_base.rb +124 -0
- data/lib/poefy/poetic_forms.rb +330 -0
- data/lib/poefy/self.rb +21 -0
- data/lib/poefy/string_manipulation.rb +81 -0
- data/lib/poefy/version.rb +29 -0
- data/lib/poefy.rb +49 -0
- data/poefy.gemspec +33 -0
- data/spec/poefy_spec.rb +464 -0
- data/spec/spec_helper.rb +9 -0
- metadata +175 -0
@@ -0,0 +1,330 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Description of various poetic forms.
|
6
|
+
# Also holds methods for parsing the form strings.
|
7
|
+
#
|
8
|
+
# All of this is better explained in the README.
|
9
|
+
#
|
10
|
+
### Rhyme strings:
|
11
|
+
# This is the most important argument.
|
12
|
+
# All other form strings are based on this.
|
13
|
+
# Each token represents a line.
|
14
|
+
# (Token examples: 'a', 'b', 'A1', ' ')
|
15
|
+
# Letters indicate rhymes, so all 'a' or 'A' lines have the same rhyme.
|
16
|
+
# (Example, limerick: 'aabba')
|
17
|
+
# Uppercase letter lines will be duplicated exactly.
|
18
|
+
# This is used to create refrain lines.
|
19
|
+
# (Example, rondeau: 'aabba aabR aabbaR')
|
20
|
+
# Numbers after a capital letter indicate which specific line to repeat.
|
21
|
+
# Letters indicate the same rhyme, uppercase or down.
|
22
|
+
# (Example, villanelle: 'A1bA2 abA1 abA2 abA1 abA2 abA1A2'
|
23
|
+
#
|
24
|
+
### Indent strings:
|
25
|
+
# Each character represents a line.
|
26
|
+
# The numbers show how many times to repeat ' ' before each line.
|
27
|
+
# Any character that doesn't map to an integer defaults to 0.
|
28
|
+
# So '0011000101' and '0011 001 1' are the same.
|
29
|
+
#
|
30
|
+
### Syllable strings:
|
31
|
+
# '10'
|
32
|
+
# '9,10,11'
|
33
|
+
# '[8,8,5,5,8]'
|
34
|
+
# '[[8,9],[8,9],[4,5,6],[4,5,6],[8,9]]'
|
35
|
+
# '{1:8,2:8,3:5,4:5,5:8}'
|
36
|
+
# '{1:[8,9],2:[8,9],3:[4,5,6],4:[4,5,6],5:[8,9]}'
|
37
|
+
# '{0:[8,9],3:[4,5,6],4:[4,5,6]}'
|
38
|
+
# '{1:8,5:8}'
|
39
|
+
# '{1:8,2:8,3:5,-2:5,-1:8}'
|
40
|
+
#
|
41
|
+
### Regex strings:
|
42
|
+
# '^[A-Z].*$'
|
43
|
+
# '^[^e]*$'
|
44
|
+
# '{1=>/^[A-Z].*$/}'
|
45
|
+
#
|
46
|
+
################################################################################
|
47
|
+
|
48
|
+
module Poefy
|
49
|
+
|
50
|
+
module PoeticForms
|
51
|
+
|
52
|
+
# If the token is an array, then a random sample will be used.
|
53
|
+
POETIC_FORMS = {
|
54
|
+
default: {
|
55
|
+
rhyme: 'a',
|
56
|
+
indent: '0',
|
57
|
+
syllable: ''
|
58
|
+
},
|
59
|
+
rondeau: {
|
60
|
+
rhyme: 'aabba aabR aabbaR',
|
61
|
+
indent: '',
|
62
|
+
syllable: ''
|
63
|
+
},
|
64
|
+
villanelle: {
|
65
|
+
rhyme: 'A1bA2 abA1 abA2 abA1 abA2 abA1A2',
|
66
|
+
indent: '010 001 001 001 001 0011',
|
67
|
+
syllable: ''
|
68
|
+
},
|
69
|
+
ballade: {
|
70
|
+
rhyme: 'ababbcbC ababbcbC ababbcbC bcbC',
|
71
|
+
indent: '',
|
72
|
+
syllable: ''
|
73
|
+
},
|
74
|
+
ballata: {
|
75
|
+
rhyme: ['AbbaA','AbbaAbbaA','AbbaAbbaAbbaA'],
|
76
|
+
indent: '',
|
77
|
+
syllable: ''
|
78
|
+
},
|
79
|
+
sonnet: {
|
80
|
+
rhyme: 'ababcdcdefefgg',
|
81
|
+
indent: '',
|
82
|
+
syllable: ''
|
83
|
+
},
|
84
|
+
petrarchan: {
|
85
|
+
rhyme: ['abbaabbacdecde','abbaabbacdccdc',
|
86
|
+
'abbaabbacddcdd','abbaabbacddece','abbaabbacdcdcd'],
|
87
|
+
indent: ['01100110010010','10001000100100'],
|
88
|
+
syllable: ''
|
89
|
+
},
|
90
|
+
limerick: {
|
91
|
+
rhyme: 'aabba',
|
92
|
+
indent: '',
|
93
|
+
syllable: '{1:[8],2:[8],3:[4,5],4:[4,5],5:[8]}'
|
94
|
+
},
|
95
|
+
haiku: {
|
96
|
+
rhyme: 'abc',
|
97
|
+
indent: '',
|
98
|
+
syllable: '[5,7,5]'
|
99
|
+
},
|
100
|
+
common: {
|
101
|
+
rhyme: 'abcb',
|
102
|
+
indent: '0101',
|
103
|
+
syllable: '[8,6,8,6]'
|
104
|
+
},
|
105
|
+
ballad: {
|
106
|
+
rhyme: 'abab',
|
107
|
+
indent: '0101',
|
108
|
+
syllable: '[8,6,8,6]'
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
# Create a regex specification for acrostics.
|
113
|
+
# acrostic('unintelligible')
|
114
|
+
# acrostic('unin tell igib le')
|
115
|
+
def acrostic word
|
116
|
+
output = {}
|
117
|
+
counter = 1
|
118
|
+
word.split('').each do |i|
|
119
|
+
output[counter] = /^[#{i.upcase}#{i.downcase}]/ if i != ' '
|
120
|
+
counter += 1
|
121
|
+
end
|
122
|
+
output
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
# Can the string be converted to integer?
|
128
|
+
def is_int? str
|
129
|
+
!(Integer(str) rescue nil).nil?
|
130
|
+
end
|
131
|
+
|
132
|
+
# Make sure the form name is in the list.
|
133
|
+
def get_valid_form form_name
|
134
|
+
return nil if form_name.nil?
|
135
|
+
POETIC_FORMS[form_name.to_sym] ? form_name.to_sym : nil
|
136
|
+
end
|
137
|
+
|
138
|
+
# Get full form, from either the user-specified options,
|
139
|
+
# or the default poetic form.
|
140
|
+
def poetic_form_full poetic_form = @poetic_form
|
141
|
+
rhyme = get_poetic_form_token :rhyme, poetic_form
|
142
|
+
indent = get_poetic_form_token :indent, poetic_form
|
143
|
+
syllable = get_poetic_form_token :syllable, poetic_form
|
144
|
+
regex = get_poetic_form_token :regex, poetic_form
|
145
|
+
poetic_form[:rhyme] = rhyme
|
146
|
+
poetic_form[:indent] = indent if indent != ''
|
147
|
+
poetic_form[:syllable] = syllable if syllable != ''
|
148
|
+
poetic_form[:regex] = regex if regex
|
149
|
+
poetic_form
|
150
|
+
end
|
151
|
+
|
152
|
+
# If the token is specified in the hash, return it,
|
153
|
+
# else get the token for the named form.
|
154
|
+
def get_poetic_form_rhyme poetic_form = @poetic_form
|
155
|
+
get_poetic_form_token :rhyme, poetic_form
|
156
|
+
end
|
157
|
+
def get_poetic_form_indent poetic_form = @poetic_form
|
158
|
+
get_poetic_form_token :indent, poetic_form
|
159
|
+
end
|
160
|
+
def get_poetic_form_token token, poetic_form = @poetic_form
|
161
|
+
if poetic_form.empty?
|
162
|
+
' '
|
163
|
+
elsif poetic_form[token]
|
164
|
+
poetic_form[token]
|
165
|
+
elsif poetic_form[:form].nil?
|
166
|
+
' '
|
167
|
+
elsif POETIC_FORMS[poetic_form[:form].to_sym].nil?
|
168
|
+
' '
|
169
|
+
else
|
170
|
+
token = POETIC_FORMS[poetic_form[:form].to_sym][token]
|
171
|
+
token = token.is_a?(Array) ? token.sample : token
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Turn a rhyme format string into a usable array of tokens.
|
176
|
+
# Example formats:
|
177
|
+
# sonnet_form = 'abab cdcd efef gg'
|
178
|
+
# villanelle_form = 'A1bA2 abA1 abA2 abA1 abA2 abA1A2'
|
179
|
+
def tokenise_rhyme rhyme_string
|
180
|
+
return rhyme_string if rhyme_string.is_a? Array
|
181
|
+
|
182
|
+
tokens = []
|
183
|
+
buffer = ''
|
184
|
+
rhyme_string.split('').each do |char|
|
185
|
+
if !numeric?(char) and buffer != ''
|
186
|
+
tokens << buffer
|
187
|
+
buffer = ''
|
188
|
+
end
|
189
|
+
buffer += char
|
190
|
+
end
|
191
|
+
tokens << buffer
|
192
|
+
|
193
|
+
# Handle invalid tokens.
|
194
|
+
# ["a1"] ["1"] ["1122"] [" 1"] [" 11"] [":1"]
|
195
|
+
boolean_array = tokens.map do |i|
|
196
|
+
keep = i.gsub(/[^A-Z,0-9]/,'')
|
197
|
+
(keep == '' or !is_int?(keep) or !is_int?(keep))
|
198
|
+
end
|
199
|
+
valid = boolean_array.reduce{ |sum, i| sum && i }
|
200
|
+
if !valid
|
201
|
+
return handle_error 'ERROR: Rhyme string is not valid', []
|
202
|
+
end
|
203
|
+
tokens = [' '] if tokens == ['']
|
204
|
+
tokens
|
205
|
+
end
|
206
|
+
|
207
|
+
# Indent an array of lines using a string of numbers.
|
208
|
+
def do_indent lines, str
|
209
|
+
return lines if str.nil? or lines.nil? or lines.empty?
|
210
|
+
|
211
|
+
# Convert the indent string into an array.
|
212
|
+
indent_arr = (str + '0' * lines.length).split('')
|
213
|
+
indent_arr = indent_arr.each_slice(lines.length).to_a[0]
|
214
|
+
|
215
|
+
# Convert to integers. Spaces should be zero.
|
216
|
+
indent_arr.map! { |i| Integer(i) rescue 0 }
|
217
|
+
|
218
|
+
# Zip, iterate, and prepend indent.
|
219
|
+
indent_arr.zip(lines).map do |line|
|
220
|
+
' ' * line[0] + (line[1] ? line[1] : '')
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Runs a block of code without warnings.
|
225
|
+
# Used for 'eval' calls.
|
226
|
+
def silence_warnings &block
|
227
|
+
warn_level = $VERBOSE
|
228
|
+
$VERBOSE = nil
|
229
|
+
result = block.call
|
230
|
+
$VERBOSE = warn_level
|
231
|
+
result
|
232
|
+
end
|
233
|
+
|
234
|
+
# Sort by keys, to make JSON more human-readable.
|
235
|
+
def sort_hash input
|
236
|
+
output = {}
|
237
|
+
input.keys.sort.each do |k|
|
238
|
+
output[k] = input[k]
|
239
|
+
end
|
240
|
+
output
|
241
|
+
end
|
242
|
+
|
243
|
+
# '10'
|
244
|
+
# '9,10,11'
|
245
|
+
# '[8,8,5,5,8]'
|
246
|
+
# '[[8,9],[8,9],[4,5,6],[4,5,6],[8,9]]'
|
247
|
+
# '{1:8,2:8,3:5,4:5,5:8}'
|
248
|
+
# '{1:[8,9],2:[8,9],3:[4,5,6],4:[4,5,6],5:[8,9]}'
|
249
|
+
# '{0:[8,9],3:[4,5,6],4:[4,5,6]}'
|
250
|
+
# '{1:8,5:8}'
|
251
|
+
# '{1:8,2:8,3:5,-2:5,-1:8}'
|
252
|
+
# Uses #eval, so pretty likely to mess up big time on error.
|
253
|
+
# Use the rhyme string as base for the number of lines in total.
|
254
|
+
def transform_string_syllable input, rhyme
|
255
|
+
return input if input.is_a? Hash
|
256
|
+
input = input.to_s
|
257
|
+
transform_string_to_hash :syllable, input.gsub(':','=>'), rhyme, 0
|
258
|
+
end
|
259
|
+
|
260
|
+
# Do the same for regular expression strings.
|
261
|
+
def transform_string_regex input, rhyme
|
262
|
+
transform_string_to_hash :regex, input, rhyme, nil
|
263
|
+
end
|
264
|
+
|
265
|
+
# This should work for both syllable and regex strings.
|
266
|
+
def transform_string_to_hash type, string, rhyme, default
|
267
|
+
return string if string.is_a? Hash
|
268
|
+
return {} if string == ' '
|
269
|
+
|
270
|
+
output = {}
|
271
|
+
line_count = tokenise_rhyme(rhyme).length
|
272
|
+
|
273
|
+
# Figure out datatype.
|
274
|
+
datatype = 'string'
|
275
|
+
datatype = 'array' if !string.is_a?(Regexp) and string[0] == '['
|
276
|
+
datatype = 'hash' if !string.is_a?(Regexp) and string[0] == '{'
|
277
|
+
|
278
|
+
# Convert string to array, and eval the others.
|
279
|
+
if datatype == 'string'
|
280
|
+
|
281
|
+
# Regex cannot be an array, but syllable can.
|
282
|
+
if type == :syllable
|
283
|
+
arr = each_to_int(string.split(','))
|
284
|
+
elsif type == :regex
|
285
|
+
arr = [Regexp.new(string)]
|
286
|
+
end
|
287
|
+
|
288
|
+
# Set this to be the default '0' hash value.
|
289
|
+
arr = arr.first if arr.count == 1
|
290
|
+
output = { 0 => arr }
|
291
|
+
datatype = 'hash'
|
292
|
+
else
|
293
|
+
output = silence_warnings { eval string }
|
294
|
+
end
|
295
|
+
|
296
|
+
# Convert array to positioned hash.
|
297
|
+
if datatype == 'array'
|
298
|
+
output = output.map.with_index do |e, i|
|
299
|
+
[i+1, e]
|
300
|
+
end.to_h
|
301
|
+
end
|
302
|
+
|
303
|
+
# Go through each line and make sure there is a value for each.
|
304
|
+
# Use default if there is no specific value.
|
305
|
+
default_value = output[0] ? output[0] : default
|
306
|
+
(1..line_count).each do |i|
|
307
|
+
output[i] = default_value if output[i].nil?
|
308
|
+
end
|
309
|
+
|
310
|
+
# Handle negative keys.
|
311
|
+
output.keys.each do |k|
|
312
|
+
if k < 0
|
313
|
+
line = line_count + 1 + k
|
314
|
+
output[line] = output[k]
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# Remove keys less than or equal to zero.
|
319
|
+
output.reject!{ |k| k <= 0 }
|
320
|
+
|
321
|
+
# Return sorted hash.
|
322
|
+
# ToDo: Doesn't need to be sorted in final code.
|
323
|
+
sort_hash output
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
################################################################################
|
data/lib/poefy/self.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Class methods for Poefy module.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
module Poefy
|
9
|
+
|
10
|
+
# Array of all '.db' files in /data/.
|
11
|
+
# Do not include databases used for testing.
|
12
|
+
def self.all_databases
|
13
|
+
path = File.expand_path('../../../data', __FILE__)
|
14
|
+
Dir["#{path}/*.db"].map do |i|
|
15
|
+
File.basename(i, '.db')
|
16
|
+
end.reject{ |i| i.start_with?('spec_') }
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
################################################################################
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# A bunch of string manipulation.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require 'ruby_rhymes'
|
9
|
+
require 'wordfilter'
|
10
|
+
|
11
|
+
################################################################################
|
12
|
+
|
13
|
+
module Poefy
|
14
|
+
|
15
|
+
module StringManipulation
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# True if the whole text string can be expressed as Float.
|
20
|
+
def numeric? text
|
21
|
+
Float(text) != nil rescue false
|
22
|
+
end
|
23
|
+
|
24
|
+
# The first word in a text string. Relies on space for whitespace.
|
25
|
+
# Discards any punctuation.
|
26
|
+
def first_word text
|
27
|
+
(text.gsub(/[[:punct:]]/,'').scan(/^[^ ]+/).first rescue '') || ''
|
28
|
+
end
|
29
|
+
|
30
|
+
# Uses 'ruby_rhymes' to find the rhyme key for a text.
|
31
|
+
def get_rhymes text
|
32
|
+
(numeric?(text[-1]) ? [] : text.to_phrase.rhymes.keys) rescue []
|
33
|
+
end
|
34
|
+
|
35
|
+
# The number of syllables in the text.
|
36
|
+
def syllables text
|
37
|
+
text.to_phrase.syllables rescue 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# Final line must close with sentence-end punctuation.
|
41
|
+
def end_the_sentence text
|
42
|
+
if find = text.scan(/[[:punct:]]+$/).first
|
43
|
+
swap = find.tr(',:;-', '.').delete('—–-')
|
44
|
+
text.reverse.sub(find.reverse, swap.reverse).reverse
|
45
|
+
else
|
46
|
+
text += '.'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Does the sentence end with a .!?
|
51
|
+
def has_stop_punctuation? text
|
52
|
+
return false if text.nil?
|
53
|
+
punct = text.scan(/[[:punct:]]+$/).first
|
54
|
+
!!(punct.match(/[\.!?]/) if punct)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Capitalise the first character of a string
|
58
|
+
def capitalize_first text
|
59
|
+
text[0] = text[0].upcase
|
60
|
+
text
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convert each element in an input array to Integer, and raise
|
64
|
+
# an error if the conversion is not possible for any element.
|
65
|
+
def each_to_int input_array, error_to_raise = TypeError
|
66
|
+
output_array = []
|
67
|
+
input_array.each do |elem|
|
68
|
+
begin
|
69
|
+
output_array << Integer(elem)
|
70
|
+
rescue ArgumentError => e
|
71
|
+
raise error_to_raise
|
72
|
+
end
|
73
|
+
end
|
74
|
+
output_array
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
################################################################################
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# The current version number and date.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
module Poefy
|
9
|
+
|
10
|
+
def self.version_number
|
11
|
+
Gem::Version.new VERSION::STRING
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.version_date
|
15
|
+
'2017-05-17'
|
16
|
+
end
|
17
|
+
|
18
|
+
module VERSION
|
19
|
+
MAJOR = 0
|
20
|
+
MINOR = 5
|
21
|
+
TINY = 1
|
22
|
+
PRE = nil
|
23
|
+
|
24
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
################################################################################
|
data/lib/poefy.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Line-based, used only to rearrange lines of text, not create new lines.
|
6
|
+
# Also uses 'wordfilter' to get rid of yucky words.
|
7
|
+
#
|
8
|
+
# https://en.wikipedia.org/wiki/Category:Western_medieval_lyric_forms
|
9
|
+
# https://en.wikipedia.org/wiki/Virelai
|
10
|
+
# https://en.wikipedia.org/wiki/List_of_compositions_by_Guillaume_de_Machaut#Virelais
|
11
|
+
################################################################################
|
12
|
+
|
13
|
+
require 'ruby_rhymes'
|
14
|
+
require 'wordfilter'
|
15
|
+
require 'tempfile'
|
16
|
+
require 'sqlite3'
|
17
|
+
require 'timeout'
|
18
|
+
require 'json'
|
19
|
+
|
20
|
+
require_relative 'poefy/version.rb'
|
21
|
+
require_relative 'poefy/self.rb'
|
22
|
+
require_relative 'poefy/poefy_gen_base.rb'
|
23
|
+
require_relative 'poefy/generation.rb'
|
24
|
+
require_relative 'poefy/poetic_forms.rb'
|
25
|
+
require_relative 'poefy/string_manipulation.rb'
|
26
|
+
require_relative 'poefy/handle_error.rb'
|
27
|
+
require_relative 'poefy/database.rb'
|
28
|
+
require_relative 'poefy/conditional_satisfaction.rb'
|
29
|
+
|
30
|
+
################################################################################
|
31
|
+
|
32
|
+
# Create a database from text lines.
|
33
|
+
# Read the database to generate poetry.
|
34
|
+
module Poefy
|
35
|
+
|
36
|
+
class PoefyGen
|
37
|
+
|
38
|
+
include Poefy::PoefyGenBase
|
39
|
+
include Poefy::Generation
|
40
|
+
include Poefy::PoeticForms
|
41
|
+
include Poefy::StringManipulation
|
42
|
+
include Poefy::ConditionalSatisfaction
|
43
|
+
include Poefy::HandleError
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
################################################################################
|
data/poefy.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Encoding: UTF-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'poefy/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'poefy'
|
9
|
+
s.authors = ['Paul Thompson']
|
10
|
+
s.email = ['nossidge@gmail.com']
|
11
|
+
|
12
|
+
s.summary = %q{Create rhyming poetry by rearranging lines of text}
|
13
|
+
s.description = %q{Create poems from an input text file, by generating and querying a SQLite database describing each line. Poems are created using a template to select lines from the database, according to closing rhyme, syllable count, and regex matching.}
|
14
|
+
s.homepage = 'https://github.com/nossidge/poefy'
|
15
|
+
|
16
|
+
s.version = Poefy.version_number
|
17
|
+
s.date = Poefy.version_date
|
18
|
+
s.license = 'GPL-3.0'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ['lib']
|
24
|
+
s.bindir = 'bin'
|
25
|
+
|
26
|
+
s.add_development_dependency('bundler', '~> 1.13')
|
27
|
+
s.add_development_dependency('rake', '~> 10.0')
|
28
|
+
s.add_development_dependency('rspec', '~> 3.0')
|
29
|
+
|
30
|
+
s.add_runtime_dependency('sqlite3', '~> 1.3', '>= 1.3.13')
|
31
|
+
s.add_runtime_dependency('ruby_rhymes', '~> 0.1', '>= 0.1.2')
|
32
|
+
s.add_runtime_dependency('wordfilter', '~> 0.2', '>= 0.2.6')
|
33
|
+
end
|