kvx 1.1.1 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/kvx.rb +143 -135
  4. data.tar.gz.sig +0 -0
  5. metadata +5 -5
  6. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea5530d34014e707b2437e10c43ba101ad30f72fbc213e4f130d1b8fd9771b56
4
- data.tar.gz: 2eb9ef7dbb42e1e664921f05745871cf3486aa55e8abf2b34e91ef803106aff1
3
+ metadata.gz: 9593cb5e316de67bd9d1f60da12863f2a7b723455292fd47b90414f432bde395
4
+ data.tar.gz: 4d9895d44ab99d29b047f9b6fc3befe12c48a1593e90e96d5ce56035be0f8efb
5
5
  SHA512:
6
- metadata.gz: 63bb7be7589852804c5b4ea5e1555c26f366f3bccef0429e7c50adac24d91a90e18c6c91ba03442450e989dd317cc9c656b4ec3768cd931fe2c90e4f05168ead
7
- data.tar.gz: 96947516061e9d56379452bd1cdb5117c1c7af11ca182f03aa37da732844bfc834df82d415aca15bbce34a985f2935e996c501d2cbe993d333b2a14c11572364
6
+ metadata.gz: 752439f262e50697f9523030846b5c2ae8298ddce5abfc4478db06029594be76ca09679cd44f8ab43a8c8462b71dffe0cf5c9bd1d9744e19a9139d90e82aa85b
7
+ data.tar.gz: f851c04b8e76a5a39aa67463c48fbce12619d2d67a1fc7dff207eb501bbc187cad36715fb4da8e88b68dcbe6f12cab59f5e7299b8d29d45864fa714626fe19c8
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/kvx.rb CHANGED
@@ -16,7 +16,7 @@ hkey_gems
16
16
  require kvx
17
17
  class Kvx
18
18
  media_type kvx
19
- '
19
+ '
20
20
  end
21
21
  end
22
22
 
@@ -34,25 +34,27 @@ class Kvx
34
34
  attr_accessor :attributes, :summary
35
35
  attr_reader :to_h
36
36
 
37
- def initialize(x=nil, summary: {}, body: {}, attributes: {}, debug: false)
37
+ def initialize(x=nil, summary: {}, body: {}, attributes: {},
38
+ comment_char: nil, debug: false)
38
39
 
39
40
  @header = attributes.any?
40
41
  @identifier = 'kvx'
41
42
  @summary, @body = summary, body
42
43
  @ignore_blank_lines ||= false
43
-
44
+
44
45
  @attributes, @debug = attributes, debug
45
-
46
+ @comment_char = comment_char
47
+
46
48
  h = {
47
- hash: :passthru,
48
- :'rexle::element' => :xml_to_h,
49
+ hash: :passthru,
50
+ :'rexle::element' => :xml_to_h,
49
51
  string: :parse_string,
50
52
  rexle: :doc_to_h,
51
53
  :"rexle::element::value" => :parse_string
52
54
  }
53
-
55
+
54
56
  if x then
55
-
57
+
56
58
  sym = h[x.class.to_s.downcase.to_sym]
57
59
  puts 'sym: ' + sym.inspect if @debug
58
60
  @body = method(sym).call x
@@ -62,127 +64,127 @@ class Kvx
62
64
  methodize(@body)
63
65
 
64
66
  end
65
-
67
+
66
68
  def import(s)
67
69
  @body = parse_string(s)
68
70
  methodize(@body)
69
71
  end
70
-
72
+
71
73
  def item()
72
74
  @body
73
75
  end
74
-
75
- alias body item
76
-
76
+
77
+ alias body item
78
+
77
79
  def save(filename)
78
80
  FileX.write filename, self.to_s
79
81
  end
80
-
81
- # flattening is helpful when passing the Hash object to
82
+
83
+ # flattening is helpful when passing the Hash object to
82
84
  # RecordX as a new record
83
85
  #
84
86
  def to_h(flatten: false)
85
-
87
+
86
88
  if @summary.empty? then
87
-
89
+
88
90
  deep_clone @body
89
-
91
+
90
92
  else
91
-
93
+
92
94
  if flatten then
93
95
  @summary.merge @body
94
96
  else
95
97
  {summary: deep_clone(@summary), body: deep_clone(@body)}
96
98
  end
97
-
99
+
98
100
  end
99
-
101
+
100
102
  end
101
-
103
+
102
104
  def to_doc()
103
-
105
+
104
106
  a = if @summary.empty? then
105
-
106
- [self.class.to_s.downcase, @attributes, '', *make_xml(@body)]
107
-
107
+
108
+ [self.class.to_s.downcase, @attributes, '', *make_xml(@body)]
109
+
108
110
  else
109
-
111
+
110
112
  summary = make_xml(@summary)
111
-
113
+
112
114
  tags_found = summary.assoc(:tags)
113
-
115
+
114
116
  if tags_found then
115
117
  tags = tags_found.pop
116
- tags_found.push *tags.split.map {|x| [:tag,{},x]}
118
+ tags_found.push *tags.split.map {|x| [:tag,{},x]}
117
119
  end
118
120
 
119
121
  summary = [:summary, {}, *summary]
120
-
122
+
121
123
  # -- use the nested description Hash object if there are multiple lines
122
124
  h = {}
123
-
125
+
124
126
  @body.each do |key, value|
125
-
127
+
126
128
  h[key] = value.is_a?(String) ? value : value[:description]
127
-
129
+
128
130
  end
129
-
131
+
130
132
  body = [:body, {}, *make_xml(h)]
131
- [self.class.to_s.downcase, @attributes, '', summary, body]
132
-
133
- end
134
-
133
+ [self.class.to_s.downcase, @attributes, '', summary, body]
134
+
135
+ end
136
+
135
137
  puts 'a: ' + a.inspect if @debug
136
138
  doc = Rexle.new a
137
139
  doc.instructions = @instructions || []
138
140
  doc
139
-
141
+
140
142
  end
141
-
143
+
142
144
  def to_s()
143
-
145
+
144
146
  header = ''
145
-
147
+
146
148
  if @header or (@summary and @summary.any?) then
147
-
149
+
148
150
  attr = @attributes ? ' ' + @attributes\
149
151
  .map {|x| "%s='%s'" % x }.join(' ') : ''
150
152
  header = '<?' + @identifier
151
153
  header += attr
152
154
  header += "?>\n"
153
-
155
+
154
156
  if @summary and @summary.any? then
155
157
  header += scan_to_s @summary
156
158
  header += "\n----------------------------------\n\n"
157
159
  end
158
-
160
+
159
161
  end
160
162
 
161
163
  # -- use the nested description Hash object if there are multiple lines
162
164
  h = {}
163
-
165
+
164
166
  @body.each do |key, value|
165
-
167
+
166
168
  h[key] = if value.is_a?(String) then
167
-
169
+
168
170
  if value.lines.length < 2 then
169
- value
171
+ value
170
172
  else
171
- "\n" + value.lines.map {|x| ' ' + x }.join
173
+ "\n" + value.lines.map {|x| ' ' + x }.join
172
174
  end
173
-
175
+
174
176
  else
175
177
  "\n" + value[:description].lines.map {|x| ' ' + x }.join
176
178
  end
177
-
178
- end
179
-
179
+
180
+ end
181
+
180
182
  header + scan_to_s(h)
181
183
 
182
- end
184
+ end
183
185
 
184
186
  def to_xml(options={pretty: true})
185
-
187
+
186
188
  doc = self.to_doc
187
189
  doc.xml(options)
188
190
 
@@ -243,7 +245,7 @@ s = "
243
245
  "
244
246
 
245
247
  end
246
-
248
+
247
249
  # used by RecordX to update a KVX record
248
250
  # id is unnecssary because there is only 1 record mapped to RecordX
249
251
  #
@@ -252,9 +254,9 @@ s = "
252
254
  end
253
255
 
254
256
  private
255
-
257
+
256
258
  def deep_clone(h)
257
-
259
+
258
260
  h.inject({}) do |r, x|
259
261
 
260
262
  h2 = if x.last.is_a? Hash then
@@ -264,31 +266,31 @@ s = "
264
266
  end
265
267
  r.merge h2[0] => h2[1]
266
268
  end
267
-
268
- end
269
-
269
+
270
+ end
271
+
270
272
  def doc_to_h(doc)
271
273
  xml_to_h(doc.root)
272
274
  end
273
275
 
274
276
  def get_attributes(raw_attributes)
275
- #
277
+ #
276
278
  r1 = /([\w\-:]+\='[^']*)'/
277
279
  r2 = /([\w\-:]+\="[^"]*)"/
278
-
280
+
279
281
  r = raw_attributes.scan(/#{r1}|#{r2}/).map(&:compact)\
280
282
  .flatten.inject(Attributes.new) do |r, x|
281
- attr_name, raw_val = x.split(/=/,2)
283
+ attr_name, raw_val = x.split(/=/,2)
282
284
  val = attr_name != 'class' ? raw_val[1..-1] : raw_val[1..-1].split
283
285
  r.merge(attr_name.to_sym => val)
284
286
  end
285
287
 
286
288
  return r
287
289
  end
288
-
290
+
289
291
  def hashify(e)
290
292
 
291
- v = if e.has_elements? then
293
+ v = if e.has_elements? then
292
294
  e.elements.inject({}) do |r, x|
293
295
  r.merge hashify(x)
294
296
  end
@@ -297,17 +299,17 @@ s = "
297
299
  end
298
300
 
299
301
  {e.name.to_sym => v}
300
- end
302
+ end
301
303
 
302
304
  def make_xml(h)
303
-
305
+
304
306
  puts 'inside make_xml: ' + h.inspect if @debug
305
307
  h2 = h.clone
306
308
  h2.each {|key,value| value.delete :items if value.is_a?(Hash) }
307
309
 
308
310
  RexleBuilder.new(h2, debug: false).to_a[3..-1]
309
311
  end
310
-
312
+
311
313
  def parse_string(s)
312
314
 
313
315
  buffer, type = RXFReader.read(s)
@@ -327,9 +329,9 @@ s = "
327
329
  end
328
330
 
329
331
  end
330
-
332
+
331
333
  def methodize(h)
332
-
334
+
333
335
  h.each do |k,v|
334
336
 
335
337
  define_singleton_method(k){v} unless self.methods.include? k
@@ -338,68 +340,68 @@ s = "
338
340
  define_singleton_method((k.to_s + '=').to_sym){|x| h[k] = x}
339
341
  end
340
342
 
341
- end
342
-
343
+ end
344
+
343
345
  end
344
346
 
345
347
  def parse_to_h(s, header_pattern: %r(^<\?kvx[\s\?]))
346
348
 
347
349
  raw_txt, _ = RXFReader.read(s)
348
350
 
349
- # does the raw_txt contain header information?
351
+ # does the raw_txt contain header information?
350
352
  a = s.strip.lines
351
353
 
352
354
  txt = if a[0] =~ header_pattern then
353
-
355
+
354
356
  raw_header = a.shift
355
357
  attr = get_attributes(raw_header)
356
-
358
+
357
359
  if attr[:created] then
358
360
  attr[:last_modified] = Time.now.to_s
359
361
  else
360
- attr[:created] = Time.now.to_s
362
+ attr[:created] = Time.now.to_s
361
363
  end
362
-
364
+
363
365
  @attributes.merge! attr
364
366
  @header = true
365
- body, summary = a.join.strip.split(/^----*$/).reverse
367
+ body, summary = a.join.strip.split(/^----*$/).reverse
366
368
  @summary = scan_to_h summary if summary
367
-
369
+
368
370
  body
369
371
  else
370
372
  raw_txt
371
373
  end
372
-
374
+
373
375
  scan_to_h(txt)
374
376
  end
375
377
 
376
378
  def passthru(x)
377
-
379
+
378
380
  if x[:summary] and x[:body]
379
381
  @summary = deep_clone x[:summary]
380
382
  deep_clone x[:body]
381
- else
383
+ else
382
384
  deep_clone x
383
385
  end
384
-
386
+
385
387
  end
386
-
388
+
387
389
  def pretty_print(a, indent='')
388
-
389
- a.map do |x|
390
+
391
+ a.map do |x|
390
392
  (x.is_a?(String) or x.nil?) ? x.to_s : pretty_print(x, indent + ' ')
391
393
  end.join("\n" + indent)
392
-
394
+
393
395
  end
394
-
395
-
396
+
397
+
396
398
  def scan_to_h(txt)
397
-
399
+
398
400
  txt.gsub!(/^\w+:(?=$)/,'\0 ')
399
401
  puts 'txt:' + txt.inspect if @debug
400
-
402
+
401
403
  # auto indent any multiline values which aren't already indented
402
-
404
+
403
405
  indent = ''
404
406
 
405
407
  lines = txt.gsub(/^-+$/m,'').lines.map do |line|
@@ -411,89 +413,95 @@ s = "
411
413
  line
412
414
  end
413
415
 
414
- end
416
+ end
415
417
  puts ('lines: ' + lines.inspect).debug if @debug
416
-
418
+
417
419
  puts ('inside scan_to_h').info if @debug
418
- raw_a = LineTree.new(lines.join.gsub(/(^-*$)|(?<=\S) +#.*/,'').strip,
420
+ txt = lines.join.gsub(/^-*$/,'')
421
+
422
+ if @comment_char then
423
+ txt.gsub!(/(?<=\S) +#{@comment_char}.*|#{@comment_char}[^\n]+/,'')
424
+ end
425
+
426
+ raw_a = LineTree.new(txt.strip,
419
427
  ignore_blank_lines: @ignore_blank_lines).to_a
420
428
  puts ('raw_a: ' + raw_a.inspect).debug if @debug
421
-
422
- # if there are any orphan lines which aren't nested underneath a
429
+
430
+ # if there are any orphan lines which aren't nested underneath a
423
431
  # label, they will be fixed using the following statement
424
-
432
+
425
433
  a = raw_a.chunk {|x| x[0][/^[^:]+:/]}.inject([]) do |r,y|
426
434
 
427
-
435
+
428
436
  puts 'r: ' + r.inspect if @debug
429
-
437
+
430
438
  if r.last and !y.first[/[^:]+:/] then
431
439
  r.last << y.last[-1]
432
440
  else
433
441
  puts 'y: ' + y.inspect if @debug
434
442
  r << y.last[-1]
435
443
  end
436
-
444
+
437
445
  r
438
-
446
+
439
447
  end
440
448
 
441
449
  @body = a.inject({}) do |r, line|
442
-
450
+
443
451
  s = line.shift
444
452
  puts ('s: ' + s.inspect).debug if @debug
445
-
453
+
446
454
  if line.join.length > 0 then
447
-
455
+
448
456
  puts 'line: ' + line.inspect if @debug
449
-
450
- padding = line[0].length < 2 ? "\n" : "\n "
457
+
458
+ padding = line[0].length < 2 ? "\n" : "\n "
451
459
  s10 = line.map{|x| x.join(padding)}.join("\n")
452
-
460
+
453
461
  r2 = if s10[/^ *\w+:[\n ]/] then
454
-
462
+
455
463
  scan_to_h(s10)
456
-
464
+
457
465
  else
458
466
 
459
- desc = pretty_print(line).split(/\n(?=\w+: )/)
467
+ desc = pretty_print(line).split(/\n(?=\w+: )/)
460
468
 
461
469
  txt2, remaining = desc
462
470
 
463
- h = txt2.lines.inject([]) do |r, x|
471
+ h = txt2.lines.inject([]) do |r, x|
464
472
  x.chomp!
465
473
  x.length > 0 ? r << x : r
466
474
  end
467
-
468
- r3 = {description: txt2, items: h}
475
+
476
+ r3 = {description: txt2, items: LineTree.new(txt2).to_a(normalize: true)}
469
477
 
470
478
  if remaining then
471
479
  r3.merge!(scan_to_h remaining + "\n ")
472
480
  end
473
-
481
+
474
482
  r3
475
483
  end
476
484
 
477
485
  r.merge({s[/[^:]+/].to_sym => r2})
478
-
486
+
479
487
  else
480
-
488
+
481
489
  value, name = s.split(/: */,2).reverse
482
- name ||= 'description'
490
+ name ||= 'description'
483
491
  v = value =~ /^\{\s*\}$/ ? {} : value.to_s
484
-
492
+
485
493
  r.merge({name.to_sym => v})
486
- end
494
+ end
487
495
 
488
496
  end
489
-
497
+
490
498
  puts ('@body: ' + @body.inspect).debug if @debug
491
499
  @body
492
500
 
493
- end
494
-
495
- def scan_to_s(h, indent='')
496
-
501
+ end
502
+
503
+ def scan_to_s(h, indent='')
504
+
497
505
  a = h.inject([]) do |r, x|
498
506
  if x.last.is_a? Hash then
499
507
  r << x.first.to_s + ":\n" + scan_to_s(x.last, ' ')
@@ -501,27 +509,27 @@ s = "
501
509
  r << "%s%s: %s" % [indent, *x]
502
510
  end
503
511
  end
504
-
512
+
505
513
  @to_s = a.join("\n")
506
514
  end
507
-
515
+
508
516
  def xml_to_h(node)
509
-
517
+
510
518
  puts 'node: ' + node.xml.inspect if @debug
511
519
  @attributes = node.attributes.to_h
512
-
520
+
513
521
  summary = node.element('summary')
514
-
522
+
515
523
  if summary then
516
524
 
517
525
  etags = summary.element 'tags'
518
-
526
+
519
527
  if etags then
520
528
 
521
529
  tags = etags.xpath('tag/text()')
522
530
  etags.delete 'tag'
523
531
  etags.text = tags.join(' ') if tags.any?
524
-
532
+
525
533
  end
526
534
 
527
535
  @summary = hashify(summary)[:summary]
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kvx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,7 +35,7 @@ cert_chain:
35
35
  kHNn+ERume1+043nzGdoGxJEUVUPYjRHDzWB1QG7OyRO+e9RZvsTQyTp2+EWVCPD
36
36
  haPJ+LVlPvQPLLPI124YDQp8
37
37
  -----END CERTIFICATE-----
38
- date: 2022-05-24 00:00:00.000000000 Z
38
+ date: 2022-09-27 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: line-tree
@@ -46,7 +46,7 @@ dependencies:
46
46
  version: '0.9'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.9.3
49
+ version: 0.9.4
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,7 +56,7 @@ dependencies:
56
56
  version: '0.9'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.9.3
59
+ version: 0.9.4
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rxfreadwrite
62
62
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  requirements: []
106
- rubygems_version: 3.2.22
106
+ rubygems_version: 3.3.7
107
107
  signing_key:
108
108
  specification_version: 4
109
109
  summary: Kvx (Keys, Values, and XML) makes it convenient to store and retrieve the
metadata.gz.sig CHANGED
Binary file