dunmanifestin 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/dunmanifestin +4 -32
- data/lib/dunmanifestin/list_loader.rb +34 -36
- data/lib/dunmanifestin/phrase.rb +35 -34
- data/lib/dunmanifestin/terminator.rb +68 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a03c9a49c939ede783019bf96c30c78ecc8da467
|
4
|
+
data.tar.gz: 94c48fa2ccfce6eb50e4d260f8e491b914daa048
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e27e5770e85c523f3183019cb265fc3fb32fb6a5188a9808f80a4010996e3a8ab3691ad5f5207da907b4a3321afd296b24ed080379fb22d47c71c2ab162a25ea
|
7
|
+
data.tar.gz: 16f143e4be5d5c5d40f562a0911c6334377d88e8ba62f335e615440e76e792f22384e823f0d58bcd42ac8ef40c3ddf180492121f2e5135916777f4aad2efdf4c
|
data/bin/dunmanifestin
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'trollop'
|
4
|
-
require_relative '../lib/dunmanifestin'
|
4
|
+
require_relative '../lib/dunmanifestin/terminator'
|
5
5
|
|
6
6
|
user_demands = Trollop::options do
|
7
7
|
opt :debug, "Display errors and logging", short: '-d'
|
@@ -9,41 +9,13 @@ user_demands = Trollop::options do
|
|
9
9
|
opt :count, "Specify how many lines of output to generate at once", type: :integer, short: '-n'
|
10
10
|
opt :copy, "Copies manifestation into your clipboard", short: '-c'
|
11
11
|
opt :genre, "Specify a genre, e.g. '-g scifi'", type: :string, short: '-g', default: 'default'
|
12
|
-
opt :phrase, "Specify a phrase or list, e.g. 'The [animal] sat on the [article]' or '[weapon]'", type: :string, short: '-p'
|
12
|
+
opt :phrase, "Specify a phrase or list, e.g. 'The [animal] sat on the [article]' or '[weapon]'", type: :string, short: '-p'
|
13
13
|
opt :chomp, "remove the trailing newline from the output", short: '-h'
|
14
|
-
|
15
|
-
|
16
|
-
def get_from_prompt
|
17
|
-
print "dunmanifestin > "
|
18
|
-
gets.chomp
|
19
|
-
end
|
20
|
-
|
21
|
-
def print_interactive_banner
|
22
|
-
print "---------------------------------------------------------------------\n"+
|
23
|
-
"Type 'quit' to exit the prompt. Press return to generate more output.\n"+
|
24
|
-
"---------------------------------------------------------------------\n\n"
|
14
|
+
opt :file, "Read a file as the phrase", type: :string, short: '-f'
|
25
15
|
end
|
26
16
|
|
27
17
|
begin
|
28
|
-
|
29
|
-
ListLoader.new(user_demands[:genre]).load
|
30
|
-
|
31
|
-
print_interactive_banner if user_demands[:interactive]
|
32
|
-
|
33
|
-
fulltext = ""
|
34
|
-
|
35
|
-
while true
|
36
|
-
(user_demands[:count] || 1).times do
|
37
|
-
text = root_phrase_class.new.to_s
|
38
|
-
fulltext += "\n#{text}"
|
39
|
-
text += "\n" unless user_demands[:chomp]
|
40
|
-
puts text
|
41
|
-
end
|
42
|
-
|
43
|
-
`echo #{fulltext.inspect} | pbcopy $1` if user_demands[:copy]
|
44
|
-
|
45
|
-
break if !user_demands[:interactive] || get_from_prompt == 'quit'
|
46
|
-
end
|
18
|
+
Terminator.new.address user_demands
|
47
19
|
rescue => e
|
48
20
|
raise e if user_demands[:debug]
|
49
21
|
ensure
|
@@ -1,44 +1,42 @@
|
|
1
1
|
class ListLoader
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
Dir[list_dir('default')].each(&method(:create_list_from))
|
8
|
-
Dir[list_dir(genre)].each(&method(:create_list_from)) unless genre == 'default'
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def list_dir(genre)
|
14
|
-
dir_of_this_file = File.dirname(__FILE__)
|
15
|
-
File.join(*%W(#{dir_of_this_file} .. .. lists #{genre} ** *))
|
16
|
-
end
|
17
|
-
|
18
|
-
def create_list_from path
|
19
|
-
newlines_before_a_pipe = /\n(?=\|)/
|
20
|
-
everything_up_to_the_first_newline_if_first_character_is_a_pipe = /^\|(.*?)\n/
|
21
|
-
everything_after_the_last_slash = /\/.+$/
|
2
|
+
class << self
|
3
|
+
def load genre=@genre
|
4
|
+
Dir[list_dir('default')].each(&method(:create_list_from))
|
5
|
+
Dir[list_dir(genre)].each(&method(:create_list_from)) unless genre == 'default'
|
6
|
+
end
|
22
7
|
|
23
|
-
|
24
|
-
lists.each_with_index do |_list, i|
|
25
|
-
list_name = _list.match(everything_up_to_the_first_newline_if_first_character_is_a_pipe)[1].to_s
|
8
|
+
private
|
26
9
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
10
|
+
def list_dir(genre)
|
11
|
+
dir_of_this_file = File.dirname(__FILE__)
|
12
|
+
File.join(*%W(#{dir_of_this_file} .. .. lists #{genre} ** *))
|
13
|
+
end
|
32
14
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
15
|
+
def create_list_from path
|
16
|
+
newlines_before_a_pipe = /\n(?=\|)/
|
17
|
+
everything_up_to_the_first_newline_if_first_character_is_a_pipe = /^\|(.*?)\n/
|
18
|
+
everything_after_the_last_slash = /\/.+$/
|
19
|
+
|
20
|
+
lists = File.open(path).read.split(newlines_before_a_pipe)
|
21
|
+
lists.each_with_index do |_list, i|
|
22
|
+
list_name = _list.match(everything_up_to_the_first_newline_if_first_character_is_a_pipe)[1].to_s
|
23
|
+
|
24
|
+
if list_name.empty?
|
25
|
+
list_name = path.match(everything_after_the_last_slash).to_s
|
26
|
+
else
|
27
|
+
_list.gsub!(everything_up_to_the_first_newline_if_first_character_is_a_pipe, '')
|
28
|
+
end
|
29
|
+
|
30
|
+
phrase_class_name = list_name.underscore.camelize
|
31
|
+
begin
|
32
|
+
qlass = "Phrase::#{phrase_class_name}".constantize
|
33
|
+
rescue NameError
|
34
|
+
qlass = Class.new(Phrase)
|
35
|
+
Phrase.const_set phrase_class_name, qlass
|
36
|
+
end
|
37
|
+
|
38
|
+
qlass.list(_list)
|
39
39
|
end
|
40
|
-
|
41
|
-
qlass.list(_list)
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
data/lib/dunmanifestin/phrase.rb
CHANGED
@@ -2,29 +2,30 @@ require 'active_support/inflector'
|
|
2
2
|
|
3
3
|
class Phrase
|
4
4
|
def self.list new_list = nil
|
5
|
-
return @list unless new_list
|
6
|
-
|
5
|
+
return (@list || []) unless new_list
|
6
|
+
|
7
7
|
if new_list.is_a? String
|
8
8
|
new_list = new_list.split_on_newlines_and_strip
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
new_list.map! do |line|
|
12
12
|
multiplier_regex = /^\d+@/
|
13
13
|
multiplier = line.match(multiplier_regex).to_s.to_i
|
14
14
|
multiplier = 1 if multiplier < 1
|
15
15
|
[line.gsub(multiplier_regex, '')] * multiplier
|
16
16
|
end.flatten!.reject! { |i| i.nil? || i.empty? }
|
17
|
-
|
17
|
+
|
18
18
|
@list = new_list
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def initialize dsl_string = self.class.list.sample
|
22
|
+
raise "Try again." unless dsl_string
|
22
23
|
compile parse dsl_string
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
def compile parsed_dsl
|
26
27
|
template = parsed_dsl[:template]
|
27
|
-
|
28
|
+
|
28
29
|
@variable_classes = []
|
29
30
|
@inflection_delegates = {
|
30
31
|
:plural => [],
|
@@ -32,22 +33,22 @@ class Phrase
|
|
32
33
|
:article => [],
|
33
34
|
:capitalize => [],
|
34
35
|
}
|
35
|
-
|
36
|
+
|
36
37
|
inflections = []
|
37
|
-
|
38
|
+
|
38
39
|
parsed_dsl[:variables].each_with_index do |variable, i|
|
39
40
|
rough_var_class = variable[:rough_variable_class]
|
40
|
-
|
41
|
+
|
41
42
|
variable[:inflections_to_delegate].each do |inflection|
|
42
43
|
@inflection_delegates[inflection.to_sym] << i
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
inflections[i] = []
|
46
|
-
|
47
|
+
|
47
48
|
variable[:inflections_to_apply].each do |inflection|
|
48
49
|
inflections[i] << inflection.to_sym
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
begin
|
52
53
|
@variable_classes << "Phrase::#{rough_var_class.camelize}".constantize
|
53
54
|
rescue NameError
|
@@ -58,7 +59,7 @@ class Phrase
|
|
58
59
|
end|)
|
59
60
|
end
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
@to_s_proc = -> {
|
63
64
|
self.variables.each_with_index do |variable, i|
|
64
65
|
inflections[i].each do |inflection|
|
@@ -68,7 +69,7 @@ class Phrase
|
|
68
69
|
template.zip(self.variables).flatten.map(&:to_s).join('')
|
69
70
|
}
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
def parse dsl_string = @dsl_string
|
73
74
|
# A dsl string like "[adjective] [noun.possessive#plural]" will be parsed into
|
74
75
|
# { :variables =>
|
@@ -86,7 +87,7 @@ class Phrase
|
|
86
87
|
#
|
87
88
|
tokens = dsl_string.split(/[\[\]]/)
|
88
89
|
template = []; variables = [];
|
89
|
-
|
90
|
+
|
90
91
|
tokens.each_with_index do |token, i|
|
91
92
|
if i % 2 == 0
|
92
93
|
template << token
|
@@ -94,69 +95,69 @@ class Phrase
|
|
94
95
|
variables << token
|
95
96
|
end
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
hash = {:variables => [], :template => template}
|
99
|
-
|
100
|
+
|
100
101
|
variables.each_with_index do |variable, i|
|
101
102
|
components = variable.split(/\b/)
|
102
103
|
rough_var_class = components.shift
|
103
104
|
inflections_to_delegate = []
|
104
105
|
inflections_to_apply = []
|
105
|
-
|
106
|
+
|
106
107
|
components.each_with_index do |v, k|
|
107
108
|
inflections_to_delegate << v if components[k-1] == '#'
|
108
109
|
inflections_to_apply << v if components[k-1] == '.'
|
109
110
|
end
|
110
|
-
|
111
|
+
|
111
112
|
hash[:variables] << {
|
112
113
|
:rough_variable_class => rough_var_class,
|
113
114
|
:inflections_to_delegate => inflections_to_delegate,
|
114
115
|
:inflections_to_apply => inflections_to_apply,
|
115
116
|
}
|
116
117
|
end
|
117
|
-
|
118
|
+
|
118
119
|
hash
|
119
120
|
end
|
120
|
-
|
121
|
+
|
121
122
|
def variables
|
122
123
|
@variables ||= @variable_classes.map(&:new)
|
123
124
|
end
|
124
|
-
|
125
|
+
|
125
126
|
def plural?; !!@plural end
|
126
127
|
def possessive?; !!@possessive end
|
127
128
|
def article?; !!@article end
|
128
129
|
def capitalize?; !!@capitalize end
|
129
|
-
|
130
|
+
|
130
131
|
def plural!
|
131
132
|
@plural = true
|
132
|
-
|
133
|
+
|
133
134
|
@inflection_delegates[:plural].each do |delegate|
|
134
135
|
variables[delegate].plural!
|
135
136
|
end
|
136
137
|
self
|
137
138
|
end
|
138
|
-
|
139
|
+
|
139
140
|
def article!
|
140
141
|
@article = true
|
141
|
-
|
142
|
+
|
142
143
|
@inflection_delegates[:article].each do |delegate|
|
143
144
|
variables[delegate].article!
|
144
145
|
end
|
145
146
|
self
|
146
147
|
end
|
147
|
-
|
148
|
+
|
148
149
|
def possessive!
|
149
150
|
@possessive = true
|
150
|
-
|
151
|
+
|
151
152
|
@inflection_delegates[:possessive].each do |delegate|
|
152
153
|
variables[delegate].possessive!
|
153
154
|
end
|
154
155
|
self
|
155
156
|
end
|
156
|
-
|
157
|
+
|
157
158
|
def capitalize!
|
158
159
|
@capitalize = true
|
159
|
-
|
160
|
+
|
160
161
|
@inflection_delegates[:capitalize].each do |delegate|
|
161
162
|
variables[delegate].capitalize!
|
162
163
|
end
|
@@ -166,7 +167,7 @@ class Phrase
|
|
166
167
|
def to_s
|
167
168
|
render_inflections @to_s_proc.call
|
168
169
|
end
|
169
|
-
|
170
|
+
|
170
171
|
def render_inflections string
|
171
172
|
if plural?
|
172
173
|
string = string.pluralize if @inflection_delegates[:plural].empty?
|
@@ -190,9 +191,9 @@ class Phrase
|
|
190
191
|
string = "#{string}'s"
|
191
192
|
end
|
192
193
|
end
|
193
|
-
|
194
|
+
|
194
195
|
string = string[0].capitalize + string[1 .. -1] if capitalize?
|
195
|
-
|
196
|
+
|
196
197
|
string
|
197
198
|
end
|
198
199
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'phrase'
|
2
|
+
require_relative 'list_loader'
|
3
|
+
require_relative 'string'
|
4
|
+
|
5
|
+
class Terminator
|
6
|
+
def initialize(list_loader: ListLoader, shell: Shell)
|
7
|
+
@list_loader = list_loader
|
8
|
+
@shell = shell
|
9
|
+
end
|
10
|
+
|
11
|
+
def address demands
|
12
|
+
phrase_string = phrasing(demands[:phrase], demands[:file])
|
13
|
+
root_phrase_class = Class.new(Phrase) { list phrase_string }
|
14
|
+
list_loader.load demands[:genre]
|
15
|
+
print interactive_banner if demands[:interactive]
|
16
|
+
|
17
|
+
construction_loop(
|
18
|
+
root_phrase_class,
|
19
|
+
(demands[:count] || 1),
|
20
|
+
demands[:chomp],
|
21
|
+
demands[:copy],
|
22
|
+
demands[:interactive]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
attr_accessor :list_loader, :shell
|
28
|
+
|
29
|
+
def construction_loop root_phrase_class, volume, chomp, copy, interact
|
30
|
+
fulltext = ""
|
31
|
+
while true
|
32
|
+
volume.times do
|
33
|
+
text = root_phrase_class.new.to_s
|
34
|
+
fulltext += "\n#{text}"
|
35
|
+
text += "\n" unless chomp
|
36
|
+
shell.puts text
|
37
|
+
end
|
38
|
+
|
39
|
+
`echo #{fulltext.inspect} | pbcopy $1` if copy
|
40
|
+
|
41
|
+
break unless interact
|
42
|
+
break if get_from_prompt == 'quit'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def phrasing given, file
|
47
|
+
given || (File.read(file) if file) || '[root]'
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_from_prompt
|
51
|
+
shell.print "dunmanifestin > "
|
52
|
+
shell.gets.chomp
|
53
|
+
end
|
54
|
+
|
55
|
+
def interactive_banner
|
56
|
+
message = "Type 'quit' to exit the prompt. Press return to generate more output."
|
57
|
+
bar = "-"*message.length
|
58
|
+
[bar, message, bar].join "\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
module Shell
|
62
|
+
class << self
|
63
|
+
def method_missing method, *args
|
64
|
+
send method, *args
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dunmanifestin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- quavmo
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- lib/dunmanifestin/member.rb
|
32
32
|
- lib/dunmanifestin/phrase.rb
|
33
33
|
- lib/dunmanifestin/string.rb
|
34
|
+
- lib/dunmanifestin/terminator.rb
|
34
35
|
- lists/default/activated
|
35
36
|
- lists/default/adverb
|
36
37
|
- lists/default/ageGroup
|