fabulator 0.0.4 → 0.0.5
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/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
|