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