relaton-bib 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/lib/relaton_bib.rb +3 -3
- data/lib/relaton_bib/bibliographic_item.rb +9 -11
- 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 +35 -18
- data/lib/relaton_bib/document_relation_collection.rb +4 -1
- data/lib/relaton_bib/document_status.rb +49 -10
- data/lib/relaton_bib/formatted_string.rb +3 -3
- data/lib/relaton_bib/hash_converter.rb +37 -7
- data/lib/relaton_bib/localized_string.rb +33 -12
- data/lib/relaton_bib/typed_title_string.rb +3 -9
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/xml_parser.rb +50 -29
- data/relaton-bib.gemspec +3 -3
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f046b9f9c341d92cec95e89a817afea83133a322255f259c34c869aafcea60c
|
4
|
+
data.tar.gz: e9535bc5707436472ef9986faa9e429d2c451c94bc9b46f0ed10b21b8304dc41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85b19d11a3eef57448df18fee645c53539fc485cf90f6b07b303311bf0d7dd2f4666c1bacfeae3f15aafc372cc93a60bfbcb3993783cba3103dd018633607633
|
7
|
+
data.tar.gz: 6a91bcba71ca9d070eb906a827ee8b5be314b888691e1f4849081163efc1c9e2b2218ac3d03e791569852cfa49ec9c2d1af7e8e16a45ff2facbf2af9b1c32824
|
data/lib/relaton_bib.rb
CHANGED
@@ -13,7 +13,8 @@ module RelatonBib
|
|
13
13
|
# @param date [String]
|
14
14
|
# @return [Date, NilClass]
|
15
15
|
def parse_date(sdate)
|
16
|
-
if
|
16
|
+
if sdate.is_a?(Date) then sdate
|
17
|
+
elsif /(?<date>\w+\s\d{4})/ =~ sdate # February 2012
|
17
18
|
Date.strptime(date, "%B %Y")
|
18
19
|
elsif /(?<date>\w+\s\d{1,2},\s\d{4})/ =~ sdate # February 11, 2012
|
19
20
|
Date.strptime(date, "%B %d, %Y")
|
@@ -21,8 +22,7 @@ module RelatonBib
|
|
21
22
|
Date.parse(date)
|
22
23
|
elsif /(?<date>\d{4}-\d{2})/ =~ sdate # 2012-02
|
23
24
|
Date.strptime date, "%Y-%m"
|
24
|
-
elsif /(?<date>\d{4})/ =~ sdate # 2012
|
25
|
-
Date.strptime date, "%Y"
|
25
|
+
elsif /(?<date>\d{4})/ =~ sdate then Date.strptime date, "%Y" # 2012
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -83,7 +83,7 @@ module RelatonBib
|
|
83
83
|
# @return [RelatonBib::DocumentStatus, NilClass]
|
84
84
|
attr_reader :status
|
85
85
|
|
86
|
-
# @return [RelatonBib::CopyrightAssociation
|
86
|
+
# @return [Array<RelatonBib::CopyrightAssociation>]
|
87
87
|
attr_reader :copyright
|
88
88
|
|
89
89
|
# @return [RelatonBib::DocRelationCollection]
|
@@ -141,10 +141,11 @@ module RelatonBib
|
|
141
141
|
# @param fetched [Date, NilClass] default nil
|
142
142
|
# @param keyword [Array<String>]
|
143
143
|
#
|
144
|
-
# @param copyright [Hash, RelatonBib::CopyrightAssociation
|
145
|
-
# @option copyright [Hash, RelatonBib::ContributionInfo] :owner
|
146
|
-
# @option copyright [String] :
|
144
|
+
# @param copyright [Array<Hash, RelatonBib::CopyrightAssociation>]
|
145
|
+
# @option copyright [Array<Hash, RelatonBib::ContributionInfo>] :owner
|
146
|
+
# @option copyright [String] :from
|
147
147
|
# @option copyright [String, NilClass] :to
|
148
|
+
# @option copyright [String, NilClass] :scope
|
148
149
|
#
|
149
150
|
# @param date [Array<Hash>]
|
150
151
|
# @option date [String] :type
|
@@ -202,11 +203,8 @@ module RelatonBib
|
|
202
203
|
a.is_a?(Hash) ? FormattedString.new(a) : a
|
203
204
|
end
|
204
205
|
|
205
|
-
|
206
|
-
|
207
|
-
CopyrightAssociation.new args[:copyright]
|
208
|
-
else args[:copyright]
|
209
|
-
end
|
206
|
+
@copyright = args.fetch(:copyright, []).map do |c|
|
207
|
+
c.is_a?(Hash) ? CopyrightAssociation.new(c) : c
|
210
208
|
end
|
211
209
|
|
212
210
|
@docidentifier = args[:docid] || []
|
@@ -308,7 +306,7 @@ module RelatonBib
|
|
308
306
|
hash["formattedref"] = formattedref.to_hash if formattedref
|
309
307
|
hash["abstract"] = single_element_array(abstract) if abstract&.any?
|
310
308
|
hash["docstatus"] = status.to_hash if status
|
311
|
-
hash["copyright"] = copyright
|
309
|
+
hash["copyright"] = single_element_array(copyright) if copyright&.any?
|
312
310
|
hash["relation"] = single_element_array(relation) if relation&.any?
|
313
311
|
hash["series"] = single_element_array(series) if series&.any?
|
314
312
|
hash["medium"] = medium.to_hash if medium
|
@@ -530,7 +528,7 @@ module RelatonBib
|
|
530
528
|
script.each { |s| builder.script s }
|
531
529
|
abstract.each { |a| builder.abstract { a.to_xml(builder) } }
|
532
530
|
status&.to_xml builder
|
533
|
-
copyright&.to_xml builder
|
531
|
+
copyright&.each { |c| c.to_xml builder }
|
534
532
|
relation.each { |r| r.to_xml builder, **opts }
|
535
533
|
series.each { |s| s.to_xml builder }
|
536
534
|
medium&.to_xml builder
|
@@ -147,17 +147,16 @@ module RelatonBib
|
|
147
147
|
# @param bibtex [BibTeX::Entry]
|
148
148
|
# @return [Array<RelatonBib::BiblioNote>]
|
149
149
|
def fetch_note(bibtex)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
150
|
+
bibtex.select do |k, _v|
|
151
|
+
%i[annote howpublished comment note content].include? k
|
152
|
+
end.reduce([]) do |mem, note|
|
153
|
+
type = case note[0]
|
154
|
+
when :note then nil
|
155
|
+
when :content then "tableOfContents"
|
156
|
+
else note[0].to_s
|
157
|
+
end
|
158
|
+
mem << BiblioNote.new(type: type, content: note[1].to_s)
|
155
159
|
end
|
156
|
-
|
157
|
-
note << BiblioNote.new(type: "comment", content: bibtex.comment.to_s) if bibtex["comment"]
|
158
|
-
note << BiblioNote.new(content: bibtex.note.to_s) if bibtex["note"]
|
159
|
-
note << BiblioNote.new(type: "tableOfContents", content: bibtex["content"]) if bibtex["content"]
|
160
|
-
note
|
161
160
|
end
|
162
161
|
|
163
162
|
# @param bibtex [BibTeX::Entry]
|
@@ -172,16 +171,19 @@ module RelatonBib
|
|
172
171
|
# @param bibtex [BibTeX::Entry]
|
173
172
|
# @return [Array<RelatonBib::BibItemLocality>]
|
174
173
|
def fetch_extent(bibtex)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
174
|
+
bibtex.select do |k, _v|
|
175
|
+
%i[chapter pages volume].include? k
|
176
|
+
end.reduce([]) do |mem, loc|
|
177
|
+
if loc[0] == :pages
|
178
|
+
type = "page"
|
179
|
+
from, to = loc[1].to_s.split "-"
|
180
|
+
else
|
181
|
+
type = loc[0].to_s
|
182
|
+
from = loc[1].to_s
|
183
|
+
to = nil
|
184
|
+
end
|
185
|
+
mem << BibItemLocality.new(type, from, to)
|
181
186
|
end
|
182
|
-
|
183
|
-
extent << BibItemLocality.new("volume", bibtex.volume.to_s) if bibtex["volume"]
|
184
|
-
extent
|
185
187
|
end
|
186
188
|
|
187
189
|
# @param bibtex [BibTeX::Entry]
|
@@ -192,7 +194,7 @@ module RelatonBib
|
|
192
194
|
series << Series.new(
|
193
195
|
type: "journal",
|
194
196
|
title: TypedTitleString.new(content: bibtex.journal.to_s),
|
195
|
-
number: bibtex["number"]&.to_s
|
197
|
+
number: bibtex["number"]&.to_s,
|
196
198
|
)
|
197
199
|
end
|
198
200
|
|
@@ -1,29 +1,41 @@
|
|
1
1
|
module RelatonBib
|
2
2
|
# Copyright association.
|
3
3
|
class CopyrightAssociation
|
4
|
+
include RelatonBib
|
5
|
+
|
4
6
|
# @return [Date]
|
5
7
|
attr_reader :from
|
6
8
|
|
7
9
|
# @return [Date, NilClass]
|
8
10
|
attr_reader :to
|
9
11
|
|
10
|
-
# @return [
|
12
|
+
# @return [String, NilClass]
|
13
|
+
attr_reader :scope
|
14
|
+
|
15
|
+
# @return [Array<RelatonBib::ContributionInfo>]
|
11
16
|
attr_reader :owner
|
12
17
|
|
13
|
-
#
|
18
|
+
# rubocop:disable Metrics/AbcSize
|
19
|
+
|
20
|
+
# @param owner [Array<Hash, RelatonBib::ContributionInfo>] contributor
|
14
21
|
# @option owner [String] :name
|
15
22
|
# @option owner [String] :abbreviation
|
16
23
|
# @option owner [String] :url
|
17
24
|
# @param from [String] date
|
18
25
|
# @param to [String, NilClass] date
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
# @param scope [String, NilClass]
|
27
|
+
def initialize(owner:, from:, to: nil, scope: nil)
|
28
|
+
unless owner.any?
|
29
|
+
raise ArgumentError, "at least one owner should exist."
|
30
|
+
end
|
31
|
+
|
32
|
+
@owner = owner.map do |o|
|
33
|
+
o.is_a?(Hash) ? ContributionInfo.new(entity: Organization.new(o)) : o
|
34
|
+
end
|
24
35
|
|
25
36
|
@from = Date.strptime(from.to_s, "%Y") if from.to_s =~ /\d{4}/
|
26
37
|
@to = Date.strptime(to.to_s, "%Y") unless to.to_s.empty?
|
38
|
+
@scope = scope
|
27
39
|
end
|
28
40
|
|
29
41
|
# @param builder [Nokogiri::XML::Builder]
|
@@ -31,14 +43,21 @@ module RelatonBib
|
|
31
43
|
builder.copyright do
|
32
44
|
builder.from from ? from.year : "unknown"
|
33
45
|
builder.to to.year if to
|
34
|
-
builder.owner {
|
46
|
+
owner.each { |o| builder.owner { o.to_xml builder } }
|
47
|
+
builder.scope scope if scope
|
35
48
|
end
|
36
49
|
end
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
37
51
|
|
38
52
|
# @return [Hash]
|
39
53
|
def to_hash
|
40
|
-
|
54
|
+
owners = single_element_array(owner.map { |o| o.to_hash["organization"] })
|
55
|
+
hash = {
|
56
|
+
"owner" => owners,
|
57
|
+
"from" => from.year.to_s,
|
58
|
+
}
|
41
59
|
hash["to"] = to.year.to_s if to
|
60
|
+
hash["scope"] = scope if scope
|
42
61
|
hash
|
43
62
|
end
|
44
63
|
end
|
@@ -1,24 +1,27 @@
|
|
1
1
|
module RelatonBib
|
2
|
-
# module DocumentRelationType
|
3
|
-
# PARENT = 'parent'
|
4
|
-
# CHILD = 'child'
|
5
|
-
# OBSOLETES = 'obsoletes'
|
6
|
-
# UPDATES = 'updates'
|
7
|
-
# COMPLEMENTS = 'complements'
|
8
|
-
# DERIVED_FORM = 'derivedForm'
|
9
|
-
# ADOPTED_FORM = 'adoptedForm'
|
10
|
-
# EQUIVALENT = 'equivalent'
|
11
|
-
# IDENTICAL = 'identical'
|
12
|
-
# NONEQUIVALENT = 'nonequivalent'
|
13
|
-
# end
|
14
|
-
|
15
2
|
# Documett relation
|
16
3
|
class DocumentRelation
|
17
4
|
include RelatonBib
|
18
5
|
|
6
|
+
TYPES = %w[
|
7
|
+
includes includedIn hasPart partOf merges mergedInto splits splitInto
|
8
|
+
instance hasInstance exemplarOf hasExemplar manifestationOf
|
9
|
+
hasManifestation reproductionOf hasReproduction reprintOf hasReprint
|
10
|
+
expressionOf hasExpression translatedFrom hasTranslation arrangementOf
|
11
|
+
hasArrangement abridgementOf hasAbridgement annotationOf hasAnnotation
|
12
|
+
draftOf hasDraft editionOf hasEdition updates updatedBy derivedFrom
|
13
|
+
derives describes describedBy catalogues cataloguedBy hasSuccessor
|
14
|
+
successorOf adaptedFrom hasAdaptation adoptedFrom adoptedAs reviewOf
|
15
|
+
hasReview commentaryOf hasCommentary related complements complementOf
|
16
|
+
obsoletes obsoletedBy cited isCitedIn
|
17
|
+
].freeze
|
18
|
+
|
19
19
|
# @return [String]
|
20
20
|
attr_reader :type
|
21
21
|
|
22
|
+
# @return [RelatonBib::FormattedString, NilClass]
|
23
|
+
attr_reader :description
|
24
|
+
|
22
25
|
# @return [String]
|
23
26
|
# attr_reader :identifier, :url
|
24
27
|
|
@@ -28,35 +31,49 @@ module RelatonBib
|
|
28
31
|
# @return [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
|
29
32
|
attr_reader :locality
|
30
33
|
|
31
|
-
# @return [Array<RelatonBib::SourceLocality,
|
34
|
+
# @return [Array<RelatonBib::SourceLocality,
|
35
|
+
# RelatonBib::SourceLocalityStack>]
|
32
36
|
attr_reader :source_locality
|
33
37
|
|
34
38
|
# @param type [String]
|
35
|
-
# @
|
39
|
+
# @parma description [RelatonBib::FormattedString, NilClass]
|
40
|
+
# @param bibitem [RelatonBib::BibliographicItem,
|
41
|
+
# RelatonIso::IsoBibliographicItem]
|
36
42
|
# @param locality [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
|
37
|
-
# @param source_locality [Array<RelatonBib::SourceLocality,
|
38
|
-
|
39
|
-
|
43
|
+
# @param source_locality [Array<RelatonBib::SourceLocality,
|
44
|
+
# RelatonBib::SourceLocalityStack>]
|
45
|
+
def initialize(type:, description: nil, bibitem:, locality: [],
|
46
|
+
source_locality: [])
|
47
|
+
type = "obsoletes" if type == "Now withdrawn"
|
48
|
+
unless TYPES.include? type
|
49
|
+
warn "[relaton-bib] WARNING: invalid relation type: #{type}"
|
50
|
+
end
|
40
51
|
@type = type
|
52
|
+
@description = description
|
41
53
|
@locality = locality
|
42
54
|
@source_locality = source_locality
|
43
55
|
@bibitem = bibitem
|
44
56
|
end
|
45
57
|
|
58
|
+
# rubocop:disable Metrics/AbcSize
|
59
|
+
|
46
60
|
# @param builder [Nokogiri::XML::Builder]
|
47
61
|
def to_xml(builder, **opts)
|
48
62
|
opts.delete :bibdata
|
49
63
|
opts.delete :note
|
50
64
|
builder.relation(type: type) do
|
65
|
+
builder.description { description.to_xml builder } if description
|
51
66
|
bibitem.to_xml(builder, **opts.merge(embedded: true))
|
52
67
|
locality.each { |l| l.to_xml builder }
|
53
68
|
source_locality.each { |l| l.to_xml builder }
|
54
69
|
end
|
55
70
|
end
|
71
|
+
# rubocop:enable Metrics/AbcSize
|
56
72
|
|
57
73
|
# @return [Hash]
|
58
74
|
def to_hash
|
59
75
|
hash = { "type" => type, "bibitem" => bibitem.to_hash }
|
76
|
+
hash["description"] = description.to_hash if description
|
60
77
|
hash["locality"] = single_element_array(locality) if locality&.any?
|
61
78
|
if source_locality&.any?
|
62
79
|
hash["source_locality"] = single_element_array(source_locality)
|
@@ -23,9 +23,12 @@ module RelatonBib
|
|
23
23
|
@array = relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(r) : r }
|
24
24
|
end
|
25
25
|
|
26
|
+
# @todo We don't have replace type anymore. Suppose we should update this
|
27
|
+
# method or delete it.
|
28
|
+
#
|
26
29
|
# @return [RelatonBib::DocRelationCollection]
|
27
30
|
def replaces
|
28
|
-
DocRelationCollection.new
|
31
|
+
DocRelationCollection.new(@array.select { |r| r.type == "replace" })
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
@@ -5,21 +5,21 @@ require "relaton_bib/localized_string"
|
|
5
5
|
module RelatonBib
|
6
6
|
# Document status.
|
7
7
|
class DocumentStatus
|
8
|
-
# @return [
|
8
|
+
# @return [RelatonBib::DocumentStatus::Stage]
|
9
9
|
attr_reader :stage
|
10
10
|
|
11
|
-
# @return [
|
11
|
+
# @return [RelatonBib::DocumentStatus::Stage, NilClass]
|
12
12
|
attr_reader :substage
|
13
13
|
|
14
14
|
# @return [String, NilClass]
|
15
15
|
attr_reader :iteration
|
16
16
|
|
17
|
-
# @param stage [String]
|
18
|
-
# @param substage [String, NilClass]
|
17
|
+
# @param stage [String, Hash, RelatonBib::DocumentStatus::Stage]
|
18
|
+
# @param substage [String, Hash, NilClass, RelatonBib::DocumentStatus::Stage]
|
19
19
|
# @param iteration [String, NilClass]
|
20
20
|
def initialize(stage:, substage: nil, iteration: nil)
|
21
|
-
@stage = stage
|
22
|
-
@substage = substage
|
21
|
+
@stage = stage_new stage
|
22
|
+
@substage = stage_new substage
|
23
23
|
@iteration = iteration
|
24
24
|
end
|
25
25
|
|
@@ -27,18 +27,57 @@ module RelatonBib
|
|
27
27
|
def to_xml(builder)
|
28
28
|
builder.status do
|
29
29
|
# FormattedString.instance_method(:to_xml).bind(status).call builder
|
30
|
-
builder.stage stage
|
31
|
-
builder.substage substage if substage
|
30
|
+
builder.stage { |b| stage.to_xml b }
|
31
|
+
builder.substage { |b| substage.to_xml b } if substage
|
32
32
|
builder.iteration iteration unless iteration.to_s.empty?
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
# @return [Hash]
|
37
37
|
def to_hash
|
38
|
-
hash = { "stage" => stage }
|
39
|
-
hash["substage"] = substage if substage
|
38
|
+
hash = { "stage" => stage.to_hash }
|
39
|
+
hash["substage"] = substage.to_hash if substage
|
40
40
|
hash["iteration"] = iteration if iteration
|
41
41
|
hash
|
42
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @param stg [RelatonBib::DocumentStatus::Stage, Hash, String, NilClass]
|
47
|
+
# @return [RelatonBib::DocumentStatus::Stage]
|
48
|
+
def stage_new(stg)
|
49
|
+
if stg.is_a?(Stage) then stg
|
50
|
+
elsif stg.is_a?(Hash) then Stage.new(stg)
|
51
|
+
elsif stg.is_a?(String) then Stage.new(value: stg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Stage
|
56
|
+
# @return [String]
|
57
|
+
attr_reader :value
|
58
|
+
|
59
|
+
# @return [String, NilClass]
|
60
|
+
attr_reader :abbreviation
|
61
|
+
|
62
|
+
# @parma value [String]
|
63
|
+
# @param abbreviation [String, NilClass]
|
64
|
+
def initialize(value:, abbreviation: nil)
|
65
|
+
@value = value
|
66
|
+
@abbreviation = abbreviation
|
67
|
+
end
|
68
|
+
|
69
|
+
# @param [Nokogiri::XML::Builder]
|
70
|
+
def to_xml(builder)
|
71
|
+
builder.parent[:abbreviation] = abbreviation if abbreviation
|
72
|
+
builder.text value
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Hash]
|
76
|
+
def to_hash
|
77
|
+
hash = { "value" => value }
|
78
|
+
hash["abbreviation"] = abbreviation if abbreviation
|
79
|
+
hash
|
80
|
+
end
|
81
|
+
end
|
43
82
|
end
|
44
83
|
end
|
@@ -12,7 +12,7 @@ module RelatonBib
|
|
12
12
|
# @return [String]
|
13
13
|
attr_reader :format
|
14
14
|
|
15
|
-
# @param content [String]
|
15
|
+
# @param content [String, Array<RelatonBib::LocalizedString>]
|
16
16
|
# @param language [String, NilClass] language code Iso639
|
17
17
|
# @param script [String, NilClass] script code Iso15924
|
18
18
|
# @param format [String] the content type
|
@@ -36,8 +36,8 @@ module RelatonBib
|
|
36
36
|
hash = super
|
37
37
|
return hash unless format
|
38
38
|
|
39
|
-
hash = { "content" => hash }
|
40
|
-
hash["format"] = format
|
39
|
+
hash = { "content" => hash } unless hash.is_a? Hash
|
40
|
+
hash["format"] = format
|
41
41
|
hash
|
42
42
|
end
|
43
43
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module RelatonBib
|
2
2
|
class HashConverter
|
3
3
|
class << self
|
4
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
5
|
+
|
6
|
+
# @param args [Hash]
|
7
|
+
# @param neated [TrueClas, FalseClass] default true
|
8
|
+
# @return [Hash]
|
4
9
|
def hash_to_bib(args, nested = false)
|
5
10
|
return nil unless args.is_a?(Hash)
|
6
11
|
|
@@ -18,6 +23,7 @@ module RelatonBib
|
|
18
23
|
formattedref_hash_to_bib(ret)
|
19
24
|
docstatus_hash_to_bib(ret)
|
20
25
|
contributors_hash_to_bib(ret)
|
26
|
+
copyright_hash_to_bib(ret)
|
21
27
|
relations_hash_to_bib(ret)
|
22
28
|
series_hash_to_bib(ret)
|
23
29
|
medium_hash_to_bib(ret)
|
@@ -30,6 +36,7 @@ module RelatonBib
|
|
30
36
|
ret[:license] = array(ret[:license])
|
31
37
|
ret
|
32
38
|
end
|
39
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
33
40
|
|
34
41
|
def timestamp_hash(ret)
|
35
42
|
ret[:fetched] ||= Date.today.to_s
|
@@ -52,7 +59,8 @@ module RelatonBib
|
|
52
59
|
ret[:title] = ret[:title].map do |t|
|
53
60
|
if t.is_a?(Hash) then t
|
54
61
|
else
|
55
|
-
{ content: t, language: "en", script: "Latn", format: "text/plain",
|
62
|
+
{ content: t, language: "en", script: "Latn", format: "text/plain",
|
63
|
+
type: "main" }
|
56
64
|
end
|
57
65
|
end
|
58
66
|
end
|
@@ -151,12 +159,21 @@ module RelatonBib
|
|
151
159
|
|
152
160
|
def docstatus_hash_to_bib(ret)
|
153
161
|
ret[:docstatus] && ret[:docstatus] = DocumentStatus.new(
|
154
|
-
stage: ret[:docstatus][:stage],
|
155
|
-
substage: ret[:docstatus][:substage],
|
162
|
+
stage: stage(ret[:docstatus][:stage]),
|
163
|
+
substage: stage(ret[:docstatus][:substage]),
|
156
164
|
iteration: ret[:docstatus][:iteration],
|
157
165
|
)
|
158
166
|
end
|
159
167
|
|
168
|
+
# @param stg [Hash]
|
169
|
+
# @return [RelatonBib::DocumentStatus::Stage]
|
170
|
+
def stage(stg)
|
171
|
+
return unless stg
|
172
|
+
|
173
|
+
args = stg.is_a?(String) ? { value: stg } : stg
|
174
|
+
DocumentStatus::Stage.new(**args)
|
175
|
+
end
|
176
|
+
|
160
177
|
def contributors_hash_to_bib(ret)
|
161
178
|
return unless ret[:contributor]
|
162
179
|
|
@@ -252,12 +269,25 @@ module RelatonBib
|
|
252
269
|
end
|
253
270
|
end
|
254
271
|
|
272
|
+
# @param ret [Hash]
|
273
|
+
def copyright_hash_to_bib(ret)
|
274
|
+
return unless ret[:copyright]
|
275
|
+
|
276
|
+
ret[:copyright] = array(ret[:copyright]).map do |c|
|
277
|
+
c[:owner] = array(c[:owner])
|
278
|
+
c
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
255
282
|
# @param ret [Hash]
|
256
283
|
def relations_hash_to_bib(ret)
|
257
284
|
return unless ret[:relation]
|
258
285
|
|
259
286
|
ret[:relation] = array(ret[:relation])
|
260
287
|
ret[:relation]&.each do |r|
|
288
|
+
if r[:description]
|
289
|
+
r[:description] = FormattedString.new r[:description]
|
290
|
+
end
|
261
291
|
relation_bibitem_hash_to_bib(r)
|
262
292
|
relation_locality_hash_to_bib(r)
|
263
293
|
relation_source_locality_hash_to_bib(r)
|
@@ -312,7 +342,7 @@ module RelatonBib
|
|
312
342
|
ret[:series] = array(ret[:series])&.map do |s|
|
313
343
|
s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
|
314
344
|
if s[:title]
|
315
|
-
s[:title] = { content: s[:title] } unless s.is_a?(Hash)
|
345
|
+
s[:title] = { content: s[:title] } unless s[:title].is_a?(Hash)
|
316
346
|
s[:title] = typed_title_strig(s[:title])
|
317
347
|
end
|
318
348
|
s[:abbreviation] && s[:abbreviation] = localizedstring(s[:abbreviation])
|
@@ -343,9 +373,9 @@ module RelatonBib
|
|
343
373
|
def validity_hash_to_bib(ret)
|
344
374
|
return unless ret[:validity]
|
345
375
|
|
346
|
-
ret[:validity][:begins] && b = Time.parse(ret[:validity][:begins])
|
347
|
-
ret[:validity][:ends] && e = Time.parse(ret[:validity][:ends])
|
348
|
-
ret[:validity][:revision] && r = Time.parse(ret[:validity][:revision])
|
376
|
+
ret[:validity][:begins] && b = Time.parse(ret[:validity][:begins].to_s)
|
377
|
+
ret[:validity][:ends] && e = Time.parse(ret[:validity][:ends].to_s)
|
378
|
+
ret[:validity][:revision] && r = Time.parse(ret[:validity][:revision].to_s)
|
349
379
|
ret[:validity] = Validity.new(begins: b, ends: e, revision: r)
|
350
380
|
end
|
351
381
|
|
@@ -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
|
@@ -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,12 @@ 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
|
39
33
|
|
40
34
|
# @param builder [Nokogiri::XML::Builder]
|
41
35
|
def to_xml(builder)
|
data/lib/relaton_bib/version.rb
CHANGED
@@ -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]
|
@@ -228,14 +244,9 @@ module RelatonBib
|
|
228
244
|
end
|
229
245
|
|
230
246
|
cn = person.at "./name/completename"
|
231
|
-
cname =
|
232
|
-
LocalizedString.new(cn.text, cn[:language], cn[:script])
|
233
|
-
else
|
234
|
-
nil
|
235
|
-
end
|
236
|
-
|
247
|
+
cname = cn && LocalizedString.new(cn.text, cn[:language], cn[:script])
|
237
248
|
sn = person.at "./name/surname"
|
238
|
-
sname = sn
|
249
|
+
sname = sn && LocalizedString.new(sn.text, sn[:language], sn[:script])
|
239
250
|
|
240
251
|
name = FullName.new(
|
241
252
|
completename: cname, surname: sname,
|
@@ -275,25 +286,24 @@ module RelatonBib
|
|
275
286
|
# @return [Array<RelatonBib::FormattedString>]
|
276
287
|
def fetch_abstract(item)
|
277
288
|
item.xpath("./abstract").map do |a|
|
278
|
-
FormattedString.new(
|
279
|
-
|
280
|
-
)
|
289
|
+
FormattedString.new(content: a.text, language: a[:language],
|
290
|
+
script: a[:script], format: a[:format])
|
281
291
|
end
|
282
292
|
end
|
283
293
|
|
284
294
|
# @param item [Nokogiri::XML::Element]
|
285
|
-
# @return [RelatonBib::CopyrightAssociation]
|
295
|
+
# @return [Array<RelatonBib::CopyrightAssociation>]
|
286
296
|
def fetch_copyright(item)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
+
item.xpath("./copyright").map do |cp|
|
298
|
+
owner = cp.xpath("owner").map do |o|
|
299
|
+
ContributionInfo.new entity: get_org(o.at("organization"))
|
300
|
+
end
|
301
|
+
from = cp.at("from")&.text
|
302
|
+
to = cp.at("to")&.text
|
303
|
+
scope = cp.at("scope")&.text
|
304
|
+
CopyrightAssociation.new(owner: owner, from: from, to: to,
|
305
|
+
scope: scope)
|
306
|
+
end
|
297
307
|
end
|
298
308
|
|
299
309
|
# @param item [Nokogiri::XML::Element]
|
@@ -310,6 +320,7 @@ module RelatonBib
|
|
310
320
|
item.xpath("./relation").map do |rel|
|
311
321
|
DocumentRelation.new(
|
312
322
|
type: rel[:type]&.empty? ? nil : rel[:type],
|
323
|
+
description: relation_description(rel),
|
313
324
|
bibitem: bib_item(item_data(rel.at("./bibitem"))),
|
314
325
|
locality: localities(rel),
|
315
326
|
source_locality: source_localities(rel),
|
@@ -317,6 +328,16 @@ module RelatonBib
|
|
317
328
|
end
|
318
329
|
end
|
319
330
|
|
331
|
+
# @param rel [Nokogiri::XML::Element]
|
332
|
+
# @return [RelatonBib::FormattedString, NilClass]
|
333
|
+
def relation_description(rel)
|
334
|
+
d = rel.at "./description"
|
335
|
+
return unless d
|
336
|
+
|
337
|
+
FormattedString.new(content: d.text, language: d[:language],
|
338
|
+
script: d[:script], format: d[:format])
|
339
|
+
end
|
340
|
+
|
320
341
|
# @param item_hash [Hash]
|
321
342
|
# @return [RelatonBib::BibliographicItem]
|
322
343
|
def bib_item(item_hash)
|
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: 1.
|
4
|
+
version: 1.1.0
|
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-06-03 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
|