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 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 enhancement:
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.4
1
+ 0.0.5
@@ -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
+
@@ -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 &amp; 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?
@@ -19,8 +19,11 @@ module Fabulator
19
19
  result = [ ]
20
20
  return result if @var.nil? || @expr.nil?
21
21
 
22
+ count = 1
22
23
  @var.each_binding(context, autovivify) do |b|
24
+ b.position = count
23
25
  result = result + @expr.run(b)
26
+ count += 1
24
27
  end
25
28
  return result
26
29
  end
@@ -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', 176)
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 = Fabulator::Expr::IndexPredicate.new(val[1])
1376
+ result = val[1]
1377
1377
  result
1378
1378
  end
1379
1379
  .,.,
1380
1380
 
1381
- module_eval(<<'.,.,', 'xsm_expression_parser.racc', 150)
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', 151)
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', 154)
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', 155)
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', 156)
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', 158)
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', 161)
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', 164)
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', 165)
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', 168)
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', 169)
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
- if p.is_a?(Fabulator::Expr::IndexPredicate)
18
- n_p = p.run(context).collect{ |i| possible[i-1] }
19
- else
20
- possible.each do |c|
21
- res = p.run(context.with_root(c))
22
- if res.is_a?(Array)
23
- n_p << c if !res.empty? && !!res.first.value
24
- else
25
- n_p << c if !!res.value
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 << XML::Node.new('default', v)
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 << XML::Node.new('default', v)
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 << XML::Node.new('default', v)
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 << XML::Node.new('error', e)
86
+ el << text_node('error', e)
87
87
  end
88
88
  else
89
- el << XML::Node.new('error', errors[id])
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 << XML::Node.new('caption', captions[id])
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
@@ -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 = Fabulator::Expr::IndexPredicate.new(val[1]) }
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: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
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-17 00:00:00 +00:00
18
+ date: 2010-08-18 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency