relaton-bib 1.1.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.gitmodules +0 -3
- data/grammars/basicdoc.rng +986 -0
- data/grammars/biblio.rng +1237 -0
- data/grammars/isodoc.rng +1504 -0
- data/grammars/reqt.rng +171 -0
- data/lib/relaton_bib.rb +4 -1
- data/lib/relaton_bib/bibliographic_item.rb +119 -15
- data/lib/relaton_bib/document_relation_collection.rb +2 -2
- data/lib/relaton_bib/editorial_group.rb +27 -0
- data/lib/relaton_bib/hash_converter.rb +64 -21
- data/lib/relaton_bib/ics.rb +26 -0
- data/lib/relaton_bib/structured_identifier.rb +141 -0
- data/lib/relaton_bib/technical_committee.rb +25 -0
- data/lib/relaton_bib/typed_title_string.rb +36 -0
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/workgroup.rb +36 -0
- data/lib/relaton_bib/xml_parser.rb +54 -2
- metadata +11 -2
@@ -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
|
@@ -34,6 +34,9 @@ module RelatonBib
|
|
34
34
|
validity_hash_to_bib(ret)
|
35
35
|
ret[:keyword] = array(ret[:keyword])
|
36
36
|
ret[:license] = array(ret[:license])
|
37
|
+
editorialgroup_hash_to_bib ret
|
38
|
+
ics_hash_to_bib ret
|
39
|
+
structuredidentifier_hash_to_bib ret
|
37
40
|
ret
|
38
41
|
end
|
39
42
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
@@ -55,12 +58,12 @@ module RelatonBib
|
|
55
58
|
def title_hash_to_bib(ret)
|
56
59
|
return unless ret[:title]
|
57
60
|
|
58
|
-
ret[:title] = array(ret[:title])
|
59
|
-
|
60
|
-
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
|
61
63
|
else
|
62
|
-
|
63
|
-
|
64
|
+
m + TypedTitleString.from_string(t)
|
65
|
+
# { content: t, language: "en", script: "Latn", format: "text/plain",
|
66
|
+
# type: "main" }
|
64
67
|
end
|
65
68
|
end
|
66
69
|
end
|
@@ -311,15 +314,16 @@ module RelatonBib
|
|
311
314
|
end
|
312
315
|
|
313
316
|
# @param rel [Hash] relation
|
317
|
+
# @return [RelatonBib::LocalityStack]
|
314
318
|
def relation_locality_hash_to_bib(rel)
|
315
319
|
rel[:locality] = array(rel[:locality])&.map do |bl|
|
316
320
|
ls = if bl[:locality_stack]
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
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
|
323
327
|
LocalityStack.new ls
|
324
328
|
end
|
325
329
|
end
|
@@ -338,6 +342,7 @@ module RelatonBib
|
|
338
342
|
end
|
339
343
|
end
|
340
344
|
|
345
|
+
# @param ret [Hash]
|
341
346
|
def series_hash_to_bib(ret)
|
342
347
|
ret[:series] = array(ret[:series])&.map do |s|
|
343
348
|
s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
|
@@ -356,20 +361,23 @@ module RelatonBib
|
|
356
361
|
TypedTitleString.new title
|
357
362
|
end
|
358
363
|
|
364
|
+
# @param ret [Hash]
|
359
365
|
def medium_hash_to_bib(ret)
|
360
366
|
ret[:medium] = Medium.new(ret[:medium]) if ret[:medium]
|
361
367
|
end
|
362
368
|
|
369
|
+
# @param ret [Hash]
|
363
370
|
def classification_hash_to_bib(ret)
|
364
|
-
# ret[:classification] = [ret[:classification]] unless ret[:classification].is_a?(Array)
|
365
|
-
# ret[:classification]&.each_with_index do |c, i|
|
366
|
-
# ret[:classification][i] = RelatonBib::Classification.new(c)
|
367
|
-
# end
|
368
371
|
if ret[:classification]
|
369
|
-
ret[:classification] = array(ret[:classification]).map
|
372
|
+
ret[:classification] = array(ret[:classification]).map do |cls|
|
373
|
+
Classification.new cls
|
374
|
+
end
|
370
375
|
end
|
371
376
|
end
|
372
377
|
|
378
|
+
# rubocop:disable Metrics/AbcSize
|
379
|
+
|
380
|
+
# @param ret [Hash]
|
373
381
|
def validity_hash_to_bib(ret)
|
374
382
|
return unless ret[:validity]
|
375
383
|
|
@@ -378,6 +386,35 @@ module RelatonBib
|
|
378
386
|
ret[:validity][:revision] && r = Time.parse(ret[:validity][:revision].to_s)
|
379
387
|
ret[:validity] = Validity.new(begins: b, ends: e, revision: r)
|
380
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
|
381
418
|
|
382
419
|
# @param ogj [Hash, Array, String]
|
383
420
|
# @return [Hash, Array, String]
|
@@ -394,6 +431,8 @@ module RelatonBib
|
|
394
431
|
end
|
395
432
|
end
|
396
433
|
|
434
|
+
# @param arr [NilClass, Array, #is_a?]
|
435
|
+
# @return [Array]
|
397
436
|
def array(arr)
|
398
437
|
return [] unless arr
|
399
438
|
return [arr] unless arr.is_a?(Array)
|
@@ -401,6 +440,9 @@ module RelatonBib
|
|
401
440
|
arr
|
402
441
|
end
|
403
442
|
|
443
|
+
# @param name [Hash, String, NilClass]
|
444
|
+
# @param person [Hash]
|
445
|
+
# @return [RelatonBib::LocalizedString]
|
404
446
|
def localname(name, person)
|
405
447
|
return nil if name.nil?
|
406
448
|
|
@@ -408,13 +450,12 @@ module RelatonBib
|
|
408
450
|
lang ||= person[:name][:language]
|
409
451
|
script = name[:script] if name.is_a?(Hash)
|
410
452
|
script ||= person[:name][:script]
|
411
|
-
|
412
|
-
|
413
|
-
else
|
414
|
-
RelatonBib::LocalizedString.new(name, lang, script)
|
415
|
-
end
|
453
|
+
n = name.is_a?(Hash) ? name[:content] : name
|
454
|
+
RelatonBib::LocalizedString.new(n, lang, script)
|
416
455
|
end
|
417
456
|
|
457
|
+
# @param lst [Hash, Array<RelatonBib::LocalizedString>]
|
458
|
+
# @return [RelatonBib::LocalizedString]
|
418
459
|
def localizedstring(lst)
|
419
460
|
if lst.is_a?(Hash)
|
420
461
|
RelatonBib::LocalizedString.new(lst[:content], lst[:language], lst[:script])
|
@@ -423,6 +464,8 @@ module RelatonBib
|
|
423
464
|
end
|
424
465
|
end
|
425
466
|
|
467
|
+
# @param frf [Hash, String]
|
468
|
+
# @return [RelatonBib::FormattedRef]
|
426
469
|
def formattedref(frf)
|
427
470
|
if frf.is_a?(Hash)
|
428
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
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "relaton_bib/workgroup"
|
2
|
+
|
3
|
+
module RelatonBib
|
4
|
+
class TechnicalCommittee
|
5
|
+
# @return [RelatonBib::WorkGroup]
|
6
|
+
attr_reader :workgroup
|
7
|
+
|
8
|
+
# @param workgroup [RelatonBib::WorkGroup]
|
9
|
+
def initialize(workgroup)
|
10
|
+
@workgroup = workgroup
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param builder [Nokogiri::XML::Builder]
|
14
|
+
def to_xml(builder)
|
15
|
+
builder.send "technical-committee" do |b|
|
16
|
+
workgroup.to_xml b
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Hash]
|
21
|
+
def to_hash
|
22
|
+
workgroup.to_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -31,6 +31,42 @@ module RelatonBib
|
|
31
31
|
end
|
32
32
|
# rubocop:enable Metrics/MethodLength
|
33
33
|
|
34
|
+
# @param title [String]
|
35
|
+
# @return [Array<self>]
|
36
|
+
def self.from_string(title, lang = nil, script = nil)
|
37
|
+
types = %w[title-intro title-main title-part]
|
38
|
+
ttls = split_title(title)
|
39
|
+
tts = ttls.map.with_index do |p, i|
|
40
|
+
new type: types[i], content: p, language: lang, script: script if p
|
41
|
+
end.compact
|
42
|
+
tts << new(type: "main", content: ttls.compact.join(" - "),
|
43
|
+
language: lang, script: script)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param title [String]
|
47
|
+
# @return [Array<String, nil>]
|
48
|
+
def self.split_title(title)
|
49
|
+
ttls = title.sub(/\w\.Imp\s?\d+\u00A0:\u00A0/, "").split " - "
|
50
|
+
case ttls.size
|
51
|
+
when 0, 1 then [nil, ttls.first.to_s, nil]
|
52
|
+
else intro_or_part ttls
|
53
|
+
# when 2, 3 then intro_or_part ttls
|
54
|
+
# else [ttls[0], ttls[1], ttls[2..-1].join(" -- ")]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param ttls [Array<String>]
|
59
|
+
# @return [Array<Strin, nil>]
|
60
|
+
def self.intro_or_part(ttls)
|
61
|
+
if /^(Part|Partie) \d+:/ =~ ttls[1]
|
62
|
+
[nil, ttls[0], ttls[1..-1].join(" -- ")]
|
63
|
+
else
|
64
|
+
parts = ttls.slice(2..-1)
|
65
|
+
part = parts.join " -- " if parts.any?
|
66
|
+
[ttls[0], ttls[1], part]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
34
70
|
# @param builder [Nokogiri::XML::Builder]
|
35
71
|
def to_xml(builder)
|
36
72
|
builder.parent[:type] = type if type
|
data/lib/relaton_bib/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
module RelatonBib
|
2
|
+
class WorkGroup
|
3
|
+
# @return [String]
|
4
|
+
attr_reader :content
|
5
|
+
|
6
|
+
# @return [Integer, nil]
|
7
|
+
attr_reader :number
|
8
|
+
|
9
|
+
# @return [String, nil]
|
10
|
+
attr_reader :type
|
11
|
+
|
12
|
+
# @param content [String]
|
13
|
+
# @param number [Integer, nil]
|
14
|
+
# @param type [String, nil]
|
15
|
+
def initialize(content:, number: nil, type: nil)
|
16
|
+
@content = content
|
17
|
+
@number = number
|
18
|
+
@type = type
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param builder [Nokogiri::XML::Builder]
|
22
|
+
def to_xml(builder)
|
23
|
+
builder.text content
|
24
|
+
builder.parent[:number] = number if number
|
25
|
+
builder.parent[:type] = type if type
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Hash]
|
29
|
+
def to_hash
|
30
|
+
hash = { "content" => content }
|
31
|
+
hash["number"] = number if number
|
32
|
+
hash["type"] = type if type
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|