poefy 1.0.0 → 1.1.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/.gitignore +0 -3
- data/README.md +73 -34
- data/bin/poefy +44 -7
- data/bin/poefy_make +6 -8
- data/lib/poefy/core_extensions/array.rb +18 -0
- data/lib/poefy/database.rb +1 -3
- data/lib/poefy/db_type.rb +7 -14
- data/lib/poefy/exceptions.rb +123 -0
- data/lib/poefy/generation.rb +29 -11
- data/lib/poefy/poem_base.rb +112 -112
- data/lib/poefy/poetic_forms.rb +529 -367
- data/lib/poefy/string_manipulation.rb +0 -14
- data/lib/poefy/version.rb +2 -2
- data/lib/poefy.rb +1 -2
- data/settings.yml +2 -0
- data/spec/poefy_unit_spec.rb +455 -33
- metadata +4 -3
- data/lib/poefy/handle_error.rb +0 -35
data/lib/poefy/generation.rb
CHANGED
@@ -16,9 +16,8 @@ module Poefy
|
|
16
16
|
# Generate specific poem types.
|
17
17
|
def poem poetic_form = @poetic_form
|
18
18
|
|
19
|
-
if
|
20
|
-
|
21
|
-
end
|
19
|
+
# Can't do much if the database doesn't exist.
|
20
|
+
raise Poefy::MissingDatabase unless @corpus.exists?
|
22
21
|
|
23
22
|
# Validate the poetic form hash.
|
24
23
|
raise ArgumentError, 'Argument must be a hash' unless
|
@@ -27,11 +26,12 @@ module Poefy
|
|
27
26
|
poetic_form = @poetic_form.merge poetic_form
|
28
27
|
|
29
28
|
# Make sure the hash contains ':form' or ':rhyme' keys.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
# Make sure the rhyme token is not empty.
|
30
|
+
rhyme = poetic_form[:rhyme]
|
31
|
+
if !(rhyme || poetic_form[:form])
|
32
|
+
raise Poefy::MissingFormOrRhyme
|
33
|
+
elsif (rhyme && rhyme.count == 1 && rhyme.first[:token] == ' ')
|
34
|
+
raise Poefy::MissingFormOrRhyme
|
35
35
|
end
|
36
36
|
|
37
37
|
# Loop until we find a valid poem.
|
@@ -59,6 +59,15 @@ module Poefy
|
|
59
59
|
output
|
60
60
|
end
|
61
61
|
|
62
|
+
# Same as the above method, but swallow any errors.
|
63
|
+
def poem! poetic_form = @poetic_form
|
64
|
+
begin
|
65
|
+
poem poetic_form
|
66
|
+
rescue Poefy::Error
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
62
71
|
private
|
63
72
|
|
64
73
|
# Use the constraints in 'poetic_form' to generate a poem.
|
@@ -69,7 +78,7 @@ module Poefy
|
|
69
78
|
# Tokenise the rhyme string, and return [] if invalid.
|
70
79
|
tokenised_rhyme = tokenise_rhyme poetic_form[:rhyme]
|
71
80
|
if tokenised_rhyme == []
|
72
|
-
|
81
|
+
raise Poefy::RhymeError
|
73
82
|
end
|
74
83
|
|
75
84
|
# Expand poetic_form[:transform], if there's just one element.
|
@@ -93,6 +102,11 @@ module Poefy
|
|
93
102
|
# Add line number as ':line' in each element's hash.
|
94
103
|
by_line = conditions_by_line(tokenised_rhyme, poetic_form)
|
95
104
|
|
105
|
+
# Remove any regexes that are empty arrays [].
|
106
|
+
by_line.each do |i|
|
107
|
+
i.delete(:regex) if i[:regex] == []
|
108
|
+
end
|
109
|
+
|
96
110
|
# If the poetic_form[:proper] option is true, we're going to
|
97
111
|
# need to add additional regex conditions to the first and
|
98
112
|
# last lines.
|
@@ -198,7 +212,11 @@ module Poefy
|
|
198
212
|
|
199
213
|
# If all the lines include a 'syllable' condition,
|
200
214
|
# then we can specify to only query for matching lines.
|
201
|
-
|
215
|
+
begin
|
216
|
+
min_max = syllable_min_max line_conds
|
217
|
+
rescue
|
218
|
+
raise Poefy::SyllableError
|
219
|
+
end
|
202
220
|
rhymes = @corpus.rhymes_by_count(line_conds.count, min_max)
|
203
221
|
|
204
222
|
# Get just the rhyme part of the hash.
|
@@ -216,7 +234,7 @@ module Poefy
|
|
216
234
|
if poetic_form[:proper]
|
217
235
|
msg += "\n Perhaps try again using the -p option."
|
218
236
|
end
|
219
|
-
|
237
|
+
raise Poefy::NotEnoughData.new(msg)
|
220
238
|
end
|
221
239
|
rhymes_already_used << out.first['rhyme']
|
222
240
|
|
data/lib/poefy/poem_base.rb
CHANGED
@@ -1,112 +1,112 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Encoding: UTF-8
|
3
|
-
|
4
|
-
################################################################################
|
5
|
-
# Base internals for the Poem class.
|
6
|
-
################################################################################
|
7
|
-
|
8
|
-
module Poefy
|
9
|
-
|
10
|
-
module PoemBase
|
11
|
-
|
12
|
-
attr_reader :corpus, :local, :overwrite
|
13
|
-
|
14
|
-
def initialize db_name, options = {}
|
15
|
-
handle_options options
|
16
|
-
@corpus = Poefy::Database.new db_name, @local
|
17
|
-
end
|
18
|
-
|
19
|
-
# Make a database using the given lines.
|
20
|
-
def make_database input, description = nil, overwrite = @overwrite
|
21
|
-
lines = validate_lines input
|
22
|
-
lines.map! do |line|
|
23
|
-
line.force_encoding('utf-8')
|
24
|
-
.gsub("\u00A0", ' ')
|
25
|
-
.strip
|
26
|
-
end
|
27
|
-
@corpus.close if @corpus
|
28
|
-
if overwrite
|
29
|
-
@corpus.make_new! lines, description
|
30
|
-
else
|
31
|
-
@corpus.make_new lines, description
|
32
|
-
end
|
33
|
-
end
|
34
|
-
def make_database! input, description = nil
|
35
|
-
make_database input, description, true
|
36
|
-
end
|
37
|
-
|
38
|
-
# Close the database.
|
39
|
-
def close
|
40
|
-
@corpus.close
|
41
|
-
end
|
42
|
-
|
43
|
-
# Validate the lines. Arg could be a filename,
|
44
|
-
# newline delimited string, or array of lines.
|
45
|
-
def validate_lines input
|
46
|
-
|
47
|
-
# If the input is a file, then read it.
|
48
|
-
lines = File.exists?(input.to_s) ? File.read(input) : input
|
49
|
-
|
50
|
-
# If lines is not an array, assume string and split on newlines.
|
51
|
-
lines.respond_to?(:each) ? lines : lines.split("\n")
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
# Handle the optional initialize options hash.
|
57
|
-
def handle_options options
|
58
|
-
@overwrite = options[:overwrite] || false
|
59
|
-
@local = options[:local] || false
|
60
|
-
@poetic_form = {}
|
61
|
-
@poetic_form[:proper] = options[:proper] || true
|
62
|
-
@poetic_form = validate_poetic_form options
|
63
|
-
end
|
64
|
-
|
65
|
-
# Make sure the options hash is in order.
|
66
|
-
def validate_poetic_form poetic_form
|
67
|
-
input, output = poetic_form, {}
|
68
|
-
form_string = get_valid_form input[:form]
|
69
|
-
|
70
|
-
# Apply ':form_from_text' before any others.
|
71
|
-
if input[:form_from_text]
|
72
|
-
lines = validate_lines input[:form_from_text]
|
73
|
-
form = poetic_form_from_text lines
|
74
|
-
input = form.merge input
|
75
|
-
end
|
76
|
-
|
77
|
-
# Handle obvious inputs.
|
78
|
-
output[:form] = form_string if form_string
|
79
|
-
output[:rhyme] = input[:rhyme] if input[:rhyme]
|
80
|
-
output[:indent] = input[:indent] if input[:indent]
|
81
|
-
output[:syllable] = input[:syllable] if input[:syllable]
|
82
|
-
output[:regex] = input[:regex] if input[:regex]
|
83
|
-
output[:acrostic] = input[:acrostic] if input[:acrostic]
|
84
|
-
output[:acrostic_x] = input[:acrostic_x] if input[:acrostic_x]
|
85
|
-
output[:transform] = input[:transform] if input[:transform]
|
86
|
-
|
87
|
-
# Tokenise string to arrays and hashes.
|
88
|
-
if output[:rhyme]
|
89
|
-
output[:rhyme] = tokenise_rhyme output[:rhyme]
|
90
|
-
end
|
91
|
-
rhyme =
|
92
|
-
if output[:syllable] and rhyme != ' '
|
93
|
-
output[:syllable] =
|
94
|
-
end
|
95
|
-
if output[:regex]
|
96
|
-
output[:regex] =
|
97
|
-
end
|
98
|
-
|
99
|
-
# Get from instance by default.
|
100
|
-
output[:proper] = input[:proper].nil? ?
|
101
|
-
@poetic_form[:proper] : input[:proper]
|
102
|
-
|
103
|
-
# Tiny amendment to solve later errors.
|
104
|
-
output[:rhyme] = ' ' if output[:rhyme] == ''
|
105
|
-
output
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
################################################################################
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Base internals for the Poem class.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
module Poefy
|
9
|
+
|
10
|
+
module PoemBase
|
11
|
+
|
12
|
+
attr_reader :corpus, :local, :overwrite
|
13
|
+
|
14
|
+
def initialize db_name, options = {}
|
15
|
+
handle_options options
|
16
|
+
@corpus = Poefy::Database.new db_name, @local
|
17
|
+
end
|
18
|
+
|
19
|
+
# Make a database using the given lines.
|
20
|
+
def make_database input, description = nil, overwrite = @overwrite
|
21
|
+
lines = validate_lines input
|
22
|
+
lines.map! do |line|
|
23
|
+
line.force_encoding('utf-8')
|
24
|
+
.gsub("\u00A0", ' ')
|
25
|
+
.strip
|
26
|
+
end
|
27
|
+
@corpus.close if @corpus
|
28
|
+
if overwrite
|
29
|
+
@corpus.make_new! lines, description
|
30
|
+
else
|
31
|
+
@corpus.make_new lines, description
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def make_database! input, description = nil
|
35
|
+
make_database input, description, true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Close the database.
|
39
|
+
def close
|
40
|
+
@corpus.close
|
41
|
+
end
|
42
|
+
|
43
|
+
# Validate the lines. Arg could be a filename,
|
44
|
+
# newline delimited string, or array of lines.
|
45
|
+
def validate_lines input
|
46
|
+
|
47
|
+
# If the input is a file, then read it.
|
48
|
+
lines = File.exists?(input.to_s) ? File.read(input) : input
|
49
|
+
|
50
|
+
# If lines is not an array, assume string and split on newlines.
|
51
|
+
lines.respond_to?(:each) ? lines : lines.split("\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Handle the optional initialize options hash.
|
57
|
+
def handle_options options
|
58
|
+
@overwrite = options[:overwrite] || false
|
59
|
+
@local = options[:local] || false
|
60
|
+
@poetic_form = {}
|
61
|
+
@poetic_form[:proper] = options[:proper] || true
|
62
|
+
@poetic_form = validate_poetic_form options
|
63
|
+
end
|
64
|
+
|
65
|
+
# Make sure the options hash is in order.
|
66
|
+
def validate_poetic_form poetic_form
|
67
|
+
input, output = poetic_form, {}
|
68
|
+
form_string = get_valid_form input[:form]
|
69
|
+
|
70
|
+
# Apply ':form_from_text' before any others.
|
71
|
+
if input[:form_from_text]
|
72
|
+
lines = validate_lines input[:form_from_text]
|
73
|
+
form = poetic_form_from_text lines
|
74
|
+
input = form.merge input
|
75
|
+
end
|
76
|
+
|
77
|
+
# Handle obvious inputs.
|
78
|
+
output[:form] = form_string if form_string
|
79
|
+
output[:rhyme] = input[:rhyme] if input[:rhyme]
|
80
|
+
output[:indent] = input[:indent] if input[:indent]
|
81
|
+
output[:syllable] = input[:syllable] if input[:syllable]
|
82
|
+
output[:regex] = input[:regex] if input[:regex]
|
83
|
+
output[:acrostic] = input[:acrostic] if input[:acrostic]
|
84
|
+
output[:acrostic_x] = input[:acrostic_x] if input[:acrostic_x]
|
85
|
+
output[:transform] = input[:transform] if input[:transform]
|
86
|
+
|
87
|
+
# Tokenise string to arrays and hashes.
|
88
|
+
if output[:rhyme]
|
89
|
+
output[:rhyme] = tokenise_rhyme output[:rhyme]
|
90
|
+
end
|
91
|
+
rhyme = get_poetic_form_rhyme_longest(output)
|
92
|
+
if output[:syllable] and rhyme != ' '
|
93
|
+
output[:syllable] = transform_input_syllable output[:syllable], rhyme
|
94
|
+
end
|
95
|
+
if output[:regex]
|
96
|
+
output[:regex] = transform_input_regex output[:regex], rhyme
|
97
|
+
end
|
98
|
+
|
99
|
+
# Get from instance by default.
|
100
|
+
output[:proper] = input[:proper].nil? ?
|
101
|
+
@poetic_form[:proper] : input[:proper]
|
102
|
+
|
103
|
+
# Tiny amendment to solve later errors.
|
104
|
+
output[:rhyme] = ' ' if output[:rhyme] == ''
|
105
|
+
output
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
################################################################################
|