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