fabulator 0.0.12 → 0.0.13
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 -0
- data/VERSION +1 -1
- data/features/functions.feature +16 -0
- data/features/simple-statemachine.feature +28 -0
- data/lib/fabulator/core/lib.rb +29 -6
- data/lib/fabulator/expr/context.rb +3 -2
- data/lib/fabulator/expr/parser.rb +4 -3
- data/lib/fabulator/lib/action.rb +7 -3
- data/lib/fabulator/lib/attribute.rb +6 -1
- data/lib/fabulator/lib/lib.rb +2 -2
- data/lib/fabulator/tag_lib.rb +2 -0
- data/lib/fabulator/template/parse_result.rb +6 -2
- data/xsm_expression_parser.racc +4 -3
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 0.0.13 2010-12-08
|
2
|
+
|
3
|
+
* 7 minor enhancements:
|
4
|
+
* Fixed f:substring and f:starts-with?
|
5
|
+
* Added f:random(n) to return a random integer in (1,n)
|
6
|
+
* Fix escaping of single and double quotes in expressions
|
7
|
+
* Fix where we look for non-inherited attributes in actions defined
|
8
|
+
in a library
|
9
|
+
* Fix handling of attributes that need to be passed through f:eval
|
10
|
+
* Fix template interaction with libraries that don't have form elements
|
11
|
+
* Fix recording of actions that act as connections to structural elements
|
12
|
+
|
1
13
|
=== 0.0.12 2010-12-03
|
2
14
|
|
3
15
|
* 1 major enhancement:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.13
|
data/features/functions.feature
CHANGED
@@ -167,3 +167,19 @@ Feature: Function calls and lists
|
|
167
167
|
When I run the expression (let xmlns:ff:="http://dh.tamu.edu/ns/fabulator/1.0#"; ff:not(ff:true()))
|
168
168
|
Then I should get 1 item
|
169
169
|
And item 0 should be [f:false()]
|
170
|
+
|
171
|
+
@rand
|
172
|
+
Scenario: Random numbers
|
173
|
+
Given a context
|
174
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
175
|
+
When I run the expression (f:random(5) < 5)
|
176
|
+
Then I should get 1 item
|
177
|
+
And item 0 should be [f:true()]
|
178
|
+
|
179
|
+
@strings
|
180
|
+
Scenario: Starts with
|
181
|
+
Given a context
|
182
|
+
And the prefix f as "http://dh.tamu.edu/ns/fabulator/1.0#"
|
183
|
+
When I run the expression (f:starts-with?('$bar', '$'))
|
184
|
+
Then I should get 1 item
|
185
|
+
And item 0 should be [f:true()]
|
@@ -191,6 +191,34 @@ Feature: Simple state machines
|
|
191
191
|
And the expression (/foo) should equal ['bar']
|
192
192
|
And the expression (/bar) should equal ['baz']
|
193
193
|
|
194
|
+
@choose
|
195
|
+
Scenario: simple machine with a <choose />
|
196
|
+
Given the statemachine
|
197
|
+
"""
|
198
|
+
<f:application xmlns:f="http://dh.tamu.edu/ns/fabulator/1.0#">
|
199
|
+
<f:choose>
|
200
|
+
<f:when f:test="f:true()">
|
201
|
+
<f:value f:path="/foo" f:select="3" />
|
202
|
+
</f:when>
|
203
|
+
<f:otherwise>
|
204
|
+
<f:value f:path="/foo" f:select="2" />
|
205
|
+
</f:otherwise>
|
206
|
+
</f:choose>
|
207
|
+
<f:value f:path="/bar">
|
208
|
+
<f:choose>
|
209
|
+
<f:when f:test="f:true()">
|
210
|
+
<f:value-of f:select="3" />
|
211
|
+
</f:when>
|
212
|
+
<f:otherwise>
|
213
|
+
<f:value-of f:select="2" />
|
214
|
+
</f:otherwise>
|
215
|
+
</f:choose>
|
216
|
+
</f:value>
|
217
|
+
</f:application>
|
218
|
+
"""
|
219
|
+
Then the expression (/foo) should equal [3]
|
220
|
+
Then the expression (/bar) should equal [3]
|
221
|
+
|
194
222
|
@var
|
195
223
|
Scenario: simple machine with a <variable /> and <value />
|
196
224
|
Given the statemachine
|
data/lib/fabulator/core/lib.rb
CHANGED
@@ -165,6 +165,15 @@ module Fabulator
|
|
165
165
|
arg.to(NUMERIC).value.to_d.floor.to_r
|
166
166
|
end
|
167
167
|
|
168
|
+
mapping 'random' do |ctx, arg|
|
169
|
+
v = arg.to(NUMERIC).value.to_i
|
170
|
+
if v <= 0
|
171
|
+
(0.0).to_d.to_r
|
172
|
+
else
|
173
|
+
(1.0*rand(v) + 1.0).floor.to_r
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
168
177
|
reduction 'sum', { :scaling => :log } do |ctx, args|
|
169
178
|
zero = TagLib.find_op(args.first.vtype, :zero)
|
170
179
|
if(zero && zero[:proc])
|
@@ -297,9 +306,9 @@ module Fabulator
|
|
297
306
|
first = args[1].first.value
|
298
307
|
if args.size == 3
|
299
308
|
last = args[2].first.value
|
300
|
-
return [ args[0].collect{ |src| src.value.to_s.
|
309
|
+
return [ args[0].collect{ |src| s = src.value.to_s; s.length > first + last - 2 ? s[first-1, s.length-1] : s[first-1, first + last - 2] } ]
|
301
310
|
else
|
302
|
-
return [ args[0].collect{ |src| src.value.to_s
|
311
|
+
return [ args[0].collect{ |src| s = src.value.to_s; s[first-1, s.length-1] } ]
|
303
312
|
end
|
304
313
|
end
|
305
314
|
|
@@ -334,7 +343,7 @@ module Fabulator
|
|
334
343
|
|
335
344
|
function 'starts-with?' do |ctx, args|
|
336
345
|
tgt = (args[1].first.to_s rescue '')
|
337
|
-
tgt_len = tgt.size
|
346
|
+
tgt_len = tgt.size
|
338
347
|
return args[0].collect{ |a| (a.to_s[0,tgt_len] == tgt rescue false) }
|
339
348
|
end
|
340
349
|
|
@@ -358,7 +367,21 @@ module Fabulator
|
|
358
367
|
|
359
368
|
return args[0].collect{ |a| a.to_s.include?(tgt) ? (a.to_s.split(tgt))[-1] : "" }
|
360
369
|
end
|
361
|
-
|
370
|
+
|
371
|
+
function 'index-of' do |ctx, args|
|
372
|
+
tgt = (args[1].first.to_s rescue ' ')
|
373
|
+
start = (args[2].first.to(NUMERIC, ctx).value.to_i rescue 0)
|
374
|
+
ret = [ ]
|
375
|
+
args[0].collect{ |a|
|
376
|
+
as = a.to_s
|
377
|
+
ret << as.index(tgt, start)
|
378
|
+
while !ret.last.nil?
|
379
|
+
ret << as.index(tgt, ret.last)
|
380
|
+
end
|
381
|
+
ret -= [ nil ]
|
382
|
+
}
|
383
|
+
ret
|
384
|
+
end
|
362
385
|
|
363
386
|
###
|
364
387
|
### Regexes
|
@@ -433,11 +456,11 @@ module Fabulator
|
|
433
456
|
mapping 'eval' do |ctx, arg|
|
434
457
|
p = Fabulator::Expr::Parser.new
|
435
458
|
if arg.vtype.join('') == FAB_NS+'expression'
|
436
|
-
return arg.value.run(ctx)
|
459
|
+
return arg.value.run(ctx, true)
|
437
460
|
else
|
438
461
|
e = arg.to_s
|
439
462
|
pe = e.nil? ? nil : p.parse(e,ctx)
|
440
|
-
return pe.nil? ? [] : pe.run(ctx)
|
463
|
+
return pe.nil? ? [] : pe.run(ctx, true)
|
441
464
|
end
|
442
465
|
end
|
443
466
|
|
@@ -286,13 +286,14 @@ module Fabulator
|
|
286
286
|
src = nil
|
287
287
|
if !v.nil?
|
288
288
|
src = v.is_a?(Fabulator::Expr::Node) ? [ v ] : ( v.is_a?(Array) ? v : v.run(self) )
|
289
|
+
src = src.select{ |s| !s.value.nil? || s.children.count > 0 }
|
289
290
|
end
|
290
291
|
|
291
292
|
tgts.each do |tgt|
|
292
293
|
tgt.prune
|
293
294
|
if src.nil? || src.empty?
|
294
|
-
tgt.value = nil
|
295
|
-
ret << tgt
|
295
|
+
#tgt.value = nil
|
296
|
+
#ret << tgt
|
296
297
|
elsif src.size == 1
|
297
298
|
tgt.copy(src.first)
|
298
299
|
ret << tgt
|
@@ -296,15 +296,16 @@ module_eval(<<'...end xsm_expression_parser.racc/module_eval...', 'xsm_expressio
|
|
296
296
|
end
|
297
297
|
elsif !res[6].nil?
|
298
298
|
s = res[6]
|
299
|
-
s = s[1..s.length-2]
|
300
299
|
@curpos = @curpos + s.length
|
301
300
|
@col = @col + s.length
|
301
|
+
s = s[1..s.length-2]
|
302
302
|
s.gsub!(/\\n/, "\n")
|
303
|
+
s.gsub!(/\\'/, "'")
|
304
|
+
s.gsub!(/\\"/, '"')
|
305
|
+
@line += s.split(/\n/).count
|
303
306
|
@curpos = @curpos - s.length
|
304
307
|
@col = @col - s.length
|
305
308
|
@token = [ :LITERAL, s ]
|
306
|
-
@curpos = @curpos + 2 # the quotes
|
307
|
-
@col = @col + 2
|
308
309
|
elsif !res[7].nil?
|
309
310
|
@token = [ :NUMBER, res[7] ]
|
310
311
|
elsif !res[8].nil?
|
data/lib/fabulator/lib/action.rb
CHANGED
@@ -11,6 +11,7 @@ module Fabulator
|
|
11
11
|
|
12
12
|
attribute :name, :static => true
|
13
13
|
attribute 'has-actions', :static => true, :as => :has_actions, :type => :boolean
|
14
|
+
attribute 'has-select', :static => true, :as => :has_select, :type => :boolean
|
14
15
|
|
15
16
|
contains :attribute
|
16
17
|
|
@@ -31,7 +32,7 @@ module Fabulator
|
|
31
32
|
@action = defining_action
|
32
33
|
@actions = actions
|
33
34
|
@static_attributes = { }
|
34
|
-
@context.get_action(@action.first, @action.last).attributes.
|
35
|
+
@context.get_action(@action.first, @action.last).attributes.select{ |a| a.is_static? }.each do |a|
|
35
36
|
@static_attributes[a.name] = a.value(@context)
|
36
37
|
end
|
37
38
|
end
|
@@ -44,14 +45,17 @@ module Fabulator
|
|
44
45
|
end
|
45
46
|
# These can be passed to f:eval to get their value
|
46
47
|
action = ctx.get_action(@action.first, @action.last)
|
47
|
-
action.attributes.
|
48
|
-
ctx.set_var(attr.name, attr.value(
|
48
|
+
action.attributes.select{ |a| !a.is_static? }.each do |attr|
|
49
|
+
ctx.set_var(attr.name, attr.value(@context))
|
49
50
|
end
|
50
51
|
# we can f:eval($actions) in whatever current context we have
|
51
52
|
if action.has_actions?
|
52
53
|
@actions.use_context(context)
|
53
54
|
ctx.set_var('actions', ctx.root.anon_node( @actions, [ FAB_NS, 'expression' ]))
|
54
55
|
end
|
56
|
+
if action.has_select?
|
57
|
+
ctx.set_var('select', ctx.root.anon_node( @select, [ FAB_NS, 'expression' ]))
|
58
|
+
end
|
55
59
|
ret = action.run(ctx)
|
56
60
|
end
|
57
61
|
ret
|
@@ -7,13 +7,18 @@ module Fabulator
|
|
7
7
|
attribute :ns, :static => true, :inherited => true
|
8
8
|
attribute :static, :static => true, :type => :boolean
|
9
9
|
attribute :eval, :static => true, :type => :boolean
|
10
|
+
attribute :inherited, :static => true, :type => :boolean
|
10
11
|
|
11
12
|
def is_static?
|
12
13
|
@static
|
13
14
|
end
|
14
15
|
|
15
16
|
def value(context)
|
16
|
-
context.attribute(@ns, @name, { :static => @static, :eval => @eval })
|
17
|
+
v = context.attribute(@ns, @name, { :static => @static, :eval => @eval, :inherited => @inherited })
|
18
|
+
if @eval || !@static
|
19
|
+
v = context.root.anon_node(v, [ FAB_NS, 'expression' ])
|
20
|
+
end
|
21
|
+
v
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
data/lib/fabulator/lib/lib.rb
CHANGED
@@ -139,8 +139,8 @@ module Fabulator
|
|
139
139
|
protected
|
140
140
|
|
141
141
|
def setup(xml)
|
142
|
-
ns = xml.attributes.get_attribute_ns(FAB_LIB_NS, 'ns').value
|
143
|
-
Fabulator::TagLib.namespaces[ns] = self
|
142
|
+
@ns = xml.attributes.get_attribute_ns(FAB_LIB_NS, 'ns').value
|
143
|
+
Fabulator::TagLib.namespaces[@ns] = self
|
144
144
|
|
145
145
|
self.init_attribute_storage
|
146
146
|
|
data/lib/fabulator/tag_lib.rb
CHANGED
@@ -347,6 +347,8 @@ module Fabulator
|
|
347
347
|
if block
|
348
348
|
define_method("action:#{name.to_s}", block)
|
349
349
|
elsif !klass.nil?
|
350
|
+
Fabulator::TagLib.structural_classes[self.name] ||= {}
|
351
|
+
Fabulator::TagLib.structural_classes[self.name][name.to_sym] = klass
|
350
352
|
action(name) { |e,c|
|
351
353
|
r = klass.new
|
352
354
|
r.compile_xml(e,c)
|
@@ -13,8 +13,10 @@ module Fabulator::Template
|
|
13
13
|
interactives = { }
|
14
14
|
|
15
15
|
Fabulator::TagLib.namespaces.each_pair do |ns, ob|
|
16
|
-
|
17
|
-
|
16
|
+
x = ob.presentation.structurals || []
|
17
|
+
structurals[ns] = x unless x.nil? || x.empty?
|
18
|
+
x = ob.presentation.interactives || []
|
19
|
+
interactives[ns] = x unless x.nil? || x.empty?
|
18
20
|
end
|
19
21
|
|
20
22
|
@namespaces = { }
|
@@ -28,12 +30,14 @@ module Fabulator::Template
|
|
28
30
|
interactive_xpaths = []
|
29
31
|
interesting_xpaths = [ ]
|
30
32
|
@fab_prefix = ''
|
33
|
+
|
31
34
|
@namespaces.keys.each do |p|
|
32
35
|
@fab_prefix = p if @namespaces[p] == Fabulator::FAB_NS
|
33
36
|
structural_xpaths += structurals[@namespaces[p]].collect{ |e| "ancestor::#{p}:#{e}" }
|
34
37
|
interactive_xpaths += interactives[@namespaces[p]].collect{ |e| "//#{p}:#{e}" }
|
35
38
|
interesting_xpaths += structurals[@namespaces[p]].collect{ |e| "//#{p}:#{e}" }
|
36
39
|
end
|
40
|
+
|
37
41
|
@structural_xpath = structural_xpaths.join("[@id != ''] | ") + "[@id != '']"
|
38
42
|
@interactive_xpath = interactive_xpaths.join(" | ")
|
39
43
|
|
data/xsm_expression_parser.racc
CHANGED
@@ -480,15 +480,16 @@ end
|
|
480
480
|
end
|
481
481
|
elsif !res[6].nil?
|
482
482
|
s = res[6]
|
483
|
-
s = s[1..s.length-2]
|
484
483
|
@curpos = @curpos + s.length
|
485
484
|
@col = @col + s.length
|
485
|
+
s = s[1..s.length-2]
|
486
486
|
s.gsub!(/\\n/, "\n")
|
487
|
+
s.gsub!(/\\'/, "'")
|
488
|
+
s.gsub!(/\\"/, '"')
|
489
|
+
@line += s.split(/\n/).count
|
487
490
|
@curpos = @curpos - s.length
|
488
491
|
@col = @col - s.length
|
489
492
|
@token = [ :LITERAL, s ]
|
490
|
-
@curpos = @curpos + 2 # the quotes
|
491
|
-
@col = @col + 2
|
492
493
|
elsif !res[7].nil?
|
493
494
|
@token = [ :NUMBER, res[7] ]
|
494
495
|
elsif !res[8].nil?
|
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: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 13
|
10
|
+
version: 0.0.13
|
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-12-
|
18
|
+
date: 2010-12-08 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|