poefy 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +46 -0
- data/bin/poefy +6 -1
- data/lib/poefy/conditional_satisfaction.rb +5 -8
- data/lib/poefy/database.rb +20 -23
- data/lib/poefy/generation.rb +75 -20
- data/lib/poefy/poefy_gen_base.rb +12 -10
- data/lib/poefy/poetic_forms.rb +46 -14
- data/lib/poefy/string_manipulation.rb +10 -0
- data/lib/poefy/version.rb +2 -2
- data/spec/poefy_spec.rb +87 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74eb4a29190ce96b7e4c49838738574986803a81
|
4
|
+
data.tar.gz: 80af1c2cbf3ea78fe04d914552e7505be66001d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb486fbdfaec63fbac58598d59fbb1f3e4711bdc3178ef83d8dcad77782543afd65d787466752f003fcd664fc6eaad6552f76370a0afc7089907b6c179b33d51
|
7
|
+
data.tar.gz: f981d141281f73e2d9203a4b568bb32a941c744ad98a1d395738a05630df97212d9f63eabec6d6f63aec505d22c010d9e2524944acde7d348221678955425096
|
data/README.md
CHANGED
@@ -211,6 +211,22 @@ You must also beware of repeated lines (uppercase letters in the rhyme string).
|
|
211
211
|
$ poefy therese rondeau -a'grown ever softer'
|
212
212
|
|
213
213
|
|
214
|
+
#### Option `-A` or `--acrostic_x`
|
215
|
+
|
216
|
+
This does the same as `-a`, but with special workarounds for 'x'. In the case that a line needs to match '^x', it will instead match '^ex' and replace with 'eX'. It will also use indentation to line-up the letters vertically:
|
217
|
+
|
218
|
+
$ poefy whitman -s8 -r abcbdd -A taxman
|
219
|
+
|
220
|
+
````
|
221
|
+
To reason's early paradise,
|
222
|
+
And that death and dismay are great.
|
223
|
+
eXult O shores, and ring O bells!
|
224
|
+
May-be kill'd, unknown to her mate,
|
225
|
+
Around the idea of thee.
|
226
|
+
now, for all you cannot see me?
|
227
|
+
````
|
228
|
+
|
229
|
+
|
214
230
|
#### Option `-p` or `--proper`
|
215
231
|
|
216
232
|
This is used to ensure that the first word in the first line is not 'and but or nor yet', and the final line ends with closing punctuation (full stop, exclamation, or question mark). The default for this is `true`, but you can set it to `false` if necessary, for example if your input lines do not use punctuation.
|
@@ -297,6 +313,36 @@ puts poefy.poem ({ indent: '01012 0012 010112' })
|
|
297
313
|
```
|
298
314
|
|
299
315
|
|
316
|
+
#### Option `transform:`
|
317
|
+
|
318
|
+
An option that is not included in the CLI interface is the `transform` poem option. This is a hash of procs that transform a line somehow.
|
319
|
+
|
320
|
+
For example, to all-caps the 4th and 12th lines:
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
transform_hash = {
|
324
|
+
4 => proc { |line, num, poem| line.upcase },
|
325
|
+
12 => proc { |line, num, poem| line.upcase }
|
326
|
+
}
|
327
|
+
poefy = Poefy::PoefyGen.new 'shakespeare'
|
328
|
+
puts poefy.poem({ form: :sonnet, transform: transform_hash })
|
329
|
+
```
|
330
|
+
|
331
|
+
The key for the hash corresponds to the line of the poem, starting from 1 (not 0). You can use negative keys to specify from the end of the poem. Any key that is not an integer or is out of the array bounds will be ignored.
|
332
|
+
|
333
|
+
If you don't include a hash, then the proc will be applied to each line. So to add line numbers to the whole poem:
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
transform_proc = proc { |line, num, poem| "#{num.to_s.rjust(2)} #{line}" }
|
337
|
+
poefy = Poefy::PoefyGen.new 'shakespeare'
|
338
|
+
puts poefy.poem({ form: :sonnet, transform: transform_proc })
|
339
|
+
```
|
340
|
+
|
341
|
+
The proc arguments `|line, num, poem|` are: the text of the line that is being replaced, the number of the line, and the full poem array as it was before any transformations had occurred.
|
342
|
+
|
343
|
+
The transformations are implemented after the poem has been generated, but before the `indent` has occurred.
|
344
|
+
|
345
|
+
|
300
346
|
## Some tips
|
301
347
|
|
302
348
|
### Make a database from a delimited file
|
data/bin/poefy
CHANGED
@@ -74,10 +74,15 @@ def parse_options
|
|
74
74
|
options[:regex] = s
|
75
75
|
end
|
76
76
|
|
77
|
+
# Options for acrostic poems.
|
77
78
|
opts.on('-a', '--acrostic STRING',
|
78
|
-
"
|
79
|
+
"Generate an acrostic on a certain word") do |s|
|
79
80
|
options[:acrostic] = s
|
80
81
|
end
|
82
|
+
opts.on('-A', '--acrostic_x STRING',
|
83
|
+
"Generate an acrostic with better handling of 'x'") do |s|
|
84
|
+
options[:acrostic_x] = s
|
85
|
+
end
|
81
86
|
|
82
87
|
# Handle proper sentence structure.
|
83
88
|
opts.separator nil
|
@@ -74,12 +74,8 @@ module Poefy
|
|
74
74
|
valid = valid && [*poetic_form[:syllable]].include?(line['syllables'])
|
75
75
|
end
|
76
76
|
if poetic_form[:regex]
|
77
|
-
|
78
|
-
|
79
|
-
valid = valid && !!(line['line'].match(i))
|
80
|
-
end
|
81
|
-
else
|
82
|
-
valid = valid && !!(line['line'].match(poetic_form[:regex]))
|
77
|
+
[*poetic_form[:regex]].each do |i|
|
78
|
+
valid = valid && !!(line['line'].match(i))
|
83
79
|
end
|
84
80
|
end
|
85
81
|
valid
|
@@ -93,9 +89,10 @@ module Poefy
|
|
93
89
|
tokenised_rhyme.each.with_index do |rhyme, index|
|
94
90
|
line_hash = {
|
95
91
|
line: index + 1,
|
96
|
-
rhyme: rhyme,
|
97
|
-
rhyme_letter: rhyme[
|
92
|
+
rhyme: rhyme[:token],
|
93
|
+
rhyme_letter: rhyme[:rhyme_letter]
|
98
94
|
}
|
95
|
+
line_hash[:refrain] = rhyme[:refrain] if rhyme[:refrain]
|
99
96
|
poetic_form.keys.each do |k|
|
100
97
|
if poetic_form[k].is_a? Hash
|
101
98
|
line_hash[k] = poetic_form[k][index + 1]
|
data/lib/poefy/database.rb
CHANGED
@@ -45,30 +45,18 @@ module Poefy
|
|
45
45
|
@db = nil
|
46
46
|
else
|
47
47
|
begin
|
48
|
-
open
|
49
|
-
|
48
|
+
@db = SQLite3::Database.open(@db_file)
|
49
|
+
@db.results_as_hash = true
|
50
50
|
rescue
|
51
51
|
@db = nil
|
52
52
|
return handle_error 'ERROR: Database contains invalid structure'
|
53
53
|
end
|
54
|
+
create_sprocs
|
54
55
|
end
|
55
56
|
end
|
56
57
|
@db
|
57
58
|
end
|
58
59
|
|
59
|
-
# Open the database file.
|
60
|
-
def open
|
61
|
-
@db = SQLite3::Database.open(@db_file)
|
62
|
-
@db.results_as_hash = true
|
63
|
-
|
64
|
-
# Create a REGEX function in SQLite.
|
65
|
-
# http://stackoverflow.com/questions/7302311
|
66
|
-
@db.create_function('regexp', 2) do |func, pattern, expression|
|
67
|
-
regexp = Regexp.new(pattern.to_s, Regexp::IGNORECASE)
|
68
|
-
func.result = expression.to_s.match(regexp) ? 1 : 0
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
60
|
# Close the database file.
|
73
61
|
def close
|
74
62
|
@sproc.each { |k, v| v.close rescue nil }
|
@@ -136,21 +124,30 @@ module Poefy
|
|
136
124
|
end
|
137
125
|
|
138
126
|
# Public interfaces for private stored procedure methods.
|
127
|
+
# Use instance variables to keep a cache of the results.
|
139
128
|
def sproc_rhymes_all! rhyme_count, syllable_min_max = nil
|
140
129
|
db
|
141
|
-
if
|
142
|
-
|
143
|
-
|
144
|
-
|
130
|
+
@rbc = Hash.new { |h,k| h[k] = {} } if @rbc.nil?
|
131
|
+
if @rbc[rhyme_count][syllable_min_max].nil?
|
132
|
+
@rbc[rhyme_count][syllable_min_max] = if syllable_min_max
|
133
|
+
sproc_rhymes_by_count_syllables(rhyme_count, syllable_min_max)
|
134
|
+
else
|
135
|
+
sproc_rhymes_by_count(rhyme_count)
|
136
|
+
end
|
145
137
|
end
|
138
|
+
@rbc[rhyme_count][syllable_min_max].dup
|
146
139
|
end
|
147
140
|
def sproc_lines_all! rhyme, syllable_min_max = nil
|
148
141
|
db
|
149
|
-
if
|
150
|
-
|
151
|
-
|
152
|
-
|
142
|
+
@la = Hash.new { |h,k| h[k] = {} } if @la.nil?
|
143
|
+
if @la[rhyme][syllable_min_max].nil?
|
144
|
+
@la[rhyme][syllable_min_max] = if syllable_min_max
|
145
|
+
sproc_lines_all_syllables(rhyme, syllable_min_max)
|
146
|
+
else
|
147
|
+
sproc_lines_all(rhyme)
|
148
|
+
end
|
153
149
|
end
|
150
|
+
@la[rhyme][syllable_min_max].dup
|
154
151
|
end
|
155
152
|
|
156
153
|
private
|
data/lib/poefy/generation.rb
CHANGED
@@ -24,6 +24,7 @@ module Poefy
|
|
24
24
|
raise ArgumentError, 'Argument must be a hash' unless
|
25
25
|
poetic_form.is_a?(Hash)
|
26
26
|
poetic_form = validate_poetic_form poetic_form
|
27
|
+
poetic_form = @poetic_form.merge poetic_form
|
27
28
|
|
28
29
|
# Make sure the hash contains ':form' or ':rhyme' keys.
|
29
30
|
if !(poetic_form[:form] or poetic_form[:rhyme])
|
@@ -34,7 +35,14 @@ module Poefy
|
|
34
35
|
end
|
35
36
|
|
36
37
|
# Loop until we find a valid poem.
|
37
|
-
|
38
|
+
# There are cases where valid permutations are not able to be
|
39
|
+
# genned on the first try, so keep trying a few more times.
|
40
|
+
output, count_down = nil, 10
|
41
|
+
loop do
|
42
|
+
output = gen_poem_using_conditions poetic_form
|
43
|
+
break if !output.nil? || count_down == 0
|
44
|
+
count_down -= 1
|
45
|
+
end
|
38
46
|
|
39
47
|
# Return nil if poem could not be created.
|
40
48
|
return nil if (output.nil? or output == [] or output == [''])
|
@@ -86,8 +94,20 @@ module Poefy
|
|
86
94
|
return handle_error 'ERROR: Rhyme string is not valid', []
|
87
95
|
end
|
88
96
|
|
97
|
+
# Expand poetic_form[:transform], if there's just one element.
|
98
|
+
if poetic_form[:transform] and !poetic_form[:transform].respond_to?(:each)
|
99
|
+
poetic_form[:transform] = fill_hash poetic_form[:transform],
|
100
|
+
1..tokenised_rhyme.count
|
101
|
+
end
|
102
|
+
|
89
103
|
# Add acrostic to the regex, if necessary.
|
90
|
-
if poetic_form[:
|
104
|
+
if poetic_form[:acrostic_x]
|
105
|
+
acrostic_opts = acrostic_x(poetic_form[:acrostic_x])
|
106
|
+
poetic_form[:regex] =
|
107
|
+
merge_hashes poetic_form[:regex], acrostic_opts[:regex]
|
108
|
+
poetic_form[:transform] =
|
109
|
+
merge_hashes acrostic_opts[:transform], poetic_form[:transform]
|
110
|
+
elsif poetic_form[:acrostic]
|
91
111
|
poetic_form[:regex] =
|
92
112
|
merge_hashes poetic_form[:regex], acrostic(poetic_form[:acrostic])
|
93
113
|
end
|
@@ -148,23 +168,21 @@ module Poefy
|
|
148
168
|
i[:rhyme_letter]
|
149
169
|
end
|
150
170
|
|
151
|
-
# Okay, this is great. But if we're making villanelles we'll need
|
152
|
-
#
|
171
|
+
# Okay, this is great. But if we're making villanelles we'll need to
|
172
|
+
# duplicate refrain lines. So we won't need unique rhymes for those.
|
153
173
|
# So make a distinct set of lines conditions, still grouped by rhyme.
|
154
|
-
# This will be the same as [conditions_by_rhyme], except duplicate
|
155
|
-
# are removed. (
|
174
|
+
# This will be the same as [conditions_by_rhyme], except duplicate
|
175
|
+
# lines are removed. (In string input, these are lines with
|
176
|
+
# capitals and numbers: i.e. A1, B2)
|
156
177
|
# It will keep the condition hash of only the first refrain line.
|
157
178
|
distinct_line_conds = Hash.new { |h,k| h[k] = [] }
|
158
179
|
conditions_by_rhyme.each do |key, values|
|
159
|
-
|
180
|
+
refrains = []
|
160
181
|
values.each do |v|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
distinct_line_conds[key] << v
|
166
|
-
end
|
167
|
-
else
|
182
|
+
if !v[:refrain]
|
183
|
+
distinct_line_conds[key] << v
|
184
|
+
elsif !refrains.include?(v[:refrain])
|
185
|
+
refrains << v[:refrain]
|
168
186
|
distinct_line_conds[key] << v
|
169
187
|
end
|
170
188
|
end
|
@@ -196,6 +214,10 @@ module Poefy
|
|
196
214
|
# words as there are lines to be matched.
|
197
215
|
rhymes = nil
|
198
216
|
|
217
|
+
# If all the lines include a 'regex' condition,
|
218
|
+
# then we can specify to only query for matching lines.
|
219
|
+
regex_all = regex_for_all line_conds
|
220
|
+
|
199
221
|
# If all the lines include a 'syllable' condition,
|
200
222
|
# then we can specify to only query for matching lines.
|
201
223
|
min_max = syllable_min_max line_conds
|
@@ -208,7 +230,7 @@ module Poefy
|
|
208
230
|
# For each rhyme, get all lines and try to sastify all conditions.
|
209
231
|
out = []
|
210
232
|
rhymes.shuffle.each do |rhyme|
|
211
|
-
out = try_rhyme(conditions, rhyme, min_max)
|
233
|
+
out = try_rhyme(conditions, rhyme, min_max, regex_all)
|
212
234
|
break if !out.empty?
|
213
235
|
end
|
214
236
|
if out.empty?
|
@@ -233,14 +255,14 @@ module Poefy
|
|
233
255
|
# Transpose lines to their actual location.
|
234
256
|
poem_lines = []
|
235
257
|
all_lines.each do |line|
|
236
|
-
poem_lines[line['line_number'] - 1] = line['line']
|
258
|
+
poem_lines[line['line_number'] - 1] = line['line'].dup
|
237
259
|
end
|
238
260
|
|
239
261
|
# Go back to the [by_line] array and find all the refrain line nos.
|
240
262
|
refrains = Hash.new { |h,k| h[k] = [] }
|
241
263
|
by_line.reject{ |i| i[:rhyme] == ' ' }.each do |line|
|
242
|
-
if line[:
|
243
|
-
refrains[line[:
|
264
|
+
if line[:refrain]
|
265
|
+
refrains[line[:refrain]] << line[:line]
|
244
266
|
end
|
245
267
|
end
|
246
268
|
refrains.keys.each do |k|
|
@@ -254,14 +276,37 @@ module Poefy
|
|
254
276
|
end
|
255
277
|
end
|
256
278
|
|
257
|
-
|
279
|
+
# Carry out transformations, if necessary.
|
280
|
+
the_poem = poem_lines
|
281
|
+
if poetic_form[:transform]
|
282
|
+
|
283
|
+
# Due to the 'merge_hashes' above, each 'poetic_form[:transform]'
|
284
|
+
# value may contain an array of procs.
|
285
|
+
poetic_form[:transform].each do |key, procs|
|
286
|
+
begin
|
287
|
+
# This is to ensure that e.g. '-2' will access from the end.
|
288
|
+
i = (key > 0) ? key - 1 : key
|
289
|
+
[*procs].each do |proc|
|
290
|
+
the_poem[i] = proc.call(the_poem[i], i + 1, poem_lines).to_s
|
291
|
+
end
|
292
|
+
rescue
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
the_poem
|
258
298
|
end
|
259
299
|
|
260
300
|
# Loop through the rhymes until we find one that works.
|
261
301
|
# (In a reasonable time-frame)
|
262
|
-
def try_rhyme conditions, rhyme, syllable_min_max = nil
|
302
|
+
def try_rhyme conditions, rhyme, syllable_min_max = nil, regex_all = nil
|
263
303
|
output = []
|
264
304
|
lines = @db.sproc_lines_all!(rhyme, syllable_min_max)
|
305
|
+
|
306
|
+
# To reduce the number of permutations, reject lines
|
307
|
+
# that do not match any of the lines regex.
|
308
|
+
lines.reject! { |i| !(i['line'].match(regex_all)) } if regex_all
|
309
|
+
|
265
310
|
begin
|
266
311
|
Timeout::timeout(2) do
|
267
312
|
output = conditional_selection(lines.shuffle, conditions)
|
@@ -288,6 +333,16 @@ module Poefy
|
|
288
333
|
min_max
|
289
334
|
end
|
290
335
|
|
336
|
+
# If every line has a regex, then return a regex union.
|
337
|
+
def regex_for_all line_conds
|
338
|
+
output = nil
|
339
|
+
if line_conds.all?{ |i| i[:regex] }
|
340
|
+
all_regex = line_conds.map{ |i| i[:regex] }
|
341
|
+
output = Regexp.union all_regex.flatten
|
342
|
+
end
|
343
|
+
output
|
344
|
+
end
|
345
|
+
|
291
346
|
end
|
292
347
|
|
293
348
|
end
|
data/lib/poefy/poefy_gen_base.rb
CHANGED
@@ -13,7 +13,7 @@ module Poefy
|
|
13
13
|
|
14
14
|
def initialize db_name, options = {}
|
15
15
|
handle_options options
|
16
|
-
@db = Poefy::Database.new get_database_file(db_name), @console
|
16
|
+
@db = Poefy::Database.new get_database_file(db_name.to_s), @console
|
17
17
|
end
|
18
18
|
|
19
19
|
# Make a database using the given lines.
|
@@ -39,7 +39,7 @@ module Poefy
|
|
39
39
|
def validate_lines input
|
40
40
|
|
41
41
|
# If the input is a file, then read it.
|
42
|
-
lines = File.exists?(input) ? File.read(input) : input
|
42
|
+
lines = File.exists?(input.to_s) ? File.read(input) : input
|
43
43
|
|
44
44
|
# If lines is not an array, assume string and split on newlines.
|
45
45
|
lines = lines.respond_to?(:each) ? lines : lines.split("\n")
|
@@ -78,19 +78,21 @@ module Poefy
|
|
78
78
|
form_string = get_valid_form input[:form]
|
79
79
|
|
80
80
|
# Handle obvious inputs.
|
81
|
-
output[:form]
|
82
|
-
output[:rhyme]
|
83
|
-
output[:indent]
|
84
|
-
output[:syllable]
|
85
|
-
output[:regex]
|
86
|
-
output[:acrostic]
|
81
|
+
output[:form] = form_string if form_string
|
82
|
+
output[:rhyme] = input[:rhyme] if input[:rhyme]
|
83
|
+
output[:indent] = input[:indent] if input[:indent]
|
84
|
+
output[:syllable] = input[:syllable] if input[:syllable]
|
85
|
+
output[:regex] = input[:regex] if input[:regex]
|
86
|
+
output[:acrostic] = input[:acrostic] if input[:acrostic]
|
87
|
+
output[:acrostic_x] = input[:acrostic_x] if input[:acrostic_x]
|
88
|
+
output[:transform] = input[:transform] if input[:transform]
|
87
89
|
|
88
90
|
# Tokenise string to arrays and hashes.
|
89
|
-
rhyme = get_poetic_form_rhyme(output)
|
90
91
|
if output[:rhyme]
|
91
92
|
output[:rhyme] = tokenise_rhyme output[:rhyme]
|
92
93
|
end
|
93
|
-
|
94
|
+
rhyme = get_poetic_form_rhyme(output)
|
95
|
+
if output[:syllable] and rhyme != ' '
|
94
96
|
output[:syllable] = transform_string_syllable output[:syllable], rhyme
|
95
97
|
end
|
96
98
|
if output[:regex]
|
data/lib/poefy/poetic_forms.rb
CHANGED
@@ -82,7 +82,7 @@ module Poefy
|
|
82
82
|
syllable: ''
|
83
83
|
},
|
84
84
|
petrarchan: {
|
85
|
-
rhyme: ['abbaabbacdecde','abbaabbacdccdc',
|
85
|
+
rhyme: ['abbaabbacdecde','abbaabbacdccdc','abbaabbacdcddc',
|
86
86
|
'abbaabbacddcdd','abbaabbacddece','abbaabbacdcdcd'],
|
87
87
|
indent: ['01100110010010','10001000100100'],
|
88
88
|
syllable: ''
|
@@ -120,14 +120,35 @@ module Poefy
|
|
120
120
|
# acrostic('unin tell igib le')
|
121
121
|
def acrostic word
|
122
122
|
output = {}
|
123
|
-
|
124
|
-
|
125
|
-
output[counter] = /^[#{i.upcase}#{i.downcase}]/ if i != ' '
|
126
|
-
counter += 1
|
123
|
+
word.split('').each.with_index do |char, i|
|
124
|
+
output[i + 1] = /^[#{char.downcase}]/i if char != ' '
|
127
125
|
end
|
128
126
|
output
|
129
127
|
end
|
130
128
|
|
129
|
+
# Create a regex specification for acrostics.
|
130
|
+
# Uses special logic for 'X'.
|
131
|
+
# Match words starting 'ex' and then change case to 'eX'.
|
132
|
+
def acrostic_x word
|
133
|
+
regex = {}
|
134
|
+
transform = {}
|
135
|
+
word.split('').each.with_index do |char, i|
|
136
|
+
if char.downcase == 'x'
|
137
|
+
regex[i + 1] = /^ex/i
|
138
|
+
transform[i + 1] = proc do |line|
|
139
|
+
line[0..1] = 'eX'
|
140
|
+
' ' + line
|
141
|
+
end
|
142
|
+
elsif char != ' '
|
143
|
+
regex[i + 1] = /^[#{char.downcase}]/i
|
144
|
+
transform[i + 1] = proc do |line|
|
145
|
+
' ' + line
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
{ regex: regex, transform: transform }
|
150
|
+
end
|
151
|
+
|
131
152
|
private
|
132
153
|
|
133
154
|
# Can the string be converted to integer?
|
@@ -144,14 +165,16 @@ module Poefy
|
|
144
165
|
# Get full form, from either the user-specified options,
|
145
166
|
# or the default poetic form.
|
146
167
|
def poetic_form_full poetic_form = @poetic_form
|
147
|
-
rhyme
|
148
|
-
indent
|
149
|
-
syllable
|
150
|
-
regex
|
151
|
-
|
152
|
-
poetic_form[:
|
153
|
-
poetic_form[:
|
154
|
-
poetic_form[:
|
168
|
+
rhyme = get_poetic_form_token :rhyme, poetic_form
|
169
|
+
indent = get_poetic_form_token :indent, poetic_form
|
170
|
+
syllable = get_poetic_form_token :syllable, poetic_form
|
171
|
+
regex = get_poetic_form_token :regex, poetic_form
|
172
|
+
transform = get_poetic_form_token :transform, poetic_form
|
173
|
+
poetic_form[:rhyme] = rhyme
|
174
|
+
poetic_form[:indent] = indent if indent != ''
|
175
|
+
poetic_form[:syllable] = syllable if syllable != ''
|
176
|
+
poetic_form[:regex] = regex if regex
|
177
|
+
poetic_form[:transform] = transform if transform != ' '
|
155
178
|
poetic_form
|
156
179
|
end
|
157
180
|
|
@@ -207,7 +230,16 @@ module Poefy
|
|
207
230
|
return handle_error 'ERROR: Rhyme string is not valid', []
|
208
231
|
end
|
209
232
|
tokens = [' '] if tokens == ['']
|
210
|
-
|
233
|
+
|
234
|
+
# Output as a hash.
|
235
|
+
tokens.map do |i|
|
236
|
+
hash = {
|
237
|
+
token: i,
|
238
|
+
rhyme_letter: i[0].downcase
|
239
|
+
}
|
240
|
+
hash[:refrain] = i if i[0] == i[0].upcase
|
241
|
+
hash
|
242
|
+
end
|
211
243
|
end
|
212
244
|
|
213
245
|
# Indent an array of lines using a string of numbers.
|
@@ -89,6 +89,16 @@ module Poefy
|
|
89
89
|
new_hash
|
90
90
|
end
|
91
91
|
|
92
|
+
# Fill a hash with a single value.
|
93
|
+
# Keys are integers in a range.
|
94
|
+
def fill_hash value, key_range
|
95
|
+
output = {}
|
96
|
+
key_range.each do |i|
|
97
|
+
output[i] = value
|
98
|
+
end
|
99
|
+
output
|
100
|
+
end
|
101
|
+
|
92
102
|
end
|
93
103
|
|
94
104
|
end
|
data/lib/poefy/version.rb
CHANGED
data/spec/poefy_spec.rb
CHANGED
@@ -531,6 +531,93 @@ describe Poefy::PoefyGen do
|
|
531
531
|
end
|
532
532
|
end
|
533
533
|
|
534
|
+
##############################################################################
|
535
|
+
|
536
|
+
describe "reusing the same PoefyGen instance" do
|
537
|
+
it "should correctly merge the option hashes" do
|
538
|
+
|
539
|
+
# Default to use rondeau poetic form, and proper sentence validation
|
540
|
+
poefy = Poefy::PoefyGen.new('shakespeare', { form: 'rondeau', proper: true })
|
541
|
+
|
542
|
+
# Generate a properly sentenced rondeau
|
543
|
+
poem = poefy.poem
|
544
|
+
expect(poem.count).to be 17
|
545
|
+
|
546
|
+
# Generate a rondeau without proper validation
|
547
|
+
poem = poefy.poem ({ proper: false })
|
548
|
+
expect(poem.count).to be 17
|
549
|
+
|
550
|
+
# Generate a proper rondeau with a certain indentation
|
551
|
+
poem = poefy.poem ({ indent: '01012 0012 010112' })
|
552
|
+
expect(poem.count).to be 17
|
553
|
+
|
554
|
+
# Generate other forms
|
555
|
+
poem = poefy.poem ({ rhyme: 'abbaabbacdecde' })
|
556
|
+
expect(poem.count).to be 14
|
557
|
+
poem = poefy.poem ({ form: 'sonnet' })
|
558
|
+
expect(poem.count).to be 14
|
559
|
+
poem = poefy.poem ({ form: 'ballade' })
|
560
|
+
expect(poem.count).to be 31
|
561
|
+
|
562
|
+
# Generate a default rondeau again
|
563
|
+
poem = poefy.poem
|
564
|
+
expect(poem.count).to be 17
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
##############################################################################
|
569
|
+
|
570
|
+
describe "using the transform option" do
|
571
|
+
|
572
|
+
it "should correctly transform the output 1" do
|
573
|
+
poefy = Poefy::PoefyGen.new :shakespeare
|
574
|
+
transform_hash = {
|
575
|
+
4 => proc { |line, num, poem| line.upcase },
|
576
|
+
12 => proc { |line, num, poem| line.upcase }
|
577
|
+
}
|
578
|
+
poem = poefy.poem({ form: :sonnet, transform: transform_hash })
|
579
|
+
expect(poem.count).to be 14
|
580
|
+
expect(poem[3]).to eq poem[3].upcase
|
581
|
+
expect(poem[11]).to eq poem[11].upcase
|
582
|
+
end
|
583
|
+
|
584
|
+
it "should correctly transform the output 2" do
|
585
|
+
poefy = Poefy::PoefyGen.new :shakespeare
|
586
|
+
transform_hash = {
|
587
|
+
4 => proc { |line, num, poem| poem.count },
|
588
|
+
-3 => proc { |line, num, poem| poem.count },
|
589
|
+
7 => proc { |line, num, poem| 'test string' }
|
590
|
+
}
|
591
|
+
poem = poefy.poem({ form: :sonnet, transform: transform_hash })
|
592
|
+
expect(poem.count).to be 14
|
593
|
+
expect(poem[3]).to eq '14'
|
594
|
+
expect(poem[11]).to eq '14'
|
595
|
+
expect(poem[6]).to eq 'test string'
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should correctly transform the output 3" do
|
599
|
+
poefy = Poefy::PoefyGen.new :shakespeare
|
600
|
+
transform_proc = proc { |line, num, poem| line.downcase }
|
601
|
+
poem = poefy.poem({ form: :sonnet, transform: transform_proc })
|
602
|
+
expect(poem.count).to be 14
|
603
|
+
poem.each do |i|
|
604
|
+
expect(i).to eq i.downcase
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
it "should correctly transform the output 4" do
|
609
|
+
poefy = Poefy::PoefyGen.new :shakespeare
|
610
|
+
transform_proc = proc { |line, num, poem| "#{num} #{line.downcase}" }
|
611
|
+
poem = poefy.poem({ form: :sonnet, transform: transform_proc })
|
612
|
+
expect(poem.count).to be 14
|
613
|
+
poem.each.with_index do |line, index|
|
614
|
+
expect(line).to eq line.downcase
|
615
|
+
first_word = line.split(' ').first
|
616
|
+
expect(first_word).to eq (index + 1).to_s
|
617
|
+
end
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
534
621
|
end
|
535
622
|
|
536
623
|
################################################################################
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poefy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|