fabulator 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/History.txt +30 -1
  2. data/VERSION +1 -1
  3. data/features/functions.feature +7 -0
  4. data/features/primitives.feature +1 -1
  5. data/features/step_definitions/template_steps.rb +40 -3
  6. data/features/step_definitions/xml_steps.rb +3 -2
  7. data/features/templates.feature +49 -22
  8. data/features/types.feature +4 -4
  9. data/lib/fabulator.rb +4 -0
  10. data/lib/fabulator/compiler.rb +27 -0
  11. data/lib/fabulator/core.rb +3 -8
  12. data/lib/fabulator/core/actions/choose.rb +0 -18
  13. data/lib/fabulator/core/actions/for_each.rb +0 -48
  14. data/lib/fabulator/core/{actions.rb → lib.rb} +189 -117
  15. data/lib/fabulator/core/structurals.rb +7 -0
  16. data/lib/fabulator/core/{constraint.rb → structurals/constraint.rb} +2 -0
  17. data/lib/fabulator/core/{filter.rb → structurals/filter.rb} +2 -0
  18. data/lib/fabulator/core/{group.rb → structurals/group.rb} +2 -0
  19. data/lib/fabulator/core/{parameter.rb → structurals/parameter.rb} +2 -0
  20. data/lib/fabulator/core/{state.rb → structurals/state.rb} +2 -0
  21. data/lib/fabulator/core/{state_machine.rb → structurals/state_machine.rb} +2 -0
  22. data/lib/fabulator/core/{transition.rb → structurals/transition.rb} +2 -0
  23. data/lib/fabulator/expr.rb +6 -0
  24. data/lib/fabulator/expr/context.rb +65 -10
  25. data/lib/fabulator/expr/node_logic.rb +3 -2
  26. data/lib/fabulator/expr/parser.rb +787 -638
  27. data/lib/fabulator/expr/statement_list.rb +27 -0
  28. data/lib/fabulator/lib.rb +3 -0
  29. data/lib/fabulator/lib/action.rb +12 -9
  30. data/lib/fabulator/lib/lib.rb +85 -9
  31. data/lib/fabulator/structural.rb +24 -5
  32. data/lib/fabulator/tag_lib.rb +78 -124
  33. data/lib/fabulator/tag_lib/presentations.rb +39 -0
  34. data/lib/fabulator/tag_lib/transformations.rb +66 -0
  35. data/lib/fabulator/tag_lib/type.rb +176 -0
  36. data/lib/fabulator/template/parse_result.rb +125 -62
  37. data/lib/fabulator/template/parser.rb +17 -1
  38. data/xslt/form.xsl +163 -2083
  39. data/xsm_expression_parser.racc +35 -20
  40. metadata +17 -13
  41. data/lib/fabulator/context.rb +0 -39
@@ -5,118 +5,147 @@ require 'fabulator/core/actions/variables'
5
5
 
6
6
  module Fabulator
7
7
  module Core
8
- module Actions
9
8
  class Lib < TagLib
10
9
  namespace FAB_NS
11
10
 
12
- structural 'application', Fabulator::Core::StateMachine
13
- structural 'view', Fabulator::Core::State
14
- structural 'goes-to', Fabulator::Core::Transition
15
- #structural 'before',
16
- #structural 'after',
17
- structural 'params', Fabulator::Core::Group
18
- structural 'group', Fabulator::Core::Group
19
- structural 'param', Fabulator::Core::Parameter
20
- structural 'value', Fabulator::Core::Constraint
21
- structural 'constraint', Fabulator::Core::Constraint
22
- structural 'filter', Fabulator::Core::Filter
23
- structural 'sort', Sort
24
- structural 'when', When
25
- structural 'otherwise', When
26
-
27
-
28
- action 'choose', Choose
29
- action 'for-each', ForEach
30
- action 'value-of', ValueOf
31
- action 'value', Value
32
- action 'while', While
33
- action 'considering', Considering
34
- action 'variable', Variable
35
- action 'if', If
36
- action 'go-to', Goto
37
- action 'raise', Raise
38
- action 'div', Block
39
- action 'catch', Catch
40
- action 'super', Super
11
+ structural :application, Structurals::StateMachine
12
+ structural :view, Structurals::State
13
+ structural 'goes-to', Structurals::Transition
14
+ structural :params, Structurals::Group
15
+ structural :group, Structurals::Group
16
+ structural :param, Structurals::Parameter
17
+ structural :value, Structurals::Constraint
18
+ structural :constraint, Structurals::Constraint
19
+ structural :filter, Structurals::Filter
20
+
21
+ structural :sort, Actions::Sort
22
+ structural :when, Actions::When
23
+ structural :otherwise, Actions::When
24
+
25
+ action :choose, Actions::Choose
26
+ action 'for-each', Actions::ForEach
27
+ action 'value-of', Actions::ValueOf
28
+ action :value, Actions::Value
29
+ action :variable, Actions::Variable
30
+ action :if, Actions::If
31
+ action 'go-to', Actions::Goto
32
+ action :raise, Actions::Raise
33
+ action :div, Actions::Block
34
+ action :catch, Actions::Catch
35
+
36
+ presentations do
37
+ transformations_into.html do
38
+ xslt_from_file File.join(File.dirname(__FILE__), "..", "..", "..", "xslt", "form.xsl")
39
+ end
40
+
41
+ interactive :text
42
+ interactive :asset
43
+ interactive :selection
44
+ interactive :password
45
+ interactive :submission
46
+
47
+ structural :form
48
+ structural :container
49
+ structural :group
50
+ structural :option
51
+ end
41
52
 
42
53
  ###
43
54
  ### core types
44
55
  ###
45
56
 
46
- register_type 'boolean', {
47
- :ops => {
48
- },
49
- :to => [
50
- { :type => [ FAB_NS, 'string' ],
51
- :weight => 1.0,
52
- :convert => lambda { |i| i.value ? 'true' : '' }
53
- },
54
- { :type => [ FAB_NS, 'numeric' ],
55
- :weight => 1.0,
56
- :convert => lambda{ |i| Rational.new(i.value ? 1 : 0, 1) }
57
- },
58
- ]
59
- }
60
-
61
- register_type 'string', {
62
- :ops => {
63
- #:plus => {
64
- #},
65
- :minus => {
66
- :proc => lambda { |a,b| a.split(b).join('')}
67
- },
68
- :mpy => {
69
- :args => [ [ FAB_NS, 'string' ], [ FAB_NS, 'integer' ] ],
70
- :proc => lambda { |a,b| a * b }
71
- },
72
- :lt => { },
73
- :eq => { },
74
- },
75
- :to => [
76
- { :type => [ FAB_NS, 'boolean' ],
77
- :weight => 0.0001,
78
- :convert => lambda { |s| !(s.value.nil? || s.value == '' || s.value =~ /\s*/) }
79
- },
80
- { :type => [ FAB_NS, 'html' ],
81
- :weight => 1.0,
82
- :convert => lambda { |s| s.value.gsub(/&/, '&amp;').gsub(/</, '&lt;') }
83
- },
84
- ],
85
- }
86
-
87
- register_type 'uri', {
88
- :to => [
89
- { :type => [ FAB_NS, 'string' ],
90
- :weight => 1.0,
91
- :convert => lambda { |u| u.get_attribute('namespace').value + u.get_attribute('name').value }
92
- }
93
- ]
94
- }
95
-
96
- register_type 'numeric', {
97
- :ops => {
98
- #:plus => { },
99
- #:minus => { },
100
- #:mpy => { },
101
- #:div => { },
102
- #:mod => { },
103
- #:lt => { },
104
- #:eq => { },
105
- },
106
- :to => [
107
- { :type => [ FAB_NS, 'string' ],
108
- :weight => 1.0,
109
- :convert => lambda { |n| (n.value % 1 == 0 ? n.value.to_i : n.value.to_d).to_s }
110
- },
111
- { :type => [ FAB_NS, 'boolean' ],
112
- :weight => 0.0001,
113
- :convert => lambda { |n| n.value != 0 }
114
- },
115
- ],
116
- }
117
-
118
- register_type 'expression', {
119
- }
57
+ has_type :boolean do
58
+ going_to [ FAB_NS, 'string' ] do
59
+ weight 1.0
60
+ converting do |i|
61
+ i.root.value ? 'true' : ''
62
+ end
63
+ end
64
+
65
+ going_to [ FAB_NS, 'numeric' ] do
66
+ weight 1.0
67
+ converting do |i|
68
+ Rational.new(i.root.value ? 1 : 0, 1)
69
+ end
70
+ end
71
+ end
72
+
73
+ has_type :string do
74
+ going_to [ FAB_NS, 'boolean' ] do
75
+ weight 0.0001
76
+ converting do |s|
77
+ !(s.root.value.nil? || s.root.value == '' || s.root.value =~ /^\s*$/)
78
+ end
79
+ end
80
+
81
+ going_to [ FAB_NS, 'html' ] do
82
+ weight 1.0
83
+ converting do |s|
84
+ s.root.value.gsub(/&/, '&amp;').gsub(/</, '&lt;').gsub(/>/, '&gt;')
85
+ end
86
+ end
87
+ end
88
+
89
+ has_type :html do
90
+ end
91
+
92
+ has_type :uri do
93
+ going_to [ FAB_NS, 'string' ] do
94
+ weight 1.0
95
+ converting do |u|
96
+ u.root.get_attribute('namespace').value + u.root.get_attribute('name').value
97
+ end
98
+ end
99
+
100
+ coming_from [ FAB_NS, 'string'] do
101
+ weight 1.0
102
+ converting do |u|
103
+ p = u.root.value
104
+ ns = nil
105
+ name = nil
106
+ if p =~ /^([a-zA-Z_][-a-zA-Z0-9_.]*):([a-zA-Z_][-a-zA-Z0-9_.]*)$/
107
+ ns_prefix = $1
108
+ name = $2
109
+ ns = u.get_ns(ns_prefix)
110
+ else
111
+ p =~ /^(.*?)([a-zA-Z_][-a-zA-Z0-9_.]*)$/
112
+ ns = $1
113
+ name = $2
114
+ end
115
+ r = u.root.anon_node(nil)
116
+ r.set_attribute('namespace', ns)
117
+ r.set_attribute('name', name)
118
+ r
119
+ end
120
+ end
121
+ end
122
+
123
+ has_type :numeric do
124
+ going_to [ FAB_NS, 'string' ] do
125
+ weight 1.0
126
+ converting do |n|
127
+ (n.root.value % 1 == 0 ? n.root.value.to_i : n.root.value.to_d).to_s
128
+ end
129
+ end
130
+
131
+ going_to [ FAB_NS, 'boolean' ] do
132
+ weight 0.0001
133
+ converting do |n|
134
+ n.root.value != 0
135
+ end
136
+ end
137
+ end
138
+
139
+ has_type :expression do
140
+ coming_from [ FAB_NS, 'string' ] do
141
+ weight 1.0
142
+ converting do |e|
143
+ p = Fabulator::Expr::Parser.new
144
+ c = e.root.value
145
+ c.nil? ? nil : p.parse(c,e)
146
+ end
147
+ end
148
+ end
120
149
 
121
150
  ###
122
151
  ### Numeric functions
@@ -268,9 +297,9 @@ module Fabulator
268
297
  first = args[1].first.value
269
298
  if args.size == 3
270
299
  last = args[2].first.value
271
- return [ args[0].collect{ |src| src.value.to_s.substr(first, last) } ]
300
+ return [ args[0].collect{ |src| src.value.to_s.substr(first-1, last-1) } ]
272
301
  else
273
- return [ args[0].collect{ |src| src.value.to_s.substr(first) } ]
302
+ return [ args[0].collect{ |src| src.value.to_s.substr(first-1) } ]
274
303
  end
275
304
  end
276
305
 
@@ -298,18 +327,18 @@ module Fabulator
298
327
  args[0].collect{ |a| a.to_s.split(div) }
299
328
  end
300
329
 
301
- function 'contains' do |ctx, args|
330
+ function 'contains?' do |ctx, args|
302
331
  tgt = (args[1].first.to_s rescue '')
303
332
  return args[0].collect{ |a| (a.to_s.include?(tgt) rescue false) }
304
333
  end
305
334
 
306
- function 'starts-with' do |ctx, args|
335
+ function 'starts-with?' do |ctx, args|
307
336
  tgt = (args[1].first.to_s rescue '')
308
337
  tgt_len = tgt.size - 1
309
338
  return args[0].collect{ |a| (a.to_s[0,tgt_len] == tgt rescue false) }
310
339
  end
311
340
 
312
- function 'ends-with' do |ctx, args|
341
+ function 'ends-with?' do |ctx, args|
313
342
  tgt = (args[1].first.to_s rescue '').reverse
314
343
  tgt_len = tgt.size
315
344
  return args[0].collect{ |a| (a.to_s[-tgt_len,-1] == tgt rescue false) }
@@ -416,11 +445,11 @@ module Fabulator
416
445
  ### Sequences
417
446
  ###
418
447
 
419
- mapping 'empty' do |ctx, arg|
448
+ reduction 'empty?' do |ctx, arg|
420
449
  arg.nil? || !arg.is_a?(Array) || arg.empty?
421
450
  end
422
451
 
423
- mapping 'exists' do |ctx, arg|
452
+ reduction 'exists?' do |ctx, arg|
424
453
  !(arg.nil? || !arg.is_a?(Array) || arg.empty?)
425
454
  end
426
455
 
@@ -428,15 +457,15 @@ module Fabulator
428
457
  args.flatten.reverse
429
458
  end
430
459
 
431
- mapping 'zero-or-one' do |ctx, arg|
460
+ reduction 'zero-or-one?' do |ctx, arg|
432
461
  arg.is_a?(Array) && arg.size <= 1
433
462
  end
434
463
 
435
- mapping 'one-or-more' do |ctx, arg|
464
+ reduction 'one-or-more?' do |ctx, arg|
436
465
  arg.is_a?(Array) && arg.size >= 1
437
466
  end
438
467
 
439
- mapping 'zero-or-one' do |ctx, arg|
468
+ reduction 'only-one?' do |ctx, arg|
440
469
  arg.is_a?(Array) && arg.size == 1
441
470
  end
442
471
 
@@ -444,6 +473,50 @@ module Fabulator
444
473
  args.size
445
474
  end
446
475
 
476
+ function 'first' do |ctx, args|
477
+ if args.size == 1 && args.vtype.join('') == FAB_NS + 'tuple'
478
+ args.value.first
479
+ else
480
+ args.first
481
+ end
482
+ end
483
+
484
+ function 'last' do |ctx, args|
485
+ if args.size == 1 && args.vtype.join('') == FAB_NS + 'tuple'
486
+ args.value.last
487
+ else
488
+ args.last
489
+ end
490
+ end
491
+
492
+ function 'all-but-first' do |ctx, args|
493
+ if args.size == 1 && args.vtype.join('') == FAB_NS + 'tuple'
494
+ if args.value.size > 1
495
+ args.value[1 .. args.value.size-1]
496
+ else
497
+ []
498
+ end
499
+ elsif args.size > 1
500
+ args[1 .. args.size-1]
501
+ else
502
+ []
503
+ end
504
+ end
505
+
506
+ function 'all-but-last' do |ctx, args|
507
+ if args.size == 1 && args.vtype.join('') == FAB_NS + 'tuple'
508
+ if args.value.size > 1
509
+ args.value[0 .. args.value.size-2]
510
+ else
511
+ []
512
+ end
513
+ elsif args.size > 1
514
+ args[0 .. args.size-2]
515
+ else
516
+ []
517
+ end
518
+ end
519
+
447
520
  ###
448
521
  ### Context
449
522
  ###
@@ -452,11 +525,11 @@ module Fabulator
452
525
  ctx.position
453
526
  end
454
527
 
455
- function 'last', BOOLEAN do |ctx, args|
528
+ function 'last?', BOOLEAN do |ctx, args|
456
529
  ctx.last?
457
530
  end
458
531
 
459
- function 'first', BOOLEAN do |ctx, args|
532
+ function 'first?', BOOLEAN do |ctx, args|
460
533
  ctx.position == 1
461
534
  end
462
535
 
@@ -529,5 +602,4 @@ module Fabulator
529
602
 
530
603
  end
531
604
  end
532
- end
533
605
  end
@@ -0,0 +1,7 @@
1
+ require 'fabulator/core/structurals/state_machine'
2
+ require 'fabulator/core/structurals/constraint'
3
+ require 'fabulator/core/structurals/filter'
4
+ require 'fabulator/core/structurals/group'
5
+ require 'fabulator/core/structurals/parameter'
6
+ require 'fabulator/core/structurals/state'
7
+ require 'fabulator/core/structurals/transition'
@@ -1,5 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
+ module Structurals
3
4
  class Constraint < Fabulator::Action
4
5
 
5
6
  namespace Fabulator::FAB_NS
@@ -134,3 +135,4 @@ module Fabulator
134
135
  end
135
136
  end
136
137
  end
138
+ end
@@ -1,5 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
+ module Structurals
3
4
  class Filter < Fabulator::Action
4
5
  namespace Fabulator::FAB_NS
5
6
  attribute :name, :static => true
@@ -26,3 +27,4 @@ module Fabulator
26
27
  end
27
28
  end
28
29
  end
30
+ end
@@ -1,5 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
+ module Structurals
3
4
  class Group < Fabulator::Structural
4
5
  attr_accessor :name, :params, :tags, :required_params
5
6
 
@@ -90,3 +91,4 @@ module Fabulator
90
91
  end
91
92
  end
92
93
  end
94
+ end
@@ -1,5 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
+ module Structurals
3
4
  class Parameter < Fabulator::Structural
4
5
  attr_accessor :name
5
6
 
@@ -96,3 +97,4 @@ module Fabulator
96
97
  end
97
98
  end
98
99
  end
100
+ end
@@ -1,5 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
+ module Structurals
3
4
  class State < Fabulator::Structural
4
5
  attr_accessor :name, :transitions
5
6
 
@@ -49,3 +50,4 @@ module Fabulator
49
50
  end
50
51
  end
51
52
  end
53
+ end