relaton-bib 1.2.0 → 1.3.1

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ubuntu.yml +1 -0
  3. data/.rubocop.yml +2 -2
  4. data/README.adoc +16 -0
  5. data/lib/relaton_bib.rb +15 -15
  6. data/lib/relaton_bib/bib_item_locality.rb +13 -1
  7. data/lib/relaton_bib/biblio_note.rb +11 -0
  8. data/lib/relaton_bib/biblio_version.rb +12 -0
  9. data/lib/relaton_bib/bibliographic_date.rb +13 -0
  10. data/lib/relaton_bib/bibliographic_item.rb +80 -24
  11. data/lib/relaton_bib/classification.rb +11 -0
  12. data/lib/relaton_bib/contribution_info.rb +27 -1
  13. data/lib/relaton_bib/contributor.rb +55 -1
  14. data/lib/relaton_bib/copyright_association.rb +14 -1
  15. data/lib/relaton_bib/document_identifier.rb +20 -4
  16. data/lib/relaton_bib/document_relation.rb +15 -5
  17. data/lib/relaton_bib/document_relation_collection.rb +12 -0
  18. data/lib/relaton_bib/document_status.rb +10 -0
  19. data/lib/relaton_bib/editorial_group.rb +9 -0
  20. data/lib/relaton_bib/formatted_ref.rb +7 -0
  21. data/lib/relaton_bib/formatted_string.rb +11 -0
  22. data/lib/relaton_bib/hash_converter.rb +55 -36
  23. data/lib/relaton_bib/ics.rb +11 -0
  24. data/lib/relaton_bib/localized_string.rb +23 -6
  25. data/lib/relaton_bib/medium.rb +11 -0
  26. data/lib/relaton_bib/organization.rb +27 -7
  27. data/lib/relaton_bib/person.rb +54 -7
  28. data/lib/relaton_bib/place.rb +13 -1
  29. data/lib/relaton_bib/series.rb +25 -4
  30. data/lib/relaton_bib/structured_identifier.rb +30 -0
  31. data/lib/relaton_bib/technical_committee.rb +11 -0
  32. data/lib/relaton_bib/typed_title_string.rb +13 -7
  33. data/lib/relaton_bib/typed_uri.rb +11 -0
  34. data/lib/relaton_bib/validity.rb +11 -0
  35. data/lib/relaton_bib/version.rb +1 -1
  36. data/lib/relaton_bib/workgroup.rb +10 -0
  37. data/lib/relaton_bib/xml_parser.rb +54 -39
  38. metadata +5 -5
@@ -54,6 +54,20 @@ module RelatonBib
54
54
  hash["postcode"] = postcode if postcode
55
55
  hash
56
56
  end
57
+
58
+ # @param prefix [String]
59
+ # @param count [Integer] number of addresses
60
+ # @return [String]
61
+ def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
62
+ pref = prefix.empty? ? "address" : prefix + ".address"
63
+ out = count > 1 ? "#{pref}::\n" : ""
64
+ street.each { |st| out += "#{pref}.street:: #{st}\n" }
65
+ out += "#{pref}.city:: #{city}\n"
66
+ out += "#{pref}.state:: #{state}\n" if state
67
+ out += "#{pref}.country:: #{country}\n"
68
+ out += "#{pref}.postcode:: #{postcode}\n" if postcode
69
+ out
70
+ end
57
71
  end
58
72
 
59
73
  # Contact class.
@@ -80,6 +94,17 @@ module RelatonBib
80
94
  def to_hash
81
95
  { "type" => type, "value" => value }
82
96
  end
97
+
98
+ # @param prefix [String]
99
+ # @param count [Integer] number of contacts
100
+ # @return [string]
101
+ def to_asciibib(prefix = "", count = 1)
102
+ pref = prefix.empty? ? prefix : prefix + "."
103
+ out = count > 1 ? "#{pref}contact::\n" : ""
104
+ out += "#{pref}contact.type:: #{type}\n"
105
+ out += "#{pref}contact.value:: #{value}\n"
106
+ out
107
+ end
83
108
  end
84
109
 
85
110
  # Affiliation.
@@ -117,9 +142,25 @@ module RelatonBib
117
142
  def to_hash
118
143
  hash = organization.to_hash
119
144
  hash["name"] = name.to_hash if name
120
- hash["description"] = single_element_array(description) if description&.any?
145
+ if description&.any?
146
+ hash["description"] = single_element_array(description)
147
+ end
121
148
  hash
122
149
  end
150
+
151
+ # @param prefix [String]
152
+ # @param count [Integer]
153
+ # @return [String]
154
+ def to_asciibib(prefix = "", count = 1)
155
+ pref = prefix.empty? ? prefix : prefix + "."
156
+ out = count > 1 ? "#{pref}affiliation::\n" : ""
157
+ out += name.to_asciibib "#{pref}affiliation.name" if name
158
+ description.each do |d|
159
+ out += d.to_asciibib "#{pref}affiliation.description", description.size
160
+ end
161
+ out += organization.to_asciibib "#{pref}affiliation.*"
162
+ out
163
+ end
123
164
  end
124
165
 
125
166
  # Contributor.
@@ -157,5 +198,18 @@ module RelatonBib
157
198
  hash["contact"] = single_element_array(contact) if contact&.any?
158
199
  hash
159
200
  end
201
+
202
+ # @param prefix [String]
203
+ # @return [String]
204
+ def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
205
+ pref = prefix.empty? ? prefix : prefix + "."
206
+ out = ""
207
+ out += "#{pref}url:: #{uri}\n" if uri
208
+ addr = contact.select { |c| c.is_a? RelatonBib::Address }
209
+ addr.each { |ct| out += ct.to_asciibib prefix, addr.size }
210
+ cont = contact.select { |c| c.is_a? RelatonBib::Contact }
211
+ cont.each { |ct| out += ct.to_asciibib prefix, cont.size }
212
+ out
213
+ end
160
214
  end
161
215
  end
@@ -33,7 +33,7 @@ module RelatonBib
33
33
  o.is_a?(Hash) ? ContributionInfo.new(entity: Organization.new(o)) : o
34
34
  end
35
35
 
36
- @from = Date.strptime(from.to_s, "%Y") if from.to_s =~ /\d{4}/
36
+ @from = Date.strptime(from.to_s, "%Y") if from.to_s.match? /\d{4}/
37
37
  @to = Date.strptime(to.to_s, "%Y") unless to.to_s.empty?
38
38
  @scope = scope
39
39
  end
@@ -60,5 +60,18 @@ module RelatonBib
60
60
  hash["scope"] = scope if scope
61
61
  hash
62
62
  end
63
+
64
+ # @param prefix [String]
65
+ # @param count [Iteger] number of copyright elements
66
+ # @return [String]
67
+ def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
68
+ pref = prefix.empty? ? "copyright" : prefix + ".copyright"
69
+ out = count > 1 ? "#{pref}::\n" : ""
70
+ owner.each { |ow| out += ow.to_asciibib "#{pref}.owner", owner.size }
71
+ out += "#{pref}.from:: #{from.year}\n" if from
72
+ out += "#{pref}.to:: #{to.year}\n" if to
73
+ out += "#{pref}.scope:: #{scope}\n" if scope
74
+ out
75
+ end
63
76
  end
64
77
  end
@@ -5,13 +5,15 @@ module RelatonBib
5
5
  attr_reader :id
6
6
 
7
7
  # @return [String, NilClass]
8
- attr_reader :type
8
+ attr_reader :type, :scope
9
9
 
10
10
  # @param id [String]
11
11
  # @param type [String, NilClass]
12
- def initialize(id:, type: nil)
13
- @id = id
14
- @type = type
12
+ # @param scoope [String, NilClass]
13
+ def initialize(id:, type: nil, scope: nil)
14
+ @id = id
15
+ @type = type
16
+ @scope = scope
15
17
  end
16
18
 
17
19
  # in docid manipulations, assume ISO as the default: id-part:year
@@ -43,13 +45,27 @@ module RelatonBib
43
45
  def to_xml(builder)
44
46
  element = builder.docidentifier id
45
47
  element[:type] = type if type
48
+ element[:scope] = scope if scope
46
49
  end
47
50
 
48
51
  # @return [Hash]
49
52
  def to_hash
50
53
  hash = { "id" => id }
51
54
  hash["type"] = type if type
55
+ hash["scope"] = scope if scope
52
56
  hash
53
57
  end
58
+
59
+ # @param prefix [String]
60
+ # @param count [Integer] number of docids
61
+ # @return [String]
62
+ def to_asciibib(prefix = "", count = 1)
63
+ pref = prefix.empty? ? prefix : prefix + "."
64
+ out = count > 1 ? "#{pref}docid::\n" : ""
65
+ out += "#{pref}docid.type:: #{type}\n" if type
66
+ out += "#{pref}docid.scope:: #{scope}\n" if scope
67
+ out += "#{pref}docid.id:: #{id}\n"
68
+ out
69
+ end
54
70
  end
55
71
  end
@@ -45,14 +45,14 @@ 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
- @type = type
52
- @description = description
53
- @locality = locality
51
+ @type = type
52
+ @description = description
53
+ @locality = locality
54
54
  @source_locality = source_locality
55
- @bibitem = bibitem
55
+ @bibitem = bibitem
56
56
  end
57
57
 
58
58
  # rubocop:disable Metrics/AbcSize
@@ -80,5 +80,15 @@ module RelatonBib
80
80
  end
81
81
  hash
82
82
  end
83
+
84
+ # @param prefix [String]
85
+ # @return [String]
86
+ def to_asciibib(prefix = "")
87
+ pref = prefix.empty? ? prefix : prefix + "."
88
+ out = "#{prefix}.type:: #{type}\n"
89
+ out += description.to_asciibib "#{pref}desctiption" if description
90
+ out += bibitem.to_asciibib "#{pref}bibitem" if bibitem
91
+ out
92
+ end
83
93
  end
84
94
  end
@@ -30,5 +30,17 @@ module RelatonBib
30
30
  def replaces
31
31
  DocRelationCollection.new(@array.select { |r| r.type == "replace" })
32
32
  end
33
+
34
+ # @param prefix [String]
35
+ # @return [String]
36
+ def to_asciibib(prefix = "")
37
+ pref = prefix.empty? ? "relation" : prefix + ".relation"
38
+ out = ""
39
+ @array.each do |r|
40
+ out += size > 1 ? "#{pref}::\n" : ""
41
+ out += r.to_asciibib pref
42
+ end
43
+ out
44
+ end
33
45
  end
34
46
  end
@@ -41,6 +41,16 @@ module RelatonBib
41
41
  hash
42
42
  end
43
43
 
44
+ # @param prefix [String]
45
+ # @return [String]
46
+ def to_asciibib(prefix = "")
47
+ pref = prefix.empty? ? prefix : prefix + "."
48
+ out = "#{pref}docstatus.stage:: #{stage.value}\n"
49
+ out += "#{pref}docstatus.substage:: #{substage.value}\n" if substage
50
+ out += "#{pref}docstatus.iteration:: #{iteration}\n" if iteration
51
+ out
52
+ end
53
+
44
54
  private
45
55
 
46
56
  # @param stg [RelatonBib::DocumentStatus::Stage, Hash, String, NilClass]
@@ -23,5 +23,14 @@ module RelatonBib
23
23
  def to_hash
24
24
  single_element_array technical_committee
25
25
  end
26
+
27
+ # @param prefix [String]
28
+ # @return [String]
29
+ def to_asciibib(prefix = "")
30
+ pref = prefix.empty? ? "editorialgroup" : prefix + ".editorialgroup"
31
+ technical_committee.map do |tc|
32
+ tc.to_asciibib pref, technical_committee.size
33
+ end.join
34
+ end
26
35
  end
27
36
  end
@@ -6,5 +6,12 @@ module RelatonBib
6
6
  def to_xml(builder)
7
7
  builder.formattedref { super }
8
8
  end
9
+
10
+ # @param prefix [String]
11
+ # @return [String]
12
+ def to_asciibib(prefix = "")
13
+ pref = prefix.empty? ? "formattedref" : prefix + ".formattedref"
14
+ super pref
15
+ end
9
16
  end
10
17
  end
@@ -40,5 +40,16 @@ module RelatonBib
40
40
  hash["format"] = format
41
41
  hash
42
42
  end
43
+
44
+ # @param prefix [String]
45
+ # @param count [Integer] number of elements
46
+ # @return [String]
47
+ def to_asciibib(prefix = "", count = 1)
48
+ pref = prefix.empty? ? prefix : prefix + "."
49
+ # out = count > 1 ? "#{prefix}::\n" : ""
50
+ out = super
51
+ out += "#{pref}format:: #{format}\n" if format
52
+ out
53
+ end
43
54
  end
44
55
  end
@@ -4,7 +4,7 @@ module RelatonBib
4
4
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
5
5
 
6
6
  # @param args [Hash]
7
- # @param neated [TrueClas, FalseClass] default true
7
+ # @param neated [TrueClas, FalseClass] default false
8
8
  # @return [Hash]
9
9
  def hash_to_bib(args, nested = false)
10
10
  return nil unless args.is_a?(Hash)
@@ -62,8 +62,6 @@ module RelatonBib
62
62
  if t.is_a?(Hash) then m << t
63
63
  else
64
64
  m + TypedTitleString.from_string(t)
65
- # { content: t, language: "en", script: "Latn", format: "text/plain",
66
- # type: "main" }
67
65
  end
68
66
  end
69
67
  end
@@ -127,7 +125,8 @@ module RelatonBib
127
125
  ret[:docid] = array(ret[:docid])
128
126
  ret[:docid]&.each_with_index do |id, i|
129
127
  type = id[:type] || id[:id].match(/^\w+/)&.to_s
130
- ret[:docid][i] = DocumentIdentifier.new(id: id[:id], type: type)
128
+ ret[:docid][i] = DocumentIdentifier.new(id: id[:id], type: type,
129
+ scope: id[:scope])
131
130
  end
132
131
  end
133
132
 
@@ -140,31 +139,33 @@ module RelatonBib
140
139
  )
141
140
  end
142
141
 
143
- def biblionote_hash_to_bib(ret)
142
+ def biblionote_hash_to_bib(ret) # rubocop:disable Metrics/MethodLength
144
143
  return unless ret[:biblionote]
145
144
 
146
145
  ret[:biblionote] = array(ret[:biblionote])
147
146
  (ret[:biblionote])&.each_with_index do |n, i|
148
147
  ret[:biblionote][i] = if n.is_a?(String)
149
- BiblioNote.new content: n
150
- else
151
- BiblioNote.new(
152
- content: n[:content], type: n[:type], language: n[:language],
153
- script: n[:script], format: n[:format]
154
- )
155
- end
148
+ BiblioNote.new content: n
149
+ else
150
+ BiblioNote.new(
151
+ content: n[:content], type: n[:type],
152
+ language: n[:language], script: n[:script],
153
+ format: n[:format]
154
+ )
155
+ end
156
156
  end
157
157
  end
158
158
 
159
159
  def formattedref_hash_to_bib(ret)
160
- ret[:formattedref] && ret[:formattedref] = formattedref(ret[:formattedref])
160
+ ret[:formattedref] &&
161
+ ret[:formattedref] = formattedref(ret[:formattedref])
161
162
  end
162
163
 
163
164
  def docstatus_hash_to_bib(ret)
164
165
  ret[:docstatus] && ret[:docstatus] = DocumentStatus.new(
165
166
  stage: stage(ret[:docstatus][:stage]),
166
167
  substage: stage(ret[:docstatus][:substage]),
167
- iteration: ret[:docstatus][:iteration],
168
+ iteration: ret[:docstatus][:iteration]
168
169
  )
169
170
  end
170
171
 
@@ -177,7 +178,7 @@ module RelatonBib
177
178
  DocumentStatus::Stage.new(**args)
178
179
  end
179
180
 
180
- def contributors_hash_to_bib(ret)
181
+ def contributors_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
181
182
  return unless ret[:contributor]
182
183
 
183
184
  ret[:contributor] = array(ret[:contributor])
@@ -216,11 +217,11 @@ module RelatonBib
216
217
  name: fullname_hash_to_bib(person),
217
218
  affiliation: affiliation_hash_to_bib(person),
218
219
  contact: contacts_hash_to_bib(person),
219
- identifier: person_identifiers_hash_to_bib(person),
220
+ identifier: person_identifiers_hash_to_bib(person)
220
221
  )
221
222
  end
222
223
 
223
- def fullname_hash_to_bib(person)
224
+ def fullname_hash_to_bib(person) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
224
225
  n = person[:name]
225
226
  FullName.new(
226
227
  forename: array(n[:forename])&.map { |f| localname(f, person) },
@@ -228,7 +229,7 @@ module RelatonBib
228
229
  addition: array(n[:addition])&.map { |f| localname(f, person) },
229
230
  prefix: array(n[:prefix])&.map { |f| localname(f, person) },
230
231
  surname: localname(n[:surname], person),
231
- completename: localname(n[:completename], person),
232
+ completename: localname(n[:completename], person)
232
233
  )
233
234
  end
234
235
 
@@ -238,7 +239,7 @@ module RelatonBib
238
239
  end
239
240
  end
240
241
 
241
- def affiliation_hash_to_bib(person)
242
+ def affiliation_hash_to_bib(person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
242
243
  return [] unless person[:affiliation]
243
244
 
244
245
  array(person[:affiliation]).map do |a|
@@ -252,12 +253,12 @@ module RelatonBib
252
253
  end
253
254
  Affiliation.new(
254
255
  organization: Organization.new(org_hash_to_bib(a[:organization])),
255
- description: a[:description],
256
+ description: a[:description]
256
257
  )
257
258
  end
258
259
  end
259
260
 
260
- def contacts_hash_to_bib(person)
261
+ def contacts_hash_to_bib(person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
261
262
  return [] unless person[:contact]
262
263
 
263
264
  array(person[:contact]).map do |a|
@@ -315,42 +316,48 @@ module RelatonBib
315
316
 
316
317
  # @param rel [Hash] relation
317
318
  # @return [RelatonBib::LocalityStack]
318
- def relation_locality_hash_to_bib(rel)
319
+ def relation_locality_hash_to_bib(rel) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
319
320
  rel[:locality] = array(rel[:locality])&.map do |bl|
320
321
  ls = if bl[:locality_stack]
321
322
  array(bl[:locality_stack]).map do |l|
322
323
  Locality.new(l[:type], l[:reference_from], l[:reference_to])
323
324
  end
324
325
  else
325
- [Locality.new(bl[:type], bl[:reference_from], bl[:reference_to])]
326
+ l = Locality.new(bl[:type], bl[:reference_from],
327
+ bl[:reference_to])
328
+ [l]
326
329
  end
327
330
  LocalityStack.new ls
328
331
  end
329
332
  end
330
333
 
331
334
  # @param rel [Hash] relation
332
- def relation_source_locality_hash_to_bib(rel)
335
+ def relation_source_locality_hash_to_bib(rel) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
333
336
  rel[:source_locality] = array(rel[:source_locality])&.map do |sl|
334
337
  sls = if sl[:source_locality_stack]
335
338
  array(sl[:source_locality_stack]).map do |l|
336
- SourceLocality.new(l[:type], l[:reference_from], l[:reference_to])
339
+ SourceLocality.new(l[:type], l[:reference_from],
340
+ l[:reference_to])
337
341
  end
338
342
  else
339
- [SourceLocality.new(sl[:type], sl[:reference_from], sl[:reference_to])]
343
+ l = SourceLocality.new(sl[:type], sl[:reference_from],
344
+ sl[:reference_to])
345
+ [l]
340
346
  end
341
347
  SourceLocalityStack.new sls
342
348
  end
343
349
  end
344
350
 
345
351
  # @param ret [Hash]
346
- def series_hash_to_bib(ret)
352
+ def series_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
347
353
  ret[:series] = array(ret[:series])&.map do |s|
348
354
  s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
349
355
  if s[:title]
350
356
  s[:title] = { content: s[:title] } unless s[:title].is_a?(Hash)
351
357
  s[:title] = typed_title_strig(s[:title])
352
358
  end
353
- s[:abbreviation] && s[:abbreviation] = localizedstring(s[:abbreviation])
359
+ s[:abbreviation] &&
360
+ s[:abbreviation] = localizedstring(s[:abbreviation])
354
361
  Series.new(s)
355
362
  end
356
363
  end
@@ -375,18 +382,29 @@ module RelatonBib
375
382
  end
376
383
  end
377
384
 
378
- # rubocop:disable Metrics/AbcSize
379
-
380
385
  # @param ret [Hash]
381
386
  def validity_hash_to_bib(ret)
382
387
  return unless ret[:validity]
383
388
 
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)
389
+ b = parse_validity_time(ret[:validity], :begins)
390
+ e = parse_validity_time(ret[:validity], :ends)
391
+ r = parse_validity_time(ret[:validity], :revision)
387
392
  ret[:validity] = Validity.new(begins: b, ends: e, revision: r)
388
393
  end
389
- # rubocop:enable Metrics/AbcSize
394
+
395
+ def parse_validity_time(val, period)
396
+ t = val[period]&.to_s
397
+ return unless t
398
+
399
+ p = period == :ends ? -1 : 1
400
+ case t
401
+ when /^\d{4}$/
402
+ Date.new(t.to_i, p, p).to_time
403
+ when /^(?<year>\d{4})-(?<month>\d{1,2})$/
404
+ Date.new($~[:year].to_i, $~[:month].to_i, p).to_time
405
+ else Time.parse t
406
+ end
407
+ end
390
408
 
391
409
  # @param ret [Hash]
392
410
  def editorialgroup_hash_to_bib(ret)
@@ -443,7 +461,7 @@ module RelatonBib
443
461
  # @param name [Hash, String, NilClass]
444
462
  # @param person [Hash]
445
463
  # @return [RelatonBib::LocalizedString]
446
- def localname(name, person)
464
+ def localname(name, person) # rubocop:disable Metrics/CyclomaticComplexity
447
465
  return nil if name.nil?
448
466
 
449
467
  lang = name[:language] if name.is_a?(Hash)
@@ -458,7 +476,8 @@ module RelatonBib
458
476
  # @return [RelatonBib::LocalizedString]
459
477
  def localizedstring(lst)
460
478
  if lst.is_a?(Hash)
461
- RelatonBib::LocalizedString.new(lst[:content], lst[:language], lst[:script])
479
+ RelatonBib::LocalizedString.new(lst[:content], lst[:language],
480
+ lst[:script])
462
481
  else
463
482
  RelatonBib::LocalizedString.new(lst)
464
483
  end