relaton-bib 1.0.4 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,41 @@
1
1
  module RelatonBib
2
2
  # Copyright association.
3
3
  class CopyrightAssociation
4
+ include RelatonBib
5
+
4
6
  # @return [Date]
5
7
  attr_reader :from
6
8
 
7
9
  # @return [Date, NilClass]
8
10
  attr_reader :to
9
11
 
10
- # @return [RelatonBib::ContributionInfo]
12
+ # @return [String, NilClass]
13
+ attr_reader :scope
14
+
15
+ # @return [Array<RelatonBib::ContributionInfo>]
11
16
  attr_reader :owner
12
17
 
13
- # @param owner [Hash, RelatonBib::ContributionInfo] contributor
18
+ # rubocop:disable Metrics/AbcSize
19
+
20
+ # @param owner [Array<Hash, RelatonBib::ContributionInfo>] contributor
14
21
  # @option owner [String] :name
15
22
  # @option owner [String] :abbreviation
16
23
  # @option owner [String] :url
17
24
  # @param from [String] date
18
25
  # @param to [String, NilClass] date
19
- def initialize(owner:, from:, to: nil)
20
- @owner = if owner.is_a?(Hash)
21
- ContributionInfo.new entity: Organization.new(owner)
22
- else owner
23
- end
26
+ # @param scope [String, NilClass]
27
+ def initialize(owner:, from:, to: nil, scope: nil)
28
+ unless owner.any?
29
+ raise ArgumentError, "at least one owner should exist."
30
+ end
31
+
32
+ @owner = owner.map do |o|
33
+ o.is_a?(Hash) ? ContributionInfo.new(entity: Organization.new(o)) : o
34
+ end
24
35
 
25
36
  @from = Date.strptime(from.to_s, "%Y") if from.to_s =~ /\d{4}/
26
37
  @to = Date.strptime(to.to_s, "%Y") unless to.to_s.empty?
38
+ @scope = scope
27
39
  end
28
40
 
29
41
  # @param builder [Nokogiri::XML::Builder]
@@ -31,14 +43,21 @@ module RelatonBib
31
43
  builder.copyright do
32
44
  builder.from from ? from.year : "unknown"
33
45
  builder.to to.year if to
34
- builder.owner { owner.to_xml builder }
46
+ owner.each { |o| builder.owner { o.to_xml builder } }
47
+ builder.scope scope if scope
35
48
  end
36
49
  end
50
+ # rubocop:enable Metrics/AbcSize
37
51
 
38
52
  # @return [Hash]
39
53
  def to_hash
40
- hash = { "owner" => owner.to_hash["organization"], "from" => from.year.to_s }
54
+ owners = single_element_array(owner.map { |o| o.to_hash["organization"] })
55
+ hash = {
56
+ "owner" => owners,
57
+ "from" => from.year.to_s,
58
+ }
41
59
  hash["to"] = to.year.to_s if to
60
+ hash["scope"] = scope if scope
42
61
  hash
43
62
  end
44
63
  end
@@ -45,7 +45,7 @@ module RelatonBib
45
45
  def initialize(type:, description: nil, bibitem:, locality: [],
46
46
  source_locality: [])
47
47
  type = "obsoletes" if type == "Now withdrawn"
48
- unless TYPES.include? type
48
+ unless self.class::TYPES.include? type
49
49
  warn "[relaton-bib] WARNING: invalid relation type: #{type}"
50
50
  end
51
51
  @type = type
@@ -8,7 +8,7 @@ module RelatonBib
8
8
  extend Forwardable
9
9
 
10
10
  def_delegators :@array, :<<, :[], :first, :last, :empty?, :any?, :size,
11
- :each, :detect, :map, :length
11
+ :each, :detect, :map, :length
12
12
 
13
13
  # @param relation [Array<RelatonBib::DocumentRelation, Hash>]
14
14
  # @option relation [String] :type
@@ -20,7 +20,7 @@ module RelatonBib
20
20
  # RelatonBib::SourceLocalityStack>] :source_locality
21
21
  # @option relation [RelatonBib::BibliographicItem, NillClass] :bibitem (nil)
22
22
  def initialize(relation)
23
- @array = relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(r) : r }
23
+ @array = relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(r) : r }
24
24
  end
25
25
 
26
26
  # @todo We don't have replace type anymore. Suppose we should update this
@@ -5,10 +5,10 @@ require "relaton_bib/localized_string"
5
5
  module RelatonBib
6
6
  # Document status.
7
7
  class DocumentStatus
8
- # @return [String]
8
+ # @return [RelatonBib::DocumentStatus::Stage]
9
9
  attr_reader :stage
10
10
 
11
- # @return [String, NilClass]
11
+ # @return [RelatonBib::DocumentStatus::Stage, NilClass]
12
12
  attr_reader :substage
13
13
 
14
14
  # @return [String, NilClass]
@@ -44,6 +44,7 @@ module RelatonBib
44
44
  private
45
45
 
46
46
  # @param stg [RelatonBib::DocumentStatus::Stage, Hash, String, NilClass]
47
+ # @return [RelatonBib::DocumentStatus::Stage]
47
48
  def stage_new(stg)
48
49
  if stg.is_a?(Stage) then stg
49
50
  elsif stg.is_a?(Hash) then Stage.new(stg)
@@ -0,0 +1,27 @@
1
+ require "relaton_bib/technical_committee"
2
+
3
+ module RelatonBib
4
+ class EditorialGroup
5
+ include RelatonBib
6
+
7
+ # @return [Array<RelatonBib::TechnicalCommittee>]
8
+ attr_accessor :technical_committee
9
+
10
+ # @param technical_committee [Array<RelatonBib::TecnicalCommittee>]
11
+ def initialize(technical_committee)
12
+ @technical_committee = technical_committee
13
+ end
14
+
15
+ # @param builder [Nokogigi::XML::Builder]
16
+ def to_xml(builder)
17
+ builder.editorialgroup do |b|
18
+ technical_committee.each { |tc| tc.to_xml b }
19
+ end
20
+ end
21
+
22
+ # @return [Hash]
23
+ def to_hash
24
+ single_element_array technical_committee
25
+ end
26
+ end
27
+ end
@@ -23,6 +23,7 @@ module RelatonBib
23
23
  formattedref_hash_to_bib(ret)
24
24
  docstatus_hash_to_bib(ret)
25
25
  contributors_hash_to_bib(ret)
26
+ copyright_hash_to_bib(ret)
26
27
  relations_hash_to_bib(ret)
27
28
  series_hash_to_bib(ret)
28
29
  medium_hash_to_bib(ret)
@@ -33,6 +34,9 @@ module RelatonBib
33
34
  validity_hash_to_bib(ret)
34
35
  ret[:keyword] = array(ret[:keyword])
35
36
  ret[:license] = array(ret[:license])
37
+ editorialgroup_hash_to_bib ret
38
+ ics_hash_to_bib ret
39
+ structuredidentifier_hash_to_bib ret
36
40
  ret
37
41
  end
38
42
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
@@ -54,11 +58,12 @@ module RelatonBib
54
58
  def title_hash_to_bib(ret)
55
59
  return unless ret[:title]
56
60
 
57
- ret[:title] = array(ret[:title])
58
- ret[:title] = ret[:title].map do |t|
59
- if t.is_a?(Hash) then t
61
+ ret[:title] = array(ret[:title]).reduce([]) do |m, t|
62
+ if t.is_a?(Hash) then m << t
60
63
  else
61
- { content: t, language: "en", script: "Latn", format: "text/plain", type: "main" }
64
+ m + TypedTitleString.from_string(t)
65
+ # { content: t, language: "en", script: "Latn", format: "text/plain",
66
+ # type: "main" }
62
67
  end
63
68
  end
64
69
  end
@@ -267,6 +272,16 @@ module RelatonBib
267
272
  end
268
273
  end
269
274
 
275
+ # @param ret [Hash]
276
+ def copyright_hash_to_bib(ret)
277
+ return unless ret[:copyright]
278
+
279
+ ret[:copyright] = array(ret[:copyright]).map do |c|
280
+ c[:owner] = array(c[:owner])
281
+ c
282
+ end
283
+ end
284
+
270
285
  # @param ret [Hash]
271
286
  def relations_hash_to_bib(ret)
272
287
  return unless ret[:relation]
@@ -299,15 +314,16 @@ module RelatonBib
299
314
  end
300
315
 
301
316
  # @param rel [Hash] relation
317
+ # @return [RelatonBib::LocalityStack]
302
318
  def relation_locality_hash_to_bib(rel)
303
319
  rel[:locality] = array(rel[:locality])&.map do |bl|
304
320
  ls = if bl[:locality_stack]
305
- array(bl[:locality_stack]).map do |l|
306
- Locality.new(l[:type], l[:reference_from], l[:reference_to])
307
- end
308
- else
309
- [Locality.new(bl[:type], bl[:reference_from], bl[:reference_to])]
310
- end
321
+ array(bl[:locality_stack]).map do |l|
322
+ Locality.new(l[:type], l[:reference_from], l[:reference_to])
323
+ end
324
+ else
325
+ [Locality.new(bl[:type], bl[:reference_from], bl[:reference_to])]
326
+ end
311
327
  LocalityStack.new ls
312
328
  end
313
329
  end
@@ -326,6 +342,7 @@ module RelatonBib
326
342
  end
327
343
  end
328
344
 
345
+ # @param ret [Hash]
329
346
  def series_hash_to_bib(ret)
330
347
  ret[:series] = array(ret[:series])&.map do |s|
331
348
  s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
@@ -344,28 +361,60 @@ module RelatonBib
344
361
  TypedTitleString.new title
345
362
  end
346
363
 
364
+ # @param ret [Hash]
347
365
  def medium_hash_to_bib(ret)
348
366
  ret[:medium] = Medium.new(ret[:medium]) if ret[:medium]
349
367
  end
350
368
 
369
+ # @param ret [Hash]
351
370
  def classification_hash_to_bib(ret)
352
- # ret[:classification] = [ret[:classification]] unless ret[:classification].is_a?(Array)
353
- # ret[:classification]&.each_with_index do |c, i|
354
- # ret[:classification][i] = RelatonBib::Classification.new(c)
355
- # end
356
371
  if ret[:classification]
357
- ret[:classification] = array(ret[:classification]).map { |cls| Classification.new cls }
372
+ ret[:classification] = array(ret[:classification]).map do |cls|
373
+ Classification.new cls
374
+ end
358
375
  end
359
376
  end
360
377
 
378
+ # rubocop:disable Metrics/AbcSize
379
+
380
+ # @param ret [Hash]
361
381
  def validity_hash_to_bib(ret)
362
382
  return unless ret[:validity]
363
383
 
364
- ret[:validity][:begins] && b = Time.parse(ret[:validity][:begins])
365
- ret[:validity][:ends] && e = Time.parse(ret[:validity][:ends])
366
- ret[:validity][:revision] && r = Time.parse(ret[:validity][:revision])
384
+ ret[:validity][:begins] && b = Time.parse(ret[:validity][:begins].to_s)
385
+ ret[:validity][:ends] && e = Time.parse(ret[:validity][:ends].to_s)
386
+ ret[:validity][:revision] && r = Time.parse(ret[:validity][:revision].to_s)
367
387
  ret[:validity] = Validity.new(begins: b, ends: e, revision: r)
368
388
  end
389
+ # rubocop:enable Metrics/AbcSize
390
+
391
+ # @param ret [Hash]
392
+ def editorialgroup_hash_to_bib(ret)
393
+ return unless ret[:editorialgroup]
394
+
395
+ technical_committee = array(ret[:editorialgroup]).map do |wg|
396
+ TechnicalCommittee.new WorkGroup.new(wg)
397
+ end
398
+ ret[:editorialgroup] = EditorialGroup.new technical_committee
399
+ end
400
+
401
+ # @param ret [Hash]
402
+ def ics_hash_to_bib(ret)
403
+ return unless ret[:ics]
404
+
405
+ ret[:ics] = array(ret[:ics]).map { |ics| ICS.new ics }
406
+ end
407
+
408
+ # @param ret [Hash]
409
+ def structuredidentifier_hash_to_bib(ret)
410
+ return unless ret[:structuredidentifier]
411
+
412
+ sids = array(ret[:structuredidentifier]).map do |si|
413
+ si[:agency] = array si[:agency]
414
+ StructuredIdentifier.new si
415
+ end
416
+ ret[:structuredidentifier] = StructuredIdentifierCollection.new sids
417
+ end
369
418
 
370
419
  # @param ogj [Hash, Array, String]
371
420
  # @return [Hash, Array, String]
@@ -382,6 +431,8 @@ module RelatonBib
382
431
  end
383
432
  end
384
433
 
434
+ # @param arr [NilClass, Array, #is_a?]
435
+ # @return [Array]
385
436
  def array(arr)
386
437
  return [] unless arr
387
438
  return [arr] unless arr.is_a?(Array)
@@ -389,6 +440,9 @@ module RelatonBib
389
440
  arr
390
441
  end
391
442
 
443
+ # @param name [Hash, String, NilClass]
444
+ # @param person [Hash]
445
+ # @return [RelatonBib::LocalizedString]
392
446
  def localname(name, person)
393
447
  return nil if name.nil?
394
448
 
@@ -396,13 +450,12 @@ module RelatonBib
396
450
  lang ||= person[:name][:language]
397
451
  script = name[:script] if name.is_a?(Hash)
398
452
  script ||= person[:name][:script]
399
- if name.is_a?(Hash)
400
- RelatonBib::LocalizedString.new(name[:content], lang, script)
401
- else
402
- RelatonBib::LocalizedString.new(name, lang, script)
403
- end
453
+ n = name.is_a?(Hash) ? name[:content] : name
454
+ RelatonBib::LocalizedString.new(n, lang, script)
404
455
  end
405
456
 
457
+ # @param lst [Hash, Array<RelatonBib::LocalizedString>]
458
+ # @return [RelatonBib::LocalizedString]
406
459
  def localizedstring(lst)
407
460
  if lst.is_a?(Hash)
408
461
  RelatonBib::LocalizedString.new(lst[:content], lst[:language], lst[:script])
@@ -411,6 +464,8 @@ module RelatonBib
411
464
  end
412
465
  end
413
466
 
467
+ # @param frf [Hash, String]
468
+ # @return [RelatonBib::FormattedRef]
414
469
  def formattedref(frf)
415
470
  if frf.is_a?(Hash)
416
471
  RelatonBib::FormattedRef.new(frf)
@@ -0,0 +1,26 @@
1
+ module RelatonBib
2
+ class ICS
3
+ # @return [String]
4
+ attr_reader :code, :text
5
+
6
+ # @param code [String]
7
+ # @param text [String]
8
+ def initialize(code:, text:)
9
+ @code = code
10
+ @text = text
11
+ end
12
+
13
+ # @param builder [Nokogiri::XML::Builder]
14
+ def to_xml(builder)
15
+ builder.ics do |b|
16
+ b.code code
17
+ b.text_ text
18
+ end
19
+ end
20
+
21
+ # @return [Hash]
22
+ def to_hash
23
+ { "code" => code, "text" => text }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,141 @@
1
+ module RelatonBib
2
+ class StructuredIdentifierCollection
3
+ include RelatonBib
4
+ extend Forwardable
5
+
6
+ def_delegators :@collection, :any?, :size, :[], :detect
7
+
8
+ # @param collection [Array<RelatonBib::StructuredIdentifier>]
9
+ def initialize(collection)
10
+ @collection = collection
11
+ end
12
+
13
+ # @param builder [Nokogiri::XML::Builder]
14
+ def to_xml(builder)
15
+ @collection.each { |si| si.to_xml builder }
16
+ end
17
+
18
+ # @return [Array<Hash>]
19
+ def to_hash
20
+ single_element_array @collection
21
+ end
22
+
23
+ # remoe year from docnumber
24
+ def remove_date
25
+ @collection.each &:remove_date
26
+ end
27
+
28
+ def remove_part
29
+ @collection.each &:remove_part
30
+ end
31
+
32
+ def all_parts
33
+ @collection.each &:all_parts
34
+ end
35
+
36
+ def presence?
37
+ any?
38
+ end
39
+
40
+ # @return [RelatonBib::StructuredIdentifierCollection]
41
+ # def map(&block)
42
+ # StructuredIdentifierCollection.new @collection.map &block
43
+ # end
44
+ end
45
+
46
+ class StructuredIdentifier
47
+ include RelatonBib
48
+
49
+ # @return [String]
50
+ attr_reader :docnumber
51
+
52
+ # @return [Array<String>]
53
+ attr_reader :agency
54
+
55
+ # @return [String, NilClass]
56
+ attr_reader :type, :klass, :partnumber, :edition, :version, :supplementtype,
57
+ :supplementnumber, :language, :year
58
+
59
+ # rubocop:disable Metrics/MethodLength
60
+
61
+ # @param type [String, NilClass]
62
+ # @param agency [Array<String>]
63
+ # @parma class [Stirng, NilClass]
64
+ # @parma docnumber [String]
65
+ # @param partnumber [String, NilClass]
66
+ # @param edition [String, NilClass]
67
+ # @param version [String, NilClass]
68
+ # @param supplementtype [String, NilClass]
69
+ # @param supplementnumber [String, NilClass]
70
+ # @param language [String, NilClass]
71
+ # @param year [String, NilClass]
72
+ def initialize(docnumber:, **args)
73
+ @type = args[:type]
74
+ @agency = args[:agency]
75
+ @klass = args[:class]
76
+ @docnumber = docnumber
77
+ @partnumber = args[:partnumber]
78
+ @edition = args[:edition]
79
+ @version = args[:version]
80
+ @supplementtype = args[:supplementtype]
81
+ @supplementnumber = args[:supplementnumber]
82
+ @language = args[:language]
83
+ @year = args[:year]
84
+ end
85
+
86
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
87
+
88
+ # @param builder [Nokogiri::XML::Builder]
89
+ def to_xml(builder)
90
+ xml = builder.structuredidentifier do |b|
91
+ agency&.each { |a| b.agency a }
92
+ b.class_ klass if klass
93
+ b.docnumber docnumber
94
+ b.partnumber partnumber if partnumber
95
+ b.edition edition if edition
96
+ b.version version if version
97
+ b.supplementtype supplementtype if supplementtype
98
+ b.supplementnumber supplementnumber if supplementnumber
99
+ b.language language if language
100
+ b.year year if year
101
+ end
102
+ xml[:type] = type if type
103
+ end
104
+
105
+ # @return [Hash]
106
+ def to_hash
107
+ hash = { "docnumber" => docnumber }
108
+ hash["type"] = type if type
109
+ hash["agency"] = single_element_array agency if agency&.any?
110
+ hash["class"] = klass if klass
111
+ hash["partnumber"] = partnumber if partnumber
112
+ hash["edition"] = edition if edition
113
+ hash["version"] = version if version
114
+ hash["supplementtype"] = supplementtype if supplementtype
115
+ hash["supplementnumber"] = supplementnumber if supplementnumber
116
+ hash["language"] = language if language
117
+ hash["year"] = year if year
118
+ hash
119
+ end
120
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
121
+
122
+ def remove_date
123
+ if @type == "Chinese Standard"
124
+ @docnumber.sub!(/-[12]\d\d\d/, "")
125
+ else
126
+ @docnumber.sub!(/:[12]\d\d\d/, "")
127
+ end
128
+ @year = nil
129
+ end
130
+
131
+ # in docid manipulations, assume ISO as the default: id-part:year
132
+ def remove_part
133
+ @partnumber = nil
134
+ @docnumber = @docnumber.sub(/-\d+/, "")
135
+ end
136
+
137
+ def all_parts
138
+ @docnumber = @docnumber + " (all parts)"
139
+ end
140
+ end
141
+ end