fabulator 0.0.8 → 0.0.9
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 +30 -1
- data/VERSION +1 -1
- data/features/functions.feature +7 -0
- data/features/primitives.feature +1 -1
- data/features/step_definitions/template_steps.rb +40 -3
- data/features/step_definitions/xml_steps.rb +3 -2
- data/features/templates.feature +49 -22
- data/features/types.feature +4 -4
- data/lib/fabulator.rb +4 -0
- data/lib/fabulator/compiler.rb +27 -0
- data/lib/fabulator/core.rb +3 -8
- data/lib/fabulator/core/actions/choose.rb +0 -18
- data/lib/fabulator/core/actions/for_each.rb +0 -48
- data/lib/fabulator/core/{actions.rb → lib.rb} +189 -117
- data/lib/fabulator/core/structurals.rb +7 -0
- data/lib/fabulator/core/{constraint.rb → structurals/constraint.rb} +2 -0
- data/lib/fabulator/core/{filter.rb → structurals/filter.rb} +2 -0
- data/lib/fabulator/core/{group.rb → structurals/group.rb} +2 -0
- data/lib/fabulator/core/{parameter.rb → structurals/parameter.rb} +2 -0
- data/lib/fabulator/core/{state.rb → structurals/state.rb} +2 -0
- data/lib/fabulator/core/{state_machine.rb → structurals/state_machine.rb} +2 -0
- data/lib/fabulator/core/{transition.rb → structurals/transition.rb} +2 -0
- data/lib/fabulator/expr.rb +6 -0
- data/lib/fabulator/expr/context.rb +65 -10
- data/lib/fabulator/expr/node_logic.rb +3 -2
- data/lib/fabulator/expr/parser.rb +787 -638
- data/lib/fabulator/expr/statement_list.rb +27 -0
- data/lib/fabulator/lib.rb +3 -0
- data/lib/fabulator/lib/action.rb +12 -9
- data/lib/fabulator/lib/lib.rb +85 -9
- data/lib/fabulator/structural.rb +24 -5
- data/lib/fabulator/tag_lib.rb +78 -124
- data/lib/fabulator/tag_lib/presentations.rb +39 -0
- data/lib/fabulator/tag_lib/transformations.rb +66 -0
- data/lib/fabulator/tag_lib/type.rb +176 -0
- data/lib/fabulator/template/parse_result.rb +125 -62
- data/lib/fabulator/template/parser.rb +17 -1
- data/xslt/form.xsl +163 -2083
- data/xsm_expression_parser.racc +35 -20
- metadata +17 -13
- data/lib/fabulator/context.rb +0 -39
data/History.txt
CHANGED
@@ -1,4 +1,33 @@
|
|
1
|
-
=== 0.0.
|
1
|
+
=== 0.0.9
|
2
|
+
|
3
|
+
* 11 major enhancements:
|
4
|
+
* Form markup is now namespaced and limited to the structural elements
|
5
|
+
(form, container, group, option) and interactive elements (asset,
|
6
|
+
selection, password, submission, text)
|
7
|
+
* Tuples in expressions are now [...] instead of ([...])
|
8
|
+
* Tag libraries can now specify an XSLT for transforming to HTML to
|
9
|
+
add presentation capabilities
|
10
|
+
* Tag libraries can specify which presentation elements in their
|
11
|
+
namespace should get default data from the application memory
|
12
|
+
* Tag libraries can specify which presentation elements participate
|
13
|
+
in the path construction for default data, caption, and error
|
14
|
+
markup
|
15
|
+
* Type conversions now are passed a context with the root node being
|
16
|
+
converted
|
17
|
+
* f:uri converts strings using namespace prefixes based on the namespace
|
18
|
+
context of the string instead of the namespace context of the function
|
19
|
+
call
|
20
|
+
* appended '?' to the following functions: f:first, f:last, f:ends-with,
|
21
|
+
f:empty, f:exists, f:only-one, f:one-or-more, and f:zero-or-one
|
22
|
+
* added f:first(list), f:last(list), f:all-but-first(list), and
|
23
|
+
f:all-but-last(list) for working with sequences
|
24
|
+
* added basic Type object to manage conversions and type information
|
25
|
+
* library actions can refer to other actions defined in the same library
|
26
|
+
|
27
|
+
1 minor enhancement
|
28
|
+
* Type converters are now mappings
|
29
|
+
|
30
|
+
=== 0.0.8 2010-09-11
|
2
31
|
|
3
32
|
* 1 major enhancement:
|
4
33
|
* Extensions can now define structural elements to be contained within
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/features/functions.feature
CHANGED
@@ -160,3 +160,10 @@ Feature: Function calls and lists
|
|
160
160
|
When I run the expression (f:not(f:true()))
|
161
161
|
Then I should get 1 item
|
162
162
|
And item 0 should be [f:false()]
|
163
|
+
@ns
|
164
|
+
Scenario: Negating logic
|
165
|
+
Given a context
|
166
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
167
|
+
When I run the expression (let xmlns:ff:="http://dh.tamu.edu/ns/fabulator/1.0#"; ff:not(ff:true()))
|
168
|
+
Then I should get 1 item
|
169
|
+
And item 0 should be [f:false()]
|
data/features/primitives.feature
CHANGED
@@ -4,6 +4,6 @@ Feature: Expression primitives
|
|
4
4
|
Scenario: Simple 1-tuple
|
5
5
|
Given a context
|
6
6
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
7
|
-
And that [/a] is set to [
|
7
|
+
And that [/a] is set to [[1,1]]
|
8
8
|
Then the expression (/a/@size) should equal [2]
|
9
9
|
And the expression (f:string(/a/@type)) should equal [f:uri-prefix('f') + "tuple"]
|
@@ -5,7 +5,7 @@ end
|
|
5
5
|
When /^I render the template$/ do
|
6
6
|
parser = Fabulator::Template::Parser.new
|
7
7
|
@template_result = parser.parse(@context, @template_text)
|
8
|
-
#puts @template_result.
|
8
|
+
#puts @template_result.to_s
|
9
9
|
end
|
10
10
|
|
11
11
|
When /^I set the captions to:$/ do |caption_table|
|
@@ -28,9 +28,46 @@ When /^I set the defaults to:$/ do |caption_table|
|
|
28
28
|
end
|
29
29
|
|
30
30
|
Then /^the rendered text should equal$/ do |doc|
|
31
|
-
@template_result.to_s
|
31
|
+
r = @template_result.to_s
|
32
|
+
|
33
|
+
cmd = 'xmllint --c14n --nsclean -'
|
34
|
+
IO.popen(cmd, "r+") { |x|
|
35
|
+
x << r
|
36
|
+
x.close_write
|
37
|
+
r = x.readlines.join("")
|
38
|
+
}
|
39
|
+
IO.popen(cmd, "r+") { |x|
|
40
|
+
x << doc
|
41
|
+
x.close_write
|
42
|
+
doc = x.readlines.join("")
|
43
|
+
}
|
44
|
+
|
45
|
+
#@template_result.to_s.should == doc + "\n"
|
46
|
+
r = r.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<")
|
47
|
+
doc = doc.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<")
|
48
|
+
r.should == doc
|
32
49
|
end
|
33
50
|
|
34
51
|
Then /^the rendered html should equal$/ do |doc|
|
35
|
-
@template_result.to_html
|
52
|
+
r = @template_result.to_html
|
53
|
+
|
54
|
+
cmd = 'xmllint --html --c14n --nsclean -'
|
55
|
+
IO.popen(cmd, "r+") { |x|
|
56
|
+
x << r
|
57
|
+
x.close_write
|
58
|
+
r = x.readlines.join("")
|
59
|
+
}
|
60
|
+
IO.popen(cmd, "r+") { |x|
|
61
|
+
x << doc
|
62
|
+
x.close_write
|
63
|
+
doc = x.readlines.join("")
|
64
|
+
}
|
65
|
+
|
66
|
+
#puts "html from template: #{r}"
|
67
|
+
#puts "html from doc : #{doc}"
|
68
|
+
r = r.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<")
|
69
|
+
doc = doc.gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>').gsub(/>\s*</, ">\n<")
|
70
|
+
|
71
|
+
|
72
|
+
r.should == doc
|
36
73
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
Given /the statemachine/ do |doc_xml|
|
2
2
|
@context ||= Fabulator::Expr::Context.new
|
3
|
+
@compiler ||= Fabulator::Compiler.new
|
3
4
|
|
4
5
|
if @sm.nil?
|
5
|
-
@sm =
|
6
|
-
|
6
|
+
@sm = @compiler.compile(doc_xml)
|
7
|
+
#@sm.compile_xml(doc_xml)
|
7
8
|
else
|
8
9
|
@sm.compile_xml(doc_xml)
|
9
10
|
end
|
data/features/templates.feature
CHANGED
@@ -6,12 +6,12 @@ Feature: Templates
|
|
6
6
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
7
7
|
And the template
|
8
8
|
"""
|
9
|
-
<foo></foo>
|
9
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#"></foo>
|
10
10
|
"""
|
11
11
|
When I render the template
|
12
12
|
Then the rendered text should equal
|
13
13
|
"""
|
14
|
-
<foo/>
|
14
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#"/>
|
15
15
|
"""
|
16
16
|
|
17
17
|
Scenario: Rendering a choice in a template
|
@@ -19,7 +19,7 @@ Feature: Templates
|
|
19
19
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
20
20
|
And the template
|
21
21
|
"""
|
22
|
-
<foo>
|
22
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
23
23
|
<r:choose>
|
24
24
|
<r:when test="f:true()">
|
25
25
|
true
|
@@ -33,7 +33,7 @@ Feature: Templates
|
|
33
33
|
When I render the template
|
34
34
|
Then the rendered text should equal
|
35
35
|
"""
|
36
|
-
<foo>
|
36
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
37
37
|
|
38
38
|
|
39
39
|
true
|
@@ -48,7 +48,7 @@ Feature: Templates
|
|
48
48
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
49
49
|
And the template
|
50
50
|
"""
|
51
|
-
<foo>
|
51
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
52
52
|
<r:choose>
|
53
53
|
<r:when test="f:false()">
|
54
54
|
true
|
@@ -62,7 +62,7 @@ Feature: Templates
|
|
62
62
|
When I render the template
|
63
63
|
Then the rendered text should equal
|
64
64
|
"""
|
65
|
-
<foo>
|
65
|
+
<foo xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
66
66
|
|
67
67
|
|
68
68
|
|
@@ -77,10 +77,10 @@ Feature: Templates
|
|
77
77
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
78
78
|
And the template
|
79
79
|
"""
|
80
|
-
<view>
|
80
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
81
81
|
<form>
|
82
|
-
<
|
83
|
-
<
|
82
|
+
<text id='foo'><caption>Foo</caption></text>
|
83
|
+
<submission id='submit'/>
|
84
84
|
</form>
|
85
85
|
</view>
|
86
86
|
"""
|
@@ -91,10 +91,10 @@ Feature: Templates
|
|
91
91
|
| submit | SubmitCaption |
|
92
92
|
Then the rendered text should equal
|
93
93
|
"""
|
94
|
-
<view>
|
94
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
95
95
|
<form>
|
96
|
-
<
|
97
|
-
<
|
96
|
+
<text id="foo"><caption>FooCaption</caption></text>
|
97
|
+
<submission id="submit"><caption>SubmitCaption</caption></submission>
|
98
98
|
</form>
|
99
99
|
</view>
|
100
100
|
"""
|
@@ -105,9 +105,9 @@ Feature: Templates
|
|
105
105
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
106
106
|
And the template
|
107
107
|
"""
|
108
|
-
<view>
|
108
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
109
109
|
<form>
|
110
|
-
<
|
110
|
+
<text id='foo'><caption>Foo</caption></text>
|
111
111
|
</form>
|
112
112
|
</view>
|
113
113
|
"""
|
@@ -117,9 +117,9 @@ Feature: Templates
|
|
117
117
|
| foo | FooDefault |
|
118
118
|
Then the rendered text should equal
|
119
119
|
"""
|
120
|
-
<view>
|
120
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
121
121
|
<form>
|
122
|
-
<
|
122
|
+
<text id="foo"><caption>Foo</caption><default>FooDefault</default></text>
|
123
123
|
</form>
|
124
124
|
</view>
|
125
125
|
"""
|
@@ -130,10 +130,10 @@ Feature: Templates
|
|
130
130
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
131
131
|
And the template
|
132
132
|
"""
|
133
|
-
<view>
|
133
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
134
134
|
<form id='foo'>
|
135
|
-
<
|
136
|
-
<
|
135
|
+
<text id='bar'><caption>Foo</caption></text>
|
136
|
+
<text id='baz'><caption>Boo</caption></text>
|
137
137
|
</form>
|
138
138
|
</view>
|
139
139
|
"""
|
@@ -144,10 +144,37 @@ Feature: Templates
|
|
144
144
|
| foo/baz | this & that |
|
145
145
|
Then the rendered text should equal
|
146
146
|
"""
|
147
|
-
<view>
|
147
|
+
<view xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
148
148
|
<form id="foo">
|
149
|
-
<
|
150
|
-
<
|
149
|
+
<text id="bar"><caption>Foo</caption><default>FooDefault</default></text>
|
150
|
+
<text id="baz"><caption>Boo</caption><default>this & that</default></text>
|
151
151
|
</form>
|
152
152
|
</view>
|
153
153
|
"""
|
154
|
+
|
155
|
+
@nst
|
156
|
+
Scenario: Rendering markup with namespaces
|
157
|
+
Given a context
|
158
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
159
|
+
And the template
|
160
|
+
"""
|
161
|
+
<form xmlns="http://dh.tamu.edu/ns/fabulator/1.0#">
|
162
|
+
<text id="foo"><caption>Foo</caption></text>
|
163
|
+
</form>
|
164
|
+
"""
|
165
|
+
When I render the template
|
166
|
+
Then the rendered html should equal
|
167
|
+
"""
|
168
|
+
<form type="application/x-multipart" method="POST" class="fabulator-form">
|
169
|
+
<table class="form-content" border="0" cellspacing="0" cellpadding="0">
|
170
|
+
<tr>
|
171
|
+
<td class="form-caption" valign="top">
|
172
|
+
<span class="caption">Foo</span>
|
173
|
+
</td>
|
174
|
+
<td class="form-element" valign="top">
|
175
|
+
<input type="text" name="foo" size="12" value="">
|
176
|
+
</td>
|
177
|
+
</tr>
|
178
|
+
</table>
|
179
|
+
</form>
|
180
|
+
"""
|
data/features/types.feature
CHANGED
@@ -40,25 +40,25 @@ Feature: Type unification
|
|
40
40
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
41
41
|
When I run the expression (f:true()/@type)
|
42
42
|
Then I should get 1 item
|
43
|
-
And item 0 should be [f:uri
|
43
|
+
And item 0 should be [f:uri('f:boolean')]
|
44
44
|
|
45
45
|
Scenario: Get the type of a string value
|
46
46
|
Given a context
|
47
47
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
48
48
|
When I run the expression ("foo"/@type)
|
49
49
|
Then I should get 1 item
|
50
|
-
And item 0 should be [f:uri
|
50
|
+
And item 0 should be [f:uri('f:string')]
|
51
51
|
|
52
52
|
Scenario: Get the type of a numeric value
|
53
53
|
Given a context
|
54
54
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
55
55
|
When I run the expression (3/@type)
|
56
56
|
Then I should get 1 item
|
57
|
-
And item 0 should be [f:uri
|
57
|
+
And item 0 should be [f:uri('f:numeric')]
|
58
58
|
|
59
59
|
Scenario: Get the type of a uri value
|
60
60
|
Given a context
|
61
61
|
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
62
62
|
When I run the expression (3/@type/@type)
|
63
63
|
Then I should get 1 item
|
64
|
-
And item 0 should be [f:uri
|
64
|
+
And item 0 should be [f:uri('f:uri')]
|
data/lib/fabulator.rb
CHANGED
@@ -5,9 +5,13 @@ module Fabulator
|
|
5
5
|
FAB_LIB_NS='http://dh.tamu.edu/ns/fabulator/library/1.0#'
|
6
6
|
|
7
7
|
require 'fabulator/expr'
|
8
|
+
require 'fabulator/tag_lib/transformations'
|
9
|
+
require 'fabulator/tag_lib/presentations'
|
10
|
+
require 'fabulator/tag_lib/type'
|
8
11
|
require 'fabulator/tag_lib'
|
9
12
|
require 'fabulator/action'
|
10
13
|
require 'fabulator/structural'
|
11
14
|
require 'fabulator/core'
|
15
|
+
require 'fabulator/compiler'
|
12
16
|
require 'fabulator/version'
|
13
17
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'xml/libxml'
|
2
|
+
|
3
|
+
module Fabulator
|
4
|
+
class Compiler
|
5
|
+
def initialize
|
6
|
+
@context = Fabulator::Expr::Context.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# Calls the right compiler object based on the root element
|
10
|
+
def compile(xml)
|
11
|
+
XML.default_line_numbers = true
|
12
|
+
|
13
|
+
doc = nil
|
14
|
+
|
15
|
+
if xml.is_a?(String)
|
16
|
+
doc = LibXML::XML::Document.string xml
|
17
|
+
doc = doc.root
|
18
|
+
elsif xml.is_a?(LibXML::XML::Document)
|
19
|
+
doc = xml.root
|
20
|
+
else
|
21
|
+
doc = xml
|
22
|
+
end
|
23
|
+
|
24
|
+
@context.compile_structural(doc)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/fabulator/core.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require 'fabulator/core/
|
2
|
-
require 'fabulator/core/
|
3
|
-
require 'fabulator/core/
|
4
|
-
require 'fabulator/core/group'
|
5
|
-
require 'fabulator/core/parameter'
|
6
|
-
require 'fabulator/core/state'
|
7
|
-
require 'fabulator/core/transition'
|
8
|
-
require 'fabulator/core/actions'
|
1
|
+
require 'fabulator/core/structurals'
|
2
|
+
#require 'fabulator/core/actions'
|
3
|
+
require 'fabulator/core/lib'
|
@@ -125,24 +125,6 @@ module Fabulator
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
class Super < Fabulator::Action
|
129
|
-
namespace Fabulator::FAB_NS
|
130
|
-
has_select
|
131
|
-
has_actions :super
|
132
|
-
|
133
|
-
def run(context, autovivify = false)
|
134
|
-
return [] if @actions.nil?
|
135
|
-
|
136
|
-
@context.with(context) do |ctx|
|
137
|
-
new_context = @select.run(ctx,autovivify)
|
138
|
-
|
139
|
-
new_context = [ new_context ] unless new_context.is_a?(Array)
|
140
|
-
|
141
|
-
return new_context.collect { |c| @actions.run(ctx.with_root(c), autovivify) }.flatten
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
128
|
end
|
147
129
|
end
|
148
130
|
end
|
@@ -42,54 +42,6 @@ module Fabulator
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
class Considering < Fabulator::Action
|
46
|
-
namespace Fabulator::FAB_NS
|
47
|
-
attribute :as, :static => true
|
48
|
-
has_select
|
49
|
-
has_actions
|
50
|
-
|
51
|
-
def run(context, autovivify = false)
|
52
|
-
return [] if @select.nil?
|
53
|
-
res = [ ]
|
54
|
-
@context.with(context) do |ctx|
|
55
|
-
c = self.select(ctx)
|
56
|
-
root = nil
|
57
|
-
if self.as.nil?
|
58
|
-
if c.size == 1
|
59
|
-
root = c.first
|
60
|
-
else
|
61
|
-
root = Fabulator::Expr::Node.new('data', context.root.roots, nil, c)
|
62
|
-
end
|
63
|
-
res = self.run_actions(ctx.with_root(root))
|
64
|
-
else
|
65
|
-
ctx.in_context do |ctx2|
|
66
|
-
ctx2.set_var(self.as, c)
|
67
|
-
res = self.run_actions(ctx2)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
res
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class While < Fabulator::Action
|
76
|
-
namespace Fabulator::FAB_NS
|
77
|
-
attribute :test, :eval => true, :static => false
|
78
|
-
attribute :limit, :default => 1000
|
79
|
-
has_actions
|
80
|
-
|
81
|
-
def run(context, autovivify = false)
|
82
|
-
res = [ ]
|
83
|
-
counter = 0
|
84
|
-
@context.with(context) do |ctx|
|
85
|
-
lim = self.limit(ctx) #@limit.nil? ? 1000 : @limit.run(ctx).first.value
|
86
|
-
while counter < lim && (!!self.test(ctx).first.value rescue false)
|
87
|
-
res = res + self.run_actions(ctx)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
res
|
91
|
-
end
|
92
|
-
end
|
93
45
|
end
|
94
46
|
end
|
95
47
|
end
|