relaton-bib 1.3.1 → 1.5.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.
@@ -1,4 +1,31 @@
1
1
  module RelatonBib
2
+ class BiblioNoteCollection
3
+ extend Forwardable
4
+
5
+ def_delegators :@array, :[], :first, :last, :empty?, :any?, :size,
6
+ :each, :map, :detect, :length
7
+
8
+ def initialize(notes)
9
+ @array = notes
10
+ end
11
+
12
+ # @param bibnote [RelatonBib::BiblioNote]
13
+ # @return [self]
14
+ def <<(bibnote)
15
+ @array << bibnote
16
+ self
17
+ end
18
+
19
+ # @param opts [Hash]
20
+ # @option opts [Nokogiri::XML::Builder] XML builder
21
+ # @option opts [String] :lang language
22
+ def to_xml(**opts)
23
+ bnc = @array.select { |bn| bn.language&.include? opts[:lang] }
24
+ bnc = @array unless bnc.any?
25
+ bnc.each { |bn| bn.to_xml opts[:builder] }
26
+ end
27
+ end
28
+
2
29
  class BiblioNote < FormattedString
3
30
  # @return [String, NilClass]
4
31
  attr_reader :type
@@ -6,7 +6,8 @@ module RelatonBib
6
6
  # Bibliographic date.
7
7
  class BibliographicDate
8
8
  TYPES = %w[published accessed created implemented obsoleted confirmed
9
- updated issued transmitted copied unchanged circulated adapted].freeze
9
+ updated issued transmitted copied unchanged circulated adapted
10
+ vote-started vote-ended].freeze
10
11
 
11
12
  # @return [String]
12
13
  attr_reader :type
@@ -45,7 +45,7 @@ module RelatonBib
45
45
  attr_reader :id, :type, :docnumber, :edition, :doctype
46
46
 
47
47
  # @!attribute [r] title
48
- # @return [Array<RelatonBib::TypedTitleString>]
48
+ # @return [RelatonBib::TypedTitleStringCollection]
49
49
 
50
50
  # @return [Array<RelatonBib::TypedUri>]
51
51
  attr_reader :link
@@ -59,10 +59,10 @@ module RelatonBib
59
59
  # @return [Array<RelatonBib::ContributionInfo>]
60
60
  attr_reader :contributor
61
61
 
62
- # @return [RelatonBib::BibliongraphicItem::Version, NilClass]
62
+ # @return [RelatonBib::BibliographicItem::Version, NilClass]
63
63
  attr_reader :version
64
64
 
65
- # @return [Array<RelatonBib::BiblioNote>]
65
+ # @return [RelatonBib::BiblioNoteCollection]
66
66
  attr_reader :biblionote
67
67
 
68
68
  # @return [Array<String>] language Iso639 code
@@ -126,7 +126,8 @@ module RelatonBib
126
126
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
127
127
 
128
128
  # @param id [String, NilClass]
129
- # @param title [Array<RelatonBib::TypedTitleString>]
129
+ # @param title [RelatonBib::TypedTitleStringCollection,
130
+ # Array<Hash, RelatonBib::TypedTitleString>]
130
131
  # @param formattedref [RelatonBib::FormattedRef, NilClass]
131
132
  # @param type [String, NilClass]
132
133
  # @param docid [Array<RelatonBib::DocumentIdentifier>]
@@ -136,7 +137,7 @@ module RelatonBib
136
137
  # @param docstatus [RelatonBib::DocumentStatus, NilClass]
137
138
  # @param edition [String, NilClass]
138
139
  # @param version [RelatonBib::BibliographicItem::Version, NilClass]
139
- # @param biblionote [Array<RelatonBib::BiblioNote>]
140
+ # @param biblionote [RelatonBib::BiblioNoteCollection]
140
141
  # @param series [Array<RelatonBib::Series>]
141
142
  # @param medium [RelatonBib::Medium, NilClas]
142
143
  # @param place [Array<String, RelatonBib::Place>]
@@ -193,9 +194,7 @@ module RelatonBib
193
194
  warn %{[relaton-bib] document type "#{args[:type]}" is invalid.}
194
195
  end
195
196
 
196
- @title = (args[:title] || []).map do |t|
197
- t.is_a?(Hash) ? TypedTitleString.new(t) : t
198
- end
197
+ @title = TypedTitleStringCollection.new(args[:title])
199
198
 
200
199
  @date = (args[:date] || []).map do |d|
201
200
  d.is_a?(Hash) ? BibliographicDate.new(d) : d
@@ -224,7 +223,7 @@ module RelatonBib
224
223
  @docnumber = args[:docnumber]
225
224
  @edition = args[:edition]
226
225
  @version = args[:version]
227
- @biblionote = args.fetch :biblionote, []
226
+ @biblionote = args.fetch :biblionote, BiblioNoteCollection.new([])
228
227
  @language = args.fetch :language, []
229
228
  @script = args.fetch :script, []
230
229
  @status = args[:docstatus]
@@ -262,12 +261,15 @@ module RelatonBib
262
261
  # @return [RelatonBib::FormattedString, Array<RelatonBib::FormattedString>]
263
262
  def abstract(lang: nil)
264
263
  if lang
265
- @abstract.detect { |a| a.language.include? lang }
264
+ @abstract.detect { |a| a.language&.include? lang }
266
265
  else
267
266
  @abstract
268
267
  end
269
268
  end
270
269
 
270
+ # @param id [RelatonBib::DocumentIdentifier]
271
+ # @param attribute [boolean, nil]
272
+ # @return [String]
271
273
  def makeid(id, attribute)
272
274
  return nil if attribute && !@id_attribute
273
275
 
@@ -282,8 +284,12 @@ module RelatonBib
282
284
  idstr.strip
283
285
  end
284
286
 
287
+ # @param identifier [RelatonBib::DocumentIdentifier]
288
+ # @param options [Hash]
289
+ # @option options [boolean, nil] :no_year
290
+ # @option options [boolean, nil] :all_parts
285
291
  # @return [String]
286
- def shortref(identifier, **opts) # rubocop:disable Metrics/CyclomaticComplexity
292
+ def shortref(identifier, **opts) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
287
293
  pubdate = date.select { |d| d.type == "published" }
288
294
  year = if opts[:no_year] || pubdate.empty? then ""
289
295
  else ":" + pubdate&.first&.on&.year.to_s
@@ -293,14 +299,18 @@ module RelatonBib
293
299
  "#{makeid(identifier, false)}#{year}"
294
300
  end
295
301
 
296
- # @param builder [Nokogiri::XML::Builder, NillClass] (nil)
297
- # @return [String]
298
- def to_xml(builder = nil, **opts, &block)
299
- if builder
300
- render_xml builder, **opts, &block
302
+ # @param opts [Hash]
303
+ # @option opts [Nokogiri::XML::Builder] :builder XML builder
304
+ # @option opts [Boolean] :bibdata
305
+ # @option opts [Symbol, NilClass] :date_format (:short), :full
306
+ # @option opts [String, Symbol] :lang language
307
+ # @return [String] XML
308
+ def to_xml(**opts, &block)
309
+ if opts[:builder]
310
+ render_xml **opts, &block
301
311
  else
302
312
  Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
303
- render_xml xml, **opts, &block
313
+ render_xml builder: xml, **opts, &block
304
314
  end.doc.root.to_xml
305
315
  end
306
316
  end
@@ -344,7 +354,9 @@ module RelatonBib
344
354
  hash["keyword"] = single_element_array(keyword) if keyword&.any?
345
355
  hash["license"] = single_element_array(license) if license&.any?
346
356
  hash["doctype"] = doctype if doctype
347
- hash["editorialgroup"] = editorialgroup.to_hash if editorialgroup
357
+ if editorialgroup&.presence?
358
+ hash["editorialgroup"] = editorialgroup.to_hash
359
+ end
348
360
  hash["ics"] = single_element_array ics if ics.any?
349
361
  if structuredidentifier&.presence?
350
362
  hash["structuredidentifier"] = structuredidentifier.to_hash
@@ -378,12 +390,10 @@ module RelatonBib
378
390
  bibtex.to_s
379
391
  end
380
392
 
381
- # @param lang [String] language code Iso639
382
- # @return [Array<RelatonIsoBib::TypedTitleString>]
393
+ # @param lang [String, nil] language code Iso639
394
+ # @return [RelatonIsoBib::TypedTitleStringCollection]
383
395
  def title(lang: nil)
384
- if lang then @title.select { |t| t.title.language&.include? lang }
385
- else @title
386
- end
396
+ @title.lang lang
387
397
  end
388
398
 
389
399
  # @param type [Symbol] type of url, can be :src/:obp/:rss
@@ -406,12 +416,12 @@ module RelatonBib
406
416
  end
407
417
 
408
418
  # remove title part components and abstract
409
- def to_all_parts # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
419
+ def to_all_parts # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
410
420
  me = deep_clone
411
421
  me.disable_id_attribute
412
422
  me.relation << DocumentRelation.new(type: "instance", bibitem: self)
413
423
  me.language.each do |l|
414
- me.title.delete_if { |t| t.type == "title-part" }
424
+ me.title.delete_title_part!
415
425
  ttl = me.title.select do |t|
416
426
  t.type != "main" && t.title.language&.include?(l)
417
427
  end
@@ -449,7 +459,7 @@ module RelatonBib
449
459
 
450
460
  # If revision_date exists then returns it else returns published date or nil
451
461
  # @return [String, NilClass]
452
- def revdate # rubocop:disable Metrics/CyclomaticComplexity
462
+ def revdate # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
453
463
  @revdate ||= if version&.revision_date
454
464
  version.revision_date
455
465
  else
@@ -526,7 +536,7 @@ module RelatonBib
526
536
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
527
537
 
528
538
  # @param [BibTeX::Entry]
529
- def bibtex_author(item) # rubocop:disable Metrics/CyclomaticComplexity
539
+ def bibtex_author(item) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
530
540
  authors = contributor.select do |c|
531
541
  c.entity.is_a?(Person) && c.role.map(&:type).include?("author")
532
542
  end.map &:entity
@@ -560,7 +570,7 @@ module RelatonBib
560
570
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
561
571
 
562
572
  # @param [BibTeX::Entry]
563
- def bibtex_note(item) # rubocop:disable Metrics/CyclomaticComplexity
573
+ def bibtex_note(item) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize
564
574
  biblionote.each do |n|
565
575
  case n.type
566
576
  when "annote" then item.annote = n.content
@@ -656,32 +666,40 @@ module RelatonBib
656
666
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
657
667
  # rubocop:disable Style/NestedParenthesizedCalls, Metrics/BlockLength
658
668
 
659
- # @param builder [Nokogiri::XML::Builder]
660
- # @return [String]
661
- def render_xml(builder, **opts)
669
+ # @param opts [Hash]
670
+ # @option opts [Nokogiri::XML::Builder] :builder XML builder
671
+ # @option opts [Boolean] bibdata
672
+ # @option opts [Symbol, NilClass] :date_format (:short), :full
673
+ # @option opts [String] :lang language
674
+ def render_xml(**opts)
662
675
  root = opts[:bibdata] ? :bibdata : :bibitem
663
- xml = builder.send(root) do
676
+ xml = opts[:builder].send(root) do |builder|
664
677
  builder.fetched fetched if fetched
665
- title.each { |t| builder.title { t.to_xml builder } }
678
+ title.to_xml **opts
666
679
  formattedref&.to_xml builder
667
680
  link.each { |s| s.to_xml builder }
668
- docidentifier.each { |di| di.to_xml builder }
681
+ docidentifier.each { |di| di.to_xml **opts }
669
682
  builder.docnumber docnumber if docnumber
670
683
  date.each { |d| d.to_xml builder, **opts }
671
684
  contributor.each do |c|
672
685
  builder.contributor do
673
- c.role.each { |r| r.to_xml builder }
674
- c.to_xml builder
686
+ c.role.each { |r| r.to_xml **opts }
687
+ c.to_xml **opts
675
688
  end
676
689
  end
677
690
  builder.edition edition if edition
678
691
  version&.to_xml builder
679
- biblionote.each { |n| n.to_xml builder }
692
+ biblionote.to_xml **opts
693
+ opts[:note]&.each do |n|
694
+ builder.note(n[:text], format: "text/plain", type: n[:type])
695
+ end
680
696
  language.each { |l| builder.language l }
681
697
  script.each { |s| builder.script s }
682
- abstract.each { |a| builder.abstract { a.to_xml(builder) } }
698
+ abstr = abstract.select { |ab| ab.language&.include? opts[:lang] }
699
+ abstr = abstract unless abstr.any?
700
+ abstr.each { |a| builder.abstract { a.to_xml(builder) } }
683
701
  status&.to_xml builder
684
- copyright&.each { |c| c.to_xml builder }
702
+ copyright&.each { |c| c.to_xml **opts }
685
703
  relation.each { |r| r.to_xml builder, **opts }
686
704
  series.each { |s| s.to_xml builder }
687
705
  medium&.to_xml builder
@@ -690,7 +708,9 @@ module RelatonBib
690
708
  accesslocation.each { |al| builder.accesslocation al }
691
709
  license.each { |l| builder.license l }
692
710
  classification.each { |cls| cls.to_xml builder }
693
- keyword.each { |kw| builder.keyword { kw.to_xml(builder) } }
711
+ kwrd = keyword.select { |kw| kw.language&.include? opts[:lang] }
712
+ kwrd = keyword unless kwrd.any?
713
+ kwrd.each { |kw| builder.keyword { kw.to_xml(builder) } }
694
714
  validity&.to_xml builder
695
715
  if block_given? then yield builder
696
716
  elsif opts[:bibdata] && (doctype || editorialgroup || ics&.any? ||
@@ -6,7 +6,7 @@ module RelatonBib
6
6
  class << self
7
7
  # @param bibtex [String]
8
8
  # @return [Hash{String=>RelatonBib::BibliographicItem}]
9
- def from_bibtex(bibtex)
9
+ def from_bibtex(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
10
10
  BibTeX.parse(bibtex).reduce({}) do |h, bt|
11
11
  h[bt.key] = BibliographicItem.new(
12
12
  id: bt.key,
@@ -35,7 +35,7 @@ module RelatonBib
35
35
 
36
36
  # @param bibtex [BibTeX::Entry]
37
37
  # @return [Array<RelatonBib::DocumentIdentifier>]
38
- def fetch_docid(bibtex)
38
+ def fetch_docid(bibtex) # rubocop:disable Metrics/AbcSize
39
39
  docid = []
40
40
  docid << DocumentIdentifier.new(id: bibtex.isbn.to_s, type: "isbn") if bibtex["isbn"]
41
41
  docid << DocumentIdentifier.new(id: bibtex.lccn.to_s, type: "lccn") if bibtex["lccn"]
@@ -67,17 +67,17 @@ module RelatonBib
67
67
  end
68
68
 
69
69
  # @param bibtex [BibTeX::Entry]
70
- # @return [Array<Hash>]
70
+ # @return [RelatonBib::TypedTitleStringCollection]
71
71
  def fetch_title(bibtex)
72
72
  title = []
73
73
  title << { type: "main", content: bibtex.title.to_s } if bibtex["title"]
74
74
  title << { type: "main", content: bibtex.subtitle.to_s } if bibtex["subtitle"]
75
- title
75
+ TypedTitleStringCollection.new title
76
76
  end
77
77
 
78
78
  # @param bibtex [BibTeX::Entry]
79
79
  # @return [Array<Hash>]
80
- def fetch_contributor(bibtex)
80
+ def fetch_contributor(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
81
81
  contributor = []
82
82
  fetch_person(bibtex["author"]).each do |entity|
83
83
  contributor << { entity: entity, role: [{ type: "author" }] }
@@ -94,7 +94,7 @@ module RelatonBib
94
94
  if bibtex["institution"]
95
95
  contributor << {
96
96
  entity: { name: bibtex.institution.to_s },
97
- role: [{ type: "distributor", description: ["sponsor"] }]
97
+ role: [{ type: "distributor", description: ["sponsor"] }],
98
98
  }
99
99
  end
100
100
 
@@ -145,11 +145,11 @@ module RelatonBib
145
145
  end
146
146
 
147
147
  # @param bibtex [BibTeX::Entry]
148
- # @return [Array<RelatonBib::BiblioNote>]
148
+ # @return [RelatonBib::BiblioNoteCollection]
149
149
  def fetch_note(bibtex)
150
150
  bibtex.select do |k, _v|
151
151
  %i[annote howpublished comment note content].include? k
152
- end.reduce([]) do |mem, note|
152
+ end.reduce(BiblioNoteCollection.new([])) do |mem, note|
153
153
  type = case note[0]
154
154
  when :note then nil
155
155
  when :content then "tableOfContents"
@@ -164,13 +164,14 @@ module RelatonBib
164
164
  def fetch_relation(bibtex)
165
165
  return [] unless bibtex["booktitle"]
166
166
 
167
- title = TypedTitleString.new(type: "main", content: bibtex.booktitle.to_s)
168
- [{ type: "partOf", bibitem: BibliographicItem.new(title: [title]) }]
167
+ ttl = TypedTitleString.new(type: "main", content: bibtex.booktitle.to_s)
168
+ title = TypedTitleStringCollection.new [ttl]
169
+ [{ type: "partOf", bibitem: BibliographicItem.new(title: title) }]
169
170
  end
170
171
 
171
172
  # @param bibtex [BibTeX::Entry]
172
173
  # @return [Array<RelatonBib::BibItemLocality>]
173
- def fetch_extent(bibtex)
174
+ def fetch_extent(bibtex) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
174
175
  bibtex.select do |k, _v|
175
176
  %i[chapter pages volume].include? k
176
177
  end.reduce([]) do |mem, loc|
@@ -188,13 +189,13 @@ module RelatonBib
188
189
 
189
190
  # @param bibtex [BibTeX::Entry]
190
191
  # @return [Array<RelatonBib::Series>]
191
- def fetch_series(bibtex)
192
+ def fetch_series(bibtex) # rubocop:disable Metrics/MethodLength
192
193
  series = []
193
194
  if bibtex["journal"]
194
195
  series << Series.new(
195
196
  type: "journal",
196
197
  title: TypedTitleString.new(content: bibtex.journal.to_s),
197
- number: bibtex["number"]&.to_s,
198
+ number: bibtex["number"]&.to_s
198
199
  )
199
200
  end
200
201
 
@@ -207,7 +208,7 @@ module RelatonBib
207
208
 
208
209
  # @param bibtex [BibTeX::Entry]
209
210
  # @return [Array<RelatonBib::TypedUri>]
210
- def fetch_link(bibtex)
211
+ def fetch_link(bibtex) # rubocop:disable Metrics/AbcSize
211
212
  link = []
212
213
  link << TypedUri.new(type: "src", content: bibtex.url.to_s) if bibtex["url"]
213
214
  link << TypedUri.new(type: "doi", content: bibtex.doi.to_s) if bibtex["doi"]
@@ -242,4 +243,4 @@ module RelatonBib
242
243
  end
243
244
  end
244
245
  end
245
- end
246
+ end
@@ -31,11 +31,15 @@ module RelatonBib
31
31
  end
32
32
  end
33
33
 
34
- # @param builder [Nokogiri::XML::Builder]
35
- def to_xml(builder)
36
- builder.role(type: type) do
37
- description.each do |d|
38
- builder.description { |desc| d.to_xml(desc) }
34
+ # @param opts [Hash]
35
+ # @option opts [Nokogiri::XML::Builder] :builder XML builder
36
+ # @option opts [String] :lang language
37
+ def to_xml(**opts) # rubocop:disable Metrics/AbcSize
38
+ opts[:builder].role(type: type) do |builder|
39
+ desc = description.select { |d| d.language&.include? opts[:lang] }
40
+ desc = description unless desc.any?
41
+ desc.each do |d|
42
+ builder.description { |b| d.to_xml(b) }
39
43
  end
40
44
  end
41
45
  end
@@ -83,9 +87,11 @@ module RelatonBib
83
87
  @role = role.map { |r| ContributorRole.new(**r) }
84
88
  end
85
89
 
86
- # @param builder [Nokogiri::XML::Builder]
87
- def to_xml(builder)
88
- entity.to_xml builder
90
+ # @param opts [Hash]
91
+ # @option opts [Nokogiri::XML::Builder] :builder XML builder
92
+ # @option opts [String, Symbol] :lang language
93
+ def to_xml(**opts)
94
+ entity.to_xml **opts
89
95
  end
90
96
 
91
97
  # @return [Hash]
@@ -129,12 +129,16 @@ module RelatonBib
129
129
  @description = description
130
130
  end
131
131
 
132
- # @params builder [Nokogiri::XML::Builder]
133
- def to_xml(builder)
134
- builder.affiliation do
132
+ # @param opts [Hash]
133
+ # @option opts [Nokogiri::XML::Builder] :builder XML builder
134
+ # @option opts [String] :lang language
135
+ def to_xml(**opts) # rubocop:disable Metrics/AbcSize
136
+ opts[:builder].affiliation do |builder|
135
137
  builder.name { name.to_xml builder } if name
136
- description.each { |d| builder.description { d.to_xml builder } }
137
- organization.to_xml builder
138
+ desc = description.select { |d| d.language&.include? opts[:lang] }
139
+ desc = description unless desc.any?
140
+ desc.each { |d| builder.description { d.to_xml builder } }
141
+ organization.to_xml **opts
138
142
  end
139
143
  end
140
144
 
@@ -151,7 +155,7 @@ module RelatonBib
151
155
  # @param prefix [String]
152
156
  # @param count [Integer]
153
157
  # @return [String]
154
- def to_asciibib(prefix = "", count = 1)
158
+ def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
155
159
  pref = prefix.empty? ? prefix : prefix + "."
156
160
  out = count > 1 ? "#{pref}affiliation::\n" : ""
157
161
  out += name.to_asciibib "#{pref}affiliation.name" if name