fabulator 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.12
1
+ 0.0.13
@@ -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
@@ -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.substr(first-1, last-1) } ]
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.substr(first-1) } ]
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 - 1
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?
@@ -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.collect{ |a| a.is_static? }.each do |a|
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.collect{ |a| !a.is_static? }.each do |attr|
48
- ctx.set_var(attr.name, attr.value(ctx))
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
@@ -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
 
@@ -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
- structurals[ns] = ob.presentation.structurals
17
- interactives[ns] = ob.presentation.interactives
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
 
@@ -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: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 12
10
- version: 0.0.12
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-03 00:00:00 +00:00
18
+ date: 2010-12-08 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency