im_onix 1.2.3 → 1.3.0

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/onix/subset.rb CHANGED
@@ -4,13 +4,13 @@ require 'cgi'
4
4
  module ONIX
5
5
  class ShortToRef
6
6
  def self.names
7
- @shortnames ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/shortnames.yml"))
7
+ @shortnames ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/shortnames.yml")).freeze
8
8
  end
9
9
  end
10
10
 
11
11
  class RefToShort
12
12
  def self.names
13
- @refnames ||= ShortToRef.names.invert
13
+ @refnames ||= ShortToRef.names.invert.freeze
14
14
  end
15
15
  end
16
16
 
@@ -25,6 +25,18 @@ module ONIX
25
25
  end
26
26
  end
27
27
 
28
+ # String only code-like class
29
+ class TextAttr
30
+ attr_accessor :code, :human
31
+
32
+ def self.from_code(code)
33
+ obj = self.new
34
+ obj.code = code
35
+ obj.human = code
36
+ obj
37
+ end
38
+ end
39
+
28
40
  module Attributes
29
41
  # @return [Hash<String,Code>]
30
42
  attr_accessor :attributes
@@ -44,16 +56,24 @@ module ONIX
44
56
  # @return [Class]
45
57
  def self.attribute_class(attr)
46
58
  case attr
47
- when "textcase"
48
- TextCase
49
- when "textformat"
50
- TextFormat
51
- when "language"
52
- LanguageCode
59
+ when "sourcename"
60
+ TextAttr
61
+ when "sourcetype"
62
+ RecordSourceType
63
+ when "collationkey"
64
+ TextAttr
53
65
  when "dateformat"
54
66
  DateFormat
55
67
  when "datestamp"
56
68
  DateStamp
69
+ when "language"
70
+ LanguageCode
71
+ when "textcase"
72
+ TextCase
73
+ when "textformat"
74
+ TextFormat
75
+ when "textscript"
76
+ ScriptCode
57
77
  else
58
78
  nil
59
79
  end
@@ -73,6 +93,7 @@ module ONIX
73
93
 
74
94
  # instanciate Subset form Nokogiri::XML::Element
75
95
  # @param [Nokogiri::XML::Element] n
96
+ # @return [Subset]
76
97
  def self.parse(n)
77
98
  o = self.new
78
99
  o.parse(n)
@@ -81,8 +102,11 @@ module ONIX
81
102
 
82
103
  # parse Nokogiri::XML::Element
83
104
  # @param [Nokogiri::XML::Element] n
105
+ # @return [void]
84
106
  def parse(n) end
85
107
 
108
+ # called when tag is not defined
109
+ # @param [String] tag
86
110
  def unsupported(tag)
87
111
  # raise SubsetUnsupported, [self.class, tag.name]
88
112
  # puts "WARN subset tag unsupported #{self.class}##{tag.name} (#{self.class.short_to_ref(tag.name)})"
@@ -91,10 +115,6 @@ module ONIX
91
115
  def tag_match(v)
92
116
  TagNameMatcher.new(v)
93
117
  end
94
-
95
- def self.tag_match(v)
96
- TagNameMatcher.new(v)
97
- end
98
118
  end
99
119
 
100
120
  # for class DSL
@@ -172,16 +192,9 @@ module ONIX
172
192
  @array
173
193
  end
174
194
 
175
- def _underscore_name
176
- if @array and @pluralize
177
- pluralize(underscore(@name))
178
- else
179
- underscore(@name)
180
- end
181
- end
182
-
195
+ # @return [String]
183
196
  def underscore_name
184
- @underscore_name ||= _underscore_name
197
+ @underscore_name ||= (@array && @pluralize) ? pluralize(underscore(@name)) : underscore(@name)
185
198
  end
186
199
 
187
200
  def class_name
@@ -216,6 +229,9 @@ module ONIX
216
229
  end
217
230
 
218
231
  class SubsetArray < Array
232
+ # @param [Symbol] k
233
+ # @param [String] p
234
+ # @return [SubsetArray]
219
235
  def human_code_match(k, p)
220
236
  case p
221
237
  when Regexp
@@ -236,6 +252,9 @@ module ONIX
236
252
  end
237
253
  end
238
254
 
255
+ # @param [Symbol] k
256
+ # @param [String] p
257
+ # @return [SubsetArray]
239
258
  def code_match(k, p)
240
259
  case p
241
260
  when Regexp
@@ -259,137 +278,155 @@ module ONIX
259
278
 
260
279
  # DSL
261
280
  class SubsetDSL < Subset
262
- def self.scope(name, lambda)
263
- @scopes ||= {}
264
- @scopes[name] = lambda
265
- end
281
+ class << self
282
+ # convert short name notation to reference
283
+ # @param [String] name
284
+ # @return [String]
285
+ def short_to_ref(name)
286
+ ShortToRef.names[name]
287
+ end
266
288
 
267
- def self._ancestor_registered_scopes
268
- els = self.registered_scopes
269
- sup = self
270
- while sup.respond_to?(:registered_scopes)
271
- els.merge!(sup.registered_scopes) if sup.registered_scopes
272
- sup = sup.superclass
289
+ # convert reference name notation to short
290
+ # @param [String] name
291
+ # @return [String]
292
+ def ref_to_short(name)
293
+ RefToShort.names[name]
273
294
  end
274
- els
275
- end
276
295
 
277
- def self.ancestor_registered_scopes
278
- @ancestors_registered_scopes ||= _ancestor_registered_scopes
279
- end
296
+ # infinity constant for cardinality
297
+ def n
298
+ Float::INFINITY
299
+ end
280
300
 
281
- def self.registered_scopes
282
- @scopes || {}
283
- end
301
+ # define a scope
302
+ # @param [Symbol] name
303
+ # @param [Lambda] lambda
304
+ # @return [void]
305
+ def scope(name, lambda)
306
+ @scopes ||= {}
307
+ @scopes[name] = lambda
308
+ end
284
309
 
285
- def self.element(name, type, options = {})
286
- @elements ||= {}
287
- @elements[name] = ElementParser.new(name, type, options)
288
- short_name = self.ref_to_short(name)
289
- if short_name
290
- @elements[short_name] = @elements[name].dup
291
- @elements[short_name].short = true
310
+ def registered_scopes
311
+ @scopes || {}
292
312
  end
293
313
 
294
- attr_accessor @elements[name].to_sym
314
+ def register_scopes(scopes)
315
+ @scopes ||= {}
316
+ @scopes = scopes.merge(@scopes)
317
+ end
295
318
 
296
- alias_method "#{@elements[name].underscore_name}_with_attributes".to_sym, @elements[name].to_sym
319
+ # define unique element
320
+ # @param [String] name
321
+ # @param [Symbol] type
322
+ # @param [Hash] options
323
+ # @return [void]
324
+ def element(name, type, options = {})
325
+ @elements ||= {}
326
+ @elements[name] = ElementParser.new(name, type, options)
327
+ short_name = self.ref_to_short(name)
328
+ if short_name
329
+ @elements[short_name] = @elements[name].dup
330
+ @elements[short_name].short = true
331
+ end
297
332
 
298
- current_element = @elements[name]
299
- define_method current_element.to_sym do |args = nil|
300
- val = instance_variable_get(current_element.to_instance)
301
- if val.respond_to?(:__getobj__)
302
- val.__getobj__
303
- else
304
- if val.is_a?(SubsetArray) and val.first and val.first.is_a?(TextWithAttributes)
305
- val.map{|v| v.respond_to?(:__getobj__) ? v.__getobj__ : v}
333
+ attr_accessor @elements[name].to_sym
334
+
335
+ alias_method "#{@elements[name].underscore_name}_with_attributes".to_sym, @elements[name].to_sym
336
+
337
+ current_element = @elements[name]
338
+ define_method current_element.to_sym do |args = nil|
339
+ val = instance_variable_get(current_element.to_instance)
340
+ if val.respond_to?(:__getobj__)
341
+ val.__getobj__
306
342
  else
307
- val
343
+ if val.is_a?(SubsetArray) and val.first and val.first.is_a?(TextWithAttributes)
344
+ val.map { |v| v.respond_to?(:__getobj__) ? v.__getobj__ : v }
345
+ else
346
+ val
347
+ end
308
348
  end
309
349
  end
350
+
351
+ if @elements[name].shortcut
352
+ current_element = @elements[name]
353
+ alias_method "#{current_element.shortcut.to_s}_with_attributes".to_sym, "#{@elements[name].underscore_name}_with_attributes".to_sym
354
+ alias_method current_element.shortcut, @elements[name].to_sym
355
+ end
356
+
357
+ @elements[name]
310
358
  end
311
359
 
312
- if @elements[name].shortcut
313
- current_element = @elements[name]
314
- alias_method "#{current_element.shortcut.to_s}_with_attributes".to_sym, "#{@elements[name].underscore_name}_with_attributes".to_sym
315
- alias_method current_element.shortcut, @elements[name].to_sym
360
+ # define multiple elements
361
+ # shortcut for element :array=>true
362
+ # @param [String] name
363
+ # @param [Symbol] type
364
+ # @param [Hash] options
365
+ # @return [void]
366
+ def elements(name, type, options = {})
367
+ self.element(name, type, options.merge(:array => true))
316
368
  end
317
- end
318
369
 
319
- # shortcut for element :array=>true
320
- def self.elements(name, type, options = {})
321
- self.element(name, type, options.merge(:array => true))
322
- end
370
+ # registered elements for this subset
371
+ # @return [Hash]
372
+ def registered_elements
373
+ @elements || {}
374
+ end
323
375
 
324
- def self._ancestors_registered_elements
325
- els = self.registered_elements
326
- sup = self
327
- while sup.respond_to?(:registered_elements)
328
- els.merge!(sup.registered_elements) if sup.registered_elements
329
- sup = sup.superclass
376
+ def register_elements(elements)
377
+ @elements ||= {}
378
+ @elements.merge!(elements)
330
379
  end
331
- els
332
- end
333
380
 
334
- def self.ancestors_registered_elements
335
- @ancestors_registered_elements ||= _ancestors_registered_elements
336
- end
381
+ def get_class(name)
382
+ ONIX.const_get(name) if ONIX.const_defined?(name)
383
+ end
337
384
 
338
- def self.registered_elements
339
- @elements || {}
385
+ def inherited(sublass)
386
+ sublass.register_scopes(self.registered_scopes)
387
+ sublass.register_elements(self.registered_elements)
388
+ end
340
389
  end
341
390
 
342
391
  def initialize
343
392
  # initialize plural as Array
344
- self.class.ancestors_registered_elements.each do |k, e|
393
+ self.registered_elements.values.each do |e|
345
394
  if e.is_array?
346
- # register a contextual SubsetArray object
347
- subset_array = SubsetArray.new
348
- subset_klass = self.class.get_class(e.class_name)
349
- if subset_klass.respond_to? :registered_scopes
350
- subset_klass.registered_scopes.each do |n, l|
351
- unless subset_array.respond_to? n.to_s
352
- subset_array.define_singleton_method(n.to_s) do
353
- instance_exec(&l)
354
- end
355
- end
356
- end
357
- end
358
- instance_variable_set(e.to_instance, subset_array)
395
+ register_subset_array(e)
359
396
  end
360
397
  end
361
398
  end
362
399
 
363
- def self.short_to_ref(name)
364
- ShortToRef.names[name]
365
- end
366
-
367
- def self.ref_to_short(name)
368
- RefToShort.names[name]
369
- end
370
-
371
- def self.get_class(name)
372
- ONIX.const_get(name) if ONIX.const_defined? name
373
- end
374
-
375
- # infinity constant for cardinality
376
- def self.n
377
- Float::INFINITY
400
+ def register_subset_array(e)
401
+ # register a contextual SubsetArray object
402
+ subset_array = SubsetArray.new
403
+ subset_klass = self.get_class(e.class_name)
404
+ if subset_klass.respond_to?(:registered_scopes)
405
+ subset_klass.registered_scopes.each do |n, l|
406
+ unless subset_array.respond_to?(n.to_s)
407
+ subset_array.define_singleton_method(n.to_s) do
408
+ instance_exec(&l)
409
+ end
410
+ end
411
+ end
412
+ end
413
+ instance_variable_set(e.to_instance, subset_array)
378
414
  end
379
415
 
380
- def get_registered_element(name)
381
- self.class.ancestors_registered_elements[name]
416
+ def registered_elements
417
+ self.class.registered_elements
382
418
  end
383
419
 
384
420
  def get_class(name)
385
421
  self.class.get_class(name)
386
422
  end
387
423
 
424
+ # @param [Nokogiri::XML::Element] n
425
+ # @return [void]
388
426
  def parse(n)
389
427
  parse_attributes(n.attributes)
390
428
  n.elements.each do |t|
391
- name = t.name
392
- e = self.get_registered_element(name)
429
+ e = self.registered_elements[t.name]
393
430
  if e
394
431
  primitive = true
395
432
  case e.type
@@ -429,7 +466,15 @@ module ONIX
429
466
  if val
430
467
  if primitive && t.attributes.length > 0
431
468
  if t.attributes["textformat"] && t.attributes["textformat"].to_s == "05" # content is XHTML
432
- val = CGI.unescapeHTML(t.children.map { |x| x.to_s }.join.strip)
469
+ xhtml = CGI.unescapeHTML(t.children.map { |x| x.to_s }.join.strip)
470
+ if Nokogiri::XML.parse(xhtml).root # check if val is really XHTML
471
+ val = xhtml
472
+ else
473
+ xhtml = CGI.unescapeHTML(val)
474
+ if Nokogiri::XML.parse(xhtml).root
475
+ val = xhtml
476
+ end
477
+ end
433
478
  end
434
479
  val = TextWithAttributes.new(val)
435
480
  val.parse(t.attributes)
@@ -441,7 +486,6 @@ module ONIX
441
486
  instance_variable_set(e.to_instance, e.parse_lambda(val))
442
487
  end
443
488
  end
444
-
445
489
  else
446
490
  unsupported(t)
447
491
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: im_onix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Boulnois
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-31 00:00:00.000000000 Z
11
+ date: 2022-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-prof
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: nokogiri
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -455,6 +483,7 @@ files:
455
483
  - lib/onix/ancillary_content.rb
456
484
  - lib/onix/audience.rb
457
485
  - lib/onix/audience_range.rb
486
+ - lib/onix/barcode.rb
458
487
  - lib/onix/builder.rb
459
488
  - lib/onix/cited_content.rb
460
489
  - lib/onix/code.rb
@@ -496,9 +525,10 @@ files:
496
525
  - lib/onix/product_contact.rb
497
526
  - lib/onix/product_form_feature.rb
498
527
  - lib/onix/product_part.rb
499
- - lib/onix/product_supplies_extractor.rb
528
+ - lib/onix/product_supplies_methods.rb
500
529
  - lib/onix/product_supply.rb
501
530
  - lib/onix/professional_affiliation.rb
531
+ - lib/onix/publisher_representative.rb
502
532
  - lib/onix/publishing_detail.rb
503
533
  - lib/onix/related_material.rb
504
534
  - lib/onix/related_product.rb