polyrex 0.8.18 → 0.8.19

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.
Files changed (2) hide show
  1. data/lib/polyrex.rb +125 -23
  2. metadata +2 -2
data/lib/polyrex.rb CHANGED
@@ -1,4 +1,4 @@
1
- #/usr/bin/ruby
1
+ #/usr/bin/env ruby
2
2
 
3
3
  # file: polyrex.rb
4
4
 
@@ -6,10 +6,30 @@ require 'polyrex-schema'
6
6
  require 'line-tree'
7
7
  require 'polyrex-objects'
8
8
  require 'polyrex-createobject'
9
- require 'ostruct'
10
9
  require 'polyrex-object-methods'
11
10
  require 'recordx-xslt'
12
11
  require 'rexle'
12
+ require 'recordx'
13
+
14
+ module Enumerable
15
+ def repeated_permutation(size, &blk)
16
+ f = proc do |memo, &blk|
17
+ if memo.size == size
18
+ blk.call memo
19
+ else
20
+ self.each do |i|
21
+ f.call memo + [i], &blk
22
+ end
23
+ end
24
+ end
25
+
26
+ if block_given?
27
+ f.call [], &blk
28
+ else
29
+ Enumerator.new(f, :call, [])
30
+ end
31
+ end
32
+ end
13
33
 
14
34
  class Polyrex
15
35
  attr_accessor :summary_fields, :xslt_schema, :id_counter, :schema
@@ -21,7 +41,8 @@ class Polyrex
21
41
  if location then
22
42
  open(location)
23
43
  summary_h = Hash[*@doc.root.xpath("summary/*").map {|x| [x.name, x.text]}.flatten]
24
- @summary = OpenStruct.new summary_h
44
+ #@summary = OpenStruct.new summary_h
45
+ @summary = RecordX.new summary_h
25
46
  @summary_fields = summary_h.keys.map(&:to_sym)
26
47
  end
27
48
 
@@ -29,7 +50,7 @@ class Polyrex
29
50
  end
30
51
 
31
52
  def create(id=nil)
32
- # @create is a PolyrexCreateObject, @parent_node is a REXML::Element pointing to the current record
53
+ # @create is a PolyrexCreateObject, @parent_node is a Rexle::Element pointing to the current record
33
54
 
34
55
  @create.id = id || @id_counter
35
56
  @create.record = @parent_node.name == 'records' ? @parent_node.root : @parent_node.root.element('records')
@@ -95,7 +116,8 @@ class Polyrex
95
116
  def schema=(s)
96
117
  open s
97
118
  summary_h = Hash[*@doc.root.xpath("summary/*").map {|x| [x.name, x.text]}.flatten]
98
- @summary = OpenStruct.new summary_h
119
+ #@summary = OpenStruct.new summary_h
120
+ @summary = RecordX.new summary_h
99
121
  @summary_fields = summary_h.keys.map(&:to_sym)
100
122
  self
101
123
  end
@@ -133,7 +155,7 @@ class Polyrex
133
155
  # -- required for the parsing feature
134
156
  doc = Rexle.new(PolyrexSchema.new(schema).to_s)
135
157
  @format_masks = doc.root.xpath('//format_mask/text()')
136
- #puts '@format_masks : ' + @format_masks.inspect
158
+
137
159
  schema_rpath = schema.gsub(/\[[^\]]+\]/,'')
138
160
 
139
161
  @recordx = schema_rpath.split('/')
@@ -185,23 +207,27 @@ class Polyrex
185
207
  self.method(name).call(value)
186
208
  end
187
209
  end
188
-
189
- raw_summary = schema[/\[([^\]]+)/,1]
210
+
211
+ raw_summary = schema[/^\w+\[([^\]]+)/,1]
190
212
  raw_lines = buffer.strip.split(/\r?\n|\r(?!\n)/)
191
-
213
+
192
214
  if raw_summary then
193
215
  a_summary = raw_summary.split(',').map(&:strip)
194
-
216
+
195
217
  while raw_lines.first[/#{a_summary.join('|')}:\s+\w+/] do
196
- label, val = raw_lines.shift.match(/(\w+):\s+([^$]+)$/).captures
218
+
219
+ label, val = raw_lines.shift.match(/(\w+):\s+([^$]+)$/).captures
197
220
  @summary.send((label + '=').to_sym, val)
198
221
  end
222
+
199
223
  end
200
224
 
201
- @summary.format_mask = @format_mask
225
+ @summary.format_mask = @format_masks
226
+
202
227
  format_line!(@parent_node.root, LineTree.new(raw_lines.join("\n").strip).to_a)
228
+
203
229
  end
204
-
230
+
205
231
  def load_handlers(schema)
206
232
  @create = PolyrexCreateObject.new(schema, @id_counter)
207
233
 
@@ -214,7 +240,7 @@ class Polyrex
214
240
  end
215
241
 
216
242
  def format_line!(records, a, i=0)
217
-
243
+
218
244
  a.each do |x|
219
245
 
220
246
  unless @recordx[i] then
@@ -225,19 +251,25 @@ class Polyrex
225
251
  tag_name = @recordx[i].to_s
226
252
  line = x.shift
227
253
 
228
-
229
254
  unless @format_masks[i][/^\(.*\)$/] then
230
255
 
231
256
  @field_names = @format_masks[i].to_s.scan(/\[!(\w+)\]/).flatten.map(&:to_sym)
232
257
 
258
+ =begin
233
259
  t = regexify_fmask(@format_masks[i]) #.sub(/\[/,'\[').sub(/\]/,'\]')
234
-
235
- a = t.reverse.split(/(?=\)[^\(]+\()/).reverse.map &:reverse
260
+ a = t.reverse.split(/(?=\)[^\(]+\()/).reverse.map &:reverse
236
261
  patterns = tail_map(a)
262
+ =end
237
263
 
264
+ patterns = possible_patterns(@format_masks[i])
238
265
  pattern = patterns.detect {|x| line.match(/#{x.join}/)}.join
239
-
240
266
  field_values = line.match(/#{pattern}/).captures
267
+ found_quotes = find_qpattern(pattern)
268
+
269
+ if found_quotes then
270
+ found_quotes.each {|i| field_values[i] = field_values[i][1..-2]}
271
+ end
272
+
241
273
  field_values += [''] * (@field_names.length - field_values.length)
242
274
  else
243
275
 
@@ -252,6 +284,7 @@ class Polyrex
252
284
  @field_names = format_masks[i].to_s.scan(/\[!(\w+)\]/).flatten.map(&:to_sym)
253
285
 
254
286
  field_values = line.match(/#{pattern}/).captures
287
+
255
288
  end
256
289
 
257
290
  @id_counter.succ!
@@ -263,7 +296,7 @@ class Polyrex
263
296
 
264
297
  @field_names.zip(field_values).each do |name, value|
265
298
  field = Rexle::Element.new(name.to_s)
266
- field.text = value
299
+ field.text = value
267
300
  summary.add field
268
301
  end
269
302
 
@@ -341,9 +374,36 @@ class Polyrex
341
374
 
342
375
  end
343
376
 
377
+ def diminishing_permutation(max_fields)
378
+ result = max_fields.times.inject([]) do |r,i|
379
+ r + [1,0].repeated_permutation(max_fields-i).to_a
380
+ end
381
+ end
382
+
383
+ def find_qpattern(s)
384
+ s.split(/(?=\([^\)]+\))/).map.with_index\
385
+ .select{|x,i| x[/\["'\]\[\^"'\]\+\["'\]/] }.map(&:last)
386
+ end
387
+
388
+ def fmask_delimiters(f)
389
+ a = f.split(/(?=\[!\w+\])/)[0..-2].map do |x|
390
+
391
+ aa = x.split(/(?=[^\]]+$)/)
392
+
393
+ if aa.length == 2 and aa.first[/\[!\w+\]/] then
394
+ field, delimiter = *aa
395
+ delimiter ||= '$'
396
+ d = delimiter[0]
397
+ d
398
+ end
399
+ end
400
+ end
401
+
402
+
403
+ # jr140412 to be removed
344
404
  def regexify_fmask(f)
345
405
 
346
- a = f.split(/(?=\[!\w+\])/).map do |x|
406
+ a = f.split(/(?=\[!\w+\])/).i do |x|
347
407
 
348
408
  aa = x.split(/(?=[^\]]+$)/)
349
409
 
@@ -351,7 +411,7 @@ class Polyrex
351
411
  field, delimiter = *aa
352
412
  delimiter ||= '$'
353
413
  d = delimiter[0]
354
- "([^%s]+)%s" % ([d] * 2)
414
+ "('[^']+'|[^%s]+)%s" % ([d] * 2)
355
415
  else
356
416
  x.sub(/\[!\w+\]/,'(.*)')
357
417
  end
@@ -360,9 +420,44 @@ class Polyrex
360
420
  a.join
361
421
  end
362
422
 
423
+ #jr140412 to be removed
363
424
  def tail_map(a)
364
425
  [a] + (a.length > 1 ? tail_map(a[0..-2]) : [])
365
426
  end
427
+
428
+ def possible_patterns(format_mask)
429
+
430
+ tot_fields = format_mask.scan(/\[!\w+\]/).length
431
+ return [['(.*)']] if tot_fields <= 1
432
+ main_fields = tot_fields - 1
433
+ qpattern = %q{(["'][^"']+["'])}
434
+
435
+ a = fmask_delimiters(format_mask)
436
+ r = diminishing_permutation(main_fields)
437
+
438
+ if r.length > 2 then
439
+ itemx = [r.slice!(-2)]
440
+ r2 = r[0..-3] + itemx + r[-2..-1]
441
+ else
442
+ r2 = r
443
+ end
444
+
445
+ rr = r2.map do |x|
446
+ x.each_with_index.map do |item, i|
447
+ d = a[i]
448
+ case item
449
+ when 1
450
+ i > 0 ? d + qpattern : qpattern
451
+ when 0
452
+ s = "([^%s]+)" % d
453
+ i > 0 ? d + s : s
454
+ end
455
+ end
456
+ end
457
+
458
+ rrr = rr.take(2**main_fields).map {|x| x + [a[-1] + '(.*)']} + rr
459
+
460
+ end
366
461
 
367
462
  def load_find_by(schema)
368
463
  a = PolyrexObjectMethods.new(schema).to_a
@@ -381,9 +476,16 @@ class Polyrex
381
476
  self.instance_eval methodx.join("\n")
382
477
  end
383
478
 
479
+
384
480
  def refresh_summary()
385
- @summary_fields.each do |x|
386
- @doc.root.element('summary/' + x.to_s).text = @summary.method(x).call
481
+ summary = @doc.root.element('summary')
482
+ @summary.to_h.each do |k,v|
483
+ e = summary.element(k.to_s)
484
+ if e then
485
+ e.text = v
486
+ else
487
+ summary.add Rexle::Element.new(k.to_s).add_text(v)
488
+ end
387
489
  end
388
490
  end
389
491
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: polyrex
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.18
5
+ version: 0.8.19
6
6
  platform: ruby
7
7
  authors:
8
8
  - James Robertson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-12 00:00:00 +01:00
13
+ date: 2012-04-15 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency