confabulator 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +34 -14
- data/lib/confabulator/language.rb +111 -18
- data/lib/confabulator/parser.rb +52 -1
- data/lib/confabulator/version.rb +1 -1
- data/spec/confabulator_spec.rb +44 -4
- data/src/confabulator_language.treetop +72 -14
- metadata +8 -8
data/README.markdown
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Confabulator
|
2
2
|
|
3
|
-
A recursive Ruby
|
3
|
+
A recursive Ruby templating language for the procedural generation of random sentences.
|
4
|
+
|
5
|
+
## Why do I care?
|
6
|
+
|
7
|
+
Perhaps you want to generate emails, text messages, or webpages that are all readable, but have different wording. Perhaps you're writing a game and want to vary character dialog. Perhaps you don't need a reason.
|
4
8
|
|
5
9
|
## Install
|
6
10
|
|
@@ -20,12 +24,16 @@ Choice blocks let the parser make a random choice.
|
|
20
24
|
Choice two and stuff
|
21
25
|
...
|
22
26
|
|
23
|
-
|
27
|
+
Choices inside of choices (ad infinitum) are fine:
|
24
28
|
|
25
|
-
> 5.times { puts Confabulator::Parser.new("{
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
> 5.times { puts Confabulator::Parser.new("This is {an example|a {good|great|mediocre} demonstration}").confabulate }
|
30
|
+
This is a great demonstration
|
31
|
+
This is a mediocre demonstration
|
32
|
+
This is an example
|
33
|
+
This is a good demonstration
|
34
|
+
This is an example
|
35
|
+
This is an example
|
36
|
+
This is a good demonstration
|
29
37
|
...
|
30
38
|
|
31
39
|
You can differentially weight the options: {5:This is 5 times more likely|than this}
|
@@ -35,19 +43,22 @@ You can differentially weight the options: {5:This is 5 times more likely|than t
|
|
35
43
|
Substitutions let you re-use common templates.
|
36
44
|
|
37
45
|
> knowledge = Confabulator::Knowledge.new
|
38
|
-
> knowledge.add "
|
39
|
-
> Confabulator::Parser.new("Hello, [
|
46
|
+
> knowledge.add "friend", "{friend|world|there}" # a hash is also acceptable
|
47
|
+
> Confabulator::Parser.new("Hello, [friend]!", :knowledge => knowledge).confabulate
|
40
48
|
=> "Hello, there!"
|
49
|
+
> Confabulator::Parser.new("Hello, [friend]!", :knowledge => knowledge).confabulate
|
50
|
+
=> "Hello, world!"
|
51
|
+
...
|
41
52
|
|
42
|
-
Equivalently:
|
53
|
+
Equivalently, as a helper on the Knowledge object:
|
43
54
|
|
44
|
-
> knowledge.confabulate("Hello, [
|
55
|
+
> knowledge.confabulate("Hello, [friend]!")
|
45
56
|
=> "Hello, there!"
|
46
57
|
|
47
58
|
You can ask a substitution to be capitalized:
|
48
59
|
|
49
|
-
> knowledge.confabulate("Hello, [
|
50
|
-
=> "Hello,
|
60
|
+
> knowledge.confabulate("Hello, [friend:c]!")
|
61
|
+
=> "Hello, World!"
|
51
62
|
|
52
63
|
Or pluralized:
|
53
64
|
|
@@ -55,7 +66,7 @@ Or pluralized:
|
|
55
66
|
> knowledge.confabulate("Hello, [dude:p]!")
|
56
67
|
=> "Hello, friends!"
|
57
68
|
|
58
|
-
Substitutions can contain other substitutions
|
69
|
+
Substitutions can contain other substitutions inside of choice nodes inside of other substitutions, etc., ad infinitum. Just try to avoid infinite loops!
|
59
70
|
|
60
71
|
### Escaping
|
61
72
|
|
@@ -76,6 +87,15 @@ Sometimes you want to insert user generated content without having to escape eve
|
|
76
87
|
|
77
88
|
At the moment, sequences of more than one backtick are never allowed inside of a protected region.
|
78
89
|
|
90
|
+
## Next Steps
|
91
|
+
|
92
|
+
Here are some things that could be added to this library:
|
93
|
+
|
94
|
+
* Depth limits
|
95
|
+
* Better escaping
|
96
|
+
* Learning through back propagation of a reward signal and optimization of the choice nodes to make the rewarded or penalized outcome more or less likely, respectively.
|
97
|
+
* Whatever you want!
|
98
|
+
|
79
99
|
## Helping out
|
80
100
|
|
81
|
-
Fork, write specs, add a feature, send me a pull request!
|
101
|
+
Fork, write specs, add a feature, write documentation, send me a pull request!
|
@@ -10,9 +10,13 @@ module Confabulator
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module Sentence0
|
13
|
-
def
|
14
|
-
elements.map {|e| e.
|
13
|
+
def confabulate(kb = nil)
|
14
|
+
elements.map {|e| e.confabulate(kb) }.join
|
15
15
|
end
|
16
|
+
|
17
|
+
def tree(kb = nil)
|
18
|
+
elements.map { |e| e.tree(kb) }
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def _nt_sentence
|
@@ -90,7 +94,7 @@ module Confabulator
|
|
90
94
|
elements[1]
|
91
95
|
end
|
92
96
|
|
93
|
-
def
|
97
|
+
def sentence_or_empty
|
94
98
|
elements[2]
|
95
99
|
end
|
96
100
|
end
|
@@ -107,13 +111,23 @@ module Confabulator
|
|
107
111
|
end
|
108
112
|
|
109
113
|
module Choice3
|
110
|
-
|
111
|
-
|
112
|
-
(first_sentence.weight.empty? ? 1 : first_sentence.weight.value).times { elems << first_sentence.sentence }
|
114
|
+
def choices(kb, no_weighting = false)
|
115
|
+
elems = []
|
116
|
+
((no_weighting || first_sentence.weight.empty?) ? 1 : first_sentence.weight.value).times { elems << first_sentence.sentence }
|
113
117
|
rest_sentences.elements.each do |s|
|
114
|
-
(s.weight.empty? ? 1 : s.weight.value).times { elems << s.
|
118
|
+
((no_weighting || s.weight.empty?) ? 1 : s.weight.value).times { elems << s.sentence_or_empty }
|
115
119
|
end
|
116
|
-
elems
|
120
|
+
elems
|
121
|
+
end
|
122
|
+
|
123
|
+
def confabulate(kb = nil)
|
124
|
+
elems = choices(kb)
|
125
|
+
elems[elems.length * rand].confabulate(kb)
|
126
|
+
end
|
127
|
+
|
128
|
+
def tree(kb = nil)
|
129
|
+
elems = choices(kb, true)
|
130
|
+
{ :choices => elems.map {|e| Confabulator::Parser.remove_singleton_arrays(e.tree(kb)) } }
|
117
131
|
end
|
118
132
|
end
|
119
133
|
|
@@ -179,7 +193,19 @@ module Confabulator
|
|
179
193
|
end
|
180
194
|
s7 << r9
|
181
195
|
if r9
|
182
|
-
|
196
|
+
i11 = index
|
197
|
+
r12 = _nt_sentence
|
198
|
+
if r12
|
199
|
+
r11 = r12
|
200
|
+
else
|
201
|
+
r13 = _nt_empty
|
202
|
+
if r13
|
203
|
+
r11 = r13
|
204
|
+
else
|
205
|
+
@index = i11
|
206
|
+
r11 = nil
|
207
|
+
end
|
208
|
+
end
|
183
209
|
s7 << r11
|
184
210
|
end
|
185
211
|
end
|
@@ -200,13 +226,13 @@ module Confabulator
|
|
200
226
|
s0 << r6
|
201
227
|
if r6
|
202
228
|
if has_terminal?('}', false, index)
|
203
|
-
|
229
|
+
r14 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
204
230
|
@index += 1
|
205
231
|
else
|
206
232
|
terminal_parse_failure('}')
|
207
|
-
|
233
|
+
r14 = nil
|
208
234
|
end
|
209
|
-
s0 <<
|
235
|
+
s0 << r14
|
210
236
|
end
|
211
237
|
end
|
212
238
|
end
|
@@ -224,6 +250,41 @@ module Confabulator
|
|
224
250
|
r0
|
225
251
|
end
|
226
252
|
|
253
|
+
module Empty0
|
254
|
+
def confabulate(kb = nil)
|
255
|
+
''
|
256
|
+
end
|
257
|
+
|
258
|
+
def tree(kb = nil)
|
259
|
+
confabulate(kb)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def _nt_empty
|
264
|
+
start_index = index
|
265
|
+
if node_cache[:empty].has_key?(index)
|
266
|
+
cached = node_cache[:empty][index]
|
267
|
+
if cached
|
268
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
269
|
+
@index = cached.interval.end
|
270
|
+
end
|
271
|
+
return cached
|
272
|
+
end
|
273
|
+
|
274
|
+
if has_terminal?('', false, index)
|
275
|
+
r0 = instantiate_node(SyntaxNode,input, index...(index + 0))
|
276
|
+
r0.extend(Empty0)
|
277
|
+
@index += 0
|
278
|
+
else
|
279
|
+
terminal_parse_failure('')
|
280
|
+
r0 = nil
|
281
|
+
end
|
282
|
+
|
283
|
+
node_cache[:empty][start_index] = r0
|
284
|
+
|
285
|
+
r0
|
286
|
+
end
|
287
|
+
|
227
288
|
module Weight0
|
228
289
|
def w
|
229
290
|
elements[0]
|
@@ -305,11 +366,15 @@ module Confabulator
|
|
305
366
|
end
|
306
367
|
|
307
368
|
module Protected2
|
308
|
-
def
|
369
|
+
def confabulate(kb = nil)
|
309
370
|
words.elements.map { |element|
|
310
371
|
element.text_value == "\\`" ? "`" : element.text_value
|
311
372
|
}.join
|
312
373
|
end
|
374
|
+
|
375
|
+
def tree(kb = nil)
|
376
|
+
confabulate(kb)
|
377
|
+
end
|
313
378
|
end
|
314
379
|
|
315
380
|
def _nt_protected
|
@@ -445,12 +510,13 @@ module Confabulator
|
|
445
510
|
end
|
446
511
|
|
447
512
|
module Substitution3
|
448
|
-
def
|
513
|
+
def confabulate(kb = nil)
|
449
514
|
if kb
|
450
515
|
result = kb.find(name.text_value).confabulate
|
451
516
|
if options.text_value =~ /p/
|
452
517
|
result = result.en.plural
|
453
|
-
|
518
|
+
end
|
519
|
+
if options.text_value =~ /c/
|
454
520
|
result[0] = result[0].upcase if result[0]
|
455
521
|
end
|
456
522
|
result
|
@@ -458,6 +524,21 @@ module Confabulator
|
|
458
524
|
""
|
459
525
|
end
|
460
526
|
end
|
527
|
+
|
528
|
+
def tree(kb = nil)
|
529
|
+
if kb
|
530
|
+
results = kb.find(name.text_value).tree
|
531
|
+
if options.text_value =~ /p/
|
532
|
+
results = { :pluralize => results }
|
533
|
+
end
|
534
|
+
if options.text_value =~ /c/
|
535
|
+
results = { :capitalize => results }
|
536
|
+
end
|
537
|
+
results
|
538
|
+
else
|
539
|
+
""
|
540
|
+
end
|
541
|
+
end
|
461
542
|
end
|
462
543
|
|
463
544
|
def _nt_substitution
|
@@ -617,9 +698,13 @@ module Confabulator
|
|
617
698
|
end
|
618
699
|
|
619
700
|
module W0
|
620
|
-
def
|
701
|
+
def confabulate(kb = nil)
|
621
702
|
text_value
|
622
703
|
end
|
704
|
+
|
705
|
+
def tree(kb = nil)
|
706
|
+
confabulate(kb)
|
707
|
+
end
|
623
708
|
end
|
624
709
|
|
625
710
|
def _nt_w
|
@@ -662,9 +747,13 @@ module Confabulator
|
|
662
747
|
end
|
663
748
|
|
664
749
|
module EscapedChar1
|
665
|
-
def
|
750
|
+
def confabulate(kb = nil)
|
666
751
|
character.text_value
|
667
752
|
end
|
753
|
+
|
754
|
+
def tree(kb = nil)
|
755
|
+
confabulate(kb)
|
756
|
+
end
|
668
757
|
end
|
669
758
|
|
670
759
|
def _nt_escaped_char
|
@@ -712,9 +801,13 @@ module Confabulator
|
|
712
801
|
end
|
713
802
|
|
714
803
|
module Words0
|
715
|
-
def
|
804
|
+
def confabulate(kb = nil)
|
716
805
|
text_value
|
717
806
|
end
|
807
|
+
|
808
|
+
def tree(kb = nil)
|
809
|
+
confabulate(kb)
|
810
|
+
end
|
718
811
|
end
|
719
812
|
|
720
813
|
def _nt_words
|
data/lib/confabulator/parser.rb
CHANGED
@@ -14,7 +14,7 @@ module Confabulator
|
|
14
14
|
|
15
15
|
def confabulate
|
16
16
|
if parser
|
17
|
-
result = parser.
|
17
|
+
result = parser.confabulate(kb)
|
18
18
|
result.gsub!(REMOVE_SPACES, '\1 \2') while result =~ REMOVE_SPACES
|
19
19
|
result
|
20
20
|
else
|
@@ -22,6 +22,14 @@ module Confabulator
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def all_confabulations
|
26
|
+
self.class.expand_tree(tree)
|
27
|
+
end
|
28
|
+
|
29
|
+
def tree
|
30
|
+
parser ? parser.tree(kb) : []
|
31
|
+
end
|
32
|
+
|
25
33
|
def parser
|
26
34
|
if !@parsed # this caches even a nil result
|
27
35
|
@cached_parser = ConfabulatorLanguageParser.new.parse(confabulation)
|
@@ -30,5 +38,48 @@ module Confabulator
|
|
30
38
|
|
31
39
|
@cached_parser
|
32
40
|
end
|
41
|
+
|
42
|
+
def self.expand_tree(s, combinations = [], x = nil, *a)
|
43
|
+
if !s.is_a?(String) && combinations == []
|
44
|
+
expand_tree("", combinations, *s)
|
45
|
+
else
|
46
|
+
case x
|
47
|
+
when Hash
|
48
|
+
if x[:choices]
|
49
|
+
x[:choices].each {|c| expand_tree(s, combinations, c, *a)}
|
50
|
+
elsif x[:pluralize]
|
51
|
+
tree_below_here = expand_tree("", [], x[:pluralize]).map { |r| r.en.plural }
|
52
|
+
expand_tree(s, combinations, { :choices => tree_below_here })
|
53
|
+
elsif x[:capitalize]
|
54
|
+
tree_below_here = expand_tree("", [], x[:capitalize])
|
55
|
+
tree_below_here.each { |r| r[0] = r[0].upcase if r[0] }
|
56
|
+
expand_tree(s, combinations, { :choices => tree_below_here })
|
57
|
+
else
|
58
|
+
raise "Hash found without :choices, :pluralize, or :capitalize in it: #{x.inspect}"
|
59
|
+
end
|
60
|
+
when Array
|
61
|
+
expand_tree(s, combinations, *x, *a)
|
62
|
+
when String
|
63
|
+
expand_tree(s+x, combinations, *a)
|
64
|
+
when nil
|
65
|
+
combinations << s
|
66
|
+
else
|
67
|
+
raise "Non String, Array, Hash, or nil value in expand_tree: #{x.inspect}"
|
68
|
+
end
|
69
|
+
combinations
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.remove_singleton_arrays(arr)
|
74
|
+
if arr.is_a?(Array)
|
75
|
+
if arr.length == 1
|
76
|
+
remove_singleton_arrays(arr.first)
|
77
|
+
else
|
78
|
+
arr.map { |a| remove_singleton_arrays(a) }
|
79
|
+
end
|
80
|
+
else
|
81
|
+
arr
|
82
|
+
end
|
83
|
+
end
|
33
84
|
end
|
34
85
|
end
|
data/lib/confabulator/version.rb
CHANGED
data/spec/confabulator_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe Confabulator do
|
|
11
11
|
"Choice two and stuff"
|
12
12
|
]
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it "should be recursive" do
|
16
16
|
100.times.map {
|
17
17
|
Confabulator::Parser.new("{Choice {1|2}|Choice 3} and stuff").confabulate
|
@@ -35,6 +35,16 @@ describe Confabulator do
|
|
35
35
|
one.should > two * 3
|
36
36
|
one.should < two * 7
|
37
37
|
end
|
38
|
+
|
39
|
+
it "should allow an empty node" do
|
40
|
+
100.times.map {
|
41
|
+
Confabulator::Parser.new("{foo|}bar").confabulate
|
42
|
+
}.uniq.sort.should == [ "bar", "foobar" ]
|
43
|
+
|
44
|
+
100.times.map {
|
45
|
+
Confabulator::Parser.new("{a|b|c|}x").confabulate
|
46
|
+
}.uniq.sort.should == [ "ax", "bx", "cx", "x" ]
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
describe "substitutions" do
|
@@ -47,7 +57,7 @@ describe Confabulator do
|
|
47
57
|
it "should return an empty string if it cannot be found" do
|
48
58
|
Confabulator::Parser.new("Hello, [world]!").confabulate.should == "Hello, !"
|
49
59
|
end
|
50
|
-
|
60
|
+
|
51
61
|
it "should work recursively" do
|
52
62
|
k = Confabulator::Knowledge.new
|
53
63
|
k.add "expand" => "is [recursive]",
|
@@ -71,12 +81,18 @@ describe Confabulator do
|
|
71
81
|
k.add "blah" => "world foo"
|
72
82
|
k.confabulate("Hello. [blah:c]!").should == "Hello. World foo!"
|
73
83
|
end
|
74
|
-
|
84
|
+
|
75
85
|
it "should be able to pluralize" do
|
76
86
|
k = Confabulator::Knowledge.new
|
77
87
|
k.add "blah" => "ancient dog"
|
78
88
|
k.confabulate("Many [blah:p]!").should == "Many ancient dogs!"
|
79
89
|
end
|
90
|
+
|
91
|
+
it "should be able to pluralize and capitalize at the same time" do
|
92
|
+
k = Confabulator::Knowledge.new
|
93
|
+
k.add "blah" => "ancient dog"
|
94
|
+
k.confabulate("Many [blah:pc]!").should == "Many Ancient dogs!"
|
95
|
+
end
|
80
96
|
end
|
81
97
|
|
82
98
|
describe "general behavior" do
|
@@ -84,7 +100,7 @@ describe Confabulator do
|
|
84
100
|
@k = Confabulator::Knowledge.new
|
85
101
|
@k.add "expand" => " is {[recursive]| not recursive}", "recursive" => "pretty cool "
|
86
102
|
end
|
87
|
-
|
103
|
+
|
88
104
|
it "should remove repeated spaces between words" do
|
89
105
|
@k.confabulate("Hello, this [expand]!").should_not =~ / /
|
90
106
|
end
|
@@ -109,4 +125,28 @@ describe Confabulator do
|
|
109
125
|
Confabulator::Parser.new("Hi \\[foo]\\{bar\\|foo\\}\\`baz\\` and stuff").confabulate.should == "Hi [foo]{bar|foo}`baz` and stuff"
|
110
126
|
end
|
111
127
|
end
|
128
|
+
|
129
|
+
describe "listing all possible confabulations" do
|
130
|
+
it "should be able to enumerate all possible onfabulations" do
|
131
|
+
k = Confabulator::Knowledge.new
|
132
|
+
k.add "friend" => "{friend|pal}"
|
133
|
+
k.add "from" => "your [friend:c]"
|
134
|
+
k.add "said" => "says"
|
135
|
+
all = Confabulator::Parser.new("{He{ll}o|Hi} {worl{d|}|there}, [said] [from:cp]", :knowledge => k).all_confabulations
|
136
|
+
all.should =~ [
|
137
|
+
"Hello world, says Your Friends",
|
138
|
+
"Hello worl, says Your Friends",
|
139
|
+
"Hello there, says Your Friends",
|
140
|
+
"Hi world, says Your Friends",
|
141
|
+
"Hi worl, says Your Friends",
|
142
|
+
"Hi there, says Your Friends",
|
143
|
+
"Hello world, says Your Pals",
|
144
|
+
"Hello worl, says Your Pals",
|
145
|
+
"Hello there, says Your Pals",
|
146
|
+
"Hi world, says Your Pals",
|
147
|
+
"Hi worl, says Your Pals",
|
148
|
+
"Hi there, says Your Pals"
|
149
|
+
]
|
150
|
+
end
|
151
|
+
end
|
112
152
|
end
|
@@ -2,25 +2,51 @@ module Confabulator
|
|
2
2
|
grammar ConfabulatorLanguage
|
3
3
|
rule sentence
|
4
4
|
(protected / substitution / choice / escaped_char / words)+ {
|
5
|
-
def
|
6
|
-
elements.map {|e| e.
|
5
|
+
def confabulate(kb = nil)
|
6
|
+
elements.map {|e| e.confabulate(kb) }.join
|
7
7
|
end
|
8
|
+
|
9
|
+
def tree(kb = nil)
|
10
|
+
elements.map { |e| e.tree(kb) }
|
11
|
+
end
|
8
12
|
}
|
9
13
|
end
|
10
14
|
|
11
15
|
rule choice
|
12
|
-
'{' first_sentence:(weight:weight? sentence) rest_sentences:('|' weight:weight? sentence)* '}' {
|
13
|
-
|
14
|
-
|
15
|
-
(first_sentence.weight.empty? ? 1 : first_sentence.weight.value).times { elems << first_sentence.sentence }
|
16
|
+
'{' first_sentence:(weight:weight? sentence) rest_sentences:('|' weight:weight? sentence_or_empty:(sentence / empty))* '}' {
|
17
|
+
def choices(kb, no_weighting = false)
|
18
|
+
elems = []
|
19
|
+
((no_weighting || first_sentence.weight.empty?) ? 1 : first_sentence.weight.value).times { elems << first_sentence.sentence }
|
16
20
|
rest_sentences.elements.each do |s|
|
17
|
-
(s.weight.empty? ? 1 : s.weight.value).times { elems << s.
|
21
|
+
((no_weighting || s.weight.empty?) ? 1 : s.weight.value).times { elems << s.sentence_or_empty }
|
18
22
|
end
|
19
|
-
elems
|
23
|
+
elems
|
24
|
+
end
|
25
|
+
|
26
|
+
def confabulate(kb = nil)
|
27
|
+
elems = choices(kb)
|
28
|
+
elems[elems.length * rand].confabulate(kb)
|
29
|
+
end
|
30
|
+
|
31
|
+
def tree(kb = nil)
|
32
|
+
elems = choices(kb, true)
|
33
|
+
{ :choices => elems.map {|e| Confabulator::Parser.remove_singleton_arrays(e.tree(kb)) } }
|
20
34
|
end
|
21
35
|
}
|
22
36
|
end
|
23
37
|
|
38
|
+
rule empty
|
39
|
+
'' {
|
40
|
+
def confabulate(kb = nil)
|
41
|
+
''
|
42
|
+
end
|
43
|
+
|
44
|
+
def tree(kb = nil)
|
45
|
+
confabulate(kb)
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
24
50
|
rule weight
|
25
51
|
w:([0-9]+) ':' {
|
26
52
|
def value
|
@@ -31,22 +57,27 @@ module Confabulator
|
|
31
57
|
|
32
58
|
rule protected
|
33
59
|
"``" words:(("`" [^`]) / [^`])+ "``" {
|
34
|
-
def
|
60
|
+
def confabulate(kb = nil)
|
35
61
|
words.elements.map { |element|
|
36
62
|
element.text_value == "\\`" ? "`" : element.text_value
|
37
63
|
}.join
|
38
64
|
end
|
65
|
+
|
66
|
+
def tree(kb = nil)
|
67
|
+
confabulate(kb)
|
68
|
+
end
|
39
69
|
}
|
40
70
|
end
|
41
71
|
|
42
72
|
rule substitution
|
43
73
|
!'\\\\' '[' w name:( [a-zA-Z] [a-zA-Z_0-9-]* ) w options:(":" [a-zA-Z]+)? w ']' {
|
44
|
-
def
|
74
|
+
def confabulate(kb = nil)
|
45
75
|
if kb
|
46
76
|
result = kb.find(name.text_value).confabulate
|
47
77
|
if options.text_value =~ /p/
|
48
78
|
result = result.en.plural
|
49
|
-
|
79
|
+
end
|
80
|
+
if options.text_value =~ /c/
|
50
81
|
result[0] = result[0].upcase if result[0]
|
51
82
|
end
|
52
83
|
result
|
@@ -54,30 +85,57 @@ module Confabulator
|
|
54
85
|
""
|
55
86
|
end
|
56
87
|
end
|
88
|
+
|
89
|
+
def tree(kb = nil)
|
90
|
+
if kb
|
91
|
+
results = kb.find(name.text_value).tree
|
92
|
+
if options.text_value =~ /p/
|
93
|
+
results = { :pluralize => results }
|
94
|
+
end
|
95
|
+
if options.text_value =~ /c/
|
96
|
+
results = { :capitalize => results }
|
97
|
+
end
|
98
|
+
results
|
99
|
+
else
|
100
|
+
""
|
101
|
+
end
|
102
|
+
end
|
57
103
|
}
|
58
104
|
end
|
59
105
|
|
60
106
|
rule w
|
61
107
|
[ \t]* {
|
62
|
-
def
|
108
|
+
def confabulate(kb = nil)
|
63
109
|
text_value
|
64
110
|
end
|
111
|
+
|
112
|
+
def tree(kb = nil)
|
113
|
+
confabulate(kb)
|
114
|
+
end
|
65
115
|
}
|
66
116
|
end
|
67
117
|
|
68
118
|
rule escaped_char
|
69
119
|
'\\' character:. {
|
70
|
-
def
|
120
|
+
def confabulate(kb = nil)
|
71
121
|
character.text_value
|
72
122
|
end
|
123
|
+
|
124
|
+
def tree(kb = nil)
|
125
|
+
confabulate(kb)
|
126
|
+
end
|
73
127
|
}
|
74
128
|
end
|
75
129
|
|
76
130
|
rule words
|
77
131
|
[^\[{}`\|\\]+ {
|
78
|
-
def
|
132
|
+
def confabulate(kb = nil)
|
79
133
|
text_value
|
80
134
|
end
|
135
|
+
|
136
|
+
def tree(kb = nil)
|
137
|
+
confabulate(kb)
|
138
|
+
end
|
81
139
|
}
|
82
140
|
end
|
83
141
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: confabulator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-25 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70350927242820 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70350927242820
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: treetop
|
27
|
-
requirement: &
|
27
|
+
requirement: &70350927242400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70350927242400
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: linguistics
|
38
|
-
requirement: &
|
38
|
+
requirement: &70350927241980 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70350927241980
|
47
47
|
description: ''
|
48
48
|
email:
|
49
49
|
- andrew@iterationlabs.com
|