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
data/bin/poefy
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Use Poefy::PoefyGen to make a poem from the command line.
|
6
|
+
################################################################################
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
|
10
|
+
require_relative '../lib/poefy.rb'
|
11
|
+
|
12
|
+
################################################################################
|
13
|
+
|
14
|
+
def parse_options
|
15
|
+
options = { console: true }
|
16
|
+
|
17
|
+
# Set up variables used later.
|
18
|
+
forms = Poefy::PoeticForms::POETIC_FORMS.keys.reject { |i| i == :default }
|
19
|
+
forms_by_4 = forms.each_slice(4).to_a.map { |i| i.join ', ' }
|
20
|
+
rhyme_docs = " This is the most important argument.
|
21
|
+
All other form strings are based on this.
|
22
|
+
Each token represents a line.
|
23
|
+
(Token examples: 'a', 'b', 'A1', ' ')
|
24
|
+
Letters indicate rhymes, so all 'a' or 'A' lines have the same rhyme.
|
25
|
+
(Example, limerick: 'aabba')
|
26
|
+
Uppercase letter lines will be duplicated exactly.
|
27
|
+
This is used to create refrain lines.
|
28
|
+
(Example, rondeau: 'aabba aabR aabbaR')
|
29
|
+
Numbers after a capital letter indicate which specific line to repeat.
|
30
|
+
(Example, villanelle: 'A1bA2 abA1 abA2 abA1 abA2 abA1A2'"
|
31
|
+
|
32
|
+
# Get all of the command-line options.
|
33
|
+
optparse = OptionParser.new do |opts|
|
34
|
+
|
35
|
+
# Set a banner, displayed at the top of the help screen.
|
36
|
+
program_info = %[ Poefy, Line-Based Poem Generator
|
37
|
+
Version #{Poefy.version_number} - #{Poefy.version_date}
|
38
|
+
https://github.com/nossidge/poefy
|
39
|
+
Paul Thompson - nossidge@gmail.com
|
40
|
+
].gsub(' ',' ')
|
41
|
+
|
42
|
+
usage = %[Usage: poefy shakespeare < shakespeare_sonnets.txt
|
43
|
+
poefy shakespeare sonnet
|
44
|
+
poefy spoke haiku
|
45
|
+
poefy therese -r 'abab cdcd efef gg' -i '0101 0101 0011 01'
|
46
|
+
poefy whitman -r 'A1bA2 abA1 abA2 abA1 abA2 abA1A2'
|
47
|
+
].gsub(' ',' ')
|
48
|
+
|
49
|
+
databases = Poefy.all_databases.join("\n" + ' ' * 21)
|
50
|
+
databases = "Databases available: " + databases
|
51
|
+
|
52
|
+
opts.banner = program_info + "\n" + usage + "\n" + databases + "\n\n"
|
53
|
+
|
54
|
+
# These will be further validated within the class.
|
55
|
+
opts.on('-f', '--form STRING',
|
56
|
+
"A named poetic form for the output\n" +
|
57
|
+
' ' * 37 + "Specifies rhyme, indent and syllable\n" +
|
58
|
+
' ' * 37 + "One of:\n" +
|
59
|
+
' ' * 39 + forms_by_4.join("\n" + ' ' * 39)) do |s|
|
60
|
+
options[:form] = s.to_sym
|
61
|
+
end
|
62
|
+
opts.on('-r', '--rhyme STRING', "See big block of text below") do |s|
|
63
|
+
options[:rhyme] = s
|
64
|
+
end
|
65
|
+
opts.on('-i', '--indent STRING', "Indentation of each line") do |s|
|
66
|
+
options[:indent] = s
|
67
|
+
end
|
68
|
+
opts.on('-s', '--syllable STRING',
|
69
|
+
"Apply syllable constraints to certain lines") do |s|
|
70
|
+
options[:syllable] = s
|
71
|
+
end
|
72
|
+
opts.on('-x', '--regex STRING',
|
73
|
+
"Apply regex constraints to certain lines") do |s|
|
74
|
+
options[:regex] = s
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on('-a', '--acrostic STRING',
|
78
|
+
"Overwrite 'regex' option to generate an acrostic") do |s|
|
79
|
+
obj = nil
|
80
|
+
obj.extend(Poefy::PoeticForms)
|
81
|
+
options[:regex] = obj.acrostic s
|
82
|
+
end
|
83
|
+
|
84
|
+
# Handle proper sentence structure.
|
85
|
+
opts.separator nil
|
86
|
+
opts.on('-p', '--proper',
|
87
|
+
"Ensure first word is not 'and but or nor yet'\n" +
|
88
|
+
' ' * 39 + "and final line ends with closing punctuation'\n" +
|
89
|
+
' ' * 39 + "Defaults to ON -- Use this option to DISABLE") do
|
90
|
+
options[:proper] = false
|
91
|
+
end
|
92
|
+
|
93
|
+
# Database options.
|
94
|
+
opts.separator nil
|
95
|
+
opts.on('-o', '--overwrite',
|
96
|
+
"Overwrite existing database with new input") do
|
97
|
+
options[:overwrite] = true
|
98
|
+
end
|
99
|
+
opts.on('-l', '--local',
|
100
|
+
"Default is to use database files from /data/\n" + ' ' * 39 +
|
101
|
+
"With this option, use files from elsewhere") do
|
102
|
+
options[:local] = true
|
103
|
+
end
|
104
|
+
|
105
|
+
# Help output.
|
106
|
+
opts.separator nil
|
107
|
+
opts.on('-h', '--help', 'Display this help screen' ) do
|
108
|
+
puts opts
|
109
|
+
exit 0
|
110
|
+
end
|
111
|
+
opts.on('-v', '--version', 'Display the version number' ) do
|
112
|
+
puts "poefy #{Poefy.version_number} (#{Poefy.version_date})"
|
113
|
+
exit 0
|
114
|
+
end
|
115
|
+
|
116
|
+
opts.separator nil
|
117
|
+
opts.separator "Description of rhyme string:"
|
118
|
+
opts.separator rhyme_docs
|
119
|
+
opts.separator nil
|
120
|
+
opts.separator "All of this is much better documented in README.md"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Parse the options and show errors on failure.
|
124
|
+
begin
|
125
|
+
optparse.parse! ARGV
|
126
|
+
rescue OptionParser::ParseError => e
|
127
|
+
puts e
|
128
|
+
exit 1
|
129
|
+
end
|
130
|
+
|
131
|
+
options
|
132
|
+
end
|
133
|
+
|
134
|
+
################################################################################
|
135
|
+
|
136
|
+
# Parse the options to shift the ARGV list.
|
137
|
+
options = parse_options
|
138
|
+
|
139
|
+
# Read data lines from STDIN.
|
140
|
+
data = (not STDIN.tty? and not STDIN.closed?) ? STDIN.read : nil
|
141
|
+
|
142
|
+
# Database is the first argument.
|
143
|
+
first_arg = ARGV.first
|
144
|
+
if first_arg.nil?
|
145
|
+
puts "ERROR: Please specify a database to read from."
|
146
|
+
exit 0
|
147
|
+
end
|
148
|
+
|
149
|
+
# If the first argument is 'makedbs', then make
|
150
|
+
# databases from the included text files.
|
151
|
+
if first_arg == 'make_dbs'
|
152
|
+
input = `sed '/[a-z]/!d' data/shakespeare_sonnets.txt`
|
153
|
+
poefy = Poefy::PoefyGen.new 'shakespeare'
|
154
|
+
poefy.make_database input, false
|
155
|
+
|
156
|
+
input = `sed '/[a-z]/!d' data/st_therese_of_lisieux.txt`
|
157
|
+
poefy = Poefy::PoefyGen.new 'therese'
|
158
|
+
poefy.make_database input, false
|
159
|
+
|
160
|
+
input = `sed '/[a-z]/!d' data/whitman_leaves.txt`
|
161
|
+
poefy = Poefy::PoefyGen.new 'whitman'
|
162
|
+
poefy.make_database input, false
|
163
|
+
|
164
|
+
input = `sed '/[a-z]/!d' data/emily_dickinson.txt`
|
165
|
+
poefy = Poefy::PoefyGen.new 'dickinson'
|
166
|
+
poefy.make_database input, false
|
167
|
+
|
168
|
+
input = `sed '/[a-z]/!d' data/english_as_she_is_spoke.txt`
|
169
|
+
poefy = Poefy::PoefyGen.new 'spoke'
|
170
|
+
poefy.make_database input, false
|
171
|
+
|
172
|
+
exit 0
|
173
|
+
end
|
174
|
+
|
175
|
+
# Poetic form name is the second argument, if it exists.
|
176
|
+
second_arg = (ARGV.length > 1) ? ARGV[1] : ''
|
177
|
+
options[:form] = second_arg.to_sym
|
178
|
+
|
179
|
+
# Create poefy object.
|
180
|
+
poefy = Poefy::PoefyGen.new first_arg, options
|
181
|
+
|
182
|
+
# If the second argument is 'rhyme', then output all
|
183
|
+
# lines that rhyme with the word.
|
184
|
+
if second_arg == 'rhyme'
|
185
|
+
third_arg = (ARGV.length > 2) ? ARGV[2] : nil
|
186
|
+
fourth_arg = (ARGV.length > 3) ? ARGV[3] : nil
|
187
|
+
puts poefy.rhymes(third_arg, fourth_arg)
|
188
|
+
exit 0
|
189
|
+
end
|
190
|
+
|
191
|
+
# Create a database using input.
|
192
|
+
if data
|
193
|
+
if options[:overwrite]
|
194
|
+
poefy.make_database! data
|
195
|
+
else
|
196
|
+
poefy.make_database data
|
197
|
+
end
|
198
|
+
|
199
|
+
# Make a new poem, and output it.
|
200
|
+
else
|
201
|
+
poem = poefy.poem
|
202
|
+
puts poem if poem
|
203
|
+
end
|
204
|
+
|
205
|
+
################################################################################
|