confabulator 0.0.2 → 0.0.3
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/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
|