relaton-nist 1.12.5 → 1.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c73a4a75166a362d34e2d1a4bec088d74863cf1ac9a4eee0798cfa84cbceca6
4
- data.tar.gz: 398bd9b074c7c10da66c86047e617e7b643ea6cc3e45f1daa6fdd6f43d38bb4c
3
+ metadata.gz: c997f338c657a003a0bff7e75b650f59b86d4a72026a0b12734357bc48c10cdc
4
+ data.tar.gz: 5d76af2d37037bb027f9875180bbcc967ca133260eb4a5494112fe81cccf5e04
5
5
  SHA512:
6
- metadata.gz: 7695197e53d2d8b8b2048f034c6d47db2ce293f7f8dedafacefae8efb4ad85ed96169f5b317957a228b32bfa1e9a8899b80238aa8be594edd94e89619c9fbb51
7
- data.tar.gz: 1b2eb51d32d0b0eb9456242e5727b891468509a55cdc2ce2251fa84857b83d6d29966bb3799557672da7cabc126949f0cc18d6581cb9464caa38293a317a7265
6
+ metadata.gz: 5971a572c9a7a5aefb4087f96787255687195c3e0cc75a49f740b57af1bb05fa48f56c2bd721cbb4b5aa7e5178cb93048c97a8782d152b4b040dd3158129ba14
7
+ data.tar.gz: f266510c36ce07666a74b9881e439df01067f6baee05e03c267ce3754bef5dcf24b7391082a4fdc1d8122121f17b1fc30e3ba8377dadd86692ff80cd8efa962d
data/grammars/biblio.rng CHANGED
@@ -225,9 +225,9 @@
225
225
  <zeroOrMore>
226
226
  <ref name="forename"/>
227
227
  </zeroOrMore>
228
- <zeroOrMore>
229
- <ref name="initial"/>
230
- </zeroOrMore>
228
+ <optional>
229
+ <ref name="formatted-initials"/>
230
+ </optional>
231
231
  <ref name="surname"/>
232
232
  <zeroOrMore>
233
233
  <ref name="addition"/>
@@ -247,8 +247,8 @@
247
247
  <ref name="LocalizedString"/>
248
248
  </element>
249
249
  </define>
250
- <define name="initial">
251
- <element name="initial">
250
+ <define name="formatted-initials">
251
+ <element name="formatted-initials">
252
252
  <ref name="LocalizedString"/>
253
253
  </element>
254
254
  </define>
@@ -264,6 +264,9 @@
264
264
  </define>
265
265
  <define name="forename">
266
266
  <element name="forename">
267
+ <optional>
268
+ <attribute name="initial"/>
269
+ </optional>
267
270
  <ref name="LocalizedString"/>
268
271
  </element>
269
272
  </define>
data/grammars/isodoc.rng CHANGED
@@ -69,6 +69,17 @@
69
69
  </zeroOrMore>
70
70
  </element>
71
71
  </define>
72
+ <define name="AdmonitionType">
73
+ <choice>
74
+ <value>warning</value>
75
+ <value>note</value>
76
+ <value>tip</value>
77
+ <value>important</value>
78
+ <value>caution</value>
79
+ <value>statement</value>
80
+ <value>editorial</value>
81
+ </choice>
82
+ </define>
72
83
  <define name="index">
73
84
  <element name="index">
74
85
  <optional>
@@ -1274,7 +1285,12 @@
1274
1285
  </define>
1275
1286
  <define name="span">
1276
1287
  <element name="span">
1277
- <attribute name="class"/>
1288
+ <optional>
1289
+ <attribute name="class"/>
1290
+ </optional>
1291
+ <optional>
1292
+ <attribute name="style"/>
1293
+ </optional>
1278
1294
  <oneOrMore>
1279
1295
  <ref name="TextElement"/>
1280
1296
  </oneOrMore>
@@ -2493,6 +2509,16 @@
2493
2509
  <text/>
2494
2510
  </element>
2495
2511
  </optional>
2512
+ <optional>
2513
+ <element name="amendment">
2514
+ <text/>
2515
+ </element>
2516
+ </optional>
2517
+ <optional>
2518
+ <element name="corrigendum">
2519
+ <text/>
2520
+ </element>
2521
+ </optional>
2496
2522
  <optional>
2497
2523
  <element name="language">
2498
2524
  <text/>
@@ -157,13 +157,13 @@ module RelatonNist
157
157
  # @return [RelatonBib::FullName] full name object
158
158
  #
159
159
  def fullname(person, doc)
160
- forename, initial = forename_initial(person, doc)
160
+ forename, initials = forename_initial(person, doc)
161
161
  surname = localized_string person.at("surname").text, doc
162
162
  ident = person.xpath("ORCID").map do |id|
163
163
  RelatonBib::PersonIdentifier.new "orcid", id.text
164
164
  end
165
165
  RelatonBib::FullName.new(surname: surname, forename: forename,
166
- initial: initial, identifier: ident)
166
+ initials: initials, identifier: ident)
167
167
  end
168
168
 
169
169
  #
@@ -174,17 +174,33 @@ module RelatonNist
174
174
  #
175
175
  # @return [Array<Array<RelatonBib::LocalizedString>>] forename and initials
176
176
  #
177
- def forename_initial(person, doc)
178
- forename = []
179
- initial = []
177
+ def forename_initial(person, doc) # rubocop:disable Metrics/MethodLength
178
+ fnames = []
180
179
  fname = person.at("given_name")&.text
181
180
  if fname
182
181
  if /^(?<inits>(?:\w[.\s]+|[A-Z]{1,2}$)+)$/ =~ fname
183
- inits.split(/[.\s]*/).each { |i| initial << localized_string(i, doc) }
184
- else forename << localized_string(fname, doc)
182
+ ints = inits.split(/[.\s]*/)
183
+ fnames << forename(doc, fname, ints.shift)
184
+ ints.each { |i| fnames << forename(doc, nil, i) }
185
+ else fnames << forename(doc, fname)
185
186
  end
186
187
  end
187
- [forename, initial]
188
+ [fnames, localized_string(inits, doc)]
189
+ end
190
+
191
+ #
192
+ # Create forename object
193
+ #
194
+ # @param [Nokogiri::XML::Element] doc document element
195
+ # @param [String, nil] cnt forename content
196
+ # @param [String, nil] init initial content
197
+ #
198
+ # @return [RelatonBib::Forename] forename object
199
+ #
200
+ def forename(doc, cnt, init = nil)
201
+ RelatonBib::Forename.new(
202
+ content: cnt, language: doc["language"], script: "Latn", initial: init,
203
+ )
188
204
  end
189
205
 
190
206
  #
@@ -5,13 +5,20 @@ module RelatonNist
5
5
  class Hit < RelatonBib::Hit
6
6
  attr_writer :fetch
7
7
 
8
+ #
8
9
  # Parse page.
9
- # @return [RelatonNist::NistBliographicItem]
10
+ #
11
+ # @return [RelatonNist::NistBliographicItem] bibliographic item
12
+ #
10
13
  def fetch
11
14
  @fetch ||= Scrapper.parse_page @hit
12
15
  end
13
16
 
14
- # @return [Iteger]
17
+ #
18
+ # Calculate sorting weigth of hit by series, code, title, addendum, and status
19
+ #
20
+ # @return [Iteger] sorting weigth
21
+ #
15
22
  def sort_value # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
16
23
  @sort_value ||= begin
17
24
  sort_phrase = [hit[:series], hit[:code], hit[:title]].join " "
@@ -7,7 +7,7 @@ require "addressable/uri"
7
7
  require "open-uri"
8
8
 
9
9
  module RelatonNist
10
- # Page of hit collection.
10
+ # Hit collection.
11
11
  class HitCollection < RelatonBib::HitCollection
12
12
  DOMAIN = "https://csrc.nist.gov"
13
13
  PUBS_EXPORT = URI.join(DOMAIN, "/CSRC/media/feeds/metanorma/pubs-export")
@@ -15,17 +15,37 @@ module RelatonNist
15
15
  DATAFILE = File.expand_path "pubs-export.zip", DATAFILEDIR
16
16
  GHNISTDATA = "https://raw.githubusercontent.com/relaton/relaton-data-nist/main/data/"
17
17
 
18
+ #
19
+ # Create hits collection instance and search hits
20
+ #
21
+ # @param [Hash] opts options
22
+ # @option opts [String] :stage stage of document
23
+ #
24
+ # @return [RelatonNist::HitCollection] hits collection
25
+ #
18
26
  def self.search(text, year = nil, opts = {})
19
27
  new(text, year).search(opts)
20
28
  end
21
29
 
30
+ #
31
+ # Search nits in JSON file or GitHub repo
32
+ #
33
+ # @param [Hash] opts options
34
+ # @option opts [String] :stage stage of document
35
+ #
36
+ # @return [RelatonNist::HitCollection] hits collection
37
+ #
22
38
  def search(opts)
23
39
  @array = from_json(**opts)
24
40
  @array = from_ga unless @array.any?
25
41
  sort_hits!
26
42
  end
27
43
 
28
- # @return [Array<RelatonNist::Hit>]
44
+ #
45
+ # Filter hits by reference's parts
46
+ #
47
+ # @return [Array<RelatonNist::Hit>] hits
48
+ #
29
49
  def search_filter # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
30
50
  @array.select do |item|
31
51
  %r{
@@ -53,6 +73,11 @@ module RelatonNist
53
73
 
54
74
  private
55
75
 
76
+ #
77
+ # Parse reference parts
78
+ #
79
+ # @return [Hash] reference parts
80
+ #
56
81
  def refparts # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
57
82
  @refparts ||= {
58
83
  perfix: match(/^(NIST|NBS)\s?/, text),
@@ -71,10 +96,23 @@ module RelatonNist
71
96
  }
72
97
  end
73
98
 
99
+ #
100
+ # Match regex to reference
101
+ #
102
+ # @param [Regexp] regex regex
103
+ # @param [String] code reference
104
+ #
105
+ # @return [String, nil] matched string
106
+ #
74
107
  def match(regex, code)
75
108
  regex.match(code)&.to_s
76
109
  end
77
110
 
111
+ #
112
+ # Generate reference from parts
113
+ #
114
+ # @return [String] reference
115
+ #
78
116
  def full_ref # rubocop:disable Metrics/AbcSize
79
117
  @full_ref ||= begin
80
118
  ref = "#{refparts[:perfix]}#{refparts[:series]} #{refparts[:code]}"
@@ -84,9 +122,16 @@ module RelatonNist
84
122
  end
85
123
  end
86
124
 
125
+ #
126
+ # Return short version of ID part with removed "-" or convert long version to short.
127
+ # Converts "pt-1" to "pt1" and "Part 1" to "pt1", "v-1" to "v1" and "Vol. 1" to "v1",
128
+ # "ver-1" to "ver1" and "Ver. 1" to "ver1", "r-1" to "r1" and "Rev. 1" to "r1".
129
+ #
87
130
  # @param short [String]
88
131
  # @param long [String]
132
+ #
89
133
  # @return [String, nil]
134
+ #
90
135
  def long_to_short(short, long)
91
136
  return short.sub(/-/, "") if short
92
137
  return unless long
@@ -94,6 +139,11 @@ module RelatonNist
94
139
  long.sub(/Part\s/, "pt").sub(/Vol\.\s/, "v").sub(/Rev\.\s/, "r").sub(/(Ver\.|Version)\s/, "ver")
95
140
  end
96
141
 
142
+ #
143
+ # Sort hits by sort_value and release date
144
+ #
145
+ # @return [self] sorted hits collection
146
+ #
97
147
  def sort_hits!
98
148
  @array.sort! do |a, b|
99
149
  if a.sort_value == b.sort_value
@@ -105,7 +155,14 @@ module RelatonNist
105
155
  self
106
156
  end
107
157
 
108
- def from_ga # rubocop:disable Metrics/AbcSize
158
+ #
159
+ # Get hit from GitHub repo
160
+ #
161
+ # @return [Array<RelatonNist::Hit>] hits
162
+ #
163
+ # @raise [OpenURI::HTTPError] if GitHub repo is not available
164
+ #
165
+ def from_ga # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
109
166
  ref = full_ref
110
167
  fn = ref.gsub(%r{[/\s:.]}, "_").upcase
111
168
  yaml = OpenURI.open_uri "#{GHNISTDATA}#{fn}.yaml"
@@ -120,9 +177,14 @@ module RelatonNist
120
177
  raise e
121
178
  end
122
179
 
180
+ #
123
181
  # Fetches data form json
124
- # @param stage [String]
125
- # @return [Array<RelatonNist::Hit>]
182
+ #
183
+ # @param opts [Hash] options
184
+ # @option opts [String] :stage stage of document
185
+ #
186
+ # @return [Array<RelatonNist::Hit>] hits
187
+ #
126
188
  def from_json(**opts)
127
189
  select_data(**opts).map do |h|
128
190
  /(?<series>(?<=-)\w+$)/ =~ h["series"]
@@ -134,8 +196,14 @@ module RelatonNist
134
196
  end
135
197
  end
136
198
 
137
- # @param stage [String]
138
- # @return [Array<Hach>]
199
+ #
200
+ # Select data from json
201
+ #
202
+ # @param opts [Hash] options
203
+ # @option opts [String] :stage stage of document
204
+ #
205
+ # @return [Array<Hash>] selected data
206
+ #
139
207
  def select_data(**opts) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
140
208
  ref = "#{refparts[:series]} #{refparts[:code]}"
141
209
  d = Date.strptime year, "%Y" if year
@@ -152,9 +220,14 @@ module RelatonNist
152
220
  end
153
221
  end
154
222
 
155
- # @param doc [Hash]
223
+ #
224
+ # Check if issued date is match to year
225
+ #
226
+ # @param doc [Hash] document's metadata
156
227
  # @param date [Date] first day of year
157
- # @return [TrueClass, FalseClass]
228
+ #
229
+ # @return [Boolean]
230
+ #
158
231
  def match_year?(doc, date)
159
232
  return true unless year
160
233
 
@@ -162,8 +235,11 @@ module RelatonNist
162
235
  idate.between? date, date.next_year.prev_day
163
236
  end
164
237
 
238
+ #
165
239
  # Fetches json data form server
166
- # @return [Hash]
240
+ #
241
+ # @return [Array<Hash>] json data
242
+ #
167
243
  def data
168
244
  ctime = File.ctime DATAFILE if File.exist? DATAFILE
169
245
  if !ctime || ctime.to_date < Date.today || File.size(DATAFILE).zero?
@@ -172,9 +248,11 @@ module RelatonNist
172
248
  unzip
173
249
  end
174
250
 
251
+ #
175
252
  # Fetch data form server and save it to file
176
253
  #
177
- # @prarm ctime [Time, NilClass]
254
+ # @prarm ctime [Time, nil] file creation time
255
+ #
178
256
  def fetch_data(ctime)
179
257
  if !ctime || ctime < OpenURI.open_uri("#{PUBS_EXPORT}.meta").last_modified
180
258
  @data = nil
@@ -184,9 +262,11 @@ module RelatonNist
184
262
  end
185
263
  end
186
264
 
265
+ #
187
266
  # upack zip file
188
267
  #
189
- # @return [Hash]
268
+ # @return [Array<Hash>] json data
269
+ #
190
270
  def unzip
191
271
  return @data if @data
192
272
 
@@ -11,8 +11,13 @@ require "relaton_nist/hash_converter"
11
11
  module RelatonNist
12
12
  class NistBibliography
13
13
  class << self
14
- # @param text [String]
15
- # @return [RelatonNist::HitCollection]
14
+ #
15
+ # Search NIST docuemnts by reference
16
+ #
17
+ # @param text [String] reference
18
+ #
19
+ # @return [RelatonNist::HitCollection] search result
20
+ #
16
21
  def search(text, year = nil, opts = {})
17
22
  ref = text.sub(/^NIST\sIR/, "NISTIR")
18
23
  HitCollection.search ref, year, opts
@@ -20,15 +25,18 @@ module RelatonNist
20
25
  raise RelatonBib::RequestError, e.message
21
26
  end
22
27
 
28
+ #
29
+ # Get NIST document by reference
30
+ #
23
31
  # @param code [String] the NIST standard Code to look up (e..g "8200")
24
32
  # @param year [String] the year the standard was published (optional)
25
33
  #
26
34
  # @param opts [Hash] options
27
- # @option opts [TrueClass, FalseClass] :all_parts restricted to all parts
35
+ # @option opts [Boolean] :all_parts restricted to all parts
28
36
  # if all-parts reference is required
29
- # @option opts [TrueClass, FalseClass] :bibdata
30
37
  #
31
- # @return [String] Relaton XML serialisation of reference
38
+ # @return [RelatonNist::NistBibliographicItem, nil] bibliographic item
39
+ #
32
40
  def get(code, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
33
41
  return fetch_ref_err(code, year, []) if code.match?(/\sEP$/)
34
42
 
@@ -61,6 +69,18 @@ module RelatonNist
61
69
 
62
70
  private
63
71
 
72
+ #
73
+ # Get NIST document by reference
74
+ #
75
+ # @param [String] code reference
76
+ # @param [String] year year
77
+ # @param [Hash] opts options
78
+ # @option opts [Date] :issued_date issued date
79
+ # @option opts [Date] :updated_date updated date
80
+ # @option opts [String] :stage stage
81
+ #
82
+ # @return [RelatonNist::NistBibliographicItem, nil] bibliographic item
83
+ #
64
84
  def nistbib_get(code, year, opts)
65
85
  result = nistbib_search_filter(code, year, opts) || (return nil)
66
86
  ret = nistbib_results_filter(result, year, opts)
@@ -72,6 +92,7 @@ module RelatonNist
72
92
  end
73
93
  end
74
94
 
95
+ #
75
96
  # Sort through the results from RelatonNist, fetching them three at a time,
76
97
  # and return the first result that matches the code,
77
98
  # matches the year (if provided), and which # has a title (amendments do not).
@@ -80,11 +101,12 @@ module RelatonNist
80
101
  # If no match, returns any years which caused mismatch, for error reporting
81
102
  #
82
103
  # @param opts [Hash] options
83
- # @option opts [Time] :issued_date
84
- # @option opts [Time] :issued_date
85
- # @option opts [String] :stage
104
+ # @option opts [Date] :issued_date issued date
105
+ # @option opts [Date] :issued_date issued date
106
+ # @option opts [String] :stage stage
107
+ #
108
+ # @return [Hash] result
86
109
  #
87
- # @return [Hash]
88
110
  def nistbib_results_filter(result, year, opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
89
111
  missed_years = []
90
112
  iter = /\w+(?=PD)|(?<=PD-)\w+/.match(opts[:stage])&.to_s
@@ -119,9 +141,14 @@ module RelatonNist
119
141
  { years: missed_years }
120
142
  end
121
143
 
122
- # @param hits [RelatonNist::HitCollection]
123
- # @param threads [Integer]
124
- # @return [Array<RelatonNist::NistBibliographicItem>]
144
+ #
145
+ # Fetch pages for all the hits in parallel
146
+ #
147
+ # @param hits [RelatonNist::HitCollection] hits
148
+ # @param threads [Integer] number of threads
149
+ #
150
+ # @return [Array<RelatonNist::NistBibliographicItem>] bibliographic items
151
+ #
125
152
  def fetch_pages(hits, threads)
126
153
  workers = RelatonBib::WorkersPool.new threads
127
154
  workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
@@ -130,16 +157,31 @@ module RelatonNist
130
157
  workers.result.sort_by { |a| a[:i] }.map { |x| x[:hit] }
131
158
  end
132
159
 
133
- # @param code [String]
134
- # @param year [String, nil]
135
- # @param opts [Hash]
136
- # @return [RelatonNist::HitCollection]
160
+ #
161
+ # Get search results and filter them by code and year
162
+ #
163
+ # @param code [String] reference
164
+ # @param year [String, nil] year
165
+ # @param opts [Hash] options
166
+ # @option opts [String] :stage stage
167
+ #
168
+ # @return [RelatonNist::HitCollection] hits collection
169
+ #
137
170
  def nistbib_search_filter(code, year, opts)
138
171
  warn "[relaton-nist] (\"#{code}\") fetching..."
139
172
  result = search(code, year, opts)
140
173
  result.search_filter
141
174
  end
142
175
 
176
+ #
177
+ # Outputs warning message if no match found
178
+ #
179
+ # @param [String] code reference
180
+ # @param [String, nil] year year
181
+ # @param [Array<String>] missed_years missed years
182
+ #
183
+ # @return [nil] nil
184
+ #
143
185
  def fetch_ref_err(code, year, missed_years) # rubocop:disable Metrics/MethodLength
144
186
  id = year ? "#{code}:#{year}" : code
145
187
  warn "[relaton-nist] WARNING: no match found online for #{id}. " \
@@ -1,3 +1,3 @@
1
1
  module RelatonNist
2
- VERSION = "1.12.5".freeze
2
+ VERSION = "1.13.0".freeze
3
3
  end
data/relaton_nist.gemspec CHANGED
@@ -32,6 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "vcr"
33
33
  spec.add_development_dependency "webmock"
34
34
 
35
- spec.add_dependency "relaton-bib", "~> 1.12.0"
35
+ spec.add_dependency "relaton-bib", "~> 1.13.0"
36
36
  spec.add_dependency "rubyzip"
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-nist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.5
4
+ version: 1.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-23 00:00:00.000000000 Z
11
+ date: 2022-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equivalent-xml
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.12.0
131
+ version: 1.13.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.12.0
138
+ version: 1.13.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rubyzip
141
141
  requirement: !ruby/object:Gem::Requirement