relaton-bib 0.9.2 → 1.0.4

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.
@@ -167,8 +167,12 @@ module RelatonBib
167
167
  #
168
168
  # @param relation [Array<Hash>]
169
169
  # @option relation [String] :type
170
- # @option relation [RelatonBib::BibliographicItem, RelatonIso::IsoBibliographicItem] :bibitem
171
- # @option relation [Array<RelatonBib::BibItemLocality>] :bib_locality
170
+ # @option relation [RelatonBib::BibliographicItem,
171
+ # RelatonIso::IsoBibliographicItem] :bibitem
172
+ # @option relation [Array<RelatonBib::Locality,
173
+ # RelatonBib::LocalityStack>] :locality
174
+ # @option relation [Array<RelatonBib::SourceLocality,
175
+ # RelatonBib::SourceLocalityStack>] :source_locality
172
176
  #
173
177
  # @param link [Array<Hash, RelatonBib::TypedUri>]
174
178
  # @option link [String] :type
@@ -147,17 +147,16 @@ module RelatonBib
147
147
  # @param bibtex [BibTeX::Entry]
148
148
  # @return [Array<RelatonBib::BiblioNote>]
149
149
  def fetch_note(bibtex)
150
- note = []
151
- note << BiblioNote.new(type: "annote", content: bibtex.annote.to_s) if bibtex["annote"]
152
-
153
- if bibtex["howpublished"]
154
- note << BiblioNote.new(type: "howpublished", content: bibtex.howpublished.to_s)
150
+ bibtex.select do |k, _v|
151
+ %i[annote howpublished comment note content].include? k
152
+ end.reduce([]) do |mem, note|
153
+ type = case note[0]
154
+ when :note then nil
155
+ when :content then "tableOfContents"
156
+ else note[0].to_s
157
+ end
158
+ mem << BiblioNote.new(type: type, content: note[1].to_s)
155
159
  end
156
-
157
- note << BiblioNote.new(type: "comment", content: bibtex.comment.to_s) if bibtex["comment"]
158
- note << BiblioNote.new(content: bibtex.note.to_s) if bibtex["note"]
159
- note << BiblioNote.new(type: "tableOfContents", content: bibtex["content"]) if bibtex["content"]
160
- note
161
160
  end
162
161
 
163
162
  # @param bibtex [BibTeX::Entry]
@@ -172,16 +171,19 @@ module RelatonBib
172
171
  # @param bibtex [BibTeX::Entry]
173
172
  # @return [Array<RelatonBib::BibItemLocality>]
174
173
  def fetch_extent(bibtex)
175
- extent = []
176
- extent << BibItemLocality.new("chapter", bibtex.chapter.to_s) if bibtex["chapter"]
177
-
178
- if bibtex["pages"]
179
- from, to = bibtex.pages.to_s.split "-"
180
- extent << BibItemLocality.new("page", from, to)
174
+ bibtex.select do |k, _v|
175
+ %i[chapter pages volume].include? k
176
+ end.reduce([]) do |mem, loc|
177
+ if loc[0] == :pages
178
+ type = "page"
179
+ from, to = loc[1].to_s.split "-"
180
+ else
181
+ type = loc[0].to_s
182
+ from = loc[1].to_s
183
+ to = nil
184
+ end
185
+ mem << BibItemLocality.new(type, from, to)
181
186
  end
182
-
183
- extent << BibItemLocality.new("volume", bibtex.volume.to_s) if bibtex["volume"]
184
- extent
185
187
  end
186
188
 
187
189
  # @param bibtex [BibTeX::Entry]
@@ -192,7 +194,7 @@ module RelatonBib
192
194
  series << Series.new(
193
195
  type: "journal",
194
196
  title: TypedTitleString.new(content: bibtex.journal.to_s),
195
- number: bibtex["number"]&.to_s
197
+ number: bibtex["number"]&.to_s,
196
198
  )
197
199
  end
198
200
 
@@ -1,59 +1,83 @@
1
1
  module RelatonBib
2
- # module DocumentRelationType
3
- # PARENT = 'parent'
4
- # CHILD = 'child'
5
- # OBSOLETES = 'obsoletes'
6
- # UPDATES = 'updates'
7
- # COMPLEMENTS = 'complements'
8
- # DERIVED_FORM = 'derivedForm'
9
- # ADOPTED_FORM = 'adoptedForm'
10
- # EQUIVALENT = 'equivalent'
11
- # IDENTICAL = 'identical'
12
- # NONEQUIVALENT = 'nonequivalent'
13
- # end
14
-
15
2
  # Documett relation
16
3
  class DocumentRelation
17
4
  include RelatonBib
18
5
 
6
+ TYPES = %w[
7
+ includes includedIn hasPart partOf merges mergedInto splits splitInto
8
+ instance hasInstance exemplarOf hasExemplar manifestationOf
9
+ hasManifestation reproductionOf hasReproduction reprintOf hasReprint
10
+ expressionOf hasExpression translatedFrom hasTranslation arrangementOf
11
+ hasArrangement abridgementOf hasAbridgement annotationOf hasAnnotation
12
+ draftOf hasDraft editionOf hasEdition updates updatedBy derivedFrom
13
+ derives describes describedBy catalogues cataloguedBy hasSuccessor
14
+ successorOf adaptedFrom hasAdaptation adoptedFrom adoptedAs reviewOf
15
+ hasReview commentaryOf hasCommentary related complements complementOf
16
+ obsoletes obsoletedBy cited isCitedIn
17
+ ].freeze
18
+
19
19
  # @return [String]
20
20
  attr_reader :type
21
21
 
22
+ # @return [RelatonBib::FormattedString, NilClass]
23
+ attr_reader :description
24
+
22
25
  # @return [String]
23
26
  # attr_reader :identifier, :url
24
27
 
25
28
  # @return [RelatonBib::BibliographicItem]
26
29
  attr_reader :bibitem
27
30
 
28
- # @return [Array<RelatonBib::BibItemLocality>]
29
- attr_reader :bib_locality
31
+ # @return [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
32
+ attr_reader :locality
33
+
34
+ # @return [Array<RelatonBib::SourceLocality,
35
+ # RelatonBib::SourceLocalityStack>]
36
+ attr_reader :source_locality
30
37
 
31
38
  # @param type [String]
32
- # @param bibitem [RelatonBib::BibliographicItem, RelatonIso::IsoBibliographicItem]
33
- # @param bib_locality [Array<RelatonBib::BibItemLocality>]
34
- def initialize(type:, bibitem:, bib_locality: [])
39
+ # @parma description [RelatonBib::FormattedString, NilClass]
40
+ # @param bibitem [RelatonBib::BibliographicItem,
41
+ # RelatonIso::IsoBibliographicItem]
42
+ # @param locality [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
43
+ # @param source_locality [Array<RelatonBib::SourceLocality,
44
+ # RelatonBib::SourceLocalityStack>]
45
+ def initialize(type:, description: nil, bibitem:, locality: [],
46
+ source_locality: [])
35
47
  type = "obsoletes" if type == "Now withdrawn"
36
- @type = type
37
- @bib_locality = bib_locality
38
- @bibitem = bibitem
48
+ unless TYPES.include? type
49
+ warn "[relaton-bib] WARNING: invalid relation type: #{type}"
50
+ end
51
+ @type = type
52
+ @description = description
53
+ @locality = locality
54
+ @source_locality = source_locality
55
+ @bibitem = bibitem
39
56
  end
40
57
 
58
+ # rubocop:disable Metrics/AbcSize
59
+
41
60
  # @param builder [Nokogiri::XML::Builder]
42
61
  def to_xml(builder, **opts)
43
62
  opts.delete :bibdata
44
63
  opts.delete :note
45
64
  builder.relation(type: type) do
65
+ builder.description { description.to_xml builder } if description
46
66
  bibitem.to_xml(builder, **opts.merge(embedded: true))
47
- bib_locality.each do |l|
48
- builder.locality { l.to_xml builder }
49
- end
67
+ locality.each { |l| l.to_xml builder }
68
+ source_locality.each { |l| l.to_xml builder }
50
69
  end
51
70
  end
71
+ # rubocop:enable Metrics/AbcSize
52
72
 
53
73
  # @return [Hash]
54
74
  def to_hash
55
75
  hash = { "type" => type, "bibitem" => bibitem.to_hash }
56
- hash["bib_locality"] = single_element_array(bib_locality) if bib_locality&.any?
76
+ hash["description"] = description.to_hash if description
77
+ hash["locality"] = single_element_array(locality) if locality&.any?
78
+ if source_locality&.any?
79
+ hash["source_locality"] = single_element_array(source_locality)
80
+ end
57
81
  hash
58
82
  end
59
83
  end
@@ -1,21 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
4
+
3
5
  module RelatonBib
4
6
  # Document relation collection
5
- class DocRelationCollection < Array
7
+ class DocRelationCollection
8
+ extend Forwardable
9
+
10
+ def_delegators :@array, :<<, :[], :first, :last, :empty?, :any?, :size,
11
+ :each, :detect, :map, :length
12
+
6
13
  # @param relation [Array<RelatonBib::DocumentRelation, Hash>]
7
14
  # @option relation [String] :type
8
15
  # @option relation [String] :identifier
9
16
  # @option relation [String, NIllClass] :url (nil)
10
- # @option relation [Array<RelatonBib::BibItemLocality>] :bib_locality
17
+ # @option relation [Array<RelatonBib::Locality,
18
+ # RelatonBib::LocalityStack>] :locality
19
+ # @option relation [Array<RelatonBib::SourceLocality,
20
+ # RelatonBib::SourceLocalityStack>] :source_locality
11
21
  # @option relation [RelatonBib::BibliographicItem, NillClass] :bibitem (nil)
12
22
  def initialize(relation)
13
- super relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(r) : r }
23
+ @array = relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(r) : r }
14
24
  end
15
25
 
16
- # @return [Array<RelatonBib::DocumentRelation>]
26
+ # @todo We don't have replace type anymore. Suppose we should update this
27
+ # method or delete it.
28
+ #
29
+ # @return [RelatonBib::DocRelationCollection]
17
30
  def replaces
18
- select { |r| r.type == "replace" }
31
+ DocRelationCollection.new(@array.select { |r| r.type == "replace" })
19
32
  end
20
33
  end
21
34
  end
@@ -14,12 +14,12 @@ module RelatonBib
14
14
  # @return [String, NilClass]
15
15
  attr_reader :iteration
16
16
 
17
- # @param stage [String]
18
- # @param substage [String, NilClass]
17
+ # @param stage [String, Hash, RelatonBib::DocumentStatus::Stage]
18
+ # @param substage [String, Hash, NilClass, RelatonBib::DocumentStatus::Stage]
19
19
  # @param iteration [String, NilClass]
20
20
  def initialize(stage:, substage: nil, iteration: nil)
21
- @stage = stage
22
- @substage = substage
21
+ @stage = stage_new stage
22
+ @substage = stage_new substage
23
23
  @iteration = iteration
24
24
  end
25
25
 
@@ -27,18 +27,56 @@ module RelatonBib
27
27
  def to_xml(builder)
28
28
  builder.status do
29
29
  # FormattedString.instance_method(:to_xml).bind(status).call builder
30
- builder.stage stage
31
- builder.substage substage if substage
30
+ builder.stage { |b| stage.to_xml b }
31
+ builder.substage { |b| substage.to_xml b } if substage
32
32
  builder.iteration iteration unless iteration.to_s.empty?
33
33
  end
34
34
  end
35
35
 
36
36
  # @return [Hash]
37
37
  def to_hash
38
- hash = { "stage" => stage }
39
- hash["substage"] = substage if substage
38
+ hash = { "stage" => stage.to_hash }
39
+ hash["substage"] = substage.to_hash if substage
40
40
  hash["iteration"] = iteration if iteration
41
41
  hash
42
42
  end
43
+
44
+ private
45
+
46
+ # @param stg [RelatonBib::DocumentStatus::Stage, Hash, String, NilClass]
47
+ def stage_new(stg)
48
+ if stg.is_a?(Stage) then stg
49
+ elsif stg.is_a?(Hash) then Stage.new(stg)
50
+ elsif stg.is_a?(String) then Stage.new(value: stg)
51
+ end
52
+ end
53
+
54
+ class Stage
55
+ # @return [String]
56
+ attr_reader :value
57
+
58
+ # @return [String, NilClass]
59
+ attr_reader :abbreviation
60
+
61
+ # @parma value [String]
62
+ # @param abbreviation [String, NilClass]
63
+ def initialize(value:, abbreviation: nil)
64
+ @value = value
65
+ @abbreviation = abbreviation
66
+ end
67
+
68
+ # @param [Nokogiri::XML::Builder]
69
+ def to_xml(builder)
70
+ builder.parent[:abbreviation] = abbreviation if abbreviation
71
+ builder.text value
72
+ end
73
+
74
+ # @return [Hash]
75
+ def to_hash
76
+ hash = { "value" => value }
77
+ hash["abbreviation"] = abbreviation if abbreviation
78
+ hash
79
+ end
80
+ end
43
81
  end
44
82
  end
@@ -12,7 +12,7 @@ module RelatonBib
12
12
  # @return [String]
13
13
  attr_reader :format
14
14
 
15
- # @param content [String]
15
+ # @param content [String, Array<RelatonBib::LocalizedString>]
16
16
  # @param language [String, NilClass] language code Iso639
17
17
  # @param script [String, NilClass] script code Iso15924
18
18
  # @param format [String] the content type
@@ -36,8 +36,8 @@ module RelatonBib
36
36
  hash = super
37
37
  return hash unless format
38
38
 
39
- hash = { "content" => hash } if hash.is_a? String
40
- hash["format"] = format if format
39
+ hash = { "content" => hash } unless hash.is_a? Hash
40
+ hash["format"] = format
41
41
  hash
42
42
  end
43
43
  end
@@ -1,6 +1,11 @@
1
1
  module RelatonBib
2
2
  class HashConverter
3
3
  class << self
4
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
5
+
6
+ # @param args [Hash]
7
+ # @param neated [TrueClas, FalseClass] default true
8
+ # @return [Hash]
4
9
  def hash_to_bib(args, nested = false)
5
10
  return nil unless args.is_a?(Hash)
6
11
 
@@ -30,6 +35,7 @@ module RelatonBib
30
35
  ret[:license] = array(ret[:license])
31
36
  ret
32
37
  end
38
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
33
39
 
34
40
  def timestamp_hash(ret)
35
41
  ret[:fetched] ||= Date.today.to_s
@@ -151,12 +157,21 @@ module RelatonBib
151
157
 
152
158
  def docstatus_hash_to_bib(ret)
153
159
  ret[:docstatus] && ret[:docstatus] = DocumentStatus.new(
154
- stage: ret[:docstatus][:stage],
155
- substage: ret[:docstatus][:substage],
160
+ stage: stage(ret[:docstatus][:stage]),
161
+ substage: stage(ret[:docstatus][:substage]),
156
162
  iteration: ret[:docstatus][:iteration],
157
163
  )
158
164
  end
159
165
 
166
+ # @param stg [Hash]
167
+ # @return [RelatonBib::DocumentStatus::Stage]
168
+ def stage(stg)
169
+ return unless stg
170
+
171
+ args = stg.is_a?(String) ? { value: stg } : stg
172
+ DocumentStatus::Stage.new(**args)
173
+ end
174
+
160
175
  def contributors_hash_to_bib(ret)
161
176
  return unless ret[:contributor]
162
177
 
@@ -252,47 +267,70 @@ module RelatonBib
252
267
  end
253
268
  end
254
269
 
270
+ # @param ret [Hash]
255
271
  def relations_hash_to_bib(ret)
256
272
  return unless ret[:relation]
257
273
 
258
274
  ret[:relation] = array(ret[:relation])
259
- ret[:relation]&.each_with_index do |r, i|
260
- relation_bibitem_hash_to_bib(ret, r, i)
261
- relation_biblocality_hash_to_bib(ret, r, i)
275
+ ret[:relation]&.each do |r|
276
+ if r[:description]
277
+ r[:description] = FormattedString.new r[:description]
278
+ end
279
+ relation_bibitem_hash_to_bib(r)
280
+ relation_locality_hash_to_bib(r)
281
+ relation_source_locality_hash_to_bib(r)
262
282
  end
263
283
  end
264
284
 
265
- # @param ret [Hash]
266
285
  # @param rel [Hash] relation
267
- # @param idx [Integr] index of relation
268
- def relation_bibitem_hash_to_bib(ret, rel, idx)
286
+ def relation_bibitem_hash_to_bib(rel)
269
287
  if rel[:bibitem]
270
- ret[:relation][idx][:bibitem] = bib_item(hash_to_bib(rel[:bibitem], true))
288
+ rel[:bibitem] = bib_item hash_to_bib(rel[:bibitem], true)
271
289
  else
272
290
  warn "[relaton-bib] bibitem missing: #{rel}"
273
- ret[:relation][idx][:bibitem] = nil
291
+ rel[:bibitem] = nil
274
292
  end
275
293
  end
276
294
 
277
- # @param item [Hash]
278
- # @retirn [RelatonBib::BibliographicItem]
279
- def bib_item(item)
280
- BibliographicItem.new(item)
295
+ # @param item_hash [Hash]
296
+ # @return [RelatonBib::BibliographicItem]
297
+ def bib_item(item_hash)
298
+ BibliographicItem.new item_hash
281
299
  end
282
300
 
283
- def relation_biblocality_hash_to_bib(ret, rel, idx)
284
- ret[:relation][idx][:bib_locality] =
285
- array(rel[:bib_locality])&.map do |bl|
286
- BibItemLocality.new(bl[:type], bl[:reference_from],
287
- bl[:reference_to])
288
- end
301
+ # @param rel [Hash] relation
302
+ def relation_locality_hash_to_bib(rel)
303
+ rel[:locality] = array(rel[:locality])&.map do |bl|
304
+ 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
311
+ LocalityStack.new ls
312
+ end
313
+ end
314
+
315
+ # @param rel [Hash] relation
316
+ def relation_source_locality_hash_to_bib(rel)
317
+ rel[:source_locality] = array(rel[:source_locality])&.map do |sl|
318
+ sls = if sl[:source_locality_stack]
319
+ array(sl[:source_locality_stack]).map do |l|
320
+ SourceLocality.new(l[:type], l[:reference_from], l[:reference_to])
321
+ end
322
+ else
323
+ [SourceLocality.new(sl[:type], sl[:reference_from], sl[:reference_to])]
324
+ end
325
+ SourceLocalityStack.new sls
326
+ end
289
327
  end
290
328
 
291
329
  def series_hash_to_bib(ret)
292
330
  ret[:series] = array(ret[:series])&.map do |s|
293
331
  s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
294
332
  if s[:title]
295
- s[:title] = { content: s[:title] } unless s.is_a?(Hash)
333
+ s[:title] = { content: s[:title] } unless s[:title].is_a?(Hash)
296
334
  s[:title] = typed_title_strig(s[:title])
297
335
  end
298
336
  s[:abbreviation] && s[:abbreviation] = localizedstring(s[:abbreviation])