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.
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,2 @@
1
+ module Guillaume
2
+ 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
@@ -0,0 +1,3 @@
1
+ module Guillaume
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,4 @@
1
+ A la fin tu es las de
2
+
3
+ ce monde ancien
4
+
@@ -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
@@ -0,0 +1,5 @@
1
+ require "guillaume"
2
+
3
+ RSpec.configure do |config|
4
+ config.color = true
5
+ end
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