relaton-bib 1.20.8 → 2.0.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/.gitignore +3 -1
- data/.rubocop.yml +1 -1
- data/CLAUDE.md +96 -0
- data/Gemfile +1 -4
- data/README.adoc +195 -154
- data/bin/console +1 -1
- data/grammars/basicdoc.rng +1572 -671
- data/grammars/biblio-standoc.rng +107 -46
- data/grammars/biblio.rng +1012 -377
- data/grammars/versions.json +26 -26
- data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
- data/lib/relaton/bib/converter/asciibib.rb +13 -0
- data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
- data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
- data/lib/relaton/bib/converter/bibtex.rb +23 -0
- data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +383 -0
- data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
- data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +305 -0
- data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
- data/lib/relaton/bib/converter/bibxml.rb +51 -0
- data/lib/relaton/bib/hash_parser_v1.rb +754 -0
- data/lib/relaton/bib/item_data.rb +229 -0
- data/lib/relaton/bib/model/abstract.rb +16 -0
- data/lib/relaton/bib/model/address.rb +22 -0
- data/lib/relaton/bib/model/affiliation.rb +16 -0
- data/lib/relaton/bib/model/bibdata.rb +24 -0
- data/lib/relaton/bib/model/bibitem.rb +23 -0
- data/lib/relaton/bib/model/contact.rb +18 -0
- data/lib/relaton/bib/model/contribution_info.rb +16 -0
- data/lib/relaton/bib/model/contributor.rb +71 -0
- data/lib/relaton/bib/model/copyright.rb +27 -0
- data/lib/relaton/bib/model/date.rb +31 -0
- data/lib/relaton/bib/model/depiction.rb +16 -0
- data/lib/relaton/bib/model/docidentifier.rb +33 -0
- data/lib/relaton/bib/model/doctype.rb +14 -0
- data/lib/relaton/bib/model/edition.rb +14 -0
- data/lib/relaton/bib/model/ext.rb +26 -0
- data/lib/relaton/bib/model/extent.rb +16 -0
- data/lib/relaton/bib/model/formattedref.rb +43 -0
- data/lib/relaton/bib/model/full_name_type.rb +64 -0
- data/lib/relaton/bib/model/fullname.rb +11 -0
- data/lib/relaton/bib/model/ics.rb +23 -0
- data/lib/relaton/bib/model/image.rb +28 -0
- data/lib/relaton/bib/model/item.rb +137 -0
- data/lib/relaton/bib/model/item_base.rb +27 -0
- data/lib/relaton/bib/model/keyword.rb +30 -0
- data/lib/relaton/bib/model/locality.rb +18 -0
- data/lib/relaton/bib/model/locality_stack.rb +14 -0
- data/lib/relaton/bib/model/localized_string.rb +57 -0
- data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
- data/lib/relaton/bib/model/logo.rb +14 -0
- data/lib/relaton/bib/model/medium.rb +22 -0
- data/lib/relaton/bib/model/note.rb +16 -0
- data/lib/relaton/bib/model/organization.rb +13 -0
- data/lib/relaton/bib/model/organization_type.rb +42 -0
- data/lib/relaton/bib/model/person.rb +36 -0
- data/lib/relaton/bib/model/phone.rb +14 -0
- data/lib/relaton/bib/model/place.rb +33 -0
- data/lib/relaton/bib/model/price.rb +14 -0
- data/lib/relaton/bib/model/relation.rb +43 -0
- data/lib/relaton/bib/model/series.rb +34 -0
- data/lib/relaton/bib/model/size.rb +23 -0
- data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
- data/lib/relaton/bib/model/status.rb +27 -0
- data/lib/relaton/bib/model/structured_identifier.rb +48 -0
- data/lib/relaton/bib/model/subdivision.rb +16 -0
- data/lib/relaton/bib/model/title.rb +56 -0
- data/lib/relaton/bib/model/type/string_date.rb +48 -0
- data/lib/relaton/bib/model/uri.rb +18 -0
- data/lib/relaton/bib/model/validity.rb +16 -0
- data/lib/relaton/bib/model/version.rb +14 -0
- data/lib/relaton/bib/namespace_helper.rb +21 -0
- data/lib/relaton/bib/util.rb +18 -0
- data/lib/relaton/bib/version.rb +5 -0
- data/lib/relaton/bib.rb +45 -0
- data/relaton-bib.gemspec +11 -8
- metadata +125 -67
- data/lib/relaton_bib/bib_item_locality.rb +0 -175
- data/lib/relaton_bib/biblio_note.rb +0 -72
- data/lib/relaton_bib/biblio_version.rb +0 -46
- data/lib/relaton_bib/bibliographic_date.rb +0 -119
- data/lib/relaton_bib/bibliographic_item.rb +0 -668
- data/lib/relaton_bib/bibliographic_size.rb +0 -103
- data/lib/relaton_bib/bibtex_parser.rb +0 -246
- data/lib/relaton_bib/bibxml_parser.rb +0 -422
- data/lib/relaton_bib/classification.rb +0 -40
- data/lib/relaton_bib/config.rb +0 -16
- data/lib/relaton_bib/contribution_info.rb +0 -117
- data/lib/relaton_bib/contributor.rb +0 -277
- data/lib/relaton_bib/copyright_association.rb +0 -79
- data/lib/relaton_bib/deep_dup.rb +0 -30
- data/lib/relaton_bib/document_identifier.rb +0 -118
- data/lib/relaton_bib/document_relation.rb +0 -95
- data/lib/relaton_bib/document_relation_collection.rb +0 -57
- data/lib/relaton_bib/document_status.rb +0 -92
- data/lib/relaton_bib/document_type.rb +0 -52
- data/lib/relaton_bib/edition.rb +0 -55
- data/lib/relaton_bib/editorial_group.rb +0 -41
- data/lib/relaton_bib/extent.rb +0 -39
- data/lib/relaton_bib/forename.rb +0 -65
- data/lib/relaton_bib/formatted_ref.rb +0 -17
- data/lib/relaton_bib/formatted_string.rb +0 -133
- data/lib/relaton_bib/full_name.rb +0 -108
- data/lib/relaton_bib/hash_converter.rb +0 -568
- data/lib/relaton_bib/hit.rb +0 -52
- data/lib/relaton_bib/hit_collection.rb +0 -105
- data/lib/relaton_bib/ics.rb +0 -42
- data/lib/relaton_bib/image.rb +0 -95
- data/lib/relaton_bib/localized_string.rb +0 -149
- data/lib/relaton_bib/medium.rb +0 -76
- data/lib/relaton_bib/organization.rb +0 -165
- data/lib/relaton_bib/person.rb +0 -129
- data/lib/relaton_bib/place.rb +0 -203
- data/lib/relaton_bib/renderer/bibtex_builder.rb +0 -312
- data/lib/relaton_bib/renderer/bibxml.rb +0 -296
- data/lib/relaton_bib/series.rb +0 -119
- data/lib/relaton_bib/structured_identifier.rb +0 -173
- data/lib/relaton_bib/technical_committee.rb +0 -34
- data/lib/relaton_bib/typed_title_string.rb +0 -191
- data/lib/relaton_bib/typed_uri.rb +0 -57
- data/lib/relaton_bib/util.rb +0 -16
- data/lib/relaton_bib/validity.rb +0 -52
- data/lib/relaton_bib/version.rb +0 -3
- data/lib/relaton_bib/workers_pool.rb +0 -43
- data/lib/relaton_bib/workgroup.rb +0 -58
- data/lib/relaton_bib/xml_parser.rb +0 -718
- data/lib/relaton_bib.rb +0 -111
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
module RelatonBib
|
|
2
|
-
module BibXMLParser
|
|
3
|
-
# SeriesInfo what should be saved as docidentifiers in the Relaton model.
|
|
4
|
-
SERIESINFONAMES = ["DOI"].freeze
|
|
5
|
-
RFCPREFIXES = %w[RFC BCP FYI STD].freeze
|
|
6
|
-
|
|
7
|
-
FLAVOR = nil
|
|
8
|
-
|
|
9
|
-
ORGNAMES = {
|
|
10
|
-
"IEEE" => "Institute of Electrical and Electronics Engineers",
|
|
11
|
-
"W3C" => "World Wide Web Consortium",
|
|
12
|
-
"3GPP" => "3rd Generation Partnership Project",
|
|
13
|
-
}.freeze
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
# Parse BibXML content
|
|
17
|
-
#
|
|
18
|
-
# @param [String] bibxml content
|
|
19
|
-
# @param [String, nil] url source URL
|
|
20
|
-
# @param [Boolean] is_relation true if the content is relation item
|
|
21
|
-
# @param [String, nil] ver version
|
|
22
|
-
#
|
|
23
|
-
# @return [<Type>] <description>
|
|
24
|
-
#
|
|
25
|
-
def parse(bibxml, url: nil, is_relation: false, ver: nil)
|
|
26
|
-
doc = Nokogiri::XML bibxml
|
|
27
|
-
fetch_rfc doc.at("/referencegroup", "/reference"), url: url, is_relation: is_relation, ver: ver
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# @param reference [Nokogiri::XML::Element, nil]
|
|
31
|
-
# @param is_relation [Boolean] don't add fetched date for relation if true
|
|
32
|
-
# @param url [String, nil]
|
|
33
|
-
# @param ver [String, nil] Internet Draft version
|
|
34
|
-
# @return [RelatonBib::BibliographicItem]
|
|
35
|
-
def fetch_rfc(reference, is_relation: false, url: nil, ver: nil) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
36
|
-
return unless reference
|
|
37
|
-
|
|
38
|
-
hash = {
|
|
39
|
-
is_relation: is_relation,
|
|
40
|
-
docnumber: docnumber(reference),
|
|
41
|
-
type: "standard",
|
|
42
|
-
docid: docids(reference, ver),
|
|
43
|
-
status: status(reference),
|
|
44
|
-
language: [language(reference)],
|
|
45
|
-
script: ["Latn"],
|
|
46
|
-
link: link(reference, url, ver),
|
|
47
|
-
title: titles(reference),
|
|
48
|
-
formattedref: formattedref(reference),
|
|
49
|
-
abstract: abstracts(reference),
|
|
50
|
-
contributor: contributors(reference),
|
|
51
|
-
relation: relations(reference),
|
|
52
|
-
date: dates(reference),
|
|
53
|
-
editorialgroup: editorialgroup(reference),
|
|
54
|
-
series: series(reference),
|
|
55
|
-
keyword: reference.xpath("front/keyword").map(&:text),
|
|
56
|
-
doctype: doctype(reference[:anchor]),
|
|
57
|
-
}
|
|
58
|
-
# hash[:fetched] = Date.today.to_s unless is_relation
|
|
59
|
-
bib_item(**hash)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def docnumber(reference)
|
|
63
|
-
reference[:anchor]&.sub(/^\w+\./, "")
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# @param attrs [Hash]
|
|
67
|
-
# @return [RelatonBib::BibliographicItem]
|
|
68
|
-
def bib_item(**attrs)
|
|
69
|
-
# attrs[:place] = ["Fremont, CA"]
|
|
70
|
-
BibliographicItem.new(**attrs)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# @param reference [Nokogiri::XML::Element]
|
|
74
|
-
# @return [String]
|
|
75
|
-
def language(reference)
|
|
76
|
-
reference[:lang] || "en"
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
#
|
|
80
|
-
# Extract document identifiers from reference
|
|
81
|
-
#
|
|
82
|
-
# @param reference [Nokogiri::XML::Element]
|
|
83
|
-
# @param ver [String, nil] Internet Draft version
|
|
84
|
-
#
|
|
85
|
-
# @return [Array<RelatonBib::DocumentIdentifier>]
|
|
86
|
-
#
|
|
87
|
-
def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
|
|
88
|
-
ret = []
|
|
89
|
-
si = reference.at("./seriesInfo[@name='Internet-Draft']",
|
|
90
|
-
"./front/seriesInfo[@name='Internet-Draft']")
|
|
91
|
-
if si
|
|
92
|
-
id = si[:value]
|
|
93
|
-
id.sub!(/(?<=-)\d{2}$/, ver) if ver
|
|
94
|
-
ret << DocumentIdentifier.new(type: "Internet-Draft", id: id, primary: true)
|
|
95
|
-
else
|
|
96
|
-
id = reference[:anchor] || reference[:docName] || reference[:number]
|
|
97
|
-
ret << create_docid(id, ver) if id
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
%w[anchor docName number].each do |atr|
|
|
101
|
-
if reference[atr]
|
|
102
|
-
pref, num = id_to_pref_num reference[atr]
|
|
103
|
-
atrid = if atr == "anchor" && RFCPREFIXES.include?(pref)
|
|
104
|
-
"#{pref}#{num.sub(/^-?0+/, '')}"
|
|
105
|
-
else
|
|
106
|
-
reference[atr]
|
|
107
|
-
end
|
|
108
|
-
type = pubid_type id
|
|
109
|
-
ret << DocumentIdentifier.new(id: atrid, type: type, scope: atr)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
ret + reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
|
|
114
|
-
next unless SERIESINFONAMES.include? si[:name]
|
|
115
|
-
|
|
116
|
-
id = si[:value]
|
|
117
|
-
# id.sub!(/(?<=-)\d{2}$/, ver) if ver && si[:name] == "Internet-Draft"
|
|
118
|
-
DocumentIdentifier.new(id: id, type: si[:name])
|
|
119
|
-
end.compact
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def create_docid(id, ver) # rubocop:disable Metrics/MethodLength
|
|
123
|
-
pref, num = id_to_pref_num(id)
|
|
124
|
-
if RFCPREFIXES.include?(pref)
|
|
125
|
-
pid = "#{pref} #{num.sub(/^-?0+/, '')}"
|
|
126
|
-
type = pubid_type id
|
|
127
|
-
elsif %w[I-D draft].include?(pref)
|
|
128
|
-
pid = "draft-#{num}"
|
|
129
|
-
pid.sub!(/(?<=-)\d{2}$/, ver) if ver
|
|
130
|
-
type = "Internet-Draft"
|
|
131
|
-
else
|
|
132
|
-
pid = pref ? "#{pref} #{num}" : id
|
|
133
|
-
type = pubid_type id
|
|
134
|
-
end
|
|
135
|
-
DocumentIdentifier.new(type: type, id: pid, primary: true)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def id_to_pref_num(id)
|
|
139
|
-
tn = /^(?<pref>I-D|draft|3GPP|W3C|[A-Z]{2,})[._-]?(?<num>.+)/.match id
|
|
140
|
-
tn && tn.to_a[1..2]
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
# Extract document identifier type from identifier
|
|
145
|
-
#
|
|
146
|
-
# @param [String] id identifier
|
|
147
|
-
#
|
|
148
|
-
# @return [String]
|
|
149
|
-
#
|
|
150
|
-
def pubid_type(id)
|
|
151
|
-
id_to_pref_num(id)&.first
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
#
|
|
155
|
-
# extract status
|
|
156
|
-
# @param reference [Nokogiri::XML::Element]
|
|
157
|
-
#
|
|
158
|
-
# @return [RelatonBib::DocumentStatus]
|
|
159
|
-
#
|
|
160
|
-
def status(reference)
|
|
161
|
-
st = reference.at("./seriesinfo[@status]")
|
|
162
|
-
DocumentStatus.new(stage: st[:status]) if st
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# @param reference [Nokogiri::XML::Element]
|
|
166
|
-
# @param url [String]
|
|
167
|
-
# @param ver [String, nil] Internet Draft version
|
|
168
|
-
# @return [Array<Hash>]
|
|
169
|
-
def link(reference, url, ver)
|
|
170
|
-
l = []
|
|
171
|
-
l << { type: "xml", content: url } if url
|
|
172
|
-
l << { type: "src", content: reference[:target] } if reference[:target]
|
|
173
|
-
if /^I-D/.match? reference[:anchor]
|
|
174
|
-
reference.xpath("format").each do |f|
|
|
175
|
-
c = ver ? f[:target].sub(/(?<=-)\d{2}(?=\.)/, ver) : f[:target]
|
|
176
|
-
l << { type: f[:type], content: c }
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
l
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
# @param reference [Nokogiri::XML::Element]
|
|
183
|
-
# @return [Array<Hash>]
|
|
184
|
-
def titles(reference)
|
|
185
|
-
reference.xpath("./front/title").map do |title|
|
|
186
|
-
{ content: title.text, language: language(reference), script: "Latn" }
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# @param reference [Nokogiri::XML::Element]
|
|
191
|
-
# @return [RelatonBib::FormattedRef, nil]
|
|
192
|
-
def formattedref(reference)
|
|
193
|
-
return if reference.at "./front/title"
|
|
194
|
-
|
|
195
|
-
cont = (reference[:anchor] || reference[:docName] || reference[:number])
|
|
196
|
-
if cont
|
|
197
|
-
FormattedRef.new(
|
|
198
|
-
content: cont, language: language(reference), script: "Latn",
|
|
199
|
-
)
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# @param reference [Nokogiri::XML::Element]
|
|
204
|
-
# @return [Array<RelatonBib::FormattedString>]
|
|
205
|
-
def abstracts(ref)
|
|
206
|
-
ref.xpath("./front/abstract").map do |a|
|
|
207
|
-
c = a.inner_html.gsub(/\s*(<\/?)t(>)\s*/, '\1p\2')
|
|
208
|
-
.gsub(/[\t\n]/, " ").squeeze " "
|
|
209
|
-
FormattedString.new(content: c, language: language(ref), script: "Latn",
|
|
210
|
-
format: "text/html")
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
# @param reference [Nokogiri::XML::Element]
|
|
215
|
-
# @return [Array<Hash>]
|
|
216
|
-
def contributors(reference)
|
|
217
|
-
lang = language reference
|
|
218
|
-
reference.xpath("./front/author").map do |contrib|
|
|
219
|
-
entity = person(contrib, lang) || organization(contrib)
|
|
220
|
-
next unless entity
|
|
221
|
-
|
|
222
|
-
{ entity: entity, role: [contributor_role(contrib)] }
|
|
223
|
-
end.compact
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
# @param author [Nokogiri::XML::Element]
|
|
227
|
-
# @param lang [String]
|
|
228
|
-
# @return [RelatonBib::Person, nil]
|
|
229
|
-
def person(author, lang)
|
|
230
|
-
return unless author[:fullname] || author[:surname]
|
|
231
|
-
|
|
232
|
-
name = full_name(author[:fullname], author[:surname], author[:initials], lang)
|
|
233
|
-
Person.new(name: name, affiliation: affiliation(author),
|
|
234
|
-
contact: contacts(author.at("./address")))
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# @param contrib [Nokogiri::XML::Element]
|
|
238
|
-
# @return [RelatonBib::Organization, nil]
|
|
239
|
-
def organization(contrib)
|
|
240
|
-
org = contrib.at("./organization")
|
|
241
|
-
return unless org
|
|
242
|
-
|
|
243
|
-
orgname = org.text.strip
|
|
244
|
-
return if orgname.empty?
|
|
245
|
-
|
|
246
|
-
name = ORGNAMES[orgname] || orgname
|
|
247
|
-
new_org name, org[:abbrev]
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
# @param fname [String] full name
|
|
251
|
-
# @param sname [String] surname
|
|
252
|
-
# @param inits [String] initials
|
|
253
|
-
# @param lang [String] language
|
|
254
|
-
# @return [RelatonBib::FullName]
|
|
255
|
-
def full_name(fname, sname, inits, lang)
|
|
256
|
-
initials = localized_string(inits, lang) if inits
|
|
257
|
-
FullName.new(
|
|
258
|
-
completename: localized_string(fname, lang), initials: initials,
|
|
259
|
-
forename: forename(inits, lang), surname: localized_string(sname, lang)
|
|
260
|
-
)
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
#
|
|
264
|
-
# Create forenames with initials
|
|
265
|
-
#
|
|
266
|
-
# @param [String] initials initials
|
|
267
|
-
# @param [String] lang language
|
|
268
|
-
#
|
|
269
|
-
# @return [Array<RelatonBib::Forename>] forenames
|
|
270
|
-
#
|
|
271
|
-
def forename(initials, lang = nil, script = nil)
|
|
272
|
-
return [] unless initials
|
|
273
|
-
|
|
274
|
-
initials.split(/\.-?\s?|\s/).map do |i|
|
|
275
|
-
Forename.new(initial: i, language: lang, script: script)
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
# @param author [Nokogiri::XML::Element]
|
|
280
|
-
# @return [Array<RelatonBib::Affiliation>]
|
|
281
|
-
def affiliation(author)
|
|
282
|
-
o = author.at("./organization")
|
|
283
|
-
return [] if o.nil? || o.text.empty?
|
|
284
|
-
|
|
285
|
-
org = new_org o.text, o[:abbrev]
|
|
286
|
-
[Affiliation.new(organization: org)]
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# @param name [String]
|
|
290
|
-
# @param abbr [String, nil]
|
|
291
|
-
# @return [RelatonBib::Organization]
|
|
292
|
-
def new_org(name, abbr = nil)
|
|
293
|
-
Organization.new name: name, abbreviation: abbr
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
# @param content [String, nil]
|
|
297
|
-
# @param lang [String, nil]
|
|
298
|
-
# @param script [String, nil]
|
|
299
|
-
# @return [RelatonBib::LocalizedString, nil]
|
|
300
|
-
def localized_string(content, lang, script = nil)
|
|
301
|
-
LocalizedString.new(content, lang, script) if content
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
# @param postal [Nokogiri::XML::Element]
|
|
305
|
-
# @return [Array<RelatonBib::Address, RelatonBib::Phone>]
|
|
306
|
-
def contacts(addr)
|
|
307
|
-
conts = []
|
|
308
|
-
return conts unless addr
|
|
309
|
-
|
|
310
|
-
postal = addr.at("./postal")
|
|
311
|
-
conts << address(postal) if postal&.at("./city") && postal&.at("./country")
|
|
312
|
-
add_contact(conts, "phone", addr.at("./phone"))
|
|
313
|
-
add_contact(conts, "email", addr.at("./email"))
|
|
314
|
-
add_contact(conts, "uri", addr.at("./uri"))
|
|
315
|
-
conts
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# @param postal [Nokogiri::XML::Element]
|
|
319
|
-
# @rerurn [RelatonBib::Address]
|
|
320
|
-
def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
|
|
321
|
-
street = [postal.at("./postalLine | ./street")&.text].compact
|
|
322
|
-
Address.new(
|
|
323
|
-
street: street,
|
|
324
|
-
city: postal.at("./city")&.text,
|
|
325
|
-
postcode: postal.at("./code")&.text,
|
|
326
|
-
country: postal.at("./country")&.text,
|
|
327
|
-
state: postal.at("./region")&.text,
|
|
328
|
-
)
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# @param conts [Array<RelatonBib::Address, RelatonBib::Contact>]
|
|
332
|
-
# @param type [String] allowed "phone", "email" or "uri"
|
|
333
|
-
# @param value [String]
|
|
334
|
-
def add_contact(conts, type, value)
|
|
335
|
-
conts << Contact.new(type: type, value: value.text) if value
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
# @param author [Nokogiri::XML::Document]
|
|
339
|
-
# @return [Hash]
|
|
340
|
-
def contributor_role(author)
|
|
341
|
-
{ type: author[:role] || "author" }
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
# @param reference [Nokogiri::XML::Element]
|
|
345
|
-
# @return [Hash]
|
|
346
|
-
def relations(reference)
|
|
347
|
-
reference.xpath("reference").map do |ref|
|
|
348
|
-
{ type: "includes", bibitem: fetch_rfc(ref, is_relation: true) }
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
#
|
|
353
|
-
# Extract date from reference.
|
|
354
|
-
#
|
|
355
|
-
# @param reference [Nokogiri::XML::Element]
|
|
356
|
-
# @return [Array<RelatonBib::BibliographicDate>] published data.
|
|
357
|
-
#
|
|
358
|
-
def dates(reference) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
|
359
|
-
date = reference.at "./front/date"
|
|
360
|
-
return [] if date.nil? || date[:year].nil? || date[:year].empty?
|
|
361
|
-
|
|
362
|
-
d = date[:year]
|
|
363
|
-
d += "-#{month(date[:month])}" if date[:month] && !date[:month].empty?
|
|
364
|
-
d += "-#{date[:day]}" if date[:day]
|
|
365
|
-
# date = Time.parse(d).strftime "%Y-%m-%d"
|
|
366
|
-
[BibliographicDate.new(type: "published", on: d)]
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
# @param reference [Nokogiri::XML::Element]
|
|
370
|
-
# @return [RelatonBib::EditorialGroup, nil]
|
|
371
|
-
def editorialgroup(reference)
|
|
372
|
-
tc = reference.xpath("./front/workgroup").map do |ed|
|
|
373
|
-
wg = WorkGroup.new name: ed.text
|
|
374
|
-
committee wg
|
|
375
|
-
end
|
|
376
|
-
EditorialGroup.new tc if tc.any?
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
# @param [RelatonBib::WorkGroup]
|
|
380
|
-
# @return [RelatonBib::TechnicalCommittee]
|
|
381
|
-
def committee(wgr)
|
|
382
|
-
TechnicalCommittee.new wgr
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def month(mon)
|
|
386
|
-
# return 1 if !mon || mon.empty?
|
|
387
|
-
return mon if /^\d+$/.match? mon
|
|
388
|
-
|
|
389
|
-
Date::MONTHNAMES.index { |m| m&.include? mon }.to_s.rjust 2, "0"
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
#
|
|
393
|
-
# Extract series form reference
|
|
394
|
-
# @param reference [Nokogiri::XML::Element]
|
|
395
|
-
#
|
|
396
|
-
# @return [Array<RelatonBib::Series>]
|
|
397
|
-
#
|
|
398
|
-
def series(reference)
|
|
399
|
-
reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
|
|
400
|
-
next if SERIESINFONAMES.include?(si[:name]) || si[:stream] || si[:status]
|
|
401
|
-
|
|
402
|
-
t = TypedTitleString.new(
|
|
403
|
-
content: si[:name], language: language(reference), script: "Latn",
|
|
404
|
-
)
|
|
405
|
-
Series.new(title: t, number: si[:value], type: "main")
|
|
406
|
-
end.compact
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
# @param anchor [String]
|
|
410
|
-
# @return [String]
|
|
411
|
-
def doctype(anchor)
|
|
412
|
-
type = case anchor
|
|
413
|
-
when /I-D/ then "internet-draft"
|
|
414
|
-
when /IEEE/ then "ieee"
|
|
415
|
-
else "rfc"
|
|
416
|
-
end
|
|
417
|
-
DocumentType.new type: type
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
extend BibXMLParser
|
|
421
|
-
end
|
|
422
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
module RelatonBib
|
|
2
|
-
class Classification
|
|
3
|
-
# @return [String, nil]
|
|
4
|
-
attr_reader :type
|
|
5
|
-
|
|
6
|
-
# @return [String]
|
|
7
|
-
attr_reader :value
|
|
8
|
-
|
|
9
|
-
# @param type [String, nil]
|
|
10
|
-
# @param value [String]
|
|
11
|
-
def initialize(type: nil, value:)
|
|
12
|
-
@type = type
|
|
13
|
-
@value = value
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# @param builder [Nokogiri::XML::Builder]
|
|
17
|
-
def to_xml(builder)
|
|
18
|
-
xml = builder.classification value
|
|
19
|
-
xml[:type] = type if type
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# @return [Hash]
|
|
23
|
-
def to_hash
|
|
24
|
-
hash = { "value" => value }
|
|
25
|
-
hash["type"] = type if type
|
|
26
|
-
hash
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# @param prefix [String]
|
|
30
|
-
# @param count [Integer] number of classifications
|
|
31
|
-
# @return [String]
|
|
32
|
-
def to_asciibib(prefix = "", count = 1)
|
|
33
|
-
pref = prefix.empty? ? "classification" : prefix + ".classification"
|
|
34
|
-
out = count > 1 ? "#{pref}::\n" : ""
|
|
35
|
-
out += "#{pref}.type:: #{type}\n" if type
|
|
36
|
-
out += "#{pref}.value:: #{value}\n"
|
|
37
|
-
out
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
data/lib/relaton_bib/config.rb
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "relaton_bib/person"
|
|
4
|
-
|
|
5
|
-
# RelatonBib module
|
|
6
|
-
module RelatonBib
|
|
7
|
-
# Contributor's role.
|
|
8
|
-
class ContributorRole
|
|
9
|
-
include RelatonBib
|
|
10
|
-
|
|
11
|
-
TYPES = %w[author performer publisher editor adapter translator
|
|
12
|
-
distributor realizer owner authorizer enabler subject].freeze
|
|
13
|
-
|
|
14
|
-
# @return [Array<RelatonBib::FormattedString>]
|
|
15
|
-
attr_reader :description
|
|
16
|
-
|
|
17
|
-
# @return [Strig]
|
|
18
|
-
attr_reader :type
|
|
19
|
-
|
|
20
|
-
# @param type [String] allowed types "author", "editor",
|
|
21
|
-
# "cartographer", "publisher"
|
|
22
|
-
# @param description [Array<String>]
|
|
23
|
-
def initialize(**args)
|
|
24
|
-
if args[:type] && !TYPES.include?(args[:type])
|
|
25
|
-
Util.warn %{Contributor's type `#{args[:type]}` is invalid.}
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
@type = args[:type]
|
|
29
|
-
@description = (args[:description] || []).map do |d|
|
|
30
|
-
FormattedString.new content: d, format: nil
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# @param opts [Hash]
|
|
35
|
-
# @option opts [Nokogiri::XML::Builder] :builder XML builder
|
|
36
|
-
# @option opts [String] :lang language
|
|
37
|
-
def to_xml(**opts) # rubocop:disable Metrics/AbcSize
|
|
38
|
-
opts[:builder].role(type: type) do |builder|
|
|
39
|
-
desc = description.select { |d| d.language&.include? opts[:lang] }
|
|
40
|
-
desc = description unless desc.any?
|
|
41
|
-
desc.each do |d|
|
|
42
|
-
builder.description { |b| d.to_xml(b) }
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# @return [Hash, String]
|
|
48
|
-
def to_hash
|
|
49
|
-
hash = {}
|
|
50
|
-
hash["description"] = description.map(&:to_hash) if description&.any?
|
|
51
|
-
hash["type"] = type if type
|
|
52
|
-
hash
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# @param prefix [String]
|
|
56
|
-
# @param count [Integer] number of contributors
|
|
57
|
-
# 2return [String]
|
|
58
|
-
def to_asciibib(prefix = "", count = 1)
|
|
59
|
-
pref = prefix.empty? ? prefix : "#{prefix}."
|
|
60
|
-
out = count > 1 ? "#{prefix}.role::\n" : ""
|
|
61
|
-
description.each do |d|
|
|
62
|
-
out += d.to_asciibib "#{pref}role.description", description.size
|
|
63
|
-
end
|
|
64
|
-
out += "#{pref}role.type:: #{type}\n" if type
|
|
65
|
-
out
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Contribution info.
|
|
70
|
-
class ContributionInfo
|
|
71
|
-
include RelatonBib
|
|
72
|
-
|
|
73
|
-
# @return [Array<RelatonBib::ContributorRole>]
|
|
74
|
-
attr_reader :role
|
|
75
|
-
|
|
76
|
-
# @return
|
|
77
|
-
# [RelatonBib::Person, RelatonBib::Organization]
|
|
78
|
-
attr_reader :entity
|
|
79
|
-
|
|
80
|
-
# @param entity [RelatonBib::Person, RelatonBib::Organization]
|
|
81
|
-
# @param role [Array<Hash>]
|
|
82
|
-
# @option role [String] :type
|
|
83
|
-
# @option role [Array<String>] :description
|
|
84
|
-
def initialize(entity:, role: [])
|
|
85
|
-
if role.empty?
|
|
86
|
-
role << { type: entity.is_a?(Person) ? "author" : "publisher" }
|
|
87
|
-
end
|
|
88
|
-
@entity = entity
|
|
89
|
-
@role = role.map { |r| ContributorRole.new(**r) }
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param opts [Hash]
|
|
93
|
-
# @option opts [Nokogiri::XML::Builder] :builder XML builder
|
|
94
|
-
# @option opts [String, Symbol] :lang language
|
|
95
|
-
def to_xml(**opts)
|
|
96
|
-
entity.to_xml(**opts)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# @return [Hash]
|
|
100
|
-
def to_hash
|
|
101
|
-
hash = entity.to_hash
|
|
102
|
-
hash["role"] = single_element_array(role) if role&.any?
|
|
103
|
-
hash
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# @param prefix [String]
|
|
107
|
-
# @param count [Integer] number of contributors
|
|
108
|
-
# @return [String]
|
|
109
|
-
def to_asciibib(prefix = "", count = 1)
|
|
110
|
-
pref = prefix.split(".").first
|
|
111
|
-
out = count > 1 ? "#{pref}::\n" : ""
|
|
112
|
-
out += entity.to_asciibib prefix
|
|
113
|
-
role.each { |r| out += r.to_asciibib pref, role.size }
|
|
114
|
-
out
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|