poefy 0.5.3 → 0.6.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 +4 -4
- data/README.md +72 -0
- data/bin/poefy +7 -1
- data/lib/poefy/conditional_satisfaction.rb +4 -1
- data/lib/poefy/generation.rb +9 -4
- data/lib/poefy/poetic_form_from_text.rb +106 -0
- data/lib/poefy/string_manipulation.rb +7 -0
- data/lib/poefy/version.rb +3 -3
- data/lib/poefy.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00e0ad3b9108ce69d617edf3971dac999fad5094
|
4
|
+
data.tar.gz: 6fda3f2e361c48616f3dfda503f86db91dc9130b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0ad8d6d99227e14f058ed9821ff4b9c2a8e7ff579b1ab97650283e088452f4632a6c5bde8a680116e50a7572fe7e7b1ab97c3caba02902b3df55cbb70309629
|
7
|
+
data.tar.gz: f14266288f23718113a20bc1b13f3d8848dd53d99f46c3a762994b3221cfc594e426de4af7b9839a67f11c1a05f138b8fc0b2b425fdc9fb77c9f002c2886c072
|
data/README.md
CHANGED
@@ -267,6 +267,78 @@ $ poefy dickinson rhyme confuse line
|
|
267
267
|
You can do the same thing for the other keys: `rhyme`, `final_word`, and `syllables`.
|
268
268
|
|
269
269
|
|
270
|
+
#### Special case: poetic form from text file
|
271
|
+
|
272
|
+
If the second argument is a reference to a text file, then the output will be a poem with the same structure as the file.
|
273
|
+
|
274
|
+
The program will scan by line, looking for rhyme, syllables and repeated lines. It will then build up a constraint hash and use that as the poetic form.
|
275
|
+
|
276
|
+
Any line that is bracketed in `[square]` or `{curly}` braces will be duplicated exactly in the output. This is for lines such as "chorus" or "1st verse" descriptions. This seems to work nicely with lyrics from genius.com.
|
277
|
+
|
278
|
+
Here's an example of a song that can be sung to the same tune as "[I Want to Hold Your Hand][1]", but using lyrics from all Beatles songs:
|
279
|
+
|
280
|
+
````
|
281
|
+
$ poefy beatles data/beatles/i_want_to_hold_your_hand.txt
|
282
|
+
[Chorus 1]
|
283
|
+
Now the sun turns out his light
|
284
|
+
And, though we may be blind
|
285
|
+
It's been a hard day's night
|
286
|
+
What goes on in your mind?
|
287
|
+
What goes on in your mind?
|
288
|
+
What goes on in your mind?
|
289
|
+
|
290
|
+
[Verse 1]
|
291
|
+
Feeling two-foot small
|
292
|
+
As I write this letter
|
293
|
+
The walrus was Paul
|
294
|
+
I left you far behind
|
295
|
+
You're not the hurting kind
|
296
|
+
What goes on in your mind?
|
297
|
+
|
298
|
+
[Bridge]
|
299
|
+
I'll remember all the little things we've done
|
300
|
+
Sleep pretty darling, do not cry
|
301
|
+
In the sun
|
302
|
+
In the sun
|
303
|
+
In the sun
|
304
|
+
|
305
|
+
[Chorus 2]
|
306
|
+
You know I feel alright
|
307
|
+
And, though we may be blind
|
308
|
+
It's been a hard day's night
|
309
|
+
What goes on in your mind?
|
310
|
+
What goes on in your mind?
|
311
|
+
What goes on in your mind?
|
312
|
+
|
313
|
+
[Bridge]
|
314
|
+
I'll remember all the little things we've done
|
315
|
+
Sleep pretty darling, do not cry
|
316
|
+
In the sun
|
317
|
+
In the sun
|
318
|
+
In the sun
|
319
|
+
|
320
|
+
[Chorus 3]
|
321
|
+
You know I feel alright
|
322
|
+
And, though we may be blind
|
323
|
+
I want a love that's right
|
324
|
+
What goes on in your mind?
|
325
|
+
What goes on in your mind?
|
326
|
+
What goes on in your mind?
|
327
|
+
What goes on in your mind?
|
328
|
+
````
|
329
|
+
|
330
|
+
You can tell that it's only based on whole line changes. Very similar lines are replaced with rhyming, but dissimilar ones. Something for me to think about.
|
331
|
+
|
332
|
+
````
|
333
|
+
[Original] [Generated]
|
334
|
+
You'll let me hold your hand I left you far behind
|
335
|
+
I'll let me hold your hand You're not the hurting kind
|
336
|
+
I want to hold your hand What goes on in your mind?
|
337
|
+
````
|
338
|
+
|
339
|
+
[1]: https://genius.com/The-beatles-i-want-to-hold-your-hand-lyrics
|
340
|
+
|
341
|
+
|
270
342
|
### As a Ruby Gem
|
271
343
|
|
272
344
|
To make a poefy database and generate poems from it:
|
data/bin/poefy
CHANGED
@@ -193,13 +193,19 @@ if second_arg == 'rhyme'
|
|
193
193
|
exit 0
|
194
194
|
end
|
195
195
|
|
196
|
+
# If the second argument is a file, then use that as the poetic_form.
|
197
|
+
updated_poetic_form = {}
|
198
|
+
if File.exists?(second_arg)
|
199
|
+
updated_poetic_form = poefy.poetic_form_from_text(second_arg)
|
200
|
+
end
|
201
|
+
|
196
202
|
# Create a database using input.
|
197
203
|
if data
|
198
204
|
poefy.make_database data, options[:overwrite]
|
199
205
|
|
200
206
|
# Make a new poem, and output it.
|
201
207
|
else
|
202
|
-
poem = poefy.poem
|
208
|
+
poem = poefy.poem(updated_poetic_form)
|
203
209
|
puts poem if poem
|
204
210
|
end
|
205
211
|
|
@@ -92,7 +92,10 @@ module Poefy
|
|
92
92
|
rhyme: rhyme[:token],
|
93
93
|
rhyme_letter: rhyme[:rhyme_letter]
|
94
94
|
}
|
95
|
-
|
95
|
+
if rhyme[:refrain] and rhyme[:refrain] != ' '
|
96
|
+
line_hash[:refrain] = rhyme[:refrain]
|
97
|
+
end
|
98
|
+
line_hash[:exact] = rhyme[:exact] if rhyme[:exact]
|
96
99
|
poetic_form.keys.each do |k|
|
97
100
|
if poetic_form[k].is_a? Hash
|
98
101
|
line_hash[k] = poetic_form[k][index + 1]
|
data/lib/poefy/generation.rb
CHANGED
@@ -137,11 +137,11 @@ module Poefy
|
|
137
137
|
line_conds += [/[\.?!]$/]
|
138
138
|
by_line[tokenised_rhyme.count-1][:regex] = line_conds
|
139
139
|
|
140
|
-
# Get all refrains
|
141
|
-
refrains = by_line.
|
142
|
-
i[:
|
140
|
+
# Get all refrains and group them.
|
141
|
+
refrains = by_line.select do |i|
|
142
|
+
i[:refrain]
|
143
143
|
end.group_by do |i|
|
144
|
-
i[:
|
144
|
+
i[:refrain]
|
145
145
|
end
|
146
146
|
|
147
147
|
# Now make each refrain :regex be an array of all.
|
@@ -276,6 +276,11 @@ module Poefy
|
|
276
276
|
end
|
277
277
|
end
|
278
278
|
|
279
|
+
# Do the same for [:exact] lines.
|
280
|
+
poetic_form[:rhyme].each.with_index do |line, index|
|
281
|
+
poem_lines[index] = line[:exact] if line[:exact]
|
282
|
+
end
|
283
|
+
|
279
284
|
# Carry out transformations, if necessary.
|
280
285
|
the_poem = poem_lines
|
281
286
|
if poetic_form[:transform]
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Read a song lyric file, output a poetic_form that matches its form.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
module Poefy
|
9
|
+
|
10
|
+
module PoeticFormFromText
|
11
|
+
|
12
|
+
# Read a song lyric file, output a poetic_form that matches its form.
|
13
|
+
def poetic_form_from_text text_file
|
14
|
+
lines = File.readlines(text_file).map(&:strip)
|
15
|
+
|
16
|
+
# For refrains, we don't care about the lines exactly, just
|
17
|
+
# the structure. So we can delete punctuation and downcase.
|
18
|
+
lines = lines.map do |line|
|
19
|
+
{
|
20
|
+
orig: line,
|
21
|
+
downcase: line.gsub(/[[:punct:]]/, '').downcase
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Find all the lines that are duplicated.
|
26
|
+
# These will be the refrain lines.
|
27
|
+
refrains = lines.map { |i| i[:downcase] }
|
28
|
+
refrains = refrains.inject(Hash.new(0)) { |h, e| h[e] += 1 ; h }
|
29
|
+
refrains = refrains.select { |k, v| v > 1 && k != '' }.keys
|
30
|
+
|
31
|
+
# Give each a unique refrain ID.
|
32
|
+
buffer = {}
|
33
|
+
refrains.each.with_index { |line, id| buffer[line] = id }
|
34
|
+
refrains = buffer
|
35
|
+
|
36
|
+
# Loop through and describe each line.
|
37
|
+
lines = lines.map.with_index do |line, index|
|
38
|
+
hash = {}
|
39
|
+
|
40
|
+
# Text of the line.
|
41
|
+
hash[:orig] = line[:orig]
|
42
|
+
hash[:downcase] = line[:downcase]
|
43
|
+
|
44
|
+
# Misc details.
|
45
|
+
hash[:num] = index + 1
|
46
|
+
hash[:syllable] = syllables(hash[:downcase])
|
47
|
+
hash[:last_word] = (text.to_phrase.last_word rescue '')
|
48
|
+
|
49
|
+
# The rhyme for the line.
|
50
|
+
# ToDo: For now, just get the first rhyme of the tag array.
|
51
|
+
rhyme_tag = get_rhymes(hash[:downcase]).first
|
52
|
+
hash[:rhyme_tag] = rhyme_tag || ' '
|
53
|
+
hash[:rhyme_letter] = rhyme_tag
|
54
|
+
hash[:rhyme] = ' ' if hash[:downcase] == ''
|
55
|
+
|
56
|
+
# Map [:refrain] and [:exact].
|
57
|
+
# (They are mutually exclusive)
|
58
|
+
# If it needs to be an exact line, we don't need rhyme tokens.
|
59
|
+
if bracketed?(line[:orig].strip)
|
60
|
+
hash[:exact] = line[:orig]
|
61
|
+
hash[:rhyme] = ' '
|
62
|
+
hash[:rhyme_letter] = nil
|
63
|
+
hash[:syllable] = 0
|
64
|
+
elsif refrains.keys.include?(line[:downcase])
|
65
|
+
hash[:refrain] = refrains[line[:downcase]]
|
66
|
+
end
|
67
|
+
|
68
|
+
hash
|
69
|
+
end
|
70
|
+
|
71
|
+
# puts '########################################'
|
72
|
+
# lines.each { |i| puts i }
|
73
|
+
|
74
|
+
# # Compare each [:rhyme_tag] against the rest of the array.
|
75
|
+
# lines_TODO = lines.map do |text|
|
76
|
+
# remaining = lines - [text]
|
77
|
+
# rhyme_tags = remaining.map { |i| i[:rhyme_tag] }
|
78
|
+
# end
|
79
|
+
|
80
|
+
# Split into separate sections, [:rhyme] and [:syllable].
|
81
|
+
rhyme = lines.map do |line|
|
82
|
+
hash = {}
|
83
|
+
hash[:token] = line[:rhyme_letter] || ' '
|
84
|
+
hash[:rhyme_letter] = hash[:token]
|
85
|
+
hash[:refrain] = line[:refrain] if line[:refrain]
|
86
|
+
hash[:exact] = line[:exact] if line[:exact]
|
87
|
+
hash
|
88
|
+
end
|
89
|
+
|
90
|
+
syllable = {}
|
91
|
+
lines.map.with_index do |line, index|
|
92
|
+
syllable[index+1] = line[:syllable] if line[:syllable] > 0
|
93
|
+
end
|
94
|
+
|
95
|
+
poetic_form = {
|
96
|
+
rhyme: rhyme,
|
97
|
+
syllable: syllable
|
98
|
+
}
|
99
|
+
poetic_form
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
################################################################################
|
@@ -99,6 +99,13 @@ module Poefy
|
|
99
99
|
output
|
100
100
|
end
|
101
101
|
|
102
|
+
# Is the string enclosed in brackets?
|
103
|
+
def bracketed? string
|
104
|
+
square = (string[0] == '[' and string[-1] == ']')
|
105
|
+
curly = (string[0] == '{' and string[-1] == '}')
|
106
|
+
square or curly
|
107
|
+
end
|
108
|
+
|
102
109
|
end
|
103
110
|
|
104
111
|
end
|
data/lib/poefy/version.rb
CHANGED
@@ -12,13 +12,13 @@ module Poefy
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.version_date
|
15
|
-
'2017-
|
15
|
+
'2017-06-02'
|
16
16
|
end
|
17
17
|
|
18
18
|
module VERSION
|
19
19
|
MAJOR = 0
|
20
|
-
MINOR =
|
21
|
-
TINY =
|
20
|
+
MINOR = 6
|
21
|
+
TINY = 0
|
22
22
|
PRE = nil
|
23
23
|
|
24
24
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
data/lib/poefy.rb
CHANGED
@@ -21,6 +21,7 @@ require_relative 'poefy/self.rb'
|
|
21
21
|
require_relative 'poefy/poefy_gen_base.rb'
|
22
22
|
require_relative 'poefy/generation.rb'
|
23
23
|
require_relative 'poefy/poetic_forms.rb'
|
24
|
+
require_relative 'poefy/poetic_form_from_text.rb'
|
24
25
|
require_relative 'poefy/string_manipulation.rb'
|
25
26
|
require_relative 'poefy/handle_error.rb'
|
26
27
|
require_relative 'poefy/database.rb'
|
@@ -37,6 +38,7 @@ module Poefy
|
|
37
38
|
include Poefy::PoefyGenBase
|
38
39
|
include Poefy::Generation
|
39
40
|
include Poefy::PoeticForms
|
41
|
+
include Poefy::PoeticFormFromText
|
40
42
|
include Poefy::StringManipulation
|
41
43
|
include Poefy::ConditionalSatisfaction
|
42
44
|
include Poefy::HandleError
|
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.
|
4
|
+
version: 0.6.0
|
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-
|
11
|
+
date: 2017-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/poefy/generation.rb
|
142
142
|
- lib/poefy/handle_error.rb
|
143
143
|
- lib/poefy/poefy_gen_base.rb
|
144
|
+
- lib/poefy/poetic_form_from_text.rb
|
144
145
|
- lib/poefy/poetic_forms.rb
|
145
146
|
- lib/poefy/self.rb
|
146
147
|
- lib/poefy/string_manipulation.rb
|