relaton-ieee 1.9.0 → 1.9.1
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 +1 -0
- data/README.adoc +19 -0
- data/lib/relaton_ieee/data_fetcher.rb +206 -0
- data/lib/relaton_ieee/data_parser.rb +266 -0
- data/lib/relaton_ieee/ieee_bibliographic_item.rb +4 -4
- data/lib/relaton_ieee/ieee_bibliography.rb +15 -2
- data/lib/relaton_ieee/processor.rb +14 -1
- data/lib/relaton_ieee/version.rb +1 -1
- data/lib/relaton_ieee.rb +1 -0
- data/relaton_ieee.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53ecd27da5566b505d1ced7fc6f29af23ec9a45124501e790596350851c362a0
|
4
|
+
data.tar.gz: 2e6b02cedacffd9d44004aa480d57037abfcd6ddf9a5371c5fed0bea2aa533f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb1c5ed0240d28a7494e0e7f7c587ad29610f1ec83aa6ca3f390b9d98256c96b2d8e735d3e46425c7d0b3457b66a1e020c0744d7dfa0b8c031535c866e0a53a7
|
7
|
+
data.tar.gz: ba00b7b538a63696c5e646953eb4f68a76e8c25dd7e1a1a221e2c8edacf1155c8f0eb14951421b253e252190d0f728f681f25712bc5798f6235e93463f97aaa8
|
data/.gitignore
CHANGED
data/README.adoc
CHANGED
@@ -158,6 +158,25 @@ hash = YAML.load_file 'spec/fixtures/ieee_528_2019.yaml'
|
|
158
158
|
...
|
159
159
|
----
|
160
160
|
|
161
|
+
=== Fetch data
|
162
|
+
|
163
|
+
There is an IEEE dataset https://github.com/ietf-ribose/ieee-rawbib which can be converted into BibXML/BibYAML formats. The dataset needs to be placed into local directiory.
|
164
|
+
|
165
|
+
The method `RelatonIeee::DataFetcher.fetch(output: "data", format: "yaml")` converts all the documents from the local `ieee-rawbib` directory and save them to the `./data` folder in YAML format.
|
166
|
+
Arguments:
|
167
|
+
|
168
|
+
- `output` - folder to save documents (default './data').
|
169
|
+
- `format` - format in which the documents are saved. Possimle formats are: `yaml`, `xml` (default `yaml`).
|
170
|
+
|
171
|
+
[source,ruby]
|
172
|
+
----
|
173
|
+
RelatonIeee::DataFetcher.fetch
|
174
|
+
Started at: 2021-09-24 17:55:07 +0200
|
175
|
+
Stopped at: 2021-09-24 17:57:30 +0200
|
176
|
+
Done in: 143 sec.
|
177
|
+
=> nil
|
178
|
+
----
|
179
|
+
|
161
180
|
== Development
|
162
181
|
|
163
182
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require "zip"
|
2
|
+
require "relaton_ieee/data_parser"
|
3
|
+
|
4
|
+
module RelatonIeee
|
5
|
+
class DataFetcher
|
6
|
+
RELATION_TYPES = {
|
7
|
+
"S" => { type: "obsoletedBy" },
|
8
|
+
"V" => { type: "updates", description: "revises" },
|
9
|
+
"T" => { type: "updates", description: "amends" },
|
10
|
+
"C" => { type: "updates", description: "corrects" },
|
11
|
+
"O" => { type: "adoptedFrom" },
|
12
|
+
"P" => { type: "complementOf", description: "supplement" },
|
13
|
+
"N" => false, "G" => false,
|
14
|
+
"F" => false, "I" => false,
|
15
|
+
"E" => false, "B" => false, "W" => false
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# @return [Hash] list of AMSID => PubID
|
19
|
+
attr_reader :backrefs
|
20
|
+
|
21
|
+
#
|
22
|
+
# Create RelatonIeee::DataFetcher instance
|
23
|
+
#
|
24
|
+
# @param [String] output output dir
|
25
|
+
# @param [Strong] format output format. Allowed values: "yaml" or "xml"
|
26
|
+
#
|
27
|
+
def initialize(output, format)
|
28
|
+
@output = output
|
29
|
+
@format = format
|
30
|
+
@crossrefs = {}
|
31
|
+
@backrefs = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Convert documents from `ieee-rawbib` dir (IEEE dataset) to BibYAML/BibXML
|
36
|
+
#
|
37
|
+
# @param [String] output ('data') output dir
|
38
|
+
# @param [String] format ('yaml') output format.
|
39
|
+
# Allowed values: "yaml" or "xml"
|
40
|
+
#
|
41
|
+
def self.fetch(output: "data", format: "yaml")
|
42
|
+
t1 = Time.now
|
43
|
+
puts "Started at: #{t1}"
|
44
|
+
FileUtils.mkdir_p output unless Dir.exist? output
|
45
|
+
new(output, format).fetch
|
46
|
+
t2 = Time.now
|
47
|
+
puts "Stopped at: #{t2}"
|
48
|
+
puts "Done in: #{(t2 - t1).round} sec."
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Convert documents from `ieee-rawbib` dir (IEEE dataset) to BibYAML/BibXML
|
53
|
+
#
|
54
|
+
def fetch # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
55
|
+
Dir["ieee-rawbib/**/*.{xml,zip}"].reject { |f| f["Deleted_"] }.each do |f|
|
56
|
+
xml = case File.extname(f)
|
57
|
+
when ".zip" then read_zip f
|
58
|
+
when ".xml" then File.read f, encoding: "UTF-8"
|
59
|
+
end
|
60
|
+
fetch_doc xml, f
|
61
|
+
rescue StandardError => e
|
62
|
+
warn "File: #{f}"
|
63
|
+
warn e.message
|
64
|
+
warn e.backtrace
|
65
|
+
end
|
66
|
+
update_relations
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Extract XML file from zip archive
|
71
|
+
#
|
72
|
+
# @param [String] file path to achive
|
73
|
+
#
|
74
|
+
# @return [String] file content
|
75
|
+
#
|
76
|
+
def read_zip(file)
|
77
|
+
Zip::File.open(file) do |zf|
|
78
|
+
entry = zf.glob("**/*.xml").first
|
79
|
+
entry.get_input_stream.read
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Parse document and save it
|
85
|
+
#
|
86
|
+
# @param [String] xml content
|
87
|
+
# @param [String] filename source file
|
88
|
+
#
|
89
|
+
def fetch_doc(xml, filename) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
90
|
+
doc = Nokogiri::XML(xml).at("/publication")
|
91
|
+
unless doc
|
92
|
+
warn "Empty file: #{filename}"
|
93
|
+
return
|
94
|
+
end
|
95
|
+
bib = DataParser.parse doc, self
|
96
|
+
amsid = doc.at("./publicationinfo/amsid").text
|
97
|
+
if backrefs.value?(bib.docidentifier[0].id) && /updates\.\d+/ !~ filename
|
98
|
+
oamsid = backrefs.key bib.docidentifier[0].id
|
99
|
+
warn "Document exists ID: \"#{bib.docidentifier[0].id}\" AMSID: "\
|
100
|
+
"\"#{amsid}\" source: \"#{filename}\". Other AMSID: \"#{oamsid}\""
|
101
|
+
if bib.docidentifier[0].id.include?(bib.docnumber)
|
102
|
+
save_doc bib # rewrite file if the PubID mathces to the docnumber
|
103
|
+
backrefs[amsid] = bib.docidentifier[0].id
|
104
|
+
end
|
105
|
+
else
|
106
|
+
save_doc bib
|
107
|
+
backrefs[amsid] = bib.docidentifier[0].id
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Save unresolved relation reference
|
113
|
+
#
|
114
|
+
# @param [String] docnumber of main document
|
115
|
+
# @param [Nokogiri::XML::Element] amsid relation data
|
116
|
+
#
|
117
|
+
def add_crossref(docnumber, amsid)
|
118
|
+
return if RELATION_TYPES[amsid[:type]] == false
|
119
|
+
|
120
|
+
ref = { amsid: amsid.text, type: amsid[:type] }
|
121
|
+
if @crossrefs[docnumber]
|
122
|
+
@crossrefs[docnumber] << ref
|
123
|
+
else @crossrefs[docnumber] = [ref]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Save document to file
|
129
|
+
#
|
130
|
+
# @param [RelatonIeee::IeeeBibliographicItem] bib
|
131
|
+
#
|
132
|
+
def save_doc(bib)
|
133
|
+
c = @format == "xml" ? bib.to_xml(bibdata: true) : bib.to_hash.to_yaml
|
134
|
+
File.write file_name(bib.docnumber), c, encoding: "UTF-8"
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Make filename from PubID
|
139
|
+
#
|
140
|
+
# @param [String] docnumber
|
141
|
+
#
|
142
|
+
# @return [String] filename
|
143
|
+
#
|
144
|
+
def file_name(docnumber)
|
145
|
+
name = docnumber.gsub(/[.\s,:\/]/, "_").squeeze("_").upcase
|
146
|
+
File.join @output, "#{name}.#{@format}"
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Update unresoverd relations
|
151
|
+
#
|
152
|
+
def update_relations # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
153
|
+
@crossrefs.each do |dnum, rfs|
|
154
|
+
bib = nil
|
155
|
+
rfs.each do |rf|
|
156
|
+
if backrefs[rf[:amsid]]
|
157
|
+
rel = create_relation(rf[:type], backrefs[rf[:amsid]])
|
158
|
+
if rel
|
159
|
+
bib ||= read_bib(dnum)
|
160
|
+
bib.relation << rel
|
161
|
+
save_doc bib
|
162
|
+
end
|
163
|
+
else
|
164
|
+
warn "Unresolved relation: '#{rf[:amsid]}' type: '#{rf[:type]}' for '#{dnum}'"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Create relation instance
|
172
|
+
#
|
173
|
+
# @param [String] type IEEE relation type
|
174
|
+
# @param [String] fref reference
|
175
|
+
#
|
176
|
+
# @return [RelatonBib::DocumentRelation]
|
177
|
+
#
|
178
|
+
def create_relation(type, fref)
|
179
|
+
return if RELATION_TYPES[type] == false
|
180
|
+
|
181
|
+
fr = RelatonBib::FormattedRef.new(content: fref)
|
182
|
+
bib = IeeeBibliographicItem.new formattedref: fr
|
183
|
+
desc = RELATION_TYPES[type][:description]
|
184
|
+
description = desc && RelatonBib::FormattedString.new(content: desc, language: "en", script: "Latn")
|
185
|
+
RelatonBib::DocumentRelation.new(
|
186
|
+
type: RELATION_TYPES[type][:type],
|
187
|
+
description: description,
|
188
|
+
bibitem: bib,
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# Read document form BibXML/BibYAML file
|
194
|
+
#
|
195
|
+
# @param [String] docnumber
|
196
|
+
#
|
197
|
+
# @return [RelatonIeee::IeeeBibliographicItem]
|
198
|
+
#
|
199
|
+
def read_bib(docnumber)
|
200
|
+
c = File.read file_name(docnumber), encoding: "UTF-8"
|
201
|
+
if @format == "xml" then XMLParser.from_xml c
|
202
|
+
else IeeeBibliographicItem.from_hash YAML.safe_load(c)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
module RelatonIeee
|
2
|
+
class DataParser
|
3
|
+
DATETYPES = { "OriginalPub" => "created", "ePub" => "published",
|
4
|
+
"LastInspecUpd" => "updated" }.freeze
|
5
|
+
|
6
|
+
attr_reader :doc, :fetcher
|
7
|
+
|
8
|
+
#
|
9
|
+
# Create RelatonIeee::DataParser instance
|
10
|
+
#
|
11
|
+
# @param [Nokogiri::XML::Element] doc document
|
12
|
+
# @param [RelatonIeee::DataFetcher] fetcher
|
13
|
+
#
|
14
|
+
def initialize(doc, fetcher)
|
15
|
+
@doc = doc
|
16
|
+
@fetcher = fetcher
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Parse IEEE document
|
21
|
+
#
|
22
|
+
# @param [Nokogiri::XML::Element] doc document
|
23
|
+
# @param [RelatonIeee::DataFetcher] fetcher <description>
|
24
|
+
#
|
25
|
+
# @return [RelatonIeee::IeeeBibliographicItem]
|
26
|
+
#
|
27
|
+
def self.parse(doc, fetcher)
|
28
|
+
new(doc, fetcher).parse
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Parse IEEE document
|
33
|
+
#
|
34
|
+
# @return [RelatonIeee::IeeeBibliographicItem]
|
35
|
+
#
|
36
|
+
def parse # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
37
|
+
args = {
|
38
|
+
type: "standard",
|
39
|
+
docnumber: docnumber,
|
40
|
+
title: parse_title,
|
41
|
+
date: parse_date,
|
42
|
+
docid: parse_docid,
|
43
|
+
contributor: parse_contributor,
|
44
|
+
abstract: parse_abstract,
|
45
|
+
copyright: parse_copyright,
|
46
|
+
language: ["en"],
|
47
|
+
script: ["Latn"],
|
48
|
+
status: parse_status,
|
49
|
+
relation: parse_relation,
|
50
|
+
link: parse_link,
|
51
|
+
keyword: parse_keyword,
|
52
|
+
ics: parse_ics,
|
53
|
+
}
|
54
|
+
IeeeBibliographicItem.new(**args)
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Parse title
|
59
|
+
#
|
60
|
+
# @return [RelatonBib::TypedTitleStringCollection]
|
61
|
+
#
|
62
|
+
def parse_title
|
63
|
+
t = doc.at("./volume/article/title").text
|
64
|
+
RelatonBib::TypedTitleString.from_string t
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Parse date
|
69
|
+
#
|
70
|
+
# @return [Array<RelatonBib::BibliographicDate>]
|
71
|
+
#
|
72
|
+
def parse_date # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
73
|
+
dates = doc.xpath("./volume/article/articleinfo/date").map do |d|
|
74
|
+
da = [d.at("./year").text]
|
75
|
+
m = d.at("./month")&.text
|
76
|
+
if m
|
77
|
+
month = Date::ABBR_MONTHNAMES.index(m.sub(/\./, "")) || m
|
78
|
+
da << month.to_s.rjust(2, "0")
|
79
|
+
end
|
80
|
+
day = d.at("./day")
|
81
|
+
da << day.text.rjust(2, "0") if day
|
82
|
+
on = da.compact.join "-"
|
83
|
+
RelatonBib::BibliographicDate.new type: DATETYPES[d[:datetype]], on: on
|
84
|
+
end
|
85
|
+
pad = doc.at("./publicationinfo/PubApprovalDate")
|
86
|
+
if pad
|
87
|
+
issued = parse_date_string pad.text
|
88
|
+
dates << RelatonBib::BibliographicDate.new(type: "issued", on: issued)
|
89
|
+
end
|
90
|
+
dates
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Convert date string with month name to numeric date
|
95
|
+
#
|
96
|
+
# @param [String] date source date
|
97
|
+
#
|
98
|
+
# @return [String] numeric date
|
99
|
+
#
|
100
|
+
def parse_date_string(date)
|
101
|
+
case date
|
102
|
+
when /^\d{4}$/ then date
|
103
|
+
when /^\d{1,2}\s\w+\.?\s\d{4}/ then Date.parse(date).to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Parse identifiers
|
109
|
+
#
|
110
|
+
# @return [Array<RelatonBib::DocumentIdentifier>]
|
111
|
+
#
|
112
|
+
def parse_docid
|
113
|
+
ids = [{ id: doc.at("./title").text, type: "IEEE" }]
|
114
|
+
isbn = doc.at("./publicationinfo/isbn")
|
115
|
+
ids << { id: isbn.text, type: "ISBN" } if isbn
|
116
|
+
doi = doc.at("./volume/article/articleinfo/articledoi")
|
117
|
+
ids << { id: doi.text, type: "DOI" } if doi
|
118
|
+
ids.map do |dcid|
|
119
|
+
RelatonBib::DocumentIdentifier.new(**dcid)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Parse docnumber
|
125
|
+
#
|
126
|
+
# @return [String] PubID
|
127
|
+
#
|
128
|
+
def docnumber
|
129
|
+
@docnumber ||= doc.at("./publicationinfo/stdnumber").text
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Parse contributors
|
134
|
+
#
|
135
|
+
# @return [Array<RelatonBib::ContributionInfo>]
|
136
|
+
#
|
137
|
+
def parse_contributor # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
138
|
+
doc.xpath("./publicationinfo/publisher").map do |contrib|
|
139
|
+
n = contrib.at("./publishername").text
|
140
|
+
addr = contrib.xpath("./address").map do |a|
|
141
|
+
RelatonBib::Address.new(
|
142
|
+
street: [],
|
143
|
+
city: a.at("./city")&.text,
|
144
|
+
country: a.at("./country").text,
|
145
|
+
)
|
146
|
+
end
|
147
|
+
e = create_org n, addr
|
148
|
+
RelatonBib::ContributionInfo.new entity: e, role: [type: "publisher"]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Create organization
|
154
|
+
#
|
155
|
+
# @param [String] name organization's name
|
156
|
+
# @param [Array<Hash>] addr address
|
157
|
+
#
|
158
|
+
# @return [RelatonBib::Organization]
|
159
|
+
def create_org(name, addr = []) # rubocop:disable Metrics/MethodLength
|
160
|
+
case name
|
161
|
+
when "IEEE"
|
162
|
+
abbr = name
|
163
|
+
n = "Institute of Electrical and Electronics Engineers"
|
164
|
+
url = "http://www.ieee.org"
|
165
|
+
when "ANSI"
|
166
|
+
abbr = name
|
167
|
+
n = "American National Standards Institute"
|
168
|
+
url = "https://www.ansi.org"
|
169
|
+
else n = name
|
170
|
+
end
|
171
|
+
RelatonBib::Organization.new(
|
172
|
+
name: n, abbreviation: abbr, url: url, contact: addr,
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
#
|
177
|
+
# Parse abstract
|
178
|
+
#
|
179
|
+
# @return [Array<RelatonBib::FormattedString>]
|
180
|
+
#
|
181
|
+
def parse_abstract
|
182
|
+
doc.xpath("./volume/article/articleinfo/abstract").map do |a|
|
183
|
+
RelatonBib::FormattedString.new(
|
184
|
+
content: a.text, language: "en", script: "Latn",
|
185
|
+
)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# Parse copyright
|
191
|
+
#
|
192
|
+
# @return [Array<RelatonBib::CopyrightAssociation>]
|
193
|
+
#
|
194
|
+
def parse_copyright
|
195
|
+
doc.xpath("./publicationinfo/copyrightgroup/copyright").map do |c|
|
196
|
+
owner = c.at("./holder").text.split("/").map do |own|
|
197
|
+
RelatonBib::ContributionInfo.new entity: create_org(own)
|
198
|
+
end
|
199
|
+
RelatonBib::CopyrightAssociation.new(
|
200
|
+
owner: owner, from: c.at("./year").text,
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# Parse status
|
207
|
+
#
|
208
|
+
# @return [RelatonBib::DocumentStatus]
|
209
|
+
#
|
210
|
+
def parse_status
|
211
|
+
stage = doc.at("./publicationinfo/standard_status").text
|
212
|
+
RelatonBib::DocumentStatus.new stage: stage
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# Parse relation
|
217
|
+
#
|
218
|
+
# @return [RelatonBib::DocRelationCollection]
|
219
|
+
#
|
220
|
+
def parse_relation # rubocop:disable Metrics/AbcSize
|
221
|
+
rels = []
|
222
|
+
doc.xpath("./publicationinfo/standard_relationship").each do |r|
|
223
|
+
if (ref = fetcher.backrefs[r.text])
|
224
|
+
rel = fetcher.create_relation(r[:type], ref)
|
225
|
+
rels << rel if rel
|
226
|
+
elsif !/Inactive Date/.match?(r) then fetcher.add_crossref(docnumber, r)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
RelatonBib::DocRelationCollection.new rels
|
230
|
+
end
|
231
|
+
|
232
|
+
#
|
233
|
+
# Parce link
|
234
|
+
#
|
235
|
+
# @return [Array<RelatonBib::TypedUri>]
|
236
|
+
#
|
237
|
+
def parse_link
|
238
|
+
doc.xpath("./volume/article/articleinfo/amsid").map do |id|
|
239
|
+
l = "https://ieeexplore.ieee.org/document/#{id.text}"
|
240
|
+
RelatonBib::TypedUri.new content: l, type: "src"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
#
|
245
|
+
# Parse keyword
|
246
|
+
#
|
247
|
+
# @return [Array<Strign>]
|
248
|
+
#
|
249
|
+
def parse_keyword
|
250
|
+
doc.xpath(
|
251
|
+
"./volume/article/articleinfo/keywordset/keyword/keywordterm",
|
252
|
+
).map &:text
|
253
|
+
end
|
254
|
+
|
255
|
+
#
|
256
|
+
# Parse ICS
|
257
|
+
#
|
258
|
+
# @return [Array<RelatonBib::ICS>]
|
259
|
+
#
|
260
|
+
def parse_ics
|
261
|
+
doc.xpath("./publicationinfo/icscodes/code_term").map do |ics|
|
262
|
+
RelatonBib::ICS.new code: ics[:codenum], text: ics.text
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -5,7 +5,7 @@ module RelatonIeee
|
|
5
5
|
|
6
6
|
# @param committee [Array<RelatonIeee::Committee>]
|
7
7
|
def initialize(**args)
|
8
|
-
@committee = args.delete
|
8
|
+
@committee = args.delete(:committee) || []
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
@@ -13,7 +13,7 @@ module RelatonIeee
|
|
13
13
|
# @return [RelatonIeee::IeeeBibliographicItem]
|
14
14
|
def self.from_hash(hash)
|
15
15
|
item_hash = ::RelatonIeee::HashConverter.hash_to_bib(hash)
|
16
|
-
new
|
16
|
+
new(**item_hash)
|
17
17
|
end
|
18
18
|
|
19
19
|
# @param opts [Hash]
|
@@ -22,7 +22,7 @@ module RelatonIeee
|
|
22
22
|
# @option opts [String] :lang language
|
23
23
|
# @return [String] XML
|
24
24
|
def to_xml(**opts)
|
25
|
-
super
|
25
|
+
super(**opts) do |bldr|
|
26
26
|
if opts[:bibdata] && committee.any?
|
27
27
|
bldr.ext do |b|
|
28
28
|
committee.each { |c| c.to_xml b }
|
@@ -34,7 +34,7 @@ module RelatonIeee
|
|
34
34
|
# @return [Hash]
|
35
35
|
def to_hash
|
36
36
|
hash = super
|
37
|
-
hash["committee"] = committee.map &:to_hash
|
37
|
+
hash["committee"] = committee.map &:to_hash if committee.any?
|
38
38
|
hash
|
39
39
|
end
|
40
40
|
|
@@ -19,7 +19,7 @@ module RelatonIeee
|
|
19
19
|
warn "[relaton-ieee] (\"#{code}\") fetching..."
|
20
20
|
result = search(code) || (return nil)
|
21
21
|
year ||= code.match(/(?<=-)\d{4}/)&.to_s
|
22
|
-
ret = bib_results_filter(result, year)
|
22
|
+
ret = bib_results_filter(result, code, year)
|
23
23
|
if ret[:ret]
|
24
24
|
item = ret[:ret].fetch
|
25
25
|
warn "[relaton-ieee] (\"#{code}\") found #{item.docidentifier.first.id}"
|
@@ -42,9 +42,13 @@ module RelatonIeee
|
|
42
42
|
# @param opts [Hash] options
|
43
43
|
#
|
44
44
|
# @return [Hash]
|
45
|
-
def bib_results_filter(result, year)
|
45
|
+
def bib_results_filter(result, ref, year)
|
46
|
+
rp1 = ref_parts ref
|
46
47
|
missed_years = []
|
47
48
|
result.each do |hit|
|
49
|
+
rp2 = ref_parts hit.hit["recordTitle"]
|
50
|
+
next if rp1[:code] != rp2[:code] || rp1[:corr] != rp2[:corr]
|
51
|
+
|
48
52
|
return { ret: hit } if !year
|
49
53
|
|
50
54
|
return { ret: hit } if year.to_i == hit.hit[:year]
|
@@ -54,6 +58,15 @@ module RelatonIeee
|
|
54
58
|
{ years: missed_years.uniq }
|
55
59
|
end
|
56
60
|
|
61
|
+
def ref_parts(ref)
|
62
|
+
%r{
|
63
|
+
^(?:IEEE\s(?:Std\s)?)?
|
64
|
+
(?<code>[^-/]+)
|
65
|
+
(?:-(?<year>\d{4}))?
|
66
|
+
(?:/(?<corr>\w+\s\d+-\d{4}))?
|
67
|
+
}x.match ref
|
68
|
+
end
|
69
|
+
|
57
70
|
# @param code [Strig]
|
58
71
|
# @param year [String]
|
59
72
|
# @param missed_years [Array<Strig>]
|
@@ -4,11 +4,12 @@ module RelatonIeee
|
|
4
4
|
class Processor < Relaton::Processor
|
5
5
|
attr_reader :idtype
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
8
8
|
@short = :relaton_ieee
|
9
9
|
@prefix = "IEEE"
|
10
10
|
@defaultprefix = %r{^IEEE\s}
|
11
11
|
@idtype = "IEEE"
|
12
|
+
@datasets = %w[ieee-rawbib]
|
12
13
|
end
|
13
14
|
|
14
15
|
# @param code [String]
|
@@ -19,6 +20,18 @@ module RelatonIeee
|
|
19
20
|
::RelatonIeee::IeeeBibliography.get(code, date, opts)
|
20
21
|
end
|
21
22
|
|
23
|
+
#
|
24
|
+
# Fetch all the documents from ./iee-rawbib directory
|
25
|
+
#
|
26
|
+
# @param [String] _source source name
|
27
|
+
# @param [Hash] opts
|
28
|
+
# @option opts [String] :output directory to output documents
|
29
|
+
# @option opts [String] :format
|
30
|
+
#
|
31
|
+
def fetch_data(_source, opts)
|
32
|
+
DataFetcher.fetch(**opts)
|
33
|
+
end
|
34
|
+
|
22
35
|
# @param xml [String]
|
23
36
|
# @return [RelatonIeee::IeeeBibliographicItem]
|
24
37
|
def from_xml(xml)
|
data/lib/relaton_ieee/version.rb
CHANGED
data/lib/relaton_ieee.rb
CHANGED
data/relaton_ieee.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relaton-ieee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: equivalent-xml
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.9.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubyzip
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.3.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.3.0
|
111
125
|
description: 'RelatonIeee: retrieve IEEE Standards for bibliographic use using the
|
112
126
|
IeeeBibliographicItem model'
|
113
127
|
email:
|
@@ -133,6 +147,8 @@ files:
|
|
133
147
|
- grammars/reqt.rng
|
134
148
|
- lib/relaton_ieee.rb
|
135
149
|
- lib/relaton_ieee/committee.rb
|
150
|
+
- lib/relaton_ieee/data_fetcher.rb
|
151
|
+
- lib/relaton_ieee/data_parser.rb
|
136
152
|
- lib/relaton_ieee/hash_converter.rb
|
137
153
|
- lib/relaton_ieee/hit.rb
|
138
154
|
- lib/relaton_ieee/hit_collection.rb
|