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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74eb4a29190ce96b7e4c49838738574986803a81
4
- data.tar.gz: 80af1c2cbf3ea78fe04d914552e7505be66001d1
3
+ metadata.gz: 00e0ad3b9108ce69d617edf3971dac999fad5094
4
+ data.tar.gz: 6fda3f2e361c48616f3dfda503f86db91dc9130b
5
5
  SHA512:
6
- metadata.gz: bb486fbdfaec63fbac58598d59fbb1f3e4711bdc3178ef83d8dcad77782543afd65d787466752f003fcd664fc6eaad6552f76370a0afc7089907b6c179b33d51
7
- data.tar.gz: f981d141281f73e2d9203a4b568bb32a941c744ad98a1d395738a05630df97212d9f63eabec6d6f63aec505d22c010d9e2524944acde7d348221678955425096
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
- line_hash[:refrain] = rhyme[:refrain] if rhyme[:refrain]
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]
@@ -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 by uppercase rhyme token.
141
- refrains = by_line.reject do |i|
142
- i[:rhyme] == i[:rhyme].downcase
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[:rhyme]
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-05-30'
15
+ '2017-06-02'
16
16
  end
17
17
 
18
18
  module VERSION
19
19
  MAJOR = 0
20
- MINOR = 5
21
- TINY = 3
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.5.3
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-05-30 00:00:00.000000000 Z
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