relaton-iec 0.8.0 → 1.1.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 +4 -4
- data/README.adoc +1 -1
- data/grammars/basicdoc.rng +986 -0
- data/grammars/biblio.rng +1237 -0
- data/grammars/iec.rng +43 -0
- data/grammars/isodoc.rng +1077 -0
- data/{grammars → grammars/isostandard.rng} +145 -472
- data/grammars/reqt.rng +165 -0
- data/lib/relaton_iec.rb +12 -9
- data/lib/relaton_iec/hash_converter.rb +14 -0
- data/lib/relaton_iec/hit.rb +2 -41
- data/lib/relaton_iec/hit_collection.rb +3 -37
- data/lib/relaton_iec/iec_bibliographic_item.rb +9 -0
- data/lib/relaton_iec/iec_bibliography.rb +16 -18
- data/lib/relaton_iec/processor.rb +7 -7
- data/lib/relaton_iec/scrapper.rb +41 -135
- data/lib/relaton_iec/version.rb +1 -1
- data/lib/relaton_iec/xml_parser.rb +14 -0
- data/relaton_iec.gemspec +6 -5
- metadata +29 -7
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_iec.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
require "relaton_iec/version"
|
2
2
|
require "relaton_iec/iec_bibliography"
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# return if caller.detect { |c| c.include? "register_gems" }
|
8
|
-
|
9
|
-
# Relaton::Registry.instance.register(RelatonIec::Processor)
|
10
|
-
# end
|
3
|
+
require "relaton_iec/iec_bibliographic_item"
|
4
|
+
require "relaton_iec/xml_parser"
|
5
|
+
require "relaton_iec/hash_converter"
|
6
|
+
require "digest/md5"
|
11
7
|
|
12
8
|
module RelatonIec
|
13
|
-
#
|
9
|
+
# Returns hash of XML reammar
|
10
|
+
# @return [String]
|
11
|
+
def self.grammar_hash
|
12
|
+
gem_path = File.expand_path "..", __dir__
|
13
|
+
grammars_path = File.join gem_path, "grammars", "*"
|
14
|
+
grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
|
15
|
+
Digest::MD5.hexdigest grammars
|
16
|
+
end
|
14
17
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RelatonIec
|
2
|
+
class HashConverter < RelatonIsoBib::HashConverter
|
3
|
+
class << self
|
4
|
+
#
|
5
|
+
# Ovverides superclass's method
|
6
|
+
#
|
7
|
+
# @param item [Hash]
|
8
|
+
# @retirn [RelatonIec::IecBibliographicItem]
|
9
|
+
def bib_item(item)
|
10
|
+
IecBibliographicItem.new(item)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/relaton_iec/hit.rb
CHANGED
@@ -2,50 +2,11 @@
|
|
2
2
|
|
3
3
|
module RelatonIec
|
4
4
|
# Hit.
|
5
|
-
class Hit
|
6
|
-
# @return [Isobib::HitCollection]
|
7
|
-
attr_reader :hit_collection
|
8
|
-
|
9
|
-
# @return [Array<Hash>]
|
10
|
-
attr_reader :hit
|
11
|
-
|
12
|
-
# @param hit [Hash]
|
13
|
-
# @param hit_collection [Isobib:HitCollection]
|
14
|
-
def initialize(hit, hit_collection = nil)
|
15
|
-
@hit = hit
|
16
|
-
@hit_collection = hit_collection
|
17
|
-
end
|
18
|
-
|
5
|
+
class Hit < RelatonBib::Hit
|
19
6
|
# Parse page.
|
20
|
-
# @return [
|
7
|
+
# @return [RelatonIec::IecBibliographicItem]
|
21
8
|
def fetch
|
22
9
|
@fetch ||= Scrapper.parse_page @hit
|
23
10
|
end
|
24
|
-
|
25
|
-
# @return [String]
|
26
|
-
def to_s
|
27
|
-
inspect
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [String]
|
31
|
-
def inspect
|
32
|
-
"<#{self.class}:#{format('%#.14x', object_id << 1)} "\
|
33
|
-
"@text=\"#{@hit_collection&.text}\" "\
|
34
|
-
"@fetched=\"#{!@fetch.nil?}\" "\
|
35
|
-
"@fullIdentifier=\"#{@fetch&.shortref(nil)}\" "\
|
36
|
-
"@title=\"#{@hit[:code]}\">"
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [String]
|
40
|
-
def to_xml(opts = {})
|
41
|
-
#if builder
|
42
|
-
#fetch.to_xml builder, opts
|
43
|
-
#else
|
44
|
-
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
45
|
-
fetch.to_xml xml, opts
|
46
|
-
end
|
47
|
-
builder.doc.root.to_xml
|
48
|
-
#end
|
49
|
-
end
|
50
11
|
end
|
51
12
|
end
|
@@ -5,24 +5,13 @@ require "addressable/uri"
|
|
5
5
|
|
6
6
|
module RelatonIec
|
7
7
|
# Page of hit collection.
|
8
|
-
class HitCollection <
|
9
|
-
|
8
|
+
class HitCollection < RelatonBib::HitCollection
|
10
9
|
DOMAIN = "https://webstore.iec.ch"
|
11
10
|
|
12
|
-
# @return [TrueClass, FalseClass]
|
13
|
-
attr_reader :fetched
|
14
|
-
|
15
|
-
# @return [String]
|
16
|
-
attr_reader :text
|
17
|
-
|
18
|
-
# @return [String]
|
19
|
-
attr_reader :year
|
20
|
-
|
21
11
|
# @param ref_nbr [String]
|
22
12
|
# @param year [String]
|
23
13
|
def initialize(ref_nbr, year = nil) #(text, hit_pages = nil)
|
24
|
-
|
25
|
-
@year = year
|
14
|
+
super
|
26
15
|
from, to = nil
|
27
16
|
if year
|
28
17
|
from = Date.strptime year, "%Y"
|
@@ -30,36 +19,13 @@ module RelatonIec
|
|
30
19
|
end
|
31
20
|
url = "#{DOMAIN}/searchkey&RefNbr=#{ref_nbr}&From=#{from}&To=#{to}&start=1"
|
32
21
|
doc = Nokogiri::HTML OpenURI.open_uri(::Addressable::URI.parse(url).normalize)
|
33
|
-
|
22
|
+
@array = doc.css("ul.search-results > li").map do |h|
|
34
23
|
link = h.at('a[@href!="#"]')
|
35
24
|
code = link.text.tr [194, 160].pack("c*").force_encoding("UTF-8"), ""
|
36
25
|
title = h.xpath("text()").text.gsub(/[\r\n]/, "")
|
37
26
|
url = DOMAIN + link[:href]
|
38
27
|
Hit.new({ code: code, title: title, url: url }, self)
|
39
28
|
end
|
40
|
-
concat hits
|
41
|
-
@fetched = false
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [RelatonIec::HitCollection]
|
45
|
-
def fetch
|
46
|
-
workers = RelatonBib::WorkersPool.new 4
|
47
|
-
workers.worker(&:fetch)
|
48
|
-
each do |hit|
|
49
|
-
workers << hit
|
50
|
-
end
|
51
|
-
workers.end
|
52
|
-
workers.result
|
53
|
-
@fetched = true
|
54
|
-
self
|
55
|
-
end
|
56
|
-
|
57
|
-
def to_s
|
58
|
-
inspect
|
59
|
-
end
|
60
|
-
|
61
|
-
def inspect
|
62
|
-
"<#{self.class}:#{format('%#.14x', object_id << 1)} @fetched=#{@fetched}>"
|
63
29
|
end
|
64
30
|
end
|
65
31
|
end
|
@@ -17,15 +17,10 @@ module RelatonIec
|
|
17
17
|
raise RelatonBib::RequestError, "Could not access http://www.iec.ch"
|
18
18
|
end
|
19
19
|
|
20
|
-
# @param text [String]
|
21
|
-
# @return [Array<IsoBibliographicItem>]
|
22
|
-
# def search_and_fetch(text, year = nil)
|
23
|
-
# Scrapper.get(text, year)
|
24
|
-
# end
|
25
|
-
|
26
20
|
# @param code [String] the ISO standard Code to look up (e..g "ISO 9000")
|
27
21
|
# @param year [String] the year the standard was published (optional)
|
28
|
-
# @param opts [Hash] options; restricted to :all_parts if all-parts
|
22
|
+
# @param opts [Hash] options; restricted to :all_parts if all-parts
|
23
|
+
# reference is required
|
29
24
|
# @return [String] Relaton XML serialisation of reference
|
30
25
|
def get(code, year = nil, opts = {})
|
31
26
|
if year.nil?
|
@@ -43,8 +38,8 @@ module RelatonIec
|
|
43
38
|
ret = iecbib_get1(code, year, opts)
|
44
39
|
return nil if ret.nil?
|
45
40
|
|
46
|
-
ret.to_most_recent_reference unless year || opts[:keep_year]
|
47
|
-
ret.to_all_parts if opts[:all_parts]
|
41
|
+
ret = ret.to_most_recent_reference unless year || opts[:keep_year]
|
42
|
+
ret = ret.to_all_parts if opts[:all_parts]
|
48
43
|
ret
|
49
44
|
end
|
50
45
|
|
@@ -52,15 +47,15 @@ module RelatonIec
|
|
52
47
|
|
53
48
|
def fetch_ref_err(code, year, missed_years)
|
54
49
|
id = year ? "#{code}:#{year}" : code
|
55
|
-
warn "WARNING: no match found online for #{id}. "\
|
50
|
+
warn "[relaton-iec] WARNING: no match found online for #{id}. "\
|
56
51
|
"The code must be exactly like it is on the standards website."
|
57
|
-
warn "(There was no match for #{year}, though there were matches "\
|
52
|
+
warn "[relaton-iec] (There was no match for #{year}, though there were matches "\
|
58
53
|
"found for #{missed_years.join(', ')}.)" unless missed_years.empty?
|
59
54
|
if /\d-\d/ =~ code
|
60
|
-
warn "The provided document part may not exist, or the document "\
|
55
|
+
warn "[relaton-iec] The provided document part may not exist, or the document "\
|
61
56
|
"may no longer be published in parts."
|
62
57
|
else
|
63
|
-
warn "If you wanted to cite all document parts for the reference, "\
|
58
|
+
warn "[relaton-iec] If you wanted to cite all document parts for the reference, "\
|
64
59
|
"use \"#{code} (all parts)\".\nIf the document is not a standard, "\
|
65
60
|
"use its document type abbreviation (TS, TR, PAS, Guide)."
|
66
61
|
end
|
@@ -72,13 +67,13 @@ module RelatonIec
|
|
72
67
|
workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
|
73
68
|
s.each_with_index { |hit, i| workers << { i: i, hit: hit } }
|
74
69
|
workers.end
|
75
|
-
workers.result.
|
70
|
+
workers.result.sort_by { |a| a[:i] }.map { |x| x[:hit] }
|
76
71
|
end
|
77
72
|
|
78
73
|
def isobib_search_filter(code)
|
79
74
|
docidrx = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+}
|
80
75
|
corrigrx = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+:[0-9]+/}
|
81
|
-
warn "
|
76
|
+
warn "[relaton-iec] (\"#{code}\") fetching..."
|
82
77
|
result = search(code)
|
83
78
|
result.select do |i|
|
84
79
|
i.hit[:code] &&
|
@@ -147,9 +142,12 @@ module RelatonIec
|
|
147
142
|
|
148
143
|
result = isobib_search_filter(code) || return
|
149
144
|
ret = isobib_results_filter(result, year)
|
150
|
-
|
151
|
-
|
152
|
-
|
145
|
+
if ret[:ret]
|
146
|
+
warn "[relaton-iec] (\"#{code}\") found #{ret[:ret].docidentifier.first.id}"
|
147
|
+
ret[:ret]
|
148
|
+
else
|
149
|
+
fetch_ref_err(code, year, ret[:years])
|
150
|
+
end
|
153
151
|
end
|
154
152
|
end
|
155
153
|
end
|
@@ -12,28 +12,28 @@ module RelatonIec
|
|
12
12
|
# @param code [String]
|
13
13
|
# @param date [String, NilClass] year
|
14
14
|
# @param opts [Hash]
|
15
|
-
# @return [RelatonIsoBib::
|
15
|
+
# @return [RelatonIsoBib::IecBibliographicItem]
|
16
16
|
def get(code, date, opts)
|
17
17
|
::RelatonIec::IecBibliography.get(code, date, opts)
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param xml [String]
|
21
|
-
# @return [RelatonIsoBib::
|
21
|
+
# @return [RelatonIsoBib::IecBibliographicItem]
|
22
22
|
def from_xml(xml)
|
23
|
-
|
23
|
+
RelatonIec::XMLParser.from_xml xml
|
24
24
|
end
|
25
25
|
|
26
26
|
# @param hash [Hash]
|
27
|
-
# @return [RelatonIsoBib::
|
27
|
+
# @return [RelatonIsoBib::IecBibliographicItem]
|
28
28
|
def hash_to_bib(hash)
|
29
|
-
item_hash = ::
|
30
|
-
::
|
29
|
+
item_hash = ::RelatonIec::HashConverter.hash_to_bib(hash)
|
30
|
+
::RelatonIec::IecBibliographicItem.new item_hash
|
31
31
|
end
|
32
32
|
|
33
33
|
# Returns hash of XML grammar
|
34
34
|
# @return [String]
|
35
35
|
def grammar_hash
|
36
|
-
@grammar_hash ||= ::
|
36
|
+
@grammar_hash ||= ::RelatonIec.grammar_hash
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|