relaton-bib 1.1.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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 +53 -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 +2 -2
@@ -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