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