unbelievable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9bc1ef5687c72e042c813574dc0b99892dac3ff8
4
+ data.tar.gz: 1475f0463e4e45c0cae4a39178e5c16db285e129
5
+ SHA512:
6
+ metadata.gz: c43997a731b744f67a632e4606e97aeefe33d71d9bcf57cbf864ad545f9fb612495b3715f6758aadd5ce3d81b0ca64b708cdd444d788f0ddd40dfd08c553951b
7
+ data.tar.gz: 17104c6d48ef7e1af27cc72c43d0ab1f1701d52f80f4f1a8601a74ef035b801cde8992f1e0fe7f921ffb025b7a265efe96b46728af95dc7bd87465620a878f3d
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .rvmrc
23
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Dvorkin
2
+ http://www.dvorkin.net
3
+ %w(mike dvorkin.net) * "@" || "twitter.com/mid"
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ ### Unbelievable ###
2
+
3
+ Unbelievable is a Ruby gem that lets you write Ruby code in plain language.
4
+ Seriously ;-) Here's a quick "Hello, RubyConf!" haiku example:
5
+
6
+ ```
7
+ $ cat haiku.rb
8
+ require "unbelievable"
9
+
10
+ Wild startling
11
+ sky. Rain therefore peaceful
12
+ mind. Startling journey over
13
+ wonderful clouds
14
+
15
+ See elegant him yet unusual
16
+ clear sky? Have you seen
17
+ painful handsome ova? Remember
18
+ journey near gracious dreams?
19
+
20
+ Miss merciful marionette yet
21
+ secluded pebble? Raw crystal
22
+ air. Dove along crisp gems
23
+
24
+ Fantastic crescent with
25
+ awesome clear
26
+ leaf. Unexpected wave over old
27
+ canyon. Warm handsome waterfalls
28
+
29
+ Eyes whenever beautiful
30
+ lips. Elegant butterfly yet
31
+ restful fine
32
+ orb. Rock among big gems
33
+
34
+ Fresh her besides crisp
35
+ him. Delightful dreams
36
+
37
+ $ ruby haiku.rb
38
+ Hello, RubyConf!
39
+ ```
40
+
41
+ The gem comes with the story generator that converts existing Ruby code to
42
+ a random story of your choice. The haiku above might be produced as follows:
43
+
44
+ ```ruby
45
+ require "unbelievable"
46
+
47
+ Unbelievable.style = :haiku # Optional story style.
48
+ puts 'require "unbelievable"' # Require the gem.
49
+ puts Unbelievable.generate('puts "Hello, RubyConf!"') # Make the story.
50
+ ```
51
+
52
+ Out of the box the gem supports five story styles: `:haiku`, `:lorem`, `:todo`,
53
+ `:secret`, and `:random` which is the default style. Check out the `/demo`
54
+ directory for more usage examples.
55
+
56
+ ### Disclaimer ###
57
+
58
+ In case you find an unbelievable bug that affects your production system consider
59
+ backporting your unbelievable stories to Ruby.
60
+
61
+ ### Specials Thanks ###
62
+
63
+ The unbelievable gem was inspired by Yusuke Endoh, one of the greatest Ruby
64
+ hackers of all time.
65
+
66
+ ### License ###
67
+
68
+ Copyright (c) 2013 Michael Dvorkin
69
+
70
+ `%w(mike dvorkin.net) * "@" || "twitter.com/mid" || "http://www.dvorkin.net"`
71
+
72
+ Released at the RubyConf 2013 in Miami. Further released under the MIT license.
73
+ See LICENSE file for details.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ require "unbelievable/core_ext/array"
7
+ require "unbelievable/version"
8
+ require "unbelievable/generator"
9
+ require "unbelievable/haiku"
10
+ require "unbelievable/lorem"
11
+ require "unbelievable/secret"
12
+ require "unbelievable/todo"
13
+ require "unbelievable/magic"
@@ -0,0 +1,11 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ class Array
7
+ def pick(size)
8
+ word = self.select { |item| item.size == size }.sample
9
+ word ||= "x" * size # Only if we miss the word in the dictionary.
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+
3
+ "singular": ["air","her","him","ice","orb","sea","sky","sun","tea","you","zen","bell","cave","dove","face","fire","hand","lake","leaf","life","monk","moon","rain","rock","sand","seed","skin","snow","tree","wave","wind","amber","apple","blood","cloud","color","creek","frost","grass","heart","leave","light","night","petal","puppy","river","smile","smoke","stone","sword","world","bamboo","breeze","candle","canyon","flower","kitten","meadow","mirror","pebble","scroll","shadow","spring","summer","temple","diamond","evening","journey","morning","origami","rainbow","retreat","someone","whisper","whisper","crescent","mountain","nighfall","sunshine","wildness","butterfly","moonlight","waterfall","breadcrumb","marionette","wheelhouse"],
4
+
5
+ "plural": ["ans","ova","eggs","eyes","gems","jars","lips","orbs","bells","birds","faces","hands","ideas","monks","rocks","seeds","trees","waves","wings","apples","clouds","colors","dreams","hearts","leaves","petals","petals","stones","wounds","breaths","candles","flowers","gardens","meadows","mirrors","pebbles","shadows","temples","blankets","diamonds","droplets","whispers","whispers","birthdays","mountains","jellybeans","scarecrows","waterfalls"],
6
+
7
+ "adjective": ["big","hot","old","raw","wet","aged","bare","cold","fine","pure","soft","tiny","warm","wild","clear","crisp","fresh","quiet","sharp","sweet","white","bright","fading","fallen","gentle","joyful","lonely","lovely","pretty","sacred","silent","simple","sleepy","smooth","tender","amazing","awesome","crystal","elegant","painful","perfect","restful","soaring","unusual","enormous","gracious","handsome","merciful","nameless","peaceful","secluded","stunning","tranquil","beautiful","fantastic","marvelous","startling","wonderful","delightful","refreshing","surprising","unexpected","weightless"],
8
+
9
+ "numeral": ["six","ten","two","five","four","many","nine","some","eight","seven","three","eleven","twelve","sixteen","hundreds","thirteen","seventeen","thousands","eighteenth","thirteenth"],
10
+
11
+ "single": ["Agh","Aha","Wow","Yay","Yes","Yum","Oops","Yeah","Enjoy","Peace","Really","Amazing","Awesome","Beautiful","Wonderful","Standstill"],
12
+
13
+ "conjunction": ["yet","near","over","with","with","above","along","among","around","besides","without","although","whenever","wherever","therefore","underneath"]
14
+
15
+ }
@@ -0,0 +1 @@
1
+ ["dui","est","hac","leo","mis","nam","nec","non","sed","sem","sit","vel","amet","ante","arcu","cras","diam","duis","eget","elit","enim","erat","eros","nibh","nisi","nisl","nunc","odio","quam","quis","angue","augue","dolor","donec","etiam","fames","felis","fusce","ipsum","justo","lacus","lorem","magna","massa","metus","morbi","neque","netus","nulla","orci!","porta","proin","purus","risus","urna?","velit","vitae","aenean","auctor","congue","curae?","cursus","dictum","enatis","lectus","libero","ligula","luctus","mattis","mauris","mollis","nullam","ornare","platea","rutrum","sapien","semper","tellus","tempor","tempus","tortor","turpis","aliquam","aliquet","blandit","commodo","cubilia","dapibus","egestas","euismod","feugiat","iaculis","lacinia","laoreet","posuere","pretium","primis!","quisque","rhoncus","sodales","varius?","vivamus","viverra","accumsan","bibendum","dictumst","eleifend","facilisi","faucibus","gravida!","habitant","integer!","interdum","lobortis","maecenas","molestie","pharetra","placerat","praesent","pretitor","pulvinar","sagittis","senectus","suscipit","ultrices","vehicula","volutpat","consequat","convallis","curabitur","dignissim","elementum","facilisis","fermentum","fringilla","habitasse","hendrerit","imperdiet","malesuada","phasellus","porttitor","tincidunt","tristique","ultricies","venenatis","vulputate","adipiscing","vestibulum","condimentum","consectetur","scelerisque","suspendisse","ullamcorper","pellentesque","sollicitudin"]
@@ -0,0 +1,15 @@
1
+ {
2
+
3
+ "verb": ["buy","dig","fix","log","use","win","zap","book","fake","grow","hack","push","rate","sack","sell","swap","build","check","draft","drive","gauge","morph","order","scale","study","create","deploy","design","enable","engage","evolve","manage","retain","target","verify","approve","deliver","develop","embrace","empower","enhance","exploit","monitor","rebrand","utilize","automate","expedite","generate","incubate","leverage","maximize","monetize","optimize","redesign","reinvent","aggregate","architect","benchmark","cultivate","implement","integrate","jumpstart","repurpose","syndicate","synergize","transform","facilitate","prioritize","productize","streamline","synthesize","transition"],
4
+
5
+ "plural": ["UIs","ads","GUIs","fabs","hubs","labs","slots","specs","users","brands","models","niches","stocks","actions","designs","drivers","markets","metrics","portals","systems","channels","networks","services","analytics","customers","eyeballs!","paradigms","platforms","solutions","synergies","appliances","interfaces","milestones","pageviews!"],
6
+
7
+ "singular": ["GUI","LTE","xml","fab","hub","lab","html","json","ldap","SaaS","beta","blog","core","spec","HTML5","brand","focus","frame","group","model","access","engine","mashup","policy","portal","adapter","archive","circuit","console","loyalty","matrix!","network","process","product","support","synergy","toolset","webinar","website","Internet","Intranet","ability!","alliance","analyzer","approach","business","capacity","commerce","concept!","customer","database","extranet","function","hardware","helpdesk","paradigm","pricing!","project!","protocol","solution","strategy","workflow","algorithm","benchmark","diversity","emulation","encoding!","firmware!","forecast!","framework","groupware","hierarchy","interface","knowledge","migration","moderator","readiness","software!","structure","taskforce","timeframe","workforce","bandwidth!","capability","challenge!","complexity","encryption","enterprise","initiative","management","middleware","mindshare!","monitoring","moratorium","projection","throughput"],
8
+
9
+ "adjective": ["big","hot","raw","bold","full","meme","local","smart","solid","viral","global","killer","mobile","modern","robust","secure","static","backend","diverse","dynamic","focused","leading","organic","virtual","advanced","balanced","critical","enhanced","european","expanded","extended","frontend","granular","holistic","holistic","magnetic","offshore","optional","profound","reactive","realtime","scalable","seamless","vertical","wireless","automated","budgetary","digitized","downsized","efficient","ergonomic","exclusive","impactful","intuitive","mandatory","networked","optimized","polarised","proactive","shareable","strategic","universal","versatile","visionary","worldwide","artificial","compatible","compelling","customized","extensible","horizontal","innovative","integrated","persistent","standalone","successful","switchable","synergized","ubiquitous","upgradable"],
10
+
11
+ "adverb": ["OMG","nvm","oh!","plz","yt?","ASAP","nvm!","omg!","only","ooh!","ASAP!","FAST!","damn!","done?","more?","yeah!","please","simply","further","quickly","quietly","rapidly","promptly","urgently","carefully","diligently","discreetly"],
12
+
13
+ "numeral": ["all","few","six","ten","five","four","many","some","dozen","three","twelve","hundred","several","sixteen","thirteen","thousand","countless","seventeen","thousands","eighteenth","thirteenth"]
14
+
15
+ }
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ require "json"
7
+
8
+ module Unbelievable
9
+ class Generator
10
+ @@dictionary = {}
11
+
12
+ def initialize(style = default_style)
13
+ file_name = "#{File.dirname(__FILE__)}/dictionary/#{style}.json"
14
+ @@dictionary[style] ||= File.open(file_name) { |f| JSON.load(f) }
15
+ end
16
+
17
+ protected
18
+ def dictionary(style = default_style)
19
+ @@dictionary[style]
20
+ end
21
+
22
+ private
23
+ def default_style
24
+ self.class.name.split("::").last.downcase.to_sym
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ module Unbelievable
7
+ class Haiku < Generator
8
+ TEMPLATES = [
9
+ [ :single ],
10
+ [ :numeral, :plural ],
11
+ [ :adjective, :plural ],
12
+ [ :adjective, :singular ],
13
+ [ :adjective, :adjective, :plural ],
14
+ [ :adjective, :adjective, :singular ],
15
+ [ :numeral, :adjective, :plural ],
16
+ [ :singular, :conjunction, :plural ],
17
+ [ :singular, :conjunction, :adjective, :plural ],
18
+ # [ :numeral, :adjective, :adjective, :plural ],
19
+ [ :adjective, :singular, :conjunction, :adjective, :singular ],
20
+ [ :adjective, :singular, :conjunction, :adjective, :adjective, :singular ]
21
+ ]
22
+
23
+ QUESTIONS = [ %w(Are you enjoying), %w(Have you seen), %w(Not enjoying),
24
+ %w(Forgot about), %w(Dream about), %w(Remember), %w(Cherish), %w(Recall),
25
+ %w(Enjoy), %w(Adore), %w(Like), %w(Love), %w(Miss), %w(See), ]
26
+
27
+ def story(words)
28
+ sentences = select_sentences(words)
29
+ each_haiku(sentences) do |haiku|
30
+ reformat(haiku)
31
+ end.join
32
+ end
33
+
34
+ private
35
+
36
+ def select_sentences(words)
37
+ sentences = []
38
+
39
+ while words.any? do
40
+ sentences += (3..7).to_a.shuffle.map do |n|
41
+ found = sentence(words[0, n]) if words.any?
42
+ words.shift(found.split.size) if found
43
+ found
44
+ end
45
+ end
46
+
47
+ sentences.compact
48
+ end
49
+
50
+ def pick_question(words)
51
+ return [] if words.size < 5 || words[-1] < 4
52
+
53
+ list = words.join
54
+ Array(QUESTIONS.select { |question| list.start_with?(question.map(&:size).join) }.sample)
55
+ end
56
+
57
+ def select_templates(words, size = 0)
58
+ limit = words.size - size
59
+ TEMPLATES.select { |template| template.size == limit }
60
+ end
61
+
62
+ def sentence(words)
63
+ question = pick_question(words)
64
+ templates = select_templates(words, question.size)
65
+
66
+ sentences = templates.map do |template|
67
+ vars, terms = words.dup, []
68
+
69
+ if question.any?
70
+ next if template.size != vars.size - question.size
71
+ terms = question # Start with question words.
72
+ vars.shift(terms.size) # Reduce variables since we've added some words already.
73
+ vars[-1] -= 1 # Make the last word shorter since we're appending "?".
74
+ end
75
+
76
+ terms.concat(template.map { |var| dictionary[var.to_s].pick(vars.shift) }).join(" ")
77
+ end.compact
78
+
79
+ if sentences.any?
80
+ best = sentences.sort_by(&:size).first # Pick the longest sentence. # sentences.sample
81
+ best << "?" if question.any?
82
+ best << "." unless best =~ /[\.\?!]$/
83
+ best.capitalize
84
+ end
85
+ end
86
+
87
+ def each_haiku(sentences)
88
+ sentences.each_slice(3).map do |slice|
89
+ yield slice.join(" ").sub(/\.\s*$/, "") # No trailing period.
90
+ end
91
+ end
92
+
93
+ def reformat(haiku)
94
+ haiku.gsub(/\s(\w+\.)/, "\n\\1") # Words ending with period must start on new line.
95
+ .gsub(/(.{1,#{30}})(?:\s+|$)|(.{1,#{30}})/, "\\1\\2\n") # Reformat paragraph.
96
+ .gsub(/\n(\w+\n)(\w+\.|$)/, " \\1\\2") # Move orphaned words to previous line.
97
+ .concat("\n")
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ module Unbelievable
7
+ class Lorem < Generator
8
+
9
+ def story(words)
10
+ terms = words.map { |size| dictionary.pick(size) }
11
+ wrap_text terms.join(" ").capitalize
12
+ end
13
+
14
+ private
15
+
16
+ def wrap_text(text, edge = 70)
17
+ text.gsub(/(.{1,#{edge}})(?:\s+|$)|(.{1,#{edge}})/, "\\1\\2\n") # Wrap at whatever the edge column is.
18
+ .gsub(/(\n\w+)(\s[a-z])/x) { $1 << %w(. ; .).sample << $2 } # Add punctiation after the first word on each line.
19
+ .gsub(/[\.\?!]\s[a-z]/) { |match| match.upcase } # Capitalize words after punctiation signs.
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ $unbelievable = { code: [], missing: [], passthrough: false, debug: false }
7
+
8
+ module Unbelievable
9
+ extend self
10
+ attr_accessor :style
11
+ STYLES = [ :random, :todo, :secret, :lorem, :haiku ]
12
+
13
+ def generate(code, style = nil)
14
+ with_method_missing do
15
+ style ||= @style || :random
16
+ unless STYLES.include?(style)
17
+ raise ArgumentError, "style must be one of #{STYLES.inspect} but not #{style.inspect}"
18
+ else
19
+ style = (STYLES - [:random]).sample if style == :random
20
+ chars = code.unpack("C*")
21
+ encoded = sprintf("%03o" * chars.size, *chars).unpack("C*").map{ |n| n - 45 }
22
+ generator = Object.const_get("#{self}::#{style.capitalize}")
23
+ generator.new.story(encoded)
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def with_method_missing(&blk)
31
+ $unbelievable[:passthrough] = true
32
+ yield
33
+ ensure
34
+ $unbelievable[:passthrough] = false
35
+ end
36
+ end
37
+
38
+ def method_missing(name, *args)
39
+ return super if $unbelievable[:passthrough] || defined?(::IRB) || defined?(::Pry)
40
+
41
+ if $unbelievable[:debug]
42
+ puts "method_missing: #{self.class.inspect} => #{self.inspect}"
43
+ puts "method_missing: #{name}: #{args}, #{$unbelievable[:missing].inspect}"
44
+ end
45
+
46
+ if args.empty? && $unbelievable[:missing].any?
47
+ $unbelievable[:code].concat($unbelievable[:missing].reverse)
48
+ $unbelievable[:missing].clear
49
+ end
50
+ $unbelievable[:missing] << (name.to_s.size - 1).to_s
51
+ end
52
+
53
+ def Object.const_missing(name)
54
+ send(name.downcase)
55
+ end
56
+
57
+ if !defined?(::IRB) && !defined?(::Pry)
58
+ at_exit do
59
+ if $unbelievable[:debug]
60
+ puts "miss: " << $unbelievable[:missing].reverse.inspect
61
+ puts "code: " << $unbelievable[:code].inspect
62
+ puts "scan: " << $unbelievable[:code].join.scan(/.../).inspect
63
+ puts "pack: " << $unbelievable[:code].join.scan(/.../).map { |o| o.bytes.map { |n| n - 2 }.pack("C*") }.inspect
64
+ puts "i(8): " << $unbelievable[:code].join.scan(/.../).map { |o| o.bytes.map { |n| n - 2 }.pack("C*").to_i(8) }.inspect
65
+ end
66
+
67
+ $unbelievable[:code].concat($unbelievable[:missing].reverse)
68
+ eval $unbelievable[:code].join.scan(/.../).map { |o| o.bytes.map { |n| n - 2 }.pack("C*").to_i(8).chr }.join
69
+ end
70
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ module Unbelievable
7
+ class Secret < Generator
8
+
9
+ def initialize(style = default_style)
10
+ super :todo
11
+ @todo ||= begin
12
+ todo = dictionary(:todo)["numeral"].concat(dictionary(:todo)["singular"])
13
+ todo.reject { |word| word.end_with?("!") }
14
+ end
15
+ end
16
+
17
+ def story(words)
18
+ terms = words.map { |size| @todo.pick(size) }
19
+ stash = wrap_text(terms.join(" "))
20
+ stash.gsub(/(\w+)/x) { rand(42) > 2 ? "_" * $1.size : $1 }
21
+ end
22
+
23
+ private
24
+
25
+ def wrap_text(text, edge = 70)
26
+ text.gsub(/(.{1,#{edge}})(?:\s+|$)|(.{1,#{edge}})/, "\\1\\2\n") # Wrap at whatever the edge column is.
27
+ .gsub(/(\n\w+)(\s[a-z])/x) { $1 << %w(. ; .).sample << $2 } # Add punctiation after the first word on each line.
28
+ .gsub(/[\.\?!]\s[a-z]/) { |match| match.upcase } # Capitalize words after punctiation signs.
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ module Unbelievable
7
+ class Todo < Generator
8
+ TEMPLATES = [
9
+ [ :verb ],
10
+ [ :verb, :plural ],
11
+ [ :verb, :singular ],
12
+ [ :adverb, :verb, :plural ],
13
+ [ :adverb, :verb, :singular ],
14
+ # [ :verb, :numeral, :plural ],
15
+ # [ :verb, :adjective, :plural ],
16
+ [ :verb, :adjective, :singular ],
17
+ [ :adverb, :verb, :adjective, :plural ],
18
+ [ :adverb, :verb, :adjective, :singular ],
19
+ # [ :adverb, :verb, :numeral, :plural ],
20
+ [ :verb, :numeral, :adjective, :plural ],
21
+ [ :adverb, :verb, :numeral, :adjective, :plural ]
22
+ ]
23
+
24
+ def story(words)
25
+ sentences = []
26
+
27
+ while words.any? do
28
+ sentences += [ 5, 4 ].shuffle.map do |n|
29
+ found = sentence(words[0, n]) if words.any?
30
+ words.shift(found.split.size) if found
31
+ found
32
+ end
33
+ end
34
+
35
+ sentences.compact.each_with_index.map { |todo, i| "#{i+1}. #{todo}" }.join("\n")
36
+ end
37
+
38
+ def sentence(words)
39
+ # Pick templates with given number of words.
40
+ templates = TEMPLATES.select { |template| template.size == words.size }
41
+
42
+ sentences = templates.map do |template|
43
+ vars = words.dup
44
+ formatted = template.map { |var| dictionary[var.to_s].pick(vars.shift) }
45
+ formatted.first.capitalize! unless formatted.first =~ /^[A-Z]|[\?!]$/
46
+ formatted.join(" ")
47
+ end
48
+
49
+ sentences.sample
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2013 Michael Dvorkin
2
+ #
3
+ # Unbelievable is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+
6
+ module Unbelievable
7
+ def self.version
8
+ "0.1.0"
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unbelievable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Dvorkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ''
14
+ email: mike@dvorkin.net
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Gemfile
20
+ - LICENSE
21
+ - Rakefile
22
+ - README.md
23
+ - lib/unbelievable/core_ext/array.rb
24
+ - lib/unbelievable/generator.rb
25
+ - lib/unbelievable/haiku.rb
26
+ - lib/unbelievable/lorem.rb
27
+ - lib/unbelievable/magic.rb
28
+ - lib/unbelievable/secret.rb
29
+ - lib/unbelievable/todo.rb
30
+ - lib/unbelievable/version.rb
31
+ - lib/unbelievable.rb
32
+ - lib/unbelievable/dictionary/haiku.json
33
+ - lib/unbelievable/dictionary/lorem.json
34
+ - lib/unbelievable/dictionary/todo.json
35
+ - .gitignore
36
+ homepage: http://github.com/michaeldv/unbelievable
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: 1.9.3
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.0.3
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: ''
60
+ test_files: []