nist-pubid 0.1.2 → 0.1.6

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: 0eda4fda43009a4ec9c9cdd35c0abcada305c5c9868d246b4df0c324f84ea326
4
- data.tar.gz: 1392bed11a8b5d05126e6eb368fa650f013f4aac7a9c78d05f319b6e785bb42f
3
+ metadata.gz: d6cbdcaa4e1cfa7c75b6709f34cfd19670e8a3b2d3bd31473cbc5a5d439843b7
4
+ data.tar.gz: 4dcb0a4b147990872fe4f72c8eecac96ba3a865bcaa477a5158404ab04fc8e42
5
5
  SHA512:
6
- metadata.gz: 13a9854c8b67b0c7fc5202306501d8ec9d61ede0b73de2afbaefc8373fb7f798b7f7baa0caca9e6ab256bd6a929c55f09376ff2728465300d7d6098d929c2cad
7
- data.tar.gz: d6e3685000eea4ccf494fc4b1ade59b5002a561bdc9597c9a11b7ae738d730461f3297b60b2f66a98b23ff4670c1c2cdc899562f409a6063e4c609096f73ea97
6
+ metadata.gz: b6331d9887c149a7dbcf49c46a0ce7c121bf973cd239e3467658065820daf8c18f752e68b977d52e08155dfa2d947d9be5fa80bb431f462453ed337e02fc1616
7
+ data.tar.gz: 35660adeef1ec90862ada64b2150162008d0b25cf01a8e9a7b15f909b6ac64265a04cc2bdf1da7ea9a7d08e99754eb8d49910de9d19119b4548b40f3870876db
@@ -0,0 +1,46 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - '*'
7
+ workflow_dispatch:
8
+ inputs:
9
+ next_version:
10
+ description: |
11
+ Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
12
+ required: true
13
+ default: 'skip'
14
+
15
+ jobs:
16
+ release:
17
+ runs-on: ubuntu-18.04
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+
21
+ - uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: '2.6'
24
+ bundler-cache: true
25
+
26
+ - run: bundle exec rake
27
+
28
+ - run: gem install gem-release
29
+
30
+ - run: |
31
+ git config user.name github-actions
32
+ git config user.email github-actions@github.com
33
+ - if: github.event_name == 'workflow_dispatch' && github.event.inputs.next_version != 'skip'
34
+ run: gem bump --version ${{ github.event.inputs.next_version }} --tag --push
35
+
36
+ - name: Publish to rubygems.org
37
+ env:
38
+ RUBYGEMS_API_KEY: ${{secrets.METANORMA_CI_RUBYGEMS_API_KEY}}
39
+ run: |
40
+ gem install gem-release
41
+ cat > ~/.gem/credentials << EOF
42
+ ---
43
+ :rubygems_api_key: ${RUBYGEMS_API_KEY}
44
+ EOF
45
+ chmod 0600 ~/.gem/credentials
46
+ gem release
data/README.adoc CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  NIST publications are numbered according to an identification scheme.
6
6
 
7
- This gem implements a mechanism to parse and utilize NIST publication identifers
7
+ This gem implements a mechanism to parse and utilize NIST publication identifiers
8
8
  provided in the https://github.com/usnistgov/NIST-Tech-Pubs[NIST-Tech-Pubs]
9
9
  repository.
10
10
 
@@ -296,9 +296,10 @@ A "Part" can also be indicated by an appended alphabetic character to the end.
296
296
  | Section | Sec. | `sec`
297
297
  | Supplement | Suppl. | `sup`
298
298
  | Index | Index | `indx`
299
- | Addendum | Add. | `add` (TBD with NIST)
299
+ | Addendum | Add. | `add` (TBC with NIST)
300
300
  | Insert | Ins. | `ins` (TBC with NIST)
301
301
  | Errata | Err. | `err` (TBC with NIST)
302
+ | Appendix | App. | `app` (TBC with NIST)
302
303
 
303
304
  |===
304
305
 
data/exe/nist-pubid ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+ require_relative "../lib/nist_pubid"
6
+ require "thor"
7
+ require "csv"
8
+
9
+ class NistPubidCLI < Thor
10
+ desc "report", "Create report for NIST Tech Pubs database (fetches from GitHub)"
11
+ option :csv, type: :boolean, desc: "Export to CSV format"
12
+ def report
13
+ if options[:csv]
14
+ NistPubid::NistTechPubs.status.each do |doc|
15
+ puts [doc[:finalPubId] == doc[:id] && doc[:mr] == doc[:doi] ? "-" : "+",
16
+ doc[:finalPubId], doc[:id], doc[:doi], doc[:mr], doc[:title]]
17
+ .to_csv
18
+ end
19
+ else
20
+ puts "Changed | New PubID | Document ID | DOI | New MR | Title + subtitle"
21
+ NistPubid::NistTechPubs.status.each do |doc|
22
+ puts "#{doc[:finalPubId] == doc[:id] && doc[:mr] == doc[:doi] ? ' -' : '✅'}"\
23
+ " | #{doc[:finalPubId]} | #{doc[:id]} | #{doc[:doi]} | #{doc[:mr]} | #{doc[:title]}"
24
+ end
25
+ end
26
+ end
27
+
28
+ desc "convert", "Convert legacy NIST Tech Pubs ID to NIST PubID"
29
+ option :style, aliases: "-s", type: :string,
30
+ desc: "Convert to PubID style (short|long|mr|abbrev)",
31
+ default: "short"
32
+ option :format, aliases: "-f", type: :string,
33
+ desc: "Render in format (JSON, string)",
34
+ default: "string"
35
+ def convert(code)
36
+ unless %w[mr long short abbrev].include?(options[:style])
37
+ raise "Invalid PubID style"
38
+ end
39
+
40
+ raise "wrong conversion format" unless %w[string json].include? options[:format]
41
+
42
+ unless code.empty?
43
+ if options[:format] == "string"
44
+ puts NistPubid::Document.parse(code).to_s(options[:style].to_sym)
45
+ else
46
+ puts NistPubid::Document.parse(code).to_json
47
+ end
48
+ end
49
+ rescue NistPubid::Errors::ParseError
50
+ puts "[Error] This does not seem to be a valid NIST Tech Pubs legacy identifier"
51
+ end
52
+ end
53
+
54
+ NistPubidCLI.start(ARGV)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "json"
2
3
 
3
4
  REVISION_DESC = {
4
5
  long: ", Revision ",
@@ -35,47 +36,200 @@ EDITION_DESC = {
35
36
  mr: "e",
36
37
  }.freeze
37
38
 
39
+ SUPPLEMENT_DESC = {
40
+ long: " Supplement ",
41
+ abbrev: " Suppl. ",
42
+ short: "sup",
43
+ mr: "sup",
44
+ }.freeze
45
+
46
+ SECTION_DESC = {
47
+ long: " Section ",
48
+ abbrev: " Sec. ",
49
+ short: "sec",
50
+ mr: "sec",
51
+ }.freeze
52
+
53
+ APPENDIX_DESC = {
54
+ long: " Appendix ",
55
+ abbrev: " App. ",
56
+ short: "app",
57
+ mr: "app",
58
+ }.freeze
59
+
60
+ ERRATA_DESC = {
61
+ long: " Errata ",
62
+ abbrev: " Err. ",
63
+ short: "err",
64
+ mr: "err",
65
+ }.freeze
66
+
67
+ INDEX_DESC = {
68
+ long: " Index ",
69
+ abbrev: " Index. ",
70
+ short: "indx",
71
+ mr: "indx",
72
+ }.freeze
73
+
74
+ INSERT_DESC = {
75
+ long: " Insert ",
76
+ abbrev: " Ins. ",
77
+ short: "ins",
78
+ mr: "ins",
79
+ }.freeze
80
+
38
81
  module NistPubid
39
82
  class Document
40
83
  attr_accessor :serie, :code, :revision, :publisher, :version, :volume,
41
- :part, :addendum, :stage, :translation, :update, :edition
84
+ :part, :addendum, :stage, :translation, :update_number,
85
+ :edition, :supplement, :update_year, :section, :appendix,
86
+ :errata, :index, :insert
42
87
 
43
- def initialize(publisher:, serie:, docnumber:, stage: nil, **opts)
88
+ def initialize(publisher:, serie:, docnumber:, **opts)
44
89
  @publisher = Publisher.new(publisher: publisher)
45
90
  @serie = Serie.new(serie: serie)
46
91
  @code = docnumber
47
- @stage = Stage.new(stage: stage)
48
92
  opts.each { |key, value| send("#{key}=", value) }
49
93
  end
50
94
 
95
+ # returns weight based on amount of defined attributes
96
+ def weight
97
+ instance_variables.inject(0) do |sum, var|
98
+ sum + (instance_variable_get(var).nil? ? 0 : 1)
99
+ end
100
+ end
101
+
102
+ def merge(document)
103
+ instance_variables.each do |var|
104
+ val = document.instance_variable_get(var)
105
+ instance_variable_set(var, val) unless val.nil?
106
+ end
107
+
108
+ self
109
+ end
110
+
111
+ def self.update_old_code(code)
112
+ code = code.gsub("FIPS", "FIPS PUB") unless code.include?("FIPS PUB")
113
+ code.gsub("NBS MONO", "NBS MN").gsub("NIST MONO", "NIST MN")
114
+ .gsub("NIST MP", "NBS MP")
115
+ .gsub("NIST SP 304a-2017", "NIST SP 304A-2017")
116
+ .gsub("NIST SP 260-162 2006ed.", "NIST SP 260-162e2006")
117
+ .gsub("NBS CIRC 154suprev", "NBS CIRC 154r1sup")
118
+ .gsub("NIST SP 260-126 rev 2013", "NIST SP 260-126r2013")
119
+ .gsub("NIST CSWP", "NIST CSRC White Paper")
120
+ .gsub("NIST.CSWP.01162020pt", "NIST.CSWP.01162020(por)")
121
+ .gsub(/(?<=NBS MP )(\d+)\((\d+)\)/, '\1e\2')
122
+ .gsub(/(?<=\d)es/, "(spa)")
123
+ .gsub(/(?<=\d)chi/, "(zho)")
124
+ .gsub(/(?<=\d)viet/, "(vie)")
125
+ .gsub(/(?<=\d)port/, "(por)")
126
+ # .gsub(/^LCIRC/, "NBS LC")
127
+ end
128
+
51
129
  def self.parse(code)
130
+ code = update_old_code(code)
52
131
  matches = {
53
132
  publisher: match(Publisher.regexp, code) || "NIST",
54
- serie: match(Serie.regexp, code)&.gsub(/\./, " "),
55
- stage: match(Stage.regexp, code),
56
- docnumber: match(/(?<=\.|\s)[0-9-]{3,}[A-Z]?/, code),
57
- part: /(?<=(\.))?pt(?(1)-)([A-Z\d]+)/.match(code)&.[](2),
58
- volume: /(?<=(\.))?v(?(1)-)(\d+)/.match(code)&.[](2),
59
- version: match(/(?<=(\.))?ver(?(1)[-\d]|[.\d])+/, code)&.gsub(/-/, "."),
60
- revision: /(?<=[^a-z])(?<=(\.))?(?:r(?(1)-)|Rev\.\s)(\d+)/
61
- .match(code)&.[](2),
62
- addendum: match(/(?<=(\.))?(add(?(1)-)\d+|Addendum)/, code),
63
- translation: match(/(?<=\()\w{3}(?=\))/, code),
64
- update: match(/(?<=Upd\s)([\d:]+)/, code),
65
- edition: /(?<=[^a-z])(?<=(\.))?(?:e(?(1)-)|Ed\.\s)(\d+)/
133
+ serie: match(Serie.regexp, code),
134
+ stage: Stage.parse(code),
135
+ part: /(?<=(\.))?(?<![a-z])+(?:pt|Pt|p)(?(1)-)([A-Z\d]+)/.match(code)
136
+ &.[](2),
137
+ version:
138
+ /(?<=\.)?(?:(?:ver)((?(1)[-\d]|[.\d])+|\d+)|(?:v)(\d+\.[.\d]+))/
139
+ .match(code).to_a[1..-1]&.compact&.first&.gsub(/-/, "."),
140
+ revision: /[\da](?:r|Rev\.\s|([0-9]+[A-Za-z]*-[0-9]+[A-Za-z]*-))([\da]+)/
66
141
  .match(code)&.[](2),
142
+ addendum: match(/(?<=(\.))?(add(?:-\d+)?|Addendum)/, code),
143
+ edition: /(?<=[^a-z])(?<=\.)?(?:e(?(1)-)|Ed\.\s)(\d+)|
144
+ NBS\sFIPS\sPUB\s[0-9]+[A-Za-z]*-[0-9]+[A-Za-z]*-([A-Za-z\d]+)
145
+ /x.match(code)&.captures&.join,
146
+ section: /(?<=sec)\d+/.match(code)&.to_s,
147
+ appendix: /\d+app/.match(code)&.to_s,
148
+ errata: /-errata|\d+err(?:ata)?/.match(code)&.to_s,
149
+ index: /\d+index|\d+indx/.match(code)&.to_s,
150
+ insert: /\d+ins(?:ert)?/.match(code)&.to_s
67
151
  }
152
+ supplement = /(?:(?:supp?)-?(\d*)|Supplement|Suppl.)/
153
+ .match(code)
154
+ unless supplement.nil?
155
+ matches[:supplement] = supplement[1].nil? ? "" : supplement[1]
156
+ end
157
+
158
+ update = code.scan(/((?<=Upd)\s?[\d:]+|-upd)-?(\d*)/).first
159
+
160
+ (matches[:update_number], matches[:update_year]) = update if update
161
+
162
+ unless matches[:serie]
163
+ raise Errors::ParseError.new("failed to parse serie for #{code}")
164
+ end
165
+
166
+ unless matches[:stage].nil?
167
+ code = code.gsub(matches[:stage].original_code, "")
168
+ end
169
+
170
+ unless ["NBS CSM", "NBS CS"].include?(matches[:serie])
171
+ matches[:volume] = /(?<=(\.))?v(?(1)-)(\d+)(?!\.\d+)/.match(code)&.[](2)
172
+ end
173
+
174
+ matches[:revision] = nil if matches[:addendum]
175
+
176
+ matches[:docnumber] = parse_docnumber(matches[:serie], code)
177
+
178
+ matches[:serie] = SERIES["mr"].invert[matches[:serie]] || matches[:serie]
179
+ # matches[:serie].gsub!(/\./, " ")
180
+ matches[:translation] = match(/(?<=\()\w{3}(?=\))/, code)
181
+
68
182
  new(**matches)
69
183
  end
70
184
 
185
+ def self.parse_docnumber(serie, code)
186
+ localities = "[Pp]t\\d+|r(?:\\d+|[A-Za-z]?)|e\\d+|p|v|sec\\d+|inde?x|err(?:ata)?|ins(?:ert)?"
187
+ excluded_parts = "(?!#{localities}|supp?)"
188
+
189
+ if ["NBS CSM", "NBS CS"].include?(serie)
190
+ docnumber = /v(\d+)n(\d+)/.match(code).to_a[1..-1]&.join("-")
191
+ else
192
+ # match docnumbers with localities in the first part, like NBS CIRC 11e2-1915
193
+ docnumber =
194
+ /(?:#{serie.gsub(" ", "\s|\.")})(?:\s|\.)?([0-9]+)(?:#{localities})(-[0-9]+)?/
195
+ .match(code)&.captures&.join
196
+
197
+ docnumber ||=
198
+ /(?:#{serie.gsub(" ", "\s|\.")})(?:\s|\.)? # match serie
199
+ ([0-9]+ # first part of report number
200
+ (?:#{excluded_parts}[A-Za-z]+)? # with letter but without localities
201
+ (?:-m)? # for NBS CRPL 4-m-5
202
+ (?:-[A-Za]+)? # for NIST SP 1075-NCNR, NIST SP 1113-BFRL, NIST IR 6529-a
203
+ (?:-[0-9.]+)? # second part
204
+ (?:
205
+ (?: # only big letter
206
+ (#{excluded_parts}[A-Z]|(?![a-z]))+|#{excluded_parts}[a-z]?|#{excluded_parts}[a-z]+
207
+ )? # or small letter but without localities
208
+ )
209
+ )/x
210
+ .match(code)&.[](1)&.upcase
211
+ end
212
+
213
+ unless docnumber
214
+ raise Errors::ParseError.new(
215
+ "failed to parse document identifier for #{code}",
216
+ )
217
+ end
218
+
219
+ docnumber
220
+ end
221
+
71
222
  def self.match(regex, code)
72
223
  regex.match(code)&.to_s
73
224
  end
74
225
 
75
- def to_s(format)
76
- result = "#{render_serie(format)}#{stage.to_s(format)}"\
77
- "#{code}#{render_part(format)}#{render_edition(format)}"\
78
- "#{render_update(format)}#{render_translation(format)}"
226
+ def to_s(format = :short)
227
+ result = render_serie(format)
228
+ result += " " unless format == :short || stage.nil?
229
+ result += "#{stage&.to_s(format)}"\
230
+ " #{code}#{render_part(format)}#{render_edition(format)}"\
231
+ "#{render_localities(format)}"\
232
+ "#{render_update(format)}#{render_translation(format)}"
79
233
  result = render_addendum(result, format)
80
234
 
81
235
  return result.gsub(" ", ".") if format == :mr
@@ -83,14 +237,32 @@ module NistPubid
83
237
  result
84
238
  end
85
239
 
240
+ def to_json(*args)
241
+ result = {
242
+ styles: {
243
+ short: to_s(:short),
244
+ abbrev: to_s(:abbrev),
245
+ long: to_s(:long),
246
+ mr: to_s(:mr),
247
+ }
248
+ }
249
+
250
+ instance_variables.each do |var|
251
+ val = instance_variable_get(var)
252
+ result[var.to_s.gsub('@', '')] = val unless val.nil?
253
+ end
254
+ result.to_json(*args)
255
+ end
256
+
86
257
  def render_serie(format)
87
- return "#{serie.to_s(format)} " if %i[mr short].include?(format)
258
+ if serie.to_s(format).include?(publisher.to_s(format))
259
+ return serie.to_s(format)
260
+ end
88
261
 
89
- "#{publisher.to_s(format)} #{serie.to_s(format)} "
262
+ "#{publisher.to_s(format)} #{serie.to_s(format)}"
90
263
  end
91
264
 
92
265
  def render_part(format)
93
- # TODO: Section, Supplement, Index, Insert, Errata
94
266
  result = ""
95
267
  result += "#{VOLUME_DESC[format]}#{volume}" unless volume.nil?
96
268
  result += "#{PART_DESC[format]}#{part}" unless part.nil?
@@ -99,24 +271,44 @@ module NistPubid
99
271
 
100
272
  def render_edition(format)
101
273
  result = ""
102
- result += "#{REVISION_DESC[format]}#{revision}" unless revision.nil?
274
+
275
+ result += "#{REVISION_DESC[format]}#{revision.to_s.upcase}" if revision
103
276
  result += "#{VERSION_DESC[format]}#{version}" unless version.nil?
104
277
  result += "#{EDITION_DESC[format]}#{edition}" unless edition.nil?
105
278
  result
106
279
  end
107
280
 
281
+ def render_localities(format)
282
+ result = ""
283
+ result += "#{SUPPLEMENT_DESC[format]}#{supplement}" unless supplement.nil?
284
+ result += "#{SECTION_DESC[format]}#{section}" unless section.nil?
285
+ result += "#{APPENDIX_DESC[format]}" unless appendix.nil?
286
+ result += "#{ERRATA_DESC[format]}" unless errata.nil?
287
+ result += INDEX_DESC[format] unless index.nil?
288
+ result += INSERT_DESC[format] unless insert.nil?
289
+
290
+ result
291
+ end
292
+
108
293
  def render_update(format)
109
- return "" if update.nil?
294
+ return "" if update_year.nil?
295
+
296
+ if update_number.match?(/\d+/)
297
+ update_text = update_number
298
+ update_text += "-#{update_year}" if update_year
299
+ else
300
+ update_text = "1"
301
+ end
110
302
 
111
303
  case format
112
304
  when :long
113
- " Update #{update}"
305
+ " Update #{update_text}"
114
306
  when :abbrev
115
- " Upd. #{update}"
307
+ " Upd. #{update_text}"
116
308
  when :short
117
- "/Upd #{update}"
309
+ "/Upd#{update_text}"
118
310
  when :mr
119
- ".u#{update.gsub(":", "-")}"
311
+ ".u#{update_text}"
120
312
  end
121
313
  end
122
314
 
@@ -0,0 +1,5 @@
1
+ module NistPubid
2
+ module Errors
3
+ class ParseError < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,104 @@
1
+ require "relaton_nist/data_fetcher"
2
+ require "nokogiri"
3
+ require "open-uri"
4
+
5
+ module NistPubid
6
+ class NistTechPubs
7
+ URL = "https://raw.githubusercontent.com/usnistgov/NIST-Tech-Pubs/nist-pages/xml/allrecords.xml".freeze
8
+
9
+ @converted_id = @converted_doi = {}
10
+
11
+ class << self
12
+
13
+ attr_accessor :documents, :converted_id, :converted_doi
14
+
15
+ def fetch
16
+ @documents ||= Nokogiri::XML(URI.open(URL))
17
+ .xpath("/body/query/doi_record/report-paper/report-paper_metadata")
18
+ .map { |doc| parse_docid doc }
19
+ rescue StandardError => e
20
+ warn e.message
21
+ []
22
+ end
23
+
24
+ def convert(doc)
25
+ id = @converted_id[doc[:id]] ||= NistPubid::Document.parse(doc[:id])
26
+ return id unless doc.key?(:doi)
27
+
28
+ begin
29
+ doi = @converted_doi[doc[:doi]] ||=
30
+ NistPubid::Document.parse(doc[:doi])
31
+ rescue Errors::ParseError
32
+ return id
33
+ end
34
+ # return more complete pubid
35
+ id.merge(doi)
36
+ rescue Errors::ParseError
37
+ @converted_doi[doc[:doi]] ||= NistPubid::Document.parse(doc[:doi])
38
+ end
39
+
40
+ def parse_docid(doc)
41
+ id = doc.at("publisher_item/item_number", "publisher_item/identifier")
42
+ .text.sub(%r{^/}, "")
43
+ doi = doc.at("doi_data/doi").text.gsub("10.6028/", "")
44
+ title = doc.at("titles/title").text
45
+ title += " #{doc.at('titles/subtitle').text}" if doc.at("titles/subtitle")
46
+ case doi
47
+ when "10.6028/NBS.CIRC.12e2revjune" then id.sub!("13e", "12e")
48
+ when "10.6028/NBS.CIRC.36e2" then id.sub!("46e", "36e")
49
+ when "10.6028/NBS.HB.67suppJune1967" then id.sub!("1965", "1967")
50
+ when "10.6028/NBS.HB.105-1r1990" then id.sub!("105-1-1990", "105-1r1990")
51
+ when "10.6028/NIST.HB.150-10-1995" then id.sub!(/150-10$/, "150-10-1995")
52
+ end
53
+
54
+ { id: id, doi: doi, title: title }
55
+ end
56
+
57
+ def comply_with_pubid
58
+ fetch.select do |doc|
59
+ convert(doc).to_s == doc[:id]
60
+ rescue Errors::ParseError
61
+ false
62
+ end
63
+ end
64
+
65
+ def different_with_pubid
66
+ fetch.reject do |doc|
67
+ convert(doc).to_s == doc[:id]
68
+ rescue Errors::ParseError
69
+ true
70
+ end
71
+ end
72
+
73
+ def parse_fail_with_pubid
74
+ fetch.select do |doc|
75
+ convert(doc).to_s && false
76
+ rescue Errors::ParseError
77
+ true
78
+ end
79
+ end
80
+
81
+ # returning current document id, doi, title and final PubID
82
+ def status
83
+ fetch.map do |doc|
84
+ final_doc = convert(doc)
85
+ {
86
+ id: doc[:id],
87
+ doi: doc[:doi],
88
+ title: doc[:title],
89
+ finalPubId: final_doc.to_s,
90
+ mr: final_doc.to_s(:mr),
91
+ }
92
+ rescue Errors::ParseError
93
+ {
94
+ id: doc[:id],
95
+ doi: doc[:doi],
96
+ title: doc[:title],
97
+ finalPubId: "parse error",
98
+ mr: "parse_error"
99
+ }
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -9,7 +9,7 @@ module NistPubid
9
9
  @publisher = publisher
10
10
  end
11
11
 
12
- def to_s(format)
12
+ def to_s(format = :short)
13
13
  return @publisher if %i[short mr].include?(format)
14
14
 
15
15
  PUBLISHERS[format.to_s][@publisher]
@@ -8,7 +8,7 @@ module NistPubid
8
8
  @serie = serie == "NISTIR" ? "NIST IR" : serie
9
9
  end
10
10
 
11
- def to_s(format)
11
+ def to_s(format = :short)
12
12
  return @serie if %i[short mr].include?(format)
13
13
 
14
14
  result = SERIES[format.to_s][@serie]
@@ -18,7 +18,9 @@ module NistPubid
18
18
  end
19
19
 
20
20
  def self.regexp
21
- /(#{(SERIES["long"].keys + SERIES["mr"].values + ["NISTIR"]).join('|')})(?=\.|\s)/
21
+ /(#{(SERIES["long"].keys + SERIES["mr"].values
22
+ .map { |v| v.gsub(".", '\.') } + ["NISTIR"])
23
+ .sort_by(&:length).reverse.join('|')})/
22
24
  end
23
25
  end
24
26
  end
@@ -2,21 +2,36 @@ STAGES = YAML.load_file(File.join(File.dirname(__FILE__), "../../stages.yaml"))
2
2
 
3
3
  module NistPubid
4
4
  class Stage
5
- attr_accessor :stage
5
+ attr_accessor :stage, :original_code
6
6
 
7
- def initialize(stage:)
8
- @stage = stage
7
+ def initialize(original_code)
8
+ self.original_code = original_code
9
+ @stage = self.class.regexp.match(original_code)&.[](1)
9
10
  end
10
11
 
11
- def to_s(format)
12
- return "" if @stage.nil?
13
- return "#{@stage} " if %i[short mr].include?(format)
12
+ def to_s(format = :short)
13
+ return "" if nil?
14
14
 
15
- "#{STAGES[@stage]} "
15
+ case format
16
+ when :short
17
+ "(#{@stage})"
18
+ when :mr
19
+ @stage
20
+ else
21
+ STAGES[@stage]
22
+ end
23
+ end
24
+
25
+ def self.parse(code)
26
+ new(regexp.match(code)&.to_s)
16
27
  end
17
28
 
18
29
  def self.regexp
19
- /(#{STAGES.keys.join('|')})(?=\.|\s)/
30
+ /\((#{STAGES.keys.join('|')})\)/
31
+ end
32
+
33
+ def nil?
34
+ @stage.nil?
20
35
  end
21
36
  end
22
37
  end
@@ -1,3 +1,3 @@
1
1
  module NistPubid
2
- VERSION = "0.1.2".freeze
2
+ VERSION = "0.1.6".freeze
3
3
  end
data/lib/nist_pubid.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "yaml"
4
- require "nist_pubid/document"
5
- require "nist_pubid/publisher"
6
- require "nist_pubid/serie"
7
- require "nist_pubid/stage"
4
+ require_relative "nist_pubid/document"
5
+ require_relative "nist_pubid/publisher"
6
+ require_relative "nist_pubid/serie"
7
+ require_relative "nist_pubid/stage"
8
+ require_relative "nist_pubid/errors"
9
+ require_relative "nist_pubid/nist_tech_pubs"
data/nist_pubid.gemspec CHANGED
@@ -28,4 +28,10 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_development_dependency "rake", "~> 13.0"
30
30
  spec.add_development_dependency "rspec", "~> 3.0"
31
+ spec.add_development_dependency "vcr"
32
+ spec.add_development_dependency "webmock"
33
+
34
+ spec.add_dependency "relaton-nist"
35
+ spec.add_dependency "nokogiri"
36
+ spec.add_dependency "thor"
31
37
  end
data/series.yaml CHANGED
@@ -87,7 +87,7 @@ mr:
87
87
  NBS BH: NBS.BH
88
88
  NBS CRPL: NBS.CRPL
89
89
  NBS CRPL-F-A: NBS.CRPL-F-A
90
- NBS CRPL-F-B: NBS CRPL-F-B245
90
+ NBS CRPL-F-B: NBS CRPL-F-B
91
91
  NBS IP: NBS.IP
92
92
  NBS CIRC: NBS.CIRC
93
93
  NBS CIS: NBS.CIS
data/stages.yaml CHANGED
@@ -2,4 +2,4 @@ IPD: Initial Public Draft
2
2
  2PD: Second Public Draft
3
3
  FPD: Final Public Draft
4
4
  WD: Work-in-Progress Draft
5
- PreD: Preliminary Draft
5
+ PRD: Preliminary Draft
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nist-pubid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.6
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-12-08 00:00:00.000000000 Z
11
+ date: 2022-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -38,24 +38,99 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: vcr
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: relaton-nist
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nokogiri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thor
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
41
111
  description: Library to generate, parse and manipulate NIST PubID.
42
112
  email:
43
113
  - open.source@ribose.com
44
- executables: []
114
+ executables:
115
+ - nist-pubid
45
116
  extensions: []
46
117
  extra_rdoc_files:
47
118
  - README.adoc
48
119
  - LICENSE.txt
49
120
  files:
50
121
  - ".github/workflows/rake.yml"
122
+ - ".github/workflows/release.yml"
51
123
  - ".rspec"
52
124
  - ".rubocop.yml"
53
125
  - Gemfile
54
126
  - LICENSE.txt
55
127
  - README.adoc
56
128
  - Rakefile
129
+ - exe/nist-pubid
57
130
  - lib/nist_pubid.rb
58
131
  - lib/nist_pubid/document.rb
132
+ - lib/nist_pubid/errors.rb
133
+ - lib/nist_pubid/nist_tech_pubs.rb
59
134
  - lib/nist_pubid/publisher.rb
60
135
  - lib/nist_pubid/serie.rb
61
136
  - lib/nist_pubid/stage.rb
@@ -83,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
158
  - !ruby/object:Gem::Version
84
159
  version: '0'
85
160
  requirements: []
86
- rubygems_version: 3.1.4
161
+ rubygems_version: 3.3.3
87
162
  signing_key:
88
163
  specification_version: 4
89
164
  summary: Library to generate, parse and manipulate NIST PubID.