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.
- checksums.yaml +4 -4
- data/.hound.yml +2 -0
- data/README.adoc +14 -7
- data/docs/hash.adoc +53 -53
- data/lib/relaton_bib/bib_item_locality.rb +59 -16
- data/lib/relaton_bib/bibliographic_item.rb +6 -2
- data/lib/relaton_bib/bibtex_parser.rb +22 -20
- data/lib/relaton_bib/document_relation.rb +49 -25
- data/lib/relaton_bib/document_relation_collection.rb +18 -5
- data/lib/relaton_bib/document_status.rb +46 -8
- data/lib/relaton_bib/formatted_string.rb +3 -3
- data/lib/relaton_bib/hash_converter.rb +59 -21
- data/lib/relaton_bib/localized_string.rb +33 -12
- data/lib/relaton_bib/typed_title_string.rb +1 -1
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/xml_parser.rb +94 -20
- data/relaton-bib.gemspec +3 -3
- metadata +17 -16
@@ -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
|
data/lib/relaton_bib/version.rb
CHANGED
@@ -8,9 +8,9 @@ module RelatonBib
|
|
8
8
|
doc.remove_namespaces!
|
9
9
|
bibitem = doc.at "/bibitem|/bibdata"
|
10
10
|
if bibitem
|
11
|
-
|
11
|
+
bib_item item_data(bibitem)
|
12
12
|
else
|
13
|
-
warn "[
|
13
|
+
warn "[relaton-bib] WARNING: can't find bibitem or bibdata element in the XML"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -91,12 +91,16 @@ module RelatonBib
|
|
91
91
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
92
92
|
|
93
93
|
def fetch_series(item)
|
94
|
-
item.xpath("./series").
|
94
|
+
item.xpath("./series").reduce([]) do |mem, sr|
|
95
95
|
abbr = sr.at "abbreviation"
|
96
96
|
abbreviation = abbr ? LocalizedString.new(abbr.text, abbr[:language], abbr[:script]) : nil
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
formattedref = fref(sr)
|
98
|
+
title = ttitle(sr.at("title"))
|
99
|
+
next mem unless formattedref || title
|
100
|
+
|
101
|
+
mem << Series.new(
|
102
|
+
type: sr[:type], formattedref: formattedref,
|
103
|
+
title: title, place: sr.at("place")&.text,
|
100
104
|
organization: sr.at("organization")&.text,
|
101
105
|
abbreviation: abbreviation, from: sr.at("from")&.text,
|
102
106
|
to: sr.at("to")&.text, number: sr.at("number")&.text,
|
@@ -155,8 +159,12 @@ module RelatonBib
|
|
155
159
|
def ttitle(title)
|
156
160
|
return unless title
|
157
161
|
|
162
|
+
variants = title.xpath("variant").map do |v|
|
163
|
+
LocalizedString.new v.text, v[:language], v[:script]
|
164
|
+
end
|
165
|
+
content = variants.any? ? variants : title.text
|
158
166
|
TypedTitleString.new(
|
159
|
-
type: title[:type], content:
|
167
|
+
type: title[:type], content: content, language: title[:language],
|
160
168
|
script: title[:script], format: title[:format]
|
161
169
|
)
|
162
170
|
end
|
@@ -165,14 +173,22 @@ module RelatonBib
|
|
165
173
|
status = item.at("./status")
|
166
174
|
return unless status
|
167
175
|
|
168
|
-
|
176
|
+
stg = status.at "stage"
|
169
177
|
DocumentStatus.new(
|
170
|
-
stage:
|
171
|
-
substage: status.at("substage")
|
178
|
+
stage: stg ? stage(stg) : status.text,
|
179
|
+
substage: stage(status.at("substage")),
|
172
180
|
iteration: status.at("iteration")&.text,
|
173
181
|
)
|
174
182
|
end
|
175
183
|
|
184
|
+
# @param node [Nokogiri::XML::Elemen]
|
185
|
+
# @return [RelatonBib::DocumentStatus::Stage]
|
186
|
+
def stage(elm)
|
187
|
+
return unless elm
|
188
|
+
|
189
|
+
DocumentStatus::Stage.new value: elm.text, abbreviation: elm[:abbreviation]
|
190
|
+
end
|
191
|
+
|
176
192
|
def fetch_dates(item)
|
177
193
|
item.xpath("./date").reduce([]) do |a, d|
|
178
194
|
type = d[:type].to_s.empty? ? "published" : d[:type]
|
@@ -257,6 +273,8 @@ module RelatonBib
|
|
257
273
|
end
|
258
274
|
end
|
259
275
|
|
276
|
+
# @param item [Nokogiri::XML::Element]
|
277
|
+
# @return [Array<RelatonBib::ContributionInfo>]
|
260
278
|
def fetch_contributors(item)
|
261
279
|
item.xpath("./contributor").map do |c|
|
262
280
|
entity = if (org = c.at "./organization") then get_org(org)
|
@@ -269,6 +287,8 @@ module RelatonBib
|
|
269
287
|
end
|
270
288
|
end
|
271
289
|
|
290
|
+
# @param item [Nokogiri::XML::Element]
|
291
|
+
# @return [Array<RelatonBib::FormattedString>]
|
272
292
|
def fetch_abstract(item)
|
273
293
|
item.xpath("./abstract").map do |a|
|
274
294
|
FormattedString.new(
|
@@ -277,6 +297,8 @@ module RelatonBib
|
|
277
297
|
end
|
278
298
|
end
|
279
299
|
|
300
|
+
# @param item [Nokogiri::XML::Element]
|
301
|
+
# @return [RelatonBib::CopyrightAssociation]
|
280
302
|
def fetch_copyright(item)
|
281
303
|
cp = item.at("./copyright") || return
|
282
304
|
org = cp&.at("owner/organization")
|
@@ -290,30 +312,82 @@ module RelatonBib
|
|
290
312
|
CopyrightAssociation.new(owner: owner, from: from, to: to)
|
291
313
|
end
|
292
314
|
|
315
|
+
# @param item [Nokogiri::XML::Element]
|
316
|
+
# @return [Arra<RelatonBib::TypedUri>]
|
293
317
|
def fetch_link(item)
|
294
318
|
item.xpath("./uri").map do |l|
|
295
319
|
TypedUri.new type: l[:type], content: l.text
|
296
320
|
end
|
297
321
|
end
|
298
322
|
|
323
|
+
# @param item [Nokogiri::XML::Element]
|
324
|
+
# @return [Array<RelatonBib::DocumentRelation>]
|
299
325
|
def fetch_relations(item)
|
300
326
|
item.xpath("./relation").map do |rel|
|
301
|
-
localities = rel.xpath("./locality").map do |l|
|
302
|
-
ref_to = (rt = l.at("./referenceTo")) ? LocalizedString.new(rt.text) : nil
|
303
|
-
BibItemLocality.new(
|
304
|
-
l[:type],
|
305
|
-
LocalizedString.new(l.at("./referenceFrom").text),
|
306
|
-
ref_to,
|
307
|
-
)
|
308
|
-
end
|
309
327
|
DocumentRelation.new(
|
310
328
|
type: rel[:type]&.empty? ? nil : rel[:type],
|
311
|
-
|
312
|
-
|
329
|
+
description: relation_description(rel),
|
330
|
+
bibitem: bib_item(item_data(rel.at("./bibitem"))),
|
331
|
+
locality: localities(rel),
|
332
|
+
source_locality: source_localities(rel),
|
313
333
|
)
|
314
334
|
end
|
315
335
|
end
|
316
336
|
|
337
|
+
# @param rel [Nokogiri::XML::Element]
|
338
|
+
# @return [RelatonBib::FormattedString, NilClass]
|
339
|
+
def relation_description(rel)
|
340
|
+
d = rel.at "./description"
|
341
|
+
return unless d
|
342
|
+
|
343
|
+
FormattedString.new(content: d.text, language: d[:language],
|
344
|
+
script: d[:script], format: d[:format])
|
345
|
+
end
|
346
|
+
|
347
|
+
# @param item_hash [Hash]
|
348
|
+
# @return [RelatonBib::BibliographicItem]
|
349
|
+
def bib_item(item_hash)
|
350
|
+
BibliographicItem.new item_hash
|
351
|
+
end
|
352
|
+
|
353
|
+
# @param rel [Nokogiri::XML::Element]
|
354
|
+
# @return [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
|
355
|
+
def localities(rel)
|
356
|
+
rel.xpath("./locality|./localityStack").map do |lc|
|
357
|
+
if lc[:type]
|
358
|
+
LocalityStack.new [locality(lc)]
|
359
|
+
else
|
360
|
+
LocalityStack.new lc.xpath("./locality").map { |l| locality l }
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# @param loc [Nokogiri::XML::Element]
|
366
|
+
# @return [RelatonBib::Locality]
|
367
|
+
def locality(loc, klass = Locality)
|
368
|
+
ref_to = (rt = loc.at("./referenceTo")) ? LocalizedString.new(rt.text) : nil
|
369
|
+
klass.new(
|
370
|
+
loc[:type],
|
371
|
+
LocalizedString.new(loc.at("./referenceFrom").text),
|
372
|
+
ref_to,
|
373
|
+
)
|
374
|
+
end
|
375
|
+
|
376
|
+
# @param rel [Nokogiri::XML::Element]
|
377
|
+
# @return [Array<RelatonBib::SourceLocality, RelatonBib::SourceLocalityStack>]
|
378
|
+
def source_localities(rel)
|
379
|
+
rel.xpath("./sourceLocality|./sourceLocalityStack").map do |lc|
|
380
|
+
if lc[:type]
|
381
|
+
SourceLocalityStack.new [locality(lc, SourceLocality)]
|
382
|
+
else
|
383
|
+
sls = lc.xpath("./sourceLocality").map { |l| locality l, SourceLocality }
|
384
|
+
SourceLocalityStack.new sls
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
# @param item [Nokogiri::XML::Element]
|
390
|
+
# @return [RelatonBib::FormattedRef, NilClass]
|
317
391
|
def fref(item)
|
318
392
|
ident = item&.at("./formattedref")
|
319
393
|
return unless ident
|
data/relaton-bib.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path("
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require "relaton_bib/version"
|
4
4
|
|
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
|
16
16
|
# Specify which files should be added to the gem when it is released.
|
17
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
-
spec.files = Dir.chdir(File.expand_path(
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
19
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
20
|
end
|
21
21
|
spec.bindir = "exe"
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
25
25
|
|
26
|
+
spec.add_development_dependency "byebug"
|
26
27
|
spec.add_development_dependency "debase"
|
27
28
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
28
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -30,7 +31,6 @@ Gem::Specification.new do |spec|
|
|
30
31
|
spec.add_development_dependency "ruby-debug-ide"
|
31
32
|
spec.add_development_dependency "ruby-jing"
|
32
33
|
spec.add_development_dependency "simplecov"
|
33
|
-
spec.add_development_dependency "byebug"
|
34
34
|
|
35
35
|
spec.add_dependency "addressable"
|
36
36
|
spec.add_dependency "bibtex-ruby"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relaton-bib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: byebug
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: debase
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,20 +122,6 @@ dependencies:
|
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: byebug
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: addressable
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +190,7 @@ files:
|
|
190
190
|
- ".github/workflows/windows.yml"
|
191
191
|
- ".gitignore"
|
192
192
|
- ".gitmodules"
|
193
|
+
- ".hound.yml"
|
193
194
|
- ".rspec"
|
194
195
|
- ".rubocop.yml"
|
195
196
|
- Gemfile
|