fabulator 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -4
- data/VERSION +1 -1
- data/features/paths.feature +34 -0
- data/features/templates.feature +28 -0
- data/lib/fabulator/expr/context.rb +11 -0
- data/lib/fabulator/expr/for_expr.rb +3 -0
- data/lib/fabulator/expr/parser.rb +13 -13
- data/lib/fabulator/expr/predicates.rb +33 -9
- data/lib/fabulator/template/parse_result.rb +14 -6
- data/xsm_expression_parser.racc +4 -1
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
=== 0.0.5
|
2
|
+
|
3
|
+
* 2 major enhancements:
|
4
|
+
* unified predicate execution so numeric indexes and boolean logic
|
5
|
+
work based on run-time evaluation results
|
6
|
+
* position(), first(), and last() should work in predicates
|
7
|
+
* correctly escape default values
|
8
|
+
|
1
9
|
=== 0.0.4 2010-08-16
|
2
10
|
|
3
|
-
* 5 minor enhancements
|
11
|
+
* 5 minor enhancements:
|
4
12
|
* Add RedCloth gem dependence to gem spec
|
5
13
|
* f:string-length() returns 0 for nil values
|
6
14
|
* f:dump() now shows attributes
|
@@ -8,19 +16,19 @@
|
|
8
16
|
* minor bug fixes in template tags
|
9
17
|
* tempate form XML element 'file' is now 'asset'
|
10
18
|
|
11
|
-
* 1 major enhancement
|
19
|
+
* 1 major enhancement:
|
12
20
|
* add_default_values() should now work for parsed templates
|
13
21
|
* to_html() can now return form contents only
|
14
22
|
* parsed templates will be returned as a string if they are not
|
15
23
|
|
16
24
|
=== 0.0.3 2010-08-10
|
17
25
|
|
18
|
-
* 1 minor enhancement
|
26
|
+
* 1 minor enhancement:
|
19
27
|
* Add libxslt-ruby gem dependence to gem spec
|
20
28
|
|
21
29
|
=== 0.0.2 2010-08-10
|
22
30
|
|
23
|
-
* 3 major
|
31
|
+
* 3 major enhancements:
|
24
32
|
* Introduce '*' suffix to indicate a consolidation of a reduction
|
25
33
|
* Reduction functions can now have a corresponding consolidation
|
26
34
|
function. The reduction will be a fallback for an undefined
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/features/paths.feature
CHANGED
@@ -31,6 +31,7 @@ Feature: Path expressions
|
|
31
31
|
Then I should get 1 item
|
32
32
|
And item 0 should be [5]
|
33
33
|
|
34
|
+
@numpred
|
34
35
|
Scenario: Finding the third and fifth odd numbers
|
35
36
|
Given a context
|
36
37
|
And that [/a] is set to [1 .. 10]
|
@@ -39,6 +40,7 @@ Feature: Path expressions
|
|
39
40
|
And item 0 should be [5]
|
40
41
|
And item 1 should be [9]
|
41
42
|
|
43
|
+
@numpred
|
42
44
|
Scenario: Using an expression to name a node test
|
43
45
|
Given a context
|
44
46
|
And that [/a] is set to [1 .. 10]
|
@@ -48,6 +50,7 @@ Feature: Path expressions
|
|
48
50
|
And item 0 should be [5]
|
49
51
|
And item 1 should be [9]
|
50
52
|
|
53
|
+
@numpred
|
51
54
|
Scenario: Using an expression to name a node test
|
52
55
|
Given a context
|
53
56
|
And that [/a] is set to [1 .. 10]
|
@@ -55,3 +58,34 @@ Feature: Path expressions
|
|
55
58
|
Then I should get 2 items
|
56
59
|
And item 0 should be [5]
|
57
60
|
And item 1 should be [9]
|
61
|
+
|
62
|
+
@pred
|
63
|
+
Scenario: Using an expression to name a node test
|
64
|
+
Given a context
|
65
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
66
|
+
And that [/a/a] is set to ['a']
|
67
|
+
And that [/a/b] is set to ['bb']
|
68
|
+
And that [/a/c] is set to ['ccc']
|
69
|
+
And that [/a/d] is set to ['dd']
|
70
|
+
And that [/a/e] is set to ['e']
|
71
|
+
When I run the expression (/a/*[f:string-length(.) > 1])
|
72
|
+
Then I should get 3 items
|
73
|
+
And item 0 should be ['bb']
|
74
|
+
And item 1 should be ['ccc']
|
75
|
+
And item 2 should be ['dd']
|
76
|
+
|
77
|
+
@pred
|
78
|
+
Scenario: Using an expression to name a node test
|
79
|
+
Given a context
|
80
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
81
|
+
And that [/a/a] is set to ['a']
|
82
|
+
And that [/a/b] is set to ['bb']
|
83
|
+
And that [/a/c] is set to ['ccc']
|
84
|
+
And that [/a/d] is set to ['dd']
|
85
|
+
And that [/a/e] is set to ['e']
|
86
|
+
When I run the expression (/a/*[f:not(f:string-length(.) < 2)])
|
87
|
+
Then I should get 3 items
|
88
|
+
And item 0 should be ['bb']
|
89
|
+
And item 1 should be ['ccc']
|
90
|
+
And item 2 should be ['dd']
|
91
|
+
|
data/features/templates.feature
CHANGED
@@ -121,5 +121,33 @@ Feature: Templates
|
|
121
121
|
<form>
|
122
122
|
<textline id="foo"><caption>Foo</caption><default>FooDefault</default></textline>
|
123
123
|
</form>
|
124
|
+
</view>
|
125
|
+
"""
|
126
|
+
|
127
|
+
@def
|
128
|
+
Scenario: Rendering a form with defaults
|
129
|
+
Given a context
|
130
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
131
|
+
And the template
|
132
|
+
"""
|
133
|
+
<view>
|
134
|
+
<form id='foo'>
|
135
|
+
<textline id='bar'><caption>Foo</caption></textline>
|
136
|
+
<textline id='baz'><caption>Boo</caption></textline>
|
137
|
+
</form>
|
138
|
+
</view>
|
139
|
+
"""
|
140
|
+
When I render the template
|
141
|
+
And I set the defaults to:
|
142
|
+
| path | default |
|
143
|
+
| foo/bar | FooDefault |
|
144
|
+
| foo/baz | this & that |
|
145
|
+
Then the rendered text should equal
|
146
|
+
"""
|
147
|
+
<view>
|
148
|
+
<form id="foo">
|
149
|
+
<textline id="bar"><caption>Foo</caption><default>FooDefault</default></textline>
|
150
|
+
<textline id="baz"><caption>Boo</caption><default>this & that</default></textline>
|
151
|
+
</form>
|
124
152
|
</view>
|
125
153
|
"""
|
@@ -366,6 +366,17 @@ module Fabulator
|
|
366
366
|
yield ctx
|
367
367
|
end
|
368
368
|
|
369
|
+
def with_roots(items, &block)
|
370
|
+
idx = 1
|
371
|
+
items.each do |i|
|
372
|
+
ctx = self.with_root(i)
|
373
|
+
ctx.position = idx
|
374
|
+
ctx.last = idx == items.size
|
375
|
+
yield ctx
|
376
|
+
idx += 1
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
369
380
|
def run_filter(ns, name)
|
370
381
|
handler = Fabulator::ActionLib.namespaces[ns]
|
371
382
|
return [] if handler.nil?
|
@@ -9,7 +9,7 @@ module Fabulator
|
|
9
9
|
module Expr
|
10
10
|
class Parser < Racc::Parser
|
11
11
|
|
12
|
-
module_eval(<<'...end xsm_expression_parser.racc/module_eval...', 'xsm_expression_parser.racc',
|
12
|
+
module_eval(<<'...end xsm_expression_parser.racc/module_eval...', 'xsm_expression_parser.racc', 179)
|
13
13
|
require 'fabulator/expr'
|
14
14
|
require 'rational'
|
15
15
|
require 'bigdecimal'
|
@@ -1373,19 +1373,19 @@ module_eval(<<'.,.,', 'xsm_expression_parser.racc', 145)
|
|
1373
1373
|
|
1374
1374
|
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 146)
|
1375
1375
|
def _reduce_83(val, _values, result)
|
1376
|
-
result =
|
1376
|
+
result = val[1]
|
1377
1377
|
result
|
1378
1378
|
end
|
1379
1379
|
.,.,
|
1380
1380
|
|
1381
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1381
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 153)
|
1382
1382
|
def _reduce_84(val, _values, result)
|
1383
1383
|
result = Fabulator::Expr::Var.new(val[0])
|
1384
1384
|
result
|
1385
1385
|
end
|
1386
1386
|
.,.,
|
1387
1387
|
|
1388
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1388
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 154)
|
1389
1389
|
def _reduce_85(val, _values, result)
|
1390
1390
|
result = val[1]
|
1391
1391
|
result
|
@@ -1396,35 +1396,35 @@ module_eval(<<'.,.,', 'xsm_expression_parser.racc', 151)
|
|
1396
1396
|
|
1397
1397
|
# reduce 87 omitted
|
1398
1398
|
|
1399
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1399
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 157)
|
1400
1400
|
def _reduce_88(val, _values, result)
|
1401
1401
|
result = Fabulator::Expr::Literal.new(val[0], [ Fabulator::FAB_NS, 'string' ])
|
1402
1402
|
result
|
1403
1403
|
end
|
1404
1404
|
.,.,
|
1405
1405
|
|
1406
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1406
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 158)
|
1407
1407
|
def _reduce_89(val, _values, result)
|
1408
1408
|
result = Fabulator::Expr::Literal.new(val[0] =~ /\./ ? val[0].to_d.to_r : val[0].to_i.to_r, [ Fabulator::FAB_NS, 'numeric' ])
|
1409
1409
|
result
|
1410
1410
|
end
|
1411
1411
|
.,.,
|
1412
1412
|
|
1413
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1413
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 159)
|
1414
1414
|
def _reduce_90(val, _values, result)
|
1415
1415
|
result = Fabulator::Expr::Function.new(@context, val[0], val[1])
|
1416
1416
|
result
|
1417
1417
|
end
|
1418
1418
|
.,.,
|
1419
1419
|
|
1420
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1420
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 161)
|
1421
1421
|
def _reduce_91(val, _values, result)
|
1422
1422
|
result = Fabulator::Expr::List.new(val[1])
|
1423
1423
|
result
|
1424
1424
|
end
|
1425
1425
|
.,.,
|
1426
1426
|
|
1427
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1427
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 164)
|
1428
1428
|
def _reduce_92(val, _values, result)
|
1429
1429
|
result = [ ]
|
1430
1430
|
result
|
@@ -1433,14 +1433,14 @@ module_eval(<<'.,.,', 'xsm_expression_parser.racc', 161)
|
|
1433
1433
|
|
1434
1434
|
# reduce 93 omitted
|
1435
1435
|
|
1436
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1436
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 167)
|
1437
1437
|
def _reduce_94(val, _values, result)
|
1438
1438
|
result = [ val[0] ]
|
1439
1439
|
result
|
1440
1440
|
end
|
1441
1441
|
.,.,
|
1442
1442
|
|
1443
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1443
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 168)
|
1444
1444
|
def _reduce_95(val, _values, result)
|
1445
1445
|
result = val[0] + [ val[2] ]
|
1446
1446
|
result
|
@@ -1449,14 +1449,14 @@ module_eval(<<'.,.,', 'xsm_expression_parser.racc', 165)
|
|
1449
1449
|
|
1450
1450
|
# reduce 96 omitted
|
1451
1451
|
|
1452
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1452
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 171)
|
1453
1453
|
def _reduce_97(val, _values, result)
|
1454
1454
|
result = val[0].to_s
|
1455
1455
|
result
|
1456
1456
|
end
|
1457
1457
|
.,.,
|
1458
1458
|
|
1459
|
-
module_eval(<<'.,.,', 'xsm_expression_parser.racc',
|
1459
|
+
module_eval(<<'.,.,', 'xsm_expression_parser.racc', 172)
|
1460
1460
|
def _reduce_98(val, _values, result)
|
1461
1461
|
result = val[1]
|
1462
1462
|
result
|
@@ -14,16 +14,40 @@ module Fabulator
|
|
14
14
|
return possible if @predicates.nil? || @predicates.empty?
|
15
15
|
@predicates.each do |p|
|
16
16
|
n_p = [ ]
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
res = p.run(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
context.with_roots(possible) do |ctx|
|
18
|
+
if p.is_a?(Array)
|
19
|
+
res = p.collect{ |pp| pp.run(ctx) }.flatten
|
20
|
+
else
|
21
|
+
res = p.run(ctx)
|
22
|
+
end
|
23
|
+
if res.is_a?(Array)
|
24
|
+
res -= [ nil ]
|
25
|
+
if !res.empty?
|
26
|
+
# if all boolean and one is true, then keep
|
27
|
+
# if numeric, then keep if position == number
|
28
|
+
# if string and non-blank, then keep
|
29
|
+
unified_type = Fabulator::ActionLib.unify_types(res.collect{ |r| r.vtype })
|
30
|
+
case unified_type.join('')
|
31
|
+
when FAB_NS+'boolean':
|
32
|
+
if res.select{ |r| r.to([FAB_NS, 'boolean']).value }.size > 0
|
33
|
+
n_p << ctx.root
|
34
|
+
end
|
35
|
+
when FAB_NS+'numeric':
|
36
|
+
if res.select{ |r| r.to([FAB_NS,'numeric']).value == ctx.position }.size > 0
|
37
|
+
n_p << ctx.root
|
38
|
+
end
|
39
|
+
when FAB_NS+'string':
|
40
|
+
if res.select{ |r| r.to_s.size > 0 }.size > 0
|
41
|
+
n_p << ctx.root
|
42
|
+
end
|
43
|
+
else # default for now is to convert to boolean
|
44
|
+
if res.select{ |r| r.to([FAB_NS, 'boolean']).value }.size > 0
|
45
|
+
n_p << ctx.root
|
46
|
+
end
|
47
|
+
end
|
26
48
|
end
|
49
|
+
else
|
50
|
+
n_p << ctx.root if !!res.value
|
27
51
|
end
|
28
52
|
end
|
29
53
|
possible = n_p
|
@@ -47,20 +47,20 @@ module Fabulator::Template
|
|
47
47
|
end
|
48
48
|
if direction == 'both'
|
49
49
|
l.collect{|ll| ll.value}.each do |v|
|
50
|
-
el <<
|
50
|
+
el << text_node('default', v)
|
51
51
|
end
|
52
52
|
elsif direction == 'row' || direction == 'column'
|
53
53
|
el.find("./#{direction}").each do |div|
|
54
54
|
id = (div.attributes['id'].to_s rescue '')
|
55
55
|
next if id == ''
|
56
56
|
l.collect{|c| context.with_root(c).traverse_path(id)}.flatten.collect{|c| c.value}.each do |v|
|
57
|
-
div <<
|
57
|
+
div << text_node('default', v)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
61
|
else
|
62
62
|
l.collect{|ll| ll.value}.each do |v|
|
63
|
-
el <<
|
63
|
+
el << text_node('default', v)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -83,10 +83,10 @@ module Fabulator::Template
|
|
83
83
|
next unless errors.has_key?(id)
|
84
84
|
if errors[id].is_a?(Array)
|
85
85
|
errors[id].each do |e|
|
86
|
-
el <<
|
86
|
+
el << text_node('error', e)
|
87
87
|
end
|
88
88
|
else
|
89
|
-
el <<
|
89
|
+
el << text_node('error', errors[id])
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -102,9 +102,11 @@ module Fabulator::Template
|
|
102
102
|
else
|
103
103
|
caption = el.find_first('./caption')
|
104
104
|
if caption.nil?
|
105
|
-
el <<
|
105
|
+
el << text_node('caption', captions[id])
|
106
106
|
else
|
107
107
|
caption.content = captions[id]
|
108
|
+
caption.parent << text_node('caption', captions[id])
|
109
|
+
caption.remove!
|
108
110
|
end
|
109
111
|
end
|
110
112
|
end
|
@@ -158,5 +160,11 @@ protected
|
|
158
160
|
ids << own_id
|
159
161
|
ids.collect{|i| i.to_s}.join('/')
|
160
162
|
end
|
163
|
+
|
164
|
+
def text_node(n,t)
|
165
|
+
e = XML::Node.new(n)
|
166
|
+
e << t
|
167
|
+
e
|
168
|
+
end
|
161
169
|
end
|
162
170
|
end
|
data/xsm_expression_parser.racc
CHANGED
@@ -144,7 +144,10 @@ rule
|
|
144
144
|
| predicates predicate { result = val[0] + [ val[1] ] }
|
145
145
|
|
146
146
|
predicate: LB expr RB { result = val[1] }
|
147
|
-
| LB num_list RB { result =
|
147
|
+
| LB num_list RB { result = val[1] }
|
148
|
+
|
149
|
+
#Fabulator::Expr::IndexPredicate.new(val[1])
|
150
|
+
|
148
151
|
|
149
152
|
#| '<' expr '>'
|
150
153
|
primary_expr:
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fabulator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-18 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|