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.
- data/lib/polyrex.rb +125 -23
- 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
|
-
|
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
|
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
|
-
|
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
|
-
|
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[
|
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
|
-
|
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 = @
|
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+\])/).
|
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
|
-
@
|
386
|
-
|
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.
|
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-
|
13
|
+
date: 2012-04-15 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|