relaton-bib 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|