relaton-bipm 1.4.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 +7 -0
- data/.github/workflows/macos.yml +32 -0
- data/.github/workflows/ubuntu.yml +32 -0
- data/.github/workflows/windows.yml +35 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/rspec +29 -0
- data/bin/setup +8 -0
- data/grammars/basicdoc.rng +986 -0
- data/grammars/biblio.rng +1237 -0
- data/grammars/isodoc.rng +1613 -0
- data/grammars/reqt.rng +165 -0
- data/lib/relaton_bipm.rb +24 -0
- data/lib/relaton_bipm/bibliographic_date.rb +5 -0
- data/lib/relaton_bipm/bipm_bibliographic_item.rb +69 -0
- data/lib/relaton_bipm/bipm_bibliography.rb +43 -0
- data/lib/relaton_bipm/comment_periond.rb +41 -0
- data/lib/relaton_bipm/document_relation.rb +5 -0
- data/lib/relaton_bipm/document_status.rb +31 -0
- data/lib/relaton_bipm/hash_converter.rb +73 -0
- data/lib/relaton_bipm/processor.rb +41 -0
- data/lib/relaton_bipm/project_team.rb +48 -0
- data/lib/relaton_bipm/version.rb +3 -0
- data/lib/relaton_bipm/xml_parser.rb +86 -0
- data/relaton_bipm.gemspec +46 -0
- metadata +217 -0
data/grammars/reqt.rng
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
3
|
+
<!--
|
4
|
+
Presupposes isodoc.rnc, is included in it
|
5
|
+
include "isodoc.rnc" { }
|
6
|
+
-->
|
7
|
+
<define name="requirement">
|
8
|
+
<element name="requirement">
|
9
|
+
<ref name="RequirementType"/>
|
10
|
+
</element>
|
11
|
+
</define>
|
12
|
+
<define name="recommendation">
|
13
|
+
<element name="recommendation">
|
14
|
+
<ref name="RequirementType"/>
|
15
|
+
</element>
|
16
|
+
</define>
|
17
|
+
<define name="permission">
|
18
|
+
<element name="permission">
|
19
|
+
<ref name="RequirementType"/>
|
20
|
+
</element>
|
21
|
+
</define>
|
22
|
+
<define name="RequirementType">
|
23
|
+
<optional>
|
24
|
+
<attribute name="obligation">
|
25
|
+
<ref name="ObligationType"/>
|
26
|
+
</attribute>
|
27
|
+
</optional>
|
28
|
+
<optional>
|
29
|
+
<attribute name="unnumbered">
|
30
|
+
<data type="boolean"/>
|
31
|
+
</attribute>
|
32
|
+
</optional>
|
33
|
+
<optional>
|
34
|
+
<attribute name="subsequence"/>
|
35
|
+
</optional>
|
36
|
+
<attribute name="id">
|
37
|
+
<data type="ID"/>
|
38
|
+
</attribute>
|
39
|
+
<optional>
|
40
|
+
<attribute name="filename"/>
|
41
|
+
</optional>
|
42
|
+
<optional>
|
43
|
+
<ref name="reqtitle"/>
|
44
|
+
</optional>
|
45
|
+
<optional>
|
46
|
+
<ref name="label"/>
|
47
|
+
</optional>
|
48
|
+
<optional>
|
49
|
+
<ref name="subject"/>
|
50
|
+
</optional>
|
51
|
+
<optional>
|
52
|
+
<ref name="reqinherit"/>
|
53
|
+
</optional>
|
54
|
+
<zeroOrMore>
|
55
|
+
<ref name="classification"/>
|
56
|
+
</zeroOrMore>
|
57
|
+
<zeroOrMore>
|
58
|
+
<choice>
|
59
|
+
<ref name="measurementtarget"/>
|
60
|
+
<ref name="specification"/>
|
61
|
+
<ref name="verification"/>
|
62
|
+
<ref name="import"/>
|
63
|
+
<ref name="description"/>
|
64
|
+
</choice>
|
65
|
+
</zeroOrMore>
|
66
|
+
<optional>
|
67
|
+
<ref name="reqt_references"/>
|
68
|
+
</optional>
|
69
|
+
<zeroOrMore>
|
70
|
+
<choice>
|
71
|
+
<ref name="requirement"/>
|
72
|
+
<ref name="recommendation"/>
|
73
|
+
<ref name="permission"/>
|
74
|
+
</choice>
|
75
|
+
</zeroOrMore>
|
76
|
+
</define>
|
77
|
+
<define name="reqtitle">
|
78
|
+
<element name="title">
|
79
|
+
<ref name="FormattedString"/>
|
80
|
+
</element>
|
81
|
+
</define>
|
82
|
+
<define name="label">
|
83
|
+
<element name="label">
|
84
|
+
<text/>
|
85
|
+
</element>
|
86
|
+
</define>
|
87
|
+
<define name="subject">
|
88
|
+
<element name="subject">
|
89
|
+
<text/>
|
90
|
+
</element>
|
91
|
+
</define>
|
92
|
+
<define name="reqinherit">
|
93
|
+
<element name="inherit">
|
94
|
+
<text/>
|
95
|
+
</element>
|
96
|
+
</define>
|
97
|
+
<define name="measurementtarget">
|
98
|
+
<element name="measurement-target">
|
99
|
+
<ref name="RequirementSubpart"/>
|
100
|
+
</element>
|
101
|
+
</define>
|
102
|
+
<define name="specification">
|
103
|
+
<element name="specification">
|
104
|
+
<ref name="RequirementSubpart"/>
|
105
|
+
</element>
|
106
|
+
</define>
|
107
|
+
<define name="verification">
|
108
|
+
<element name="verification">
|
109
|
+
<ref name="RequirementSubpart"/>
|
110
|
+
</element>
|
111
|
+
</define>
|
112
|
+
<define name="import">
|
113
|
+
<element name="import">
|
114
|
+
<ref name="RequirementSubpart"/>
|
115
|
+
</element>
|
116
|
+
</define>
|
117
|
+
<define name="description">
|
118
|
+
<element name="description">
|
119
|
+
<ref name="RequirementSubpart"/>
|
120
|
+
</element>
|
121
|
+
</define>
|
122
|
+
<define name="reqt_references">
|
123
|
+
<element name="references">
|
124
|
+
<oneOrMore>
|
125
|
+
<ref name="bibitem"/>
|
126
|
+
</oneOrMore>
|
127
|
+
</element>
|
128
|
+
</define>
|
129
|
+
<define name="RequirementSubpart">
|
130
|
+
<optional>
|
131
|
+
<attribute name="type"/>
|
132
|
+
</optional>
|
133
|
+
<optional>
|
134
|
+
<attribute name="exclude">
|
135
|
+
<data type="boolean"/>
|
136
|
+
</attribute>
|
137
|
+
</optional>
|
138
|
+
<oneOrMore>
|
139
|
+
<ref name="BasicBlock"/>
|
140
|
+
</oneOrMore>
|
141
|
+
</define>
|
142
|
+
<define name="ObligationType">
|
143
|
+
<choice>
|
144
|
+
<value>requirement</value>
|
145
|
+
<value>recommendation</value>
|
146
|
+
<value>permission</value>
|
147
|
+
</choice>
|
148
|
+
</define>
|
149
|
+
<define name="classification">
|
150
|
+
<element name="classification">
|
151
|
+
<ref name="classification_tag"/>
|
152
|
+
<ref name="classification_value"/>
|
153
|
+
</element>
|
154
|
+
</define>
|
155
|
+
<define name="classification_tag">
|
156
|
+
<element name="tag">
|
157
|
+
<text/>
|
158
|
+
</element>
|
159
|
+
</define>
|
160
|
+
<define name="classification_value">
|
161
|
+
<element name="value">
|
162
|
+
<text/>
|
163
|
+
</element>
|
164
|
+
</define>
|
165
|
+
</grammar>
|
data/lib/relaton_bipm.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "relaton_bib"
|
2
|
+
require "relaton_bipm/version"
|
3
|
+
require "relaton_bipm/project_team"
|
4
|
+
require "relaton_bipm/bibliographic_date"
|
5
|
+
require "relaton_bipm/document_relation"
|
6
|
+
require "relaton_bipm/comment_periond"
|
7
|
+
require "relaton_bipm/document_status"
|
8
|
+
require "relaton_bipm/bipm_bibliographic_item"
|
9
|
+
require "relaton_bipm/bipm_bibliography"
|
10
|
+
require "relaton_bipm/hash_converter"
|
11
|
+
require "relaton_bipm/xml_parser"
|
12
|
+
|
13
|
+
module RelatonBipm
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
# Returns hash of XML reammar
|
17
|
+
# @return [String]
|
18
|
+
def self.grammar_hash
|
19
|
+
gem_path = File.expand_path "..", __dir__
|
20
|
+
grammars_path = File.join gem_path, "grammars", "*"
|
21
|
+
grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
|
22
|
+
Digest::MD5.hexdigest grammars
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RelatonBipm
|
2
|
+
class BipmBibliographicItem < RelatonBib::BibliographicItem
|
3
|
+
include RelatonBib
|
4
|
+
|
5
|
+
TYPES = %w[brochure mise-en-pratique rapport monographie guide
|
6
|
+
meeting-report technical-report working-party-note strategy
|
7
|
+
cipm-mra resolutions].freeze
|
8
|
+
|
9
|
+
STATUSES = %w[draft-proposal draft-development in-force retired].freeze
|
10
|
+
|
11
|
+
# @return [Array<RelatonBipm::BipmProjectTeam>]
|
12
|
+
attr_reader :project_group
|
13
|
+
|
14
|
+
# @return [RelatonIho::CommentPeriod, NilClass]
|
15
|
+
attr_reader :commentperiod
|
16
|
+
|
17
|
+
# @param project_group [Array<RelatonBipm::ProjectTeam>]
|
18
|
+
# @param title [Array<RelatonBib::FormattedString>]
|
19
|
+
# @param date [Array<RelatonBipm::BibliographicDate>]
|
20
|
+
# @param relation [Array<RelatonBipm::DocumentRelation>]
|
21
|
+
# @param docstatus [RelatonBipm::DocumentStatus, nil]
|
22
|
+
# @param commentperiod [RelatonBipm::CommentPeriod, NilClass]
|
23
|
+
def initialize(**args)
|
24
|
+
if args[:docstatus] && !STATUSES.include?(args[:docstatus].status)
|
25
|
+
warn "[relaton-bipm] Warning: invalid docstatus #{args[:docstatus]}. "\
|
26
|
+
"It should be one of: #{STATUSES}"
|
27
|
+
end
|
28
|
+
@project_group = args.delete(:project_group) || []
|
29
|
+
# @status = args.delete :docstatus
|
30
|
+
@commentperiod = args.delete :commentperiod
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param builder [Nokogiri::XML::Builder]
|
35
|
+
# @param bibdata [TrueClasss, FalseClass, NilClass]
|
36
|
+
def to_xml(builer = nil, **opts) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
37
|
+
opts[:ext] = !commentperiod.nil?
|
38
|
+
super do |b|
|
39
|
+
if opts[:bibdata] && (doctype || editorialgroup&.presence? ||
|
40
|
+
ics.any? || commentperiod)
|
41
|
+
b.ext do
|
42
|
+
b.doctype doctype if doctype
|
43
|
+
editorialgroup&.to_xml b
|
44
|
+
ics.each { |i| i.to_xml b }
|
45
|
+
project_group.each { |pg| pg.to_xml b }
|
46
|
+
commentperiod&.to_xml b
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Hash]
|
53
|
+
def to_hash
|
54
|
+
hash = super
|
55
|
+
hash["project_group"] = single_element_array project_group
|
56
|
+
hash["commentperiod"] = commentperiod.to_hash if commentperiod
|
57
|
+
hash
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param prefix [String]
|
61
|
+
# @return [String]
|
62
|
+
def to_asciibib(prefix = "")
|
63
|
+
out = super
|
64
|
+
project_group.each { |p| out += p.to_asciibib prefix, project_group.size }
|
65
|
+
out += commentperiod.to_asciibib prefix if commentperiod
|
66
|
+
out
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "net/http"
|
2
|
+
|
3
|
+
module RelatonBipm
|
4
|
+
class BipmBibliography
|
5
|
+
ENDPOINT = "https://raw.githubusercontent.com/relaton/relaton-data-bipm/master/data/"
|
6
|
+
.freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# @param text [String]
|
10
|
+
# @return [RelatonBipm::BipmBibliographicItem]
|
11
|
+
def search(text, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
12
|
+
warn "[relaton-bipm] (\"#{text}\") fetching..."
|
13
|
+
ref = text.sub(/^BIPM\s/, "").downcase # .sub /^([[:alpha:]]+)(\d+)/, '\1-\2'
|
14
|
+
uri = URI("#{ENDPOINT}#{ref}.yaml")
|
15
|
+
resp = Net::HTTP.get_response uri
|
16
|
+
return unless resp.code == "200"
|
17
|
+
|
18
|
+
hash = HashConverter.hash_to_bib YAML.safe_load(resp.body, [Date])
|
19
|
+
item = BipmBibliographicItem.new hash
|
20
|
+
warn "[relaton-bipm] (\"#{text}\") found #{item.docidentifier.first.id}"
|
21
|
+
item
|
22
|
+
rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
23
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
24
|
+
Net::ProtocolError, Net::ReadTimeout, # OpenSSL::SSL::SSLError,
|
25
|
+
Errno::ETIMEDOUT => e
|
26
|
+
raise RelatonBib::RequestError, "Could not access #{uri}: #{e.message}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param ref [String] the BIPM standard Code to look up (e..g "BIPM B-11")
|
30
|
+
# @param year [String] the year the standard was published (optional)
|
31
|
+
#
|
32
|
+
# @param opts [Hash] options
|
33
|
+
# @option opts [TrueClass, FalseClass] :all_parts restricted to all parts
|
34
|
+
# if all-parts reference is required
|
35
|
+
# @option opts [TrueClass, FalseClass] :bibdata
|
36
|
+
#
|
37
|
+
# @return [RelatonBipm::BipmBibliographicItem]
|
38
|
+
def get(ref, year = nil, opts = {})
|
39
|
+
search(ref, year, opts)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RelatonBipm
|
2
|
+
class CommentPeriond
|
3
|
+
# @return [Date]
|
4
|
+
attr_reader :from
|
5
|
+
|
6
|
+
# @return [Date, NilClass]
|
7
|
+
attr_reader :to
|
8
|
+
|
9
|
+
# @param from [String] date
|
10
|
+
# @parma to [String, NilClass] date
|
11
|
+
def initialize(from:, to: nil)
|
12
|
+
@from = Date.parse from
|
13
|
+
@to = Date.parse to if to
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param builder [Nokogiri::XML::builder]
|
17
|
+
def to_xml(builder)
|
18
|
+
builder.commentperiod do
|
19
|
+
builder.from from.to_s
|
20
|
+
builder.to to.to_s if to
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Hash]
|
25
|
+
def to_hash
|
26
|
+
hash = { "from" => from.to_s }
|
27
|
+
hash["to"] = to.to_s if to
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param prefix [String]
|
32
|
+
# @return [String]
|
33
|
+
def to_asciibib(prefix)
|
34
|
+
pref = prefix.empty? ? prefix : prefix + "."
|
35
|
+
pref += "commentperiod"
|
36
|
+
out = "#{pref}.from:: #{from}\n"
|
37
|
+
out += "#{pref}.to:: #{to}\n" if to
|
38
|
+
out
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RelatonBipm
|
4
|
+
# Document status.
|
5
|
+
class DocumentStatus
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :status
|
8
|
+
|
9
|
+
# @param status [String]
|
10
|
+
def initialize(status)
|
11
|
+
@status = status
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [Nokogiri::XML::Builder]
|
15
|
+
def to_xml(builder)
|
16
|
+
builder.status status
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
def to_hash
|
21
|
+
status
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param prefix [String]
|
25
|
+
# @return [String]
|
26
|
+
def to_asciibib(prefix = "")
|
27
|
+
pref = prefix.empty? ? prefix : prefix + "."
|
28
|
+
"#{pref}docstatus:: #{status}\n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module RelatonBipm
|
4
|
+
class HashConverter < RelatonBib::HashConverter
|
5
|
+
class << self
|
6
|
+
# @override RelatonIsoBib::HashConverter.hash_to_bib
|
7
|
+
# @param args [Hash]
|
8
|
+
# @param nested [TrueClass, FalseClass]
|
9
|
+
# @return [Hash]
|
10
|
+
def hash_to_bib(args, nested = false)
|
11
|
+
ret = super
|
12
|
+
return if ret.nil?
|
13
|
+
|
14
|
+
project_group_hash_to_bib ret
|
15
|
+
commentperiod_hash_to_bib ret
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @param item_hash [Hash]
|
22
|
+
# @return [RelatonBib::BibliographicItem]
|
23
|
+
def bib_item(item_hash)
|
24
|
+
BipmBibliographicItem.new item_hash
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param ret [Hash]
|
28
|
+
def title_hash_to_bib(ret)
|
29
|
+
ret[:title] &&= array(ret[:title]).map do |t|
|
30
|
+
if t.is_a? Hash
|
31
|
+
RelatonBib::FormattedString.new t
|
32
|
+
else
|
33
|
+
RelatonBib::FormattedString.new content: t
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param ret [Hash]
|
39
|
+
def docstatus_hash_to_bib(ret)
|
40
|
+
ret[:docstatus] &&= DocumentStatus.new ret[:docstatus]
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param ret [Hash]
|
44
|
+
def commentperiod_hash_to_bib(ret)
|
45
|
+
ret[:commentperiod] &&= CommentPeriond.new(ret[:commentperiod])
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param ret [Hash]
|
49
|
+
def project_group_hash_to_bib(ret)
|
50
|
+
ret[:project_group] &&= array(ret[:project_group]).map do |pg|
|
51
|
+
wg = RelatonBib::FormattedString.new pg[:workgroup]
|
52
|
+
ProjectTeam.new(committee: pg[:committee], workgroup: wg)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param ret [Hash]
|
57
|
+
def dates_hash_to_bib(ret)
|
58
|
+
super
|
59
|
+
ret[:date] &&= ret[:date].map do |d|
|
60
|
+
BibliographicDate.new d
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param ret [Hash]
|
65
|
+
def relations_hash_to_bib(ret)
|
66
|
+
super
|
67
|
+
ret[:relation] &&= ret[:relation].map do |r|
|
68
|
+
RelatonBipm::DocumentRelation.new r
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|