relaton-bib 1.0.1 → 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 +7 -4
- data/lib/relaton_bib/bibliographic_item.rb +128 -26
- data/lib/relaton_bib/bibtex_parser.rb +22 -20
- data/lib/relaton_bib/copyright_association.rb +28 -9
- data/lib/relaton_bib/document_relation.rb +22 -10
- data/lib/relaton_bib/document_relation_collection.rb +5 -5
- data/lib/relaton_bib/document_status.rb +49 -10
- data/lib/relaton_bib/editorial_group.rb +27 -0
- data/lib/relaton_bib/formatted_string.rb +3 -3
- data/lib/relaton_bib/hash_converter.rb +96 -26
- data/lib/relaton_bib/ics.rb +26 -0
- data/lib/relaton_bib/localized_string.rb +33 -12
- 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 +39 -9
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/workgroup.rb +36 -0
- data/lib/relaton_bib/xml_parser.rb +85 -27
- data/relaton-bib.gemspec +3 -3
- metadata +25 -16
@@ -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
|
@@ -11,21 +11,35 @@ module RelatonBib
|
|
11
11
|
# @return [Array<String>] script Iso15924 code
|
12
12
|
attr_reader :script
|
13
13
|
|
14
|
-
# @return [String]
|
14
|
+
# @return [String, Array<RelatonBib::LocalizedString>]
|
15
15
|
attr_accessor :content
|
16
16
|
|
17
|
-
# @param content [String]
|
17
|
+
# @param content [String, Array<RelatonBib::LocalizedString>]
|
18
18
|
# @param language [String] language code Iso639
|
19
19
|
# @param script [String] script code Iso15924
|
20
20
|
def initialize(content, language = nil, script = nil)
|
21
|
+
unless content.is_a?(String) || content.is_a?(Array) &&
|
22
|
+
(inv = content.reject { |c| c.is_a?(LocalizedString) || c.is_a?(Hash) }).
|
23
|
+
none? && content.any?
|
24
|
+
klass = content.is_a?(Array) ? inv.first.class : content.class
|
25
|
+
raise ArgumentError, "invalid LocalizedString content type: #{klass}"
|
26
|
+
end
|
21
27
|
@language = language.is_a?(String) ? [language] : language
|
22
28
|
@script = script.is_a?(String) ? [script] : script
|
23
|
-
@content = content
|
29
|
+
@content = if content.is_a?(Array)
|
30
|
+
content.map do |c|
|
31
|
+
if c.is_a?(Hash)
|
32
|
+
LocalizedString.new c[:content], c[:language], c[:script]
|
33
|
+
else c
|
34
|
+
end
|
35
|
+
end
|
36
|
+
else content
|
37
|
+
end
|
24
38
|
end
|
25
39
|
|
26
40
|
# @return [String]
|
27
41
|
def to_s
|
28
|
-
content
|
42
|
+
content.is_a?(String) ? content : content.first.to_s
|
29
43
|
end
|
30
44
|
|
31
45
|
# @return [TrueClass, FalseClass]
|
@@ -37,19 +51,26 @@ module RelatonBib
|
|
37
51
|
def to_xml(builder)
|
38
52
|
return unless content
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
|
54
|
+
if content.is_a?(Array)
|
55
|
+
content.each { |c| builder.variant { c.to_xml builder } }
|
56
|
+
else
|
57
|
+
builder.parent["language"] = language.join(",") if language&.any?
|
58
|
+
builder.parent["script"] = script.join(",") if script&.any?
|
59
|
+
builder.text content.encode(xml: :text)
|
60
|
+
end
|
43
61
|
end
|
44
62
|
|
45
63
|
# @return [Hash]
|
46
64
|
def to_hash
|
47
|
-
|
65
|
+
if content.is_a? String
|
66
|
+
return content unless language || script
|
48
67
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
68
|
+
hash = { "content" => content }
|
69
|
+
hash["language"] = single_element_array(language) if language&.any?
|
70
|
+
hash["script"] = single_element_array(script) if script&.any?
|
71
|
+
hash
|
72
|
+
else content.map &:to_hash
|
73
|
+
end
|
53
74
|
end
|
54
75
|
end
|
55
76
|
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
|
@@ -1,14 +1,12 @@
|
|
1
1
|
module RelatonBib
|
2
2
|
class TypedTitleString
|
3
|
-
# TITLE_TYPES = %w[alternative original unofficial subtitle main].freeze
|
4
|
-
|
5
3
|
# @return [String]
|
6
4
|
attr_reader :type
|
7
5
|
|
8
6
|
# @return [RelatonBib::FormattedString]
|
9
7
|
attr_reader :title
|
10
8
|
|
11
|
-
# rubocop:disable Metrics/
|
9
|
+
# rubocop:disable Metrics/MethodLength
|
12
10
|
|
13
11
|
# @param type [String]
|
14
12
|
# @param title [RelatonBib::FormattedString, Hash]
|
@@ -16,10 +14,6 @@ module RelatonBib
|
|
16
14
|
# @param language [String]
|
17
15
|
# @param script [String]
|
18
16
|
def initialize(**args)
|
19
|
-
# if args[:type] && !TITLE_TYPES.include?(args[:type])
|
20
|
-
# warn %{[relaton-bib] title type "#{args[:type]}" is invalid.}
|
21
|
-
# end
|
22
|
-
|
23
17
|
unless args[:title] || args[:content]
|
24
18
|
raise ArgumentError, %{Keyword "title" or "content" should be passed.}
|
25
19
|
end
|
@@ -30,12 +24,48 @@ module RelatonBib
|
|
30
24
|
@title = args[:title]
|
31
25
|
else
|
32
26
|
fsargs = args.select do |k, _v|
|
33
|
-
%i[content language script format].include? k
|
27
|
+
%i[content language script format].include? k
|
34
28
|
end
|
35
29
|
@title = FormattedString.new(fsargs)
|
36
30
|
end
|
37
31
|
end
|
38
|
-
# rubocop:enable Metrics/
|
32
|
+
# rubocop:enable Metrics/MethodLength
|
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
|
39
69
|
|
40
70
|
# @param builder [Nokogiri::XML::Builder]
|
41
71
|
def to_xml(builder)
|
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
|
@@ -20,6 +20,7 @@ module RelatonBib
|
|
20
20
|
|
21
21
|
# @return [Hash]
|
22
22
|
def item_data(bibitem)
|
23
|
+
ext = bibitem.at "//ext"
|
23
24
|
{
|
24
25
|
id: bibitem[:id]&.empty? ? nil : bibitem[:id],
|
25
26
|
type: bibitem[:type]&.empty? ? nil : bibitem[:type],
|
@@ -49,6 +50,10 @@ module RelatonBib
|
|
49
50
|
keyword: bibitem.xpath("keyword").map(&:text),
|
50
51
|
license: bibitem.xpath("license").map(&:text),
|
51
52
|
validity: fetch_validity(bibitem),
|
53
|
+
doctype: ext&.at("doctype")&.text,
|
54
|
+
editorialgroup: fetch_editorialgroup(ext),
|
55
|
+
ics: fetch_ics(ext),
|
56
|
+
structuredidentifier: fetch_structuredidentifier(ext),
|
52
57
|
}
|
53
58
|
end
|
54
59
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
@@ -159,8 +164,12 @@ module RelatonBib
|
|
159
164
|
def ttitle(title)
|
160
165
|
return unless title
|
161
166
|
|
167
|
+
variants = title.xpath("variant").map do |v|
|
168
|
+
LocalizedString.new v.text, v[:language], v[:script]
|
169
|
+
end
|
170
|
+
content = variants.any? ? variants : title.text
|
162
171
|
TypedTitleString.new(
|
163
|
-
type: title[:type], content:
|
172
|
+
type: title[:type], content: content, language: title[:language],
|
164
173
|
script: title[:script], format: title[:format]
|
165
174
|
)
|
166
175
|
end
|
@@ -169,14 +178,22 @@ module RelatonBib
|
|
169
178
|
status = item.at("./status")
|
170
179
|
return unless status
|
171
180
|
|
172
|
-
|
181
|
+
stg = status.at "stage"
|
173
182
|
DocumentStatus.new(
|
174
|
-
stage:
|
175
|
-
substage: status.at("substage")
|
183
|
+
stage: stg ? stage(stg) : status.text,
|
184
|
+
substage: stage(status.at("substage")),
|
176
185
|
iteration: status.at("iteration")&.text,
|
177
186
|
)
|
178
187
|
end
|
179
188
|
|
189
|
+
# @param node [Nokogiri::XML::Elemen]
|
190
|
+
# @return [RelatonBib::DocumentStatus::Stage]
|
191
|
+
def stage(elm)
|
192
|
+
return unless elm
|
193
|
+
|
194
|
+
DocumentStatus::Stage.new value: elm.text, abbreviation: elm[:abbreviation]
|
195
|
+
end
|
196
|
+
|
180
197
|
def fetch_dates(item)
|
181
198
|
item.xpath("./date").reduce([]) do |a, d|
|
182
199
|
type = d[:type].to_s.empty? ? "published" : d[:type]
|
@@ -232,14 +249,9 @@ module RelatonBib
|
|
232
249
|
end
|
233
250
|
|
234
251
|
cn = person.at "./name/completename"
|
235
|
-
cname =
|
236
|
-
LocalizedString.new(cn.text, cn[:language], cn[:script])
|
237
|
-
else
|
238
|
-
nil
|
239
|
-
end
|
240
|
-
|
252
|
+
cname = cn && LocalizedString.new(cn.text, cn[:language], cn[:script])
|
241
253
|
sn = person.at "./name/surname"
|
242
|
-
sname = sn
|
254
|
+
sname = sn && LocalizedString.new(sn.text, sn[:language], sn[:script])
|
243
255
|
|
244
256
|
name = FullName.new(
|
245
257
|
completename: cname, surname: sname,
|
@@ -279,25 +291,24 @@ module RelatonBib
|
|
279
291
|
# @return [Array<RelatonBib::FormattedString>]
|
280
292
|
def fetch_abstract(item)
|
281
293
|
item.xpath("./abstract").map do |a|
|
282
|
-
FormattedString.new(
|
283
|
-
|
284
|
-
)
|
294
|
+
FormattedString.new(content: a.text, language: a[:language],
|
295
|
+
script: a[:script], format: a[:format])
|
285
296
|
end
|
286
297
|
end
|
287
298
|
|
288
299
|
# @param item [Nokogiri::XML::Element]
|
289
|
-
# @return [RelatonBib::CopyrightAssociation]
|
300
|
+
# @return [Array<RelatonBib::CopyrightAssociation>]
|
290
301
|
def fetch_copyright(item)
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
302
|
+
item.xpath("./copyright").map do |cp|
|
303
|
+
owner = cp.xpath("owner").map do |o|
|
304
|
+
ContributionInfo.new entity: get_org(o.at("organization"))
|
305
|
+
end
|
306
|
+
from = cp.at("from")&.text
|
307
|
+
to = cp.at("to")&.text
|
308
|
+
scope = cp.at("scope")&.text
|
309
|
+
CopyrightAssociation.new(owner: owner, from: from, to: to,
|
310
|
+
scope: scope)
|
311
|
+
end
|
301
312
|
end
|
302
313
|
|
303
314
|
# @param item [Nokogiri::XML::Element]
|
@@ -345,7 +356,7 @@ module RelatonBib
|
|
345
356
|
if lc[:type]
|
346
357
|
LocalityStack.new [locality(lc)]
|
347
358
|
else
|
348
|
-
LocalityStack.new
|
359
|
+
LocalityStack.new(lc.xpath("./locality").map { |l| locality l })
|
349
360
|
end
|
350
361
|
end
|
351
362
|
end
|
@@ -353,7 +364,7 @@ module RelatonBib
|
|
353
364
|
# @param loc [Nokogiri::XML::Element]
|
354
365
|
# @return [RelatonBib::Locality]
|
355
366
|
def locality(loc, klass = Locality)
|
356
|
-
ref_to = (rt = loc.at("./referenceTo"))
|
367
|
+
ref_to = (rt = loc.at("./referenceTo")) && LocalizedString.new(rt.text)
|
357
368
|
klass.new(
|
358
369
|
loc[:type],
|
359
370
|
LocalizedString.new(loc.at("./referenceFrom").text),
|
@@ -385,6 +396,53 @@ module RelatonBib
|
|
385
396
|
language: ident[:language], script: ident[:script]
|
386
397
|
)
|
387
398
|
end
|
399
|
+
|
400
|
+
# @param ext [Nokogiri::XML::Element]
|
401
|
+
# @return [RelatonBib::EditorialGroup, nil]
|
402
|
+
def fetch_editorialgroup(ext)
|
403
|
+
return unless ext && (eg = ext.at "editorialgroup")
|
404
|
+
|
405
|
+
eg = eg.xpath("technical-committee").map do |tc|
|
406
|
+
wg = WorkGroup.new(content: tc.text, number: tc[:number]&.to_i,
|
407
|
+
type: tc[:type])
|
408
|
+
TechnicalCommittee.new wg
|
409
|
+
end
|
410
|
+
EditorialGroup.new eg if eg.any?
|
411
|
+
end
|
412
|
+
|
413
|
+
def fetch_ics(ext)
|
414
|
+
return [] unless ext
|
415
|
+
|
416
|
+
ext.xpath("ics").map do |ics|
|
417
|
+
ICS.new code: ics.at("code").text, text: ics.at("text").text
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
422
|
+
|
423
|
+
# @param ext [Nokogiri::XML::Element]
|
424
|
+
# @return [RelatonBib::StructuredIdentifierCollection]
|
425
|
+
def fetch_structuredidentifier(ext)
|
426
|
+
return unless ext
|
427
|
+
|
428
|
+
sids = ext.xpath("structuredidentifier").map do |si|
|
429
|
+
StructuredIdentifier.new(
|
430
|
+
type: si[:type],
|
431
|
+
agency: si.xpath("agency").map(&:text),
|
432
|
+
class: si.at("class")&.text,
|
433
|
+
docnumber: si.at("docnumber")&.text,
|
434
|
+
partnumber: si.at("partnumber")&.text,
|
435
|
+
edition: si.at("edition")&.text,
|
436
|
+
version: si.at("version")&.text,
|
437
|
+
supplementtype: si.at("supplementtype")&.text,
|
438
|
+
supplementnumber: si.at("supplementnumber")&.text,
|
439
|
+
language: si.at("language")&.text,
|
440
|
+
year: si.at("year")&.text,
|
441
|
+
)
|
442
|
+
end
|
443
|
+
StructuredIdentifierCollection.new sids
|
444
|
+
end
|
445
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
388
446
|
end
|
389
447
|
end
|
390
448
|
end
|