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