guillaume 0.0.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 +21 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.markdown +46 -0
- data/Rakefile +4 -0
- data/bin/guillaume +38 -0
- data/config/database.yaml.example +1 -0
- data/data/call_of_the_wild.txt +400 -0
- data/data/heart_of_darkness.txt +228 -0
- data/data/moby_dick.txt +21712 -0
- data/data/the_picture_of_dorian_gray.txt +3118 -0
- data/guillaume.gemspec +23 -0
- data/lib/guillaume/base.rb +2 -0
- data/lib/guillaume/line.rb +29 -0
- data/lib/guillaume/poem.rb +51 -0
- data/lib/guillaume/poetics.rb +13 -0
- data/lib/guillaume/source_text.rb +34 -0
- data/lib/guillaume/version.rb +3 -0
- data/lib/guillaume.rb +13 -0
- data/spec/data/zone.txt +4 -0
- data/spec/source_text_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -0
- metadata +100 -0
data/guillaume.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'guillaume/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "guillaume"
|
8
|
+
spec.version = Guillaume::VERSION
|
9
|
+
spec.authors = ["Jamey J. DeOrio"]
|
10
|
+
spec.email = ["jdeorio@gmail.com"]
|
11
|
+
spec.description = %q{Guillaume is a generative poetry creation tool using ngrams for predictive writing and a defined poetics for guiding its creation.}
|
12
|
+
spec.summary = "A generative poetry creation tool"
|
13
|
+
spec.homepage = "http://rubygems.org/gems/guillaume"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake", "~> 0"
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Guillaume::Line
|
2
|
+
def initialize(seed = nil)
|
3
|
+
@line_parts = seed.split(/ /)
|
4
|
+
end
|
5
|
+
|
6
|
+
def build(ngrams)
|
7
|
+
begin
|
8
|
+
@line_parts << next_word(ngrams)
|
9
|
+
end until @line_parts.last.nil?
|
10
|
+
@line_parts.join(" ").strip
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_word(ngrams, options = { look_behind: 1 })
|
14
|
+
search_words = @line_parts[-options[:look_behind]..-1]
|
15
|
+
choose_word(ngram_matches(ngrams, search_words))
|
16
|
+
end
|
17
|
+
|
18
|
+
def ngram_matches(ngrams, search_words)
|
19
|
+
ngrams.select { |gram| gram[0..search_words.count-1] == search_words }
|
20
|
+
end
|
21
|
+
|
22
|
+
def choose_word(matches)
|
23
|
+
possible_choices(matches).sample
|
24
|
+
end
|
25
|
+
|
26
|
+
def possible_choices(matches)
|
27
|
+
matches.map { |res| res.last }.sort
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Guillaume::Poem
|
2
|
+
attr_accessor :corpora, :lines, :poem
|
3
|
+
|
4
|
+
def initialize(corpora, options = { seed: nil, max_stanzas: 10 })
|
5
|
+
@corpora = corpora
|
6
|
+
@first_seed = options[:seed].nil? ? random_seed(@corpora.unigrams) : options[:seed]
|
7
|
+
@max_stanzas = options[:max_stanzas]
|
8
|
+
@lines = 0
|
9
|
+
@stanzas = 0
|
10
|
+
@poem = write
|
11
|
+
end
|
12
|
+
|
13
|
+
def random_seed(ngrams)
|
14
|
+
ngrams.select { |word| word.first[0] =~ /[A-Z]/ }.sample.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(lines_memo = [])
|
18
|
+
if rand(@max_stanzas) < @stanzas
|
19
|
+
return lines_memo
|
20
|
+
else
|
21
|
+
$LOGGER.info("Writing stanza #{@stanzas + 1}...")
|
22
|
+
lines_memo += stanza
|
23
|
+
@stanzas += 1
|
24
|
+
write(lines_memo)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# TODO: which_gram
|
30
|
+
# TODO: thesaurus stuff for topic staying/straying
|
31
|
+
# TODO: explicit num_lines option
|
32
|
+
#
|
33
|
+
def stanza(lines_memo = [])
|
34
|
+
#which_gram = :bigrams
|
35
|
+
|
36
|
+
if rand(100) <= lines_memo.count * 10 # never more than 10 lines this way
|
37
|
+
return lines_memo << ""
|
38
|
+
else
|
39
|
+
line = Guillaume::Line.new(random_seed(@corpora.unigrams)).build(@corpora.bigrams)
|
40
|
+
if line.length > 80
|
41
|
+
line = Guillaume::Poetics.enjamb 40, line # 40% chance to break a long line
|
42
|
+
end
|
43
|
+
lines_memo << line
|
44
|
+
stanza(lines_memo)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def formatted
|
49
|
+
@formatted ||= @poem.join("\n")
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Guillaume::Poetics
|
2
|
+
def self.enjamb(chance=100, line)
|
3
|
+
if rand(100) <= chance
|
4
|
+
line_parts = line.split(/(?<=[\.,;!-])/)
|
5
|
+
if line_parts.count > 1 # if the line contains any . , ; ! -
|
6
|
+
random_index = rand(line_parts.count)
|
7
|
+
line_parts[random_index] = line_parts[random_index] + "\n"
|
8
|
+
line_parts.join.strip
|
9
|
+
end
|
10
|
+
end
|
11
|
+
line
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
class Guillaume::SourceText
|
4
|
+
def initialize(file_name)
|
5
|
+
@file_name = file_name
|
6
|
+
@raw_source = File.open(file_name, "rb") { |f| f.read }
|
7
|
+
@sentences = normalized.split(/(?<=\.|\?|!) /).reject(&:empty?)
|
8
|
+
end
|
9
|
+
|
10
|
+
def normalized
|
11
|
+
@raw_source.gsub(/[\r\n ]+/, " ").strip
|
12
|
+
end
|
13
|
+
|
14
|
+
def ngrams(n)
|
15
|
+
$LOGGER.info("Grabbing #{n}-grams from #{@file_name}...")
|
16
|
+
result = []
|
17
|
+
@sentences.each do |sentence|
|
18
|
+
result += sentence.split(" ").each_cons(n).to_a
|
19
|
+
end
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
def unigrams
|
24
|
+
@unigrams ||= ngrams 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def bigrams
|
28
|
+
@bigrams ||= ngrams 2
|
29
|
+
end
|
30
|
+
|
31
|
+
def trigrams
|
32
|
+
@trigrams ||= ngrams 3
|
33
|
+
end
|
34
|
+
end
|
data/lib/guillaume.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "logger"
|
3
|
+
require "guillaume/version"
|
4
|
+
require "guillaume/source_text"
|
5
|
+
require "guillaume/line"
|
6
|
+
require "guillaume/poem"
|
7
|
+
require "guillaume/poetics"
|
8
|
+
|
9
|
+
$LOGGER = Logger.new(STDOUT)
|
10
|
+
$LOGGER.level = Logger::ERROR
|
11
|
+
|
12
|
+
module Guillaume
|
13
|
+
end
|
data/spec/data/zone.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
describe Guillaume::SourceText do
|
2
|
+
let(:file_path) { "spec/data/zone.txt" }
|
3
|
+
|
4
|
+
subject do
|
5
|
+
Guillaume::SourceText.new(file_path)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "can normalize the input file" do
|
9
|
+
expect(subject.normalized).to eq("A la fin tu es las de ce monde ancien")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has unigrams" do
|
13
|
+
expect(subject.unigrams).to eq([%w(A), %w(la), %w(fin), %w(tu), %w(es), %w(las), %w(de), %w(ce), %w(monde), %w(ancien)])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has bigrams" do
|
17
|
+
expect(subject.bigrams).to eq([%w(A la), %w(la fin), %w(fin tu), %w(tu es), %w(es las), %w(las de), %w(de ce), %w(ce monde), %w(monde ancien)])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has trigrams" do
|
21
|
+
expect(subject.trigrams).to eq([%w(A la fin), %w(la fin tu), %w(fin tu es), %w(tu es las), %w(es las de), %w(las de ce), %w( de ce monde), %w(ce monde ancien)])
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: guillaume
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamey J. DeOrio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Guillaume is a generative poetry creation tool using ngrams for predictive
|
42
|
+
writing and a defined poetics for guiding its creation.
|
43
|
+
email:
|
44
|
+
- jdeorio@gmail.com
|
45
|
+
executables:
|
46
|
+
- guillaume
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rspec"
|
52
|
+
- Gemfile
|
53
|
+
- LICENSE.txt
|
54
|
+
- README.markdown
|
55
|
+
- Rakefile
|
56
|
+
- bin/guillaume
|
57
|
+
- config/database.yaml.example
|
58
|
+
- data/call_of_the_wild.txt
|
59
|
+
- data/heart_of_darkness.txt
|
60
|
+
- data/moby_dick.txt
|
61
|
+
- data/the_picture_of_dorian_gray.txt
|
62
|
+
- guillaume.gemspec
|
63
|
+
- lib/guillaume.rb
|
64
|
+
- lib/guillaume/base.rb
|
65
|
+
- lib/guillaume/line.rb
|
66
|
+
- lib/guillaume/poem.rb
|
67
|
+
- lib/guillaume/poetics.rb
|
68
|
+
- lib/guillaume/source_text.rb
|
69
|
+
- lib/guillaume/version.rb
|
70
|
+
- spec/data/zone.txt
|
71
|
+
- spec/source_text_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
homepage: http://rubygems.org/gems/guillaume
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.2.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: A generative poetry creation tool
|
97
|
+
test_files:
|
98
|
+
- spec/data/zone.txt
|
99
|
+
- spec/source_text_spec.rb
|
100
|
+
- spec/spec_helper.rb
|