relaton-bib 0.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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +57 -0
- data/LICENSE.txt +21 -0
- data/README.adoc +272 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/relaton_bib.rb +7 -0
- data/lib/relaton_bib/bib_item_locality.rb +46 -0
- data/lib/relaton_bib/bibliographic_date.rb +76 -0
- data/lib/relaton_bib/bibliographic_item.rb +343 -0
- data/lib/relaton_bib/classification.rb +22 -0
- data/lib/relaton_bib/contribution_info.rb +61 -0
- data/lib/relaton_bib/contributor.rb +121 -0
- data/lib/relaton_bib/copyright_association.rb +38 -0
- data/lib/relaton_bib/document_identifier.rb +26 -0
- data/lib/relaton_bib/document_relation.rb +49 -0
- data/lib/relaton_bib/document_relation_collection.rb +21 -0
- data/lib/relaton_bib/document_status.rb +24 -0
- data/lib/relaton_bib/formatted_ref.rb +11 -0
- data/lib/relaton_bib/formatted_string.rb +33 -0
- data/lib/relaton_bib/localized_string.rb +45 -0
- data/lib/relaton_bib/medium.rb +24 -0
- data/lib/relaton_bib/organization.rb +103 -0
- data/lib/relaton_bib/person.rb +131 -0
- data/lib/relaton_bib/series.rb +96 -0
- data/lib/relaton_bib/typed_title_string.rb +41 -0
- data/lib/relaton_bib/typed_uri.rb +20 -0
- data/lib/relaton_bib/validity.rb +31 -0
- data/lib/relaton_bib/version.rb +3 -0
- data/lib/relaton_bib/xml_parser.rb +289 -0
- data/relaton-bib.gemspec +34 -0
- metadata +192 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module RelatonBib
|
2
|
+
# class SpecificLocalityType
|
3
|
+
# SECTION = 'section'
|
4
|
+
# CLAUSE = 'clause'
|
5
|
+
# PART = 'part'
|
6
|
+
# PARAGRAPH = 'paragraph'
|
7
|
+
# CHAPTER = 'chapter'
|
8
|
+
# PAGE = 'page'
|
9
|
+
# WHOLE = 'whole'
|
10
|
+
# TABLE = 'table'
|
11
|
+
# ANNEX = 'annex'
|
12
|
+
# FIGURE = 'figure'
|
13
|
+
# NOTE = 'note'
|
14
|
+
# EXAMPLE = 'example'
|
15
|
+
# # generic String is allowed
|
16
|
+
# end
|
17
|
+
|
18
|
+
# Bibliographic item locality.
|
19
|
+
class BibItemLocality
|
20
|
+
# @return [RelatonBib::SpecificLocalityType]
|
21
|
+
attr_reader :type
|
22
|
+
|
23
|
+
# @return [RelatonBib::LocalizedString]
|
24
|
+
attr_reader :reference_from
|
25
|
+
|
26
|
+
# @return [RelatonBib::LocalizedString]
|
27
|
+
attr_reader :reference_to
|
28
|
+
|
29
|
+
# @param type [String]
|
30
|
+
# @param referenceFrom [String]
|
31
|
+
# @param referenceTo [String]
|
32
|
+
def initialize(type, reference_from, reference_to = nil)
|
33
|
+
@type = type
|
34
|
+
@reference_from = reference_from
|
35
|
+
@reference_to = reference_to
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param builder [Nokogiri::XML::Builder]
|
39
|
+
def to_xml(builder)
|
40
|
+
builder.locality(type: type) do
|
41
|
+
builder.referenceFrom reference_from # { reference_from.to_xml(builder) }
|
42
|
+
builder.referenceTo reference_to if reference_to
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
module RelatonBib
|
6
|
+
# Bibliographic date.
|
7
|
+
class BibliographicDate
|
8
|
+
TYPES = %w[published accessed created implemented obsoleted confirmed
|
9
|
+
updated issued].freeze
|
10
|
+
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :type
|
13
|
+
|
14
|
+
# @return [Time]
|
15
|
+
attr_reader :from
|
16
|
+
|
17
|
+
# @return [Time]
|
18
|
+
attr_reader :to
|
19
|
+
|
20
|
+
# @return [Time]
|
21
|
+
attr_reader :on
|
22
|
+
|
23
|
+
# @param type [String] "published", "accessed", "created", "activated"
|
24
|
+
# @param from [String]
|
25
|
+
# @param to [String]
|
26
|
+
def initialize(type:, on: nil, from: nil, to: nil)
|
27
|
+
raise ArgumentError, "expected :on or :form argument" unless on || from
|
28
|
+
|
29
|
+
raise ArgumentError, %{Type "#{type}" is ivalid.} unless TYPES.include?(type)
|
30
|
+
|
31
|
+
@type = type
|
32
|
+
@on = parse_date on
|
33
|
+
@from = parse_date from
|
34
|
+
@to = parse_date to
|
35
|
+
end
|
36
|
+
|
37
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
38
|
+
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
39
|
+
|
40
|
+
# @param builder [Nokogiri::XML::Builder]
|
41
|
+
# @return [Nokogiri::XML::Builder]
|
42
|
+
def to_xml(builder, **opts)
|
43
|
+
builder.date(type: type) do
|
44
|
+
if on
|
45
|
+
date = opts[:full_date] ? on.strftime("%Y-%m") : on.year
|
46
|
+
builder.on(opts[:no_year] ? "--" : date)
|
47
|
+
elsif from
|
48
|
+
if opts[:full_date]
|
49
|
+
date_form = from.strftime("%Y-%m")
|
50
|
+
date_to = to.strftime("%Y-%m") if to
|
51
|
+
else
|
52
|
+
date_form = from.year
|
53
|
+
date_to = to.year if to
|
54
|
+
end
|
55
|
+
builder.from(opts[:no_year] ? "--" : date_form)
|
56
|
+
builder.to date_to if to
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
61
|
+
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# @params date [String] 'yyyy' or 'yyyy-mm'
|
66
|
+
def parse_date(date)
|
67
|
+
return unless date
|
68
|
+
|
69
|
+
if date =~ /^\d{4}$/
|
70
|
+
Time.strptime date, "%Y"
|
71
|
+
else
|
72
|
+
Time.strptime date, "%Y-%m"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,343 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "relaton_bib/typed_uri"
|
4
|
+
require "relaton_bib/document_identifier"
|
5
|
+
require "relaton_bib/copyright_association"
|
6
|
+
require "relaton_bib/formatted_string"
|
7
|
+
require "relaton_bib/contribution_info"
|
8
|
+
require "relaton_bib/bibliographic_date"
|
9
|
+
require "relaton_bib/series"
|
10
|
+
require "relaton_bib/document_status"
|
11
|
+
require "relaton_bib/organization"
|
12
|
+
require "relaton_bib/document_relation_collection"
|
13
|
+
require "relaton_bib/typed_title_string"
|
14
|
+
require "relaton_bib/formatted_ref"
|
15
|
+
require "relaton_bib/medium"
|
16
|
+
require "relaton_bib/classification"
|
17
|
+
require "relaton_bib/validity"
|
18
|
+
require "relaton_bib/document_relation"
|
19
|
+
require "relaton_bib/bib_item_locality"
|
20
|
+
require "relaton_bib/xml_parser"
|
21
|
+
|
22
|
+
|
23
|
+
module RelatonBib
|
24
|
+
# module BibItemType
|
25
|
+
# ARTICLE = 'article'
|
26
|
+
# BOOK = 'book'
|
27
|
+
# BOOKLET = 'booklet'
|
28
|
+
# CONFERENCE = 'conference'
|
29
|
+
# MANUAL = 'manual'
|
30
|
+
# PROCEEDINGS = 'proceedings'
|
31
|
+
# PRESENTATION = 'presentation'
|
32
|
+
# THESIS = 'thesis'
|
33
|
+
# TECHREPORT = 'techreport'
|
34
|
+
# STANDARD = 'standard'
|
35
|
+
# UNPUBLISHED = 'unpublished'
|
36
|
+
# end
|
37
|
+
|
38
|
+
# Bibliographic item
|
39
|
+
class BibliographicItem
|
40
|
+
class Version
|
41
|
+
# @return [String]
|
42
|
+
attr_reader :revision_date
|
43
|
+
|
44
|
+
# @return [Array<String>]
|
45
|
+
attr_reader :draft
|
46
|
+
|
47
|
+
# @oaram revision_date [String]
|
48
|
+
# @param draft [Array<String>]
|
49
|
+
def initialize(revision_date = nil, draft = [])
|
50
|
+
@revision_date = revision_date
|
51
|
+
@draft = draft
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param builder [Nokogiri::XML::Builder]
|
55
|
+
def to_xml(builder)
|
56
|
+
builder.version do
|
57
|
+
builder.revision_date revision_date if revision_date
|
58
|
+
draft.each { |d| builder.draft d }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
TYPES = %W[article book booklet conference manual proceedings presentation
|
64
|
+
thesis techreport standard unpublished map electronic\sresource
|
65
|
+
audiovisual film video broadcast graphic_work music patent
|
66
|
+
inbook incollection inproceedings journal].freeze
|
67
|
+
|
68
|
+
# @return [String]
|
69
|
+
attr_reader :id
|
70
|
+
|
71
|
+
# @return [Array<RelatonBib::TypedTitleString>]
|
72
|
+
attr_reader :title
|
73
|
+
|
74
|
+
# @return [Array<RelatonBib::TypedUri>]
|
75
|
+
attr_reader :link
|
76
|
+
|
77
|
+
# @return [String]
|
78
|
+
attr_reader :type
|
79
|
+
|
80
|
+
# @return [Array<RelatonBib::DocumentIdentifier>]
|
81
|
+
attr_reader :docidentifier
|
82
|
+
|
83
|
+
# @return [String] docnumber
|
84
|
+
attr_reader :docnumber
|
85
|
+
|
86
|
+
# @return [Array<RelatonBib::BibliographicDate>]
|
87
|
+
attr_reader :dates
|
88
|
+
|
89
|
+
# @return [Array<RelatonBib::ContributionInfo>]
|
90
|
+
attr_reader :contributors
|
91
|
+
|
92
|
+
# @return [String, NillClass]
|
93
|
+
attr_reader :edition
|
94
|
+
|
95
|
+
# @return [RelatonBib::BibliongraphicItem::Version]
|
96
|
+
attr_reader :version
|
97
|
+
|
98
|
+
# @return [Array<RelatonBib::FormattedString>, NilClass]
|
99
|
+
attr_reader :biblionote
|
100
|
+
|
101
|
+
# @return [Array<String>] language Iso639 code
|
102
|
+
attr_reader :language
|
103
|
+
|
104
|
+
# @return [Array<String>] script Iso15924 code
|
105
|
+
attr_reader :script
|
106
|
+
|
107
|
+
# @return [RelatonBib::FormattedRef]
|
108
|
+
attr_reader :formattedref
|
109
|
+
|
110
|
+
# @!attribute [r] abstract
|
111
|
+
# @return [Array<RelatonBib::FormattedString>]
|
112
|
+
|
113
|
+
# @return [RelatonBib::DocumentStatus]
|
114
|
+
attr_reader :status
|
115
|
+
|
116
|
+
# @return [RelatonBib::CopyrightAssociation]
|
117
|
+
attr_reader :copyright
|
118
|
+
|
119
|
+
# @return [RelatonBib::DocRelationCollection]
|
120
|
+
attr_reader :relations
|
121
|
+
|
122
|
+
# @return [Array<RelatonBib::Series>]
|
123
|
+
attr_reader :series
|
124
|
+
|
125
|
+
# @return [RelatonBib::Medium, NilClass]
|
126
|
+
attr_reader :medium
|
127
|
+
|
128
|
+
# @return [Array<String>]
|
129
|
+
attr_reader :place
|
130
|
+
|
131
|
+
# @return [Array<RelatonBib::BibItemLocality>]
|
132
|
+
attr_reader :extent
|
133
|
+
|
134
|
+
# @return [Array<Strig>]
|
135
|
+
attr_reader :accesslocation
|
136
|
+
|
137
|
+
# @return [Relaton::Classification, NilClass]
|
138
|
+
attr_reader :classification
|
139
|
+
|
140
|
+
# @return [RelatonBib:Validity, NilClass]
|
141
|
+
attr_reader :validity
|
142
|
+
|
143
|
+
# @return [Date]
|
144
|
+
attr_reader :fetched
|
145
|
+
|
146
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
147
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
148
|
+
|
149
|
+
# @param id [String, NilClass]
|
150
|
+
# @param title [Array<RelatonBib::TypedTitleString>]
|
151
|
+
# @param formattedref [RelatonBib::FormattedRef, NilClass]
|
152
|
+
# @param type [String, NilClass]
|
153
|
+
# @param docid [Array<RelatonBib::DocumentIdentifier>]
|
154
|
+
# @param docnumber [String, NilClass]
|
155
|
+
# @param language [Arra<String>]
|
156
|
+
# @param script [Array<String>]
|
157
|
+
# @param docstatus [RelatonBib::DocumentStatus, NilClass]
|
158
|
+
# @param edition [String, NilClass]
|
159
|
+
# @param version [RelatonBib::BibliographicItem::Version, NilClass]
|
160
|
+
# @param biblionote [Array<RelatonBib::FormattedStrong>]
|
161
|
+
# @param series [Array<RelatonBib::Series>]
|
162
|
+
# @param medium [RelatonBib::Medium, NilClas]
|
163
|
+
# @param place [Array<String>]
|
164
|
+
# @param extent [Array<Relaton::BibItemLocality>]
|
165
|
+
# @param accesslocation [Array<String>]
|
166
|
+
# @param classification [RelatonBib::Classification, NilClass]
|
167
|
+
# @param validity [RelatonBib:Validity, NilClass]
|
168
|
+
# @param fetched [Date, NilClass] default nil
|
169
|
+
#
|
170
|
+
# @param dates [Array<Hash>]
|
171
|
+
# @option dates [String] :type
|
172
|
+
# @option dates [String] :from
|
173
|
+
# @option dates [String] :to
|
174
|
+
#
|
175
|
+
# @param contributors [Array<Hash>]
|
176
|
+
# @option contributors [String] :type
|
177
|
+
# @option contributors [String] :from
|
178
|
+
# @option contributirs [String] :to
|
179
|
+
# @option contributors [String] :abbreviation
|
180
|
+
# @option contributors [Array<String>] :roles
|
181
|
+
#
|
182
|
+
# @param abstract [Array<Hash>]
|
183
|
+
# @option abstract [String] :content
|
184
|
+
# @option abstract [String] :language
|
185
|
+
# @option abstract [String] :script
|
186
|
+
# @option abstract [String] :type
|
187
|
+
#
|
188
|
+
# @param relations [Array<Hash>]
|
189
|
+
# @option relations [String] :type
|
190
|
+
# @option relations [RelatonBib::BibliographicItem] :bibitem
|
191
|
+
# @option relations [Array<RelatonBib::BibItemLocality>] :bib_locality
|
192
|
+
def initialize(**args)
|
193
|
+
if args[:type] && !TYPES.include?(args[:type])
|
194
|
+
raise ArgumentError, %{Type "#{args[:type]}" is invalid.}
|
195
|
+
end
|
196
|
+
|
197
|
+
@title = (args[:titles] || []).map do |t|
|
198
|
+
t.is_a?(Hash) ? TypedTitleString.new(t) : t
|
199
|
+
end
|
200
|
+
|
201
|
+
@dates = (args[:dates] || []).map do |d|
|
202
|
+
d.is_a?(Hash) ? BibliographicDate.new(d) : d
|
203
|
+
end
|
204
|
+
|
205
|
+
@contributors = (args[:contributors] || []).map do |c|
|
206
|
+
if c.is_a? Hash
|
207
|
+
e = c[:entity].is_a?(Hash) ? Organization.new(c[:entity]) : c[:entity]
|
208
|
+
ContributionInfo.new(entity: e, role: c[:roles])
|
209
|
+
else c
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
@abstract = (args[:abstract] || []).map do |a|
|
214
|
+
a.is_a?(Hash) ? FormattedString.new(a) : a
|
215
|
+
end
|
216
|
+
|
217
|
+
if args[:copyright]
|
218
|
+
@copyright = if args[:copyright].is_a?(Hash)
|
219
|
+
CopyrightAssociation.new args[:copyright]
|
220
|
+
else args[:copyright]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
@id = args[:id]
|
225
|
+
@formattedref = args[:formattedref] if title.empty?
|
226
|
+
@type = args[:type]
|
227
|
+
@docidentifier = args[:docid] || []
|
228
|
+
@docnumber = args[:docnumber]
|
229
|
+
@edition = args[:edition]
|
230
|
+
@version = args[:version]
|
231
|
+
@biblionote = args.fetch :biblionote, []
|
232
|
+
@language = args.fetch :language, []
|
233
|
+
@script = args.fetch :script, []
|
234
|
+
@status = args[:docstatus]
|
235
|
+
@relations = DocRelationCollection.new(args[:relations] || [])
|
236
|
+
@link = args.fetch(:link, []).map { |s| s.is_a?(Hash) ? TypedUri.new(s) : s }
|
237
|
+
@series = args[:series]
|
238
|
+
@medium = args[:medium]
|
239
|
+
@place = args.fetch(:place, [])
|
240
|
+
@extent = args[:extent] || []
|
241
|
+
@accesslocation = args.fetch :accesslocation, []
|
242
|
+
@classification = args[:classification]
|
243
|
+
@validity = args[:validity]
|
244
|
+
@fetched = args.fetch :fetched, nil # , Date.today # we should pass the fetched arg from scrappers
|
245
|
+
end
|
246
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
247
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
248
|
+
|
249
|
+
# @param lang [String] language code Iso639
|
250
|
+
# @return [RelatonBib::FormattedString, Array<RelatonBib::FormattedString>]
|
251
|
+
def abstract(lang: nil)
|
252
|
+
if lang
|
253
|
+
@abstract.detect { |a| a.language.include? lang }
|
254
|
+
else
|
255
|
+
@abstract
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def makeid(id, attribute)
|
260
|
+
return nil if attribute && !@id_attribute
|
261
|
+
|
262
|
+
id ||= @docidentifier.reject { |i| i.type == "DOI" }[0]
|
263
|
+
# contribs = publishers.map { |p| p&.entity&.abbreviation }.join '/'
|
264
|
+
# idstr = "#{contribs}#{delim}#{id.project_number}"
|
265
|
+
# idstr = id.project_number.to_s
|
266
|
+
idstr = id.id.gsub(/:/, "-")
|
267
|
+
# if id.part_number&.size&.positive? then idstr += "-#{id.part_number}"
|
268
|
+
idstr.strip
|
269
|
+
end
|
270
|
+
|
271
|
+
# @return [String]
|
272
|
+
def shortref(identifier, **opts)
|
273
|
+
pubdate = dates.select { |d| d.type == "published" }
|
274
|
+
year = if opts[:no_year] || pubdate.empty? then ""
|
275
|
+
else ":" + pubdate&.first&.on&.year.to_s
|
276
|
+
end
|
277
|
+
year += ": All Parts" if opts[:all_parts] || @all_parts
|
278
|
+
|
279
|
+
"#{makeid(identifier, false)}#{year}"
|
280
|
+
end
|
281
|
+
|
282
|
+
# @param builder [Nokogiri::XML::Builder, NillClass] (nil)
|
283
|
+
# @return [String]
|
284
|
+
def to_xml(builder = nil, root = "bibitem", &block)
|
285
|
+
if builder
|
286
|
+
render_xml builder, root, &block
|
287
|
+
else
|
288
|
+
Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
289
|
+
render_xml xml, root, &block
|
290
|
+
end.doc.root.to_xml
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
private
|
295
|
+
|
296
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
297
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
298
|
+
|
299
|
+
# @param builder [Nokogiri::XML::Builder]
|
300
|
+
# @return [String]
|
301
|
+
def render_xml(builder, root)
|
302
|
+
xml = builder.send(root) do
|
303
|
+
builder.fetched fetched if fetched
|
304
|
+
title.each { |t| builder.title { t.to_xml builder } }
|
305
|
+
formattedref.to_xml builder if formattedref
|
306
|
+
link.each { |s| s.to_xml builder }
|
307
|
+
docidentifier.each { |di| di.to_xml builder }
|
308
|
+
builder.docnumber docnumber if docnumber
|
309
|
+
dates.each { |d| d.to_xml builder, full_date: true }
|
310
|
+
contributors.each do |c|
|
311
|
+
builder.contributor do
|
312
|
+
c.role.each { |r| r.to_xml builder }
|
313
|
+
c.to_xml builder
|
314
|
+
end
|
315
|
+
end
|
316
|
+
builder.edition edition if edition
|
317
|
+
version.to_xml builder if version
|
318
|
+
biblionote.each { |n| builder.note { n.to_xml builder } }
|
319
|
+
language.each { |l| builder.language l }
|
320
|
+
script.each { |s| builder.script s }
|
321
|
+
abstract.each { |a| builder.abstract { a.to_xml(builder) } }
|
322
|
+
status.to_xml builder if status
|
323
|
+
copyright.to_xml builder if copyright
|
324
|
+
relations.each { |r| r.to_xml builder }
|
325
|
+
series.each { |s| s.to_xml builder } if series
|
326
|
+
medium.to_xml builder if medium
|
327
|
+
place.each { |pl| builder.place pl }
|
328
|
+
extent.each { |e| e.to_xml builder }
|
329
|
+
accesslocation.each { |al| builder.accesslocation al }
|
330
|
+
classification.to_xml builder if classification
|
331
|
+
validity.to_xml builder if validity
|
332
|
+
if block_given?
|
333
|
+
yield builder
|
334
|
+
end
|
335
|
+
end
|
336
|
+
xml[:id] = id if id
|
337
|
+
xml[:type] = type if type
|
338
|
+
xml
|
339
|
+
end
|
340
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
341
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
342
|
+
end
|
343
|
+
end
|