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 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