pubid-iso 0.1.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +177 -0
- data/lib/pubid/iso/identifier/french.rb +32 -0
- data/lib/pubid/iso/identifier/russian.rb +41 -0
- data/lib/pubid/iso/identifier.rb +175 -30
- data/lib/pubid/iso/parser.rb +110 -29
- data/lib/pubid/iso/transformer.rb +86 -9
- data/lib/pubid/iso/urn.rb +79 -24
- data/lib/pubid/iso/version.rb +1 -1
- data/lib/pubid/iso.rb +3 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9a5dae3e19189666e2259f498813de7aa502ee7d68e1ec4567d493be74e3acb
|
4
|
+
data.tar.gz: f7834ffc05c7eaeec131aaef54804512d2e6d9e5494da8fe286e9730493dd7be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a3319d163496c073813d052ecc873fb6f2f90e2351f1c8ac891c2c093c56a59d8405bc942f44b3f57e013f1f7149a7b3a35fc7b73ca3c58a0116ebce5e85b63
|
7
|
+
data.tar.gz: 3c72a547b1abaa06142caa496e8ce6d3769499954bfeaf3f9b01a470017bd3f38a1682be9e793f7eaab019ce202367feeda9d771f13ad14cf11b9cd901dafd42
|
data/README.adoc
CHANGED
@@ -1,2 +1,179 @@
|
|
1
1
|
= ISO publication identifiers ("ISO PubID")
|
2
2
|
|
3
|
+
== Purpose
|
4
|
+
|
5
|
+
This gem implements a mechanism to parse and utilize ISO publication
|
6
|
+
identifiers.
|
7
|
+
|
8
|
+
== Use cases to support
|
9
|
+
|
10
|
+
. generate the corresponding URN format (according to RFC 5141)
|
11
|
+
. generate updated PubID
|
12
|
+
. generate language specific PubID
|
13
|
+
. generate dated vs undated PubIDs
|
14
|
+
|
15
|
+
|
16
|
+
== Elements of the PubID
|
17
|
+
|
18
|
+
=== Document identifier
|
19
|
+
|
20
|
+
==== General
|
21
|
+
|
22
|
+
The ISO document identifier is assembled out of these metadata elements:
|
23
|
+
|
24
|
+
publisher:: publisher of the document
|
25
|
+
document stage:: stage of development of document, according to the Harmonized Stage Codes
|
26
|
+
document number:: numeric identifier of document
|
27
|
+
update number:: serial number of update (for amendments and technical corrigenda)
|
28
|
+
document type:: type of ISO deliverable
|
29
|
+
copyright year:: year of publication of document
|
30
|
+
language:: language of document
|
31
|
+
|
32
|
+
==== Publisher
|
33
|
+
|
34
|
+
This is the abbreviation of the publishing organization, typically `ISO`.
|
35
|
+
|
36
|
+
If the document is published under co-publishing agreements, it can contain the
|
37
|
+
abbreviations of other publishing SDOs, delimited by `/` after `ISO`.
|
38
|
+
|
39
|
+
An International Workshop Agreement document has publisher abbreviation of
|
40
|
+
`IWA`.
|
41
|
+
|
42
|
+
[example]
|
43
|
+
====
|
44
|
+
`ISO`, `ISO/IEC`, `ISO/IEC/IEEE`, `ISO/IEEE`, `ISO/SAE`, `IWA`
|
45
|
+
====
|
46
|
+
|
47
|
+
|
48
|
+
==== Document type and stage
|
49
|
+
|
50
|
+
ISO document stages in document identifiers are mapped as follows.
|
51
|
+
|
52
|
+
International Standard::
|
53
|
+
|
54
|
+
`00.00` to `00.99`::: "`PWI`"
|
55
|
+
`10.00` to `10.98`::: "`NP`"
|
56
|
+
`10.99` to `20.00`::: "`AWI`"
|
57
|
+
`20.20` to `20.99`::: "`WD`"
|
58
|
+
`30.00` to `30.99`::: "`CD`"
|
59
|
+
`40.00` to `40.99`::: "`DIS`"
|
60
|
+
`50.00` to `50.99`::: "`FDIS`"
|
61
|
+
`60.00`::: "`PRF`"
|
62
|
+
`60.60`::: empty designation
|
63
|
+
|
64
|
+
Technical Specification, Technical Report::
|
65
|
+
|
66
|
+
`00.00` to `00.99`::: "`PWI {TR,TS}`"
|
67
|
+
`10.00` to `10.98`::: "`NP {TR,TS}`"
|
68
|
+
`10.98` to `20.00`::: "`AWI {TR,TS}`"
|
69
|
+
`20.20` to `20.99`::: "`WD {TR,TS}`"
|
70
|
+
`30.00` to `30.99`::: "`CD {TR,TS}`"
|
71
|
+
`40.00` to `40.99`::: TS/TRs do not have DIS stage because they are not
|
72
|
+
international standards.
|
73
|
+
`50.00` to `50.99`::: TS/TRs do not have FDIS stage because they are not
|
74
|
+
international standards.
|
75
|
+
`60.00`::: "`PRF {TR,TS}`"
|
76
|
+
`60.60`::: "`{TR,TS}`"
|
77
|
+
|
78
|
+
//The stage abbreviations DIS and FDIS change to DTS and FDTS
|
79
|
+
|
80
|
+
Amendment::
|
81
|
+
|
82
|
+
`00.00` to `00.99`::: "`{base-document-id}/PWI Amd {num}`"
|
83
|
+
`10.00` to `10.98`::: "`{base-document-id}/NP Amd {num}`"
|
84
|
+
`10.99` to `20.00`::: "`{base-document-id}/AWI Amd {num}`"
|
85
|
+
`20.20` to `20.99`::: "`{base-document-id}/WD Amd {num}`"
|
86
|
+
`30.00` to `30.99`::: "`{base-document-id}/CD Amd {num}`"
|
87
|
+
`40.00` to `40.99`::: "`{base-document-id}/DAmd {num}`"
|
88
|
+
`50.00` to `50.99`::: "`{base-document-id}/FDAmd {num}`"
|
89
|
+
`60.00`::: "`{base-document-id}/PRF Amd {num}`"
|
90
|
+
`60.60`::: "`{base-document-id}/Amd {num}`"
|
91
|
+
|
92
|
+
Technical Corrigendum::
|
93
|
+
|
94
|
+
`00.00` to `00.99`::: "`{base-document-id}/PWI Cor {num}`"
|
95
|
+
`10.00` to `10.98`::: "`{base-document-id}/NP Cor {num}`"
|
96
|
+
`10.99` to `20.00`::: "`{base-document-id}/AWI Cor {num}`"
|
97
|
+
`20.20` to `20.99`::: "`{base-document-id}/WD Cor {num}`"
|
98
|
+
`30.00` to `30.99`::: "`{base-document-id}/CD Cor {num}`"
|
99
|
+
`40.00` to `40.99`::: "`{base-document-id}/DIS Cor {num}`"
|
100
|
+
`50.00` to `50.99`::: "`{base-document-id}/FDCor {num}`"
|
101
|
+
`60.00`::: "`{base-document-id}/PRF Cor {num}`"
|
102
|
+
`60.60`::: "`{base-document-id}/Cor {num}`"
|
103
|
+
|
104
|
+
|
105
|
+
When the Publisher element contains a "`slash`" ("`/`"), the separation in front
|
106
|
+
of the document stage will be converted into an empty space.
|
107
|
+
|
108
|
+
[example]
|
109
|
+
====
|
110
|
+
`ISO/NP 33333` but `ISO/IEC NP 33333`.
|
111
|
+
`ISO/NP TR 33333` but `ISO/IEC NP TR 33333`.
|
112
|
+
====
|
113
|
+
|
114
|
+
According to ISO Directives Part 1 (11ed), SE.2:
|
115
|
+
|
116
|
+
[quote]
|
117
|
+
____
|
118
|
+
Working drafts (WD), committee drafts (CD), draft International Standards (DIS),
|
119
|
+
final draft International Standards (FDIS) and International Standards`",
|
120
|
+
"`Successive DIS on the same subject will carry the same number but will be
|
121
|
+
distinguished by a numerical suffix (.2, .3, etc.).
|
122
|
+
____
|
123
|
+
|
124
|
+
The stage iteration number is assigned accordingly for all stages, which is
|
125
|
+
patterned as:
|
126
|
+
|
127
|
+
* `{document stage}` (no suffix if iteration is 1); or
|
128
|
+
* `{document stage}.{iteration number}`
|
129
|
+
(suffix including iteration number after 1).
|
130
|
+
|
131
|
+
Once the document is published (stage 60 substage 60), no status abbreviation is
|
132
|
+
given.
|
133
|
+
|
134
|
+
|
135
|
+
==== Full PubID patterns
|
136
|
+
|
137
|
+
The patterns are as follows:
|
138
|
+
|
139
|
+
*International Standard*::
|
140
|
+
`{publisher} (/{document type and stage})? ({document number}) (- {part number})? (: {copyright year}) ({ISO 639 language code})?` +
|
141
|
+
+
|
142
|
+
====
|
143
|
+
`ISO/IEEE/FDIS 33333-2`, `ISO/IEEE 33333-2:2030(E)`
|
144
|
+
====
|
145
|
+
|
146
|
+
*Technical Report*, *Technical Specification*::
|
147
|
+
`{publisher} (/{document type and stage}) ({document number}) (- {part number})? (: {copyright year}) ({ISO 639 language code})?` +
|
148
|
+
+
|
149
|
+
====
|
150
|
+
`ISO/IEC/FDIS TS 33333-2`, `ISO/TR 33333-2:2030(E)`, `ISO/IEC TR 33333-2:2030(E)`
|
151
|
+
====
|
152
|
+
|
153
|
+
*Amendments*, *Technical Corrigendum*::
|
154
|
+
`{source document ID}/{document type and stage} {update number} (: {copyright year}) ({ISO 639 language code})?` +
|
155
|
+
+
|
156
|
+
====
|
157
|
+
`ISO 33333-2:2030/DIS Cor 2:2031`, `ISO 33333-2:2030/Cor 2:2032`, `ISO/IEC 33333-2:2030/Cor 2:2032`
|
158
|
+
====
|
159
|
+
|
160
|
+
|
161
|
+
// === Title
|
162
|
+
|
163
|
+
// `:title-intro-{en,fr}:`:: The introductory component of the English or French
|
164
|
+
// title of the document.
|
165
|
+
|
166
|
+
// `:title-main-{en,fr}:`:: The main component of the English or French title of
|
167
|
+
// the document (mandatory).
|
168
|
+
|
169
|
+
// `:title-part-{en,fr}:`:: The English or French title of the document part.
|
170
|
+
|
171
|
+
// `:title-amendment-{en,fr}:`:: (only when `doctype` is set to `amendment` or `technical-corrigendum`)
|
172
|
+
// The English or French title of the amendment [added in https://github.com/metanorma/isodoc/releases/tag/v1.3.25]
|
173
|
+
|
174
|
+
// `:amendment-number:`:: (only when `doctype` is set to `amendment`)
|
175
|
+
// The number of the amendment [added in https://github.com/metanorma/isodoc/releases/tag/v1.3.25]
|
176
|
+
|
177
|
+
// `:corrigendum-number:`:: (only when `doctype` is set to `technical-corrigendum`)
|
178
|
+
// The number of the technical corrigendum [added in https://github.com/metanorma/isodoc/releases/tag/v1.3.25]
|
179
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Pubid::Iso
|
2
|
+
class French < Identifier
|
3
|
+
def identifier(with_date, with_language_code)
|
4
|
+
if @type == "Guide"
|
5
|
+
"Guide #{originator}#{stage} #{number}#{part}#{iteration}"\
|
6
|
+
"#{with_date && rendered_year || ''}#{edition}#{supplements}#{language(with_language_code)}"
|
7
|
+
else
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def copublisher
|
13
|
+
super.map { |copublisher| copublisher.sub("IEC", "CEI") }
|
14
|
+
end
|
15
|
+
|
16
|
+
def amendment
|
17
|
+
if @amendment_number
|
18
|
+
"Amd.#{@amendment_version}:#{@amendment_number}"
|
19
|
+
else
|
20
|
+
"Amd.#{@amendment_version}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def corrigendum
|
25
|
+
if @corrigendum_number
|
26
|
+
"Cor.#{@corrigendum_version}:#{@corrigendum_number}"
|
27
|
+
else
|
28
|
+
"Cor.#{@corrigendum_version}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Pubid::Iso
|
2
|
+
class Russian < Identifier
|
3
|
+
PUBLISHER = { "ISO" => "ИСО", "IEC" => "МЭК" }.freeze
|
4
|
+
STAGE = { "FDIS" => "ОПМС",
|
5
|
+
"DIS" => "ПМС",
|
6
|
+
"NP" => "НП",
|
7
|
+
"AWI" => "АВИ",
|
8
|
+
"CD" => "КПК",
|
9
|
+
"PD" => "ПД",
|
10
|
+
"FPD" => "ФПД",
|
11
|
+
|
12
|
+
|
13
|
+
}.freeze
|
14
|
+
TYPE = { "Guide" => "Руководство",
|
15
|
+
"TS" => "ТС",
|
16
|
+
"TR" => "ТО",
|
17
|
+
"ISP" => "ИСП",
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
def identifier(with_date, with_language_code)
|
21
|
+
if @type == "Guide"
|
22
|
+
"Руководство #{originator}#{stage} #{number}#{part}#{iteration}"\
|
23
|
+
"#{with_date && rendered_year || ''}#{edition}#{supplements}#{language(with_language_code)}"
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def publisher
|
30
|
+
PUBLISHER[@publisher]
|
31
|
+
end
|
32
|
+
|
33
|
+
def copublisher
|
34
|
+
super&.map { |copublisher| PUBLISHER[copublisher] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def stage
|
38
|
+
"#{(@copublisher && ' ') || '/'}#{STAGE[@stage]}" if @stage
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/pubid/iso/identifier.rb
CHANGED
@@ -1,46 +1,191 @@
|
|
1
1
|
module Pubid::Iso
|
2
2
|
class Identifier
|
3
|
-
STAGES = { NP: 10,
|
4
|
-
WD: 20,
|
5
|
-
CD: 30,
|
6
|
-
DIS: 40,
|
7
|
-
FDIS: 50,
|
8
|
-
PRF: 50,
|
9
|
-
IS: 60,
|
10
|
-
Fpr: 50 }.freeze
|
11
|
-
|
12
3
|
attr_accessor :number, :publisher, :copublisher, :stage, :substage, :part,
|
13
|
-
:type, :year, :edition, :iteration, :supplements, :language
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@substage = 0
|
19
|
-
end
|
20
|
-
|
21
|
-
# XXX: temporary hack for ISO/IEC 19794-7:2014/Amd 1:2015/CD Cor 1 parsing
|
22
|
-
supplements&.each do |supplement|
|
23
|
-
if supplement[:stage]
|
24
|
-
@stage = STAGES[Transformer.new.apply(stage: supplement[:stage].to_s)[:stage].to_sym]
|
25
|
-
@substage = 0
|
26
|
-
end
|
27
|
-
end
|
4
|
+
:type, :year, :edition, :iteration, :supplements, :language,
|
5
|
+
:amendment, :amendment_version, :amendment_number,
|
6
|
+
:corrigendum, :corrigendum_version, :corrigendum_number,
|
7
|
+
:amendment_stage, :corrigendum_stage, :joint_document,
|
8
|
+
:tctype, :sctype, :wgtype, :tcnumber, :scnumber, :wgnumber
|
28
9
|
|
29
|
-
|
10
|
+
LANGUAGES = {
|
11
|
+
"ru" => "R",
|
12
|
+
"fr" => "F",
|
13
|
+
"en" => "E",
|
14
|
+
"ar" => "A",
|
15
|
+
}.freeze
|
30
16
|
|
17
|
+
def initialize(**opts)
|
31
18
|
opts.each { |key, value| send("#{key}=", value.is_a?(Array) && value || value.to_s) }
|
32
19
|
end
|
33
20
|
|
21
|
+
def get_params
|
22
|
+
instance_variables.map { |var| [var.to_s.gsub("@", "").to_sym, instance_variable_get(var)] }.to_h
|
23
|
+
end
|
24
|
+
|
34
25
|
def urn
|
35
|
-
|
26
|
+
Urn.new(**get_params)
|
36
27
|
end
|
37
28
|
|
38
|
-
def self.parse(
|
39
|
-
|
40
|
-
|
41
|
-
|
29
|
+
def self.parse(code_or_params)
|
30
|
+
params = code_or_params.is_a?(String) ? Parser.new.parse(code_or_params) : code_or_params
|
31
|
+
# Parslet returns an array when match any copublisher
|
32
|
+
# otherwise it's hash
|
33
|
+
if params.is_a?(Array)
|
34
|
+
new(
|
35
|
+
**(
|
36
|
+
params.inject({}) do |r, i|
|
37
|
+
result = r
|
38
|
+
i.map {|k, v| Transformer.new.apply(k => v).to_a.first }.each do |k, v|
|
39
|
+
result = result.merge(k => r.key?(k) ? [v, r[k]] : v)
|
40
|
+
end
|
41
|
+
result
|
42
|
+
end
|
43
|
+
)
|
44
|
+
)
|
45
|
+
else
|
46
|
+
new(**params.map do |k, v|
|
47
|
+
Transformer.new.apply(k => v).to_a.first
|
48
|
+
end.to_h)
|
49
|
+
end
|
50
|
+
# merge values repeating keys into array (for copublishers)
|
51
|
+
|
52
|
+
|
53
|
+
# params.to_h)
|
42
54
|
rescue Parslet::ParseFailed => failure
|
43
55
|
raise Pubid::Iso::Errors::ParseError, "#{failure.message}\ncause: #{failure.parse_failure_cause.ascii_tree}"
|
44
56
|
end
|
57
|
+
|
58
|
+
def to_s(lang: nil, with_date: true, with_language_code: :iso)
|
59
|
+
# @pubid_language = lang
|
60
|
+
case lang
|
61
|
+
when :french
|
62
|
+
French.new(**get_params)
|
63
|
+
when :russian
|
64
|
+
Russian.new(**get_params)
|
65
|
+
else
|
66
|
+
self
|
67
|
+
end.identifier(with_date, with_language_code) + (@joint_document && "|#{@joint_document}").to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def identifier(with_date, with_language_code)
|
71
|
+
if @tctype
|
72
|
+
"#{originator} #{tctype} #{tcnumber}#{sctype}#{wgtype} N#{number}"
|
73
|
+
else
|
74
|
+
"#{originator}#{type}#{stage} #{number}#{part}#{iteration}"\
|
75
|
+
"#{with_date && rendered_year || ''}#{edition}#{supplements}#{language(with_language_code)}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def tctype
|
80
|
+
return @tctype.join("/") if @tctype.is_a?(Array)
|
81
|
+
|
82
|
+
@tctype
|
83
|
+
end
|
84
|
+
|
85
|
+
# TC 184/SC/WG 4 - no wg number
|
86
|
+
# TC 184/SC 4/WG 12 - separate sc and wg number
|
87
|
+
def sctype
|
88
|
+
return unless @sctype
|
89
|
+
|
90
|
+
if @wgnumber || !@wgtype
|
91
|
+
"/#{@sctype} #{@scnumber}"
|
92
|
+
else
|
93
|
+
"/#{@sctype}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def wgtype
|
98
|
+
return unless @wgtype
|
99
|
+
|
100
|
+
if @wgnumber
|
101
|
+
"/#{@wgtype} #{@wgnumber}"
|
102
|
+
else
|
103
|
+
"/#{@wgtype} #{@scnumber}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def copublisher
|
108
|
+
return nil unless @copublisher
|
109
|
+
|
110
|
+
(!@copublisher.is_a?(Array) && [@copublisher]) || @copublisher
|
111
|
+
end
|
112
|
+
|
113
|
+
def originator
|
114
|
+
if copublisher
|
115
|
+
# @copublisher = [@copublisher] unless @copublisher.is_a?(Array)
|
116
|
+
# @copublisher.map! { |copublisher| copublisher.sub("IEC", "CEI") } if @french
|
117
|
+
publisher + copublisher.map(&:to_s).sort.map do |copublisher|
|
118
|
+
"/#{copublisher.gsub('-', '/')}"
|
119
|
+
end.join
|
120
|
+
else
|
121
|
+
publisher
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def stage
|
126
|
+
"#{(@copublisher && ' ') || '/'}#{@stage}" if @stage
|
127
|
+
end
|
128
|
+
|
129
|
+
def part
|
130
|
+
"-#{@part}" if @part
|
131
|
+
end
|
132
|
+
|
133
|
+
def rendered_year
|
134
|
+
@year && ":#{@year}"
|
135
|
+
end
|
136
|
+
|
137
|
+
def type
|
138
|
+
"#{(@copublisher && ' ') || '/'}#{@type}" if @type
|
139
|
+
end
|
140
|
+
|
141
|
+
def edition
|
142
|
+
" ED#{@edition}" if @edition
|
143
|
+
end
|
144
|
+
|
145
|
+
def iteration
|
146
|
+
".#{@iteration}" if @iteration
|
147
|
+
end
|
148
|
+
|
149
|
+
def amendment
|
150
|
+
if @amendment_number
|
151
|
+
"Amd #{@amendment_version}:#{@amendment_number}"
|
152
|
+
else
|
153
|
+
"Amd #{@amendment_version}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def corrigendum
|
158
|
+
if @corrigendum_number
|
159
|
+
"Cor #{@corrigendum_version}:#{@corrigendum_number}"
|
160
|
+
else
|
161
|
+
"Cor #{@corrigendum_version}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def supplements
|
166
|
+
result = ""
|
167
|
+
if @amendment_version
|
168
|
+
result += (@amendment_stage && "/#{@amendment_stage} ") || "/"
|
169
|
+
result += amendment
|
170
|
+
end
|
171
|
+
|
172
|
+
if @corrigendum_version
|
173
|
+
result += (@corrigendum_stage && "/#{@corrigendum_stage} ") || "/"
|
174
|
+
result += corrigendum
|
175
|
+
end
|
176
|
+
|
177
|
+
result
|
178
|
+
end
|
179
|
+
|
180
|
+
def language(with_language_code = :iso)
|
181
|
+
if @language
|
182
|
+
if with_language_code == :single
|
183
|
+
"(#{LANGUAGES[@language]})"
|
184
|
+
else
|
185
|
+
"(#{@language})"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
45
190
|
end
|
46
191
|
end
|
data/lib/pubid/iso/parser.rb
CHANGED
@@ -17,13 +17,22 @@ module Pubid::Iso
|
|
17
17
|
# Stage 50.60: PRF ("proof") (non-public)
|
18
18
|
# Stage 60: IS
|
19
19
|
class Parser < Parslet::Parser
|
20
|
+
rule(:space) { str(" ") }
|
21
|
+
rule(:space?) { space.maybe }
|
22
|
+
|
20
23
|
rule(:digits) do
|
21
24
|
match('\d').repeat(1)
|
22
25
|
end
|
23
26
|
|
24
27
|
rule(:stage) do
|
25
|
-
(
|
26
|
-
|
28
|
+
Russian::STAGE.values.reduce(
|
29
|
+
# other stages
|
30
|
+
str("NP") | str("WD") | str("CD") | str("DIS") | str("FDIS") | str("PRF") |
|
31
|
+
str("IS") | str("AWI") | str("PWI") |
|
32
|
+
# AMD and COR stages
|
33
|
+
str("FPD") | str("pD") | str("PD") | str("FD") | str("D")) do |acc, stage|
|
34
|
+
acc | str(stage)
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
# TYPES = {
|
@@ -36,32 +45,62 @@ module Pubid::Iso
|
|
36
45
|
# # type = "data" / "guide" / "isp" / "iwa" /
|
37
46
|
# # "pas" / "r" / "tr" / "ts" / "tta"
|
38
47
|
rule(:type) do
|
39
|
-
(
|
40
|
-
|
48
|
+
(
|
49
|
+
Russian::TYPE.values.reduce(
|
50
|
+
str("DATA") | str("ISP") | str("IWA") | str("R") | str("TTA") |
|
51
|
+
str("TS") | str("TR") | str("PAS") | str("Guide") | str("GUIDE")) do |acc, type|
|
52
|
+
acc | str(type)
|
53
|
+
end
|
54
|
+
).as(:type)
|
55
|
+
end
|
56
|
+
|
57
|
+
rule(:tctype) do
|
58
|
+
# tc-types
|
59
|
+
str("TC") | str("JTC") | str("PC") | str("IT") | str("CAB") | str("CASCO") | str("COPOLCO") |
|
60
|
+
str("COUNCIL") | str("CPSG") | str("CS") | str("DEVCO") | str("GA") | str("GAAB") | str("INFCO") |
|
61
|
+
str("ISOlutions") | str("ITN") | str("REMCO") | str("TMB") | str("TMBG") | str("WMO") |
|
62
|
+
str("DMT") | str("JCG") | str("SGPM") | str("ATMG") | str("CCCC") | str("CCCC-TG") | str("JDMT") |
|
63
|
+
str("JSAG") | str("JSCTF-TF") | str("JTCG") | str("JTCG-TF") | str("SAG_Acc") | str("SAG_CRMI") |
|
64
|
+
str("SAG_CRMI_CG") | str("SAG_ESG") | str("SAG_ESG_CG") | str("SAG_MRS") | str("SAG SF") | str("SAG SF_CG") |
|
65
|
+
str("SMCC") | str("STMG") | str("MENA STAR")
|
66
|
+
end
|
67
|
+
|
68
|
+
rule(:sctype) do
|
69
|
+
str("SC")
|
70
|
+
end
|
71
|
+
|
72
|
+
rule(:wgtype) do
|
73
|
+
str("AG") | str("AHG") | str("AhG") | str("WG") | str("JWG") | str("QC") | str("TF") |
|
74
|
+
str("PPC") | str("CAG") | str("WG SGDG") | str("WG SR") | str("STAR") | str("STTF") | str("TIG") |
|
75
|
+
str("CPAG") | str("CSC") | str("ITSAG") | str("CSC/FIN") | str("CSC/NOM") | str("CSC/OVE") |
|
76
|
+
str("CSC/SP") | str("CSC/FIN") | str("JAG")
|
41
77
|
end
|
42
78
|
|
43
79
|
rule(:year) do
|
44
|
-
match('\d').repeat(4, 4)
|
80
|
+
match('\d').repeat(4, 4).as(:year)
|
45
81
|
end
|
46
82
|
|
47
83
|
rule(:part) do
|
48
|
-
(str("-") | str("/")) >>
|
49
|
-
(match['[\dA-Z]'] | str("-")).repeat(1).as(:part)
|
84
|
+
(str("-") | str("/")) >> space? >>
|
85
|
+
(str("Amd") | str("Cor")).absent? >> (match['[\dA-Z]'] | str("-")).repeat(1).as(:part)
|
50
86
|
end
|
51
87
|
|
52
88
|
rule(:originator) do
|
53
89
|
organization.as(:publisher) >>
|
54
|
-
(
|
90
|
+
(space? >> str("/") >> organization.as(:copublisher)).repeat
|
55
91
|
end
|
56
92
|
|
57
93
|
rule(:organization) do
|
58
|
-
|
94
|
+
Russian::PUBLISHER.values.reduce(
|
95
|
+
str("IEC") | str("IEEE") | str("CIW") | str("SAE") |
|
59
96
|
str("CIE") | str("ASME") | str("ASTM") | str("OECD") | str("ISO") |
|
60
|
-
str("IWA") | str("HL7")
|
97
|
+
str("IWA") | str("HL7") | str("CEI")) do |acc, publisher|
|
98
|
+
acc | str(publisher)
|
99
|
+
end
|
61
100
|
end
|
62
101
|
|
63
102
|
rule(:edition) do
|
64
|
-
|
103
|
+
space >> ((str("ED") | str("Ed ") | str("Ed.")) >>
|
65
104
|
digits.as(:edition) | str("Ed").as(:edition))
|
66
105
|
end
|
67
106
|
|
@@ -69,33 +108,75 @@ module Pubid::Iso
|
|
69
108
|
str(".") >> digits.as(:iteration)
|
70
109
|
end
|
71
110
|
|
72
|
-
rule(:
|
73
|
-
(str("/")
|
74
|
-
|
75
|
-
str(" ") >>
|
76
|
-
|
77
|
-
|
111
|
+
rule(:amendment) do
|
112
|
+
(str("/") >> stage.as(:amendment_stage)).maybe >>
|
113
|
+
(str("/") | space).maybe >>
|
114
|
+
(str("Amd") | str("AMD") | str("AM")).as(:amendment) >>
|
115
|
+
(space | str(".")) >>
|
116
|
+
digits.as(:amendment_version) >>
|
117
|
+
(str(":") >> digits.as(:amendment_number)).maybe
|
118
|
+
end
|
119
|
+
|
120
|
+
rule(:corrigendum) do
|
121
|
+
(str("/") >> stage.as(:corrigendum_stage)).maybe >>
|
122
|
+
(str("/") | space).maybe >>
|
123
|
+
(str("Cor") | str("COR")).as(:corrigendum) >>
|
124
|
+
(space | str(".")) >>
|
125
|
+
digits.as(:corrigendum_version) >>
|
126
|
+
(str(":") >> digits.as(:corrigendum_number)).maybe
|
78
127
|
end
|
79
128
|
|
80
129
|
rule(:language) do
|
81
|
-
str("(") >>
|
130
|
+
str("(") >> (
|
131
|
+
( # parse ru,en,fr
|
132
|
+
(match["a-z"].repeat(1) >> str(",").maybe) |
|
133
|
+
# parse R/E/F
|
134
|
+
((str("E") | str("F") | str("A") | str("R")) >> str("/").maybe)
|
135
|
+
).repeat.as(:language)
|
136
|
+
) >> str(")")
|
137
|
+
end
|
138
|
+
|
139
|
+
rule(:guide_prefix) do
|
140
|
+
str("Guide") | str("GUIDE") | str("Руководство") | str("Руководства")
|
141
|
+
end
|
142
|
+
|
143
|
+
# Parse technical committee documents
|
144
|
+
rule(:tc_document_body) do
|
145
|
+
(tctype.as(:tctype) >> str("/").maybe).repeat >> space >> digits.as(:tcnumber) >>
|
146
|
+
(str("/") >> (
|
147
|
+
((sctype.as(:sctype) >> space >> digits.as(:scnumber) >> str("/")).maybe >>
|
148
|
+
wgtype.as(:wgtype) >> space >> digits.as(:wgnumber)) |
|
149
|
+
(sctype.as(:sctype) >> (space | str("/") >> wgtype.as(:wgtype) >> space) >> digits.as(:scnumber))
|
150
|
+
)).maybe >>
|
151
|
+
str(" N") >> space? >> digits.as(:number)
|
152
|
+
end
|
153
|
+
|
154
|
+
rule(:std_document_body) do
|
155
|
+
(type | stage.as(:stage)).maybe >>
|
156
|
+
# for ISO/IEC WD TS 25025
|
157
|
+
space? >> ((stage.as(:stage) | type) >> space).maybe >>
|
158
|
+
digits.as(:number) >>
|
159
|
+
# for identifiers like ISO 5537/IDF 26
|
160
|
+
(str("|") >> (str("IDF") >> space >> digits).as(:joint_document)).maybe >>
|
161
|
+
part.maybe >> iteration.maybe >>
|
162
|
+
(space? >> str(":") >> year).maybe >>
|
163
|
+
# stage before amendment
|
164
|
+
(
|
165
|
+
# stage before corrigendum
|
166
|
+
((amendment >> corrigendum.maybe) | corrigendum).maybe) >>
|
167
|
+
edition.maybe >>
|
168
|
+
language.maybe
|
82
169
|
end
|
83
170
|
|
84
171
|
rule(:identifier) do
|
85
172
|
str("Fpr").as(:stage).maybe >>
|
86
173
|
# Withdrawn e.g: WD/ISO 10360-5:2000
|
87
174
|
str("WD/").maybe >>
|
88
|
-
|
89
|
-
|
90
|
-
(
|
91
|
-
|
92
|
-
|
93
|
-
digits.as(:number) >> part.maybe >> iteration.maybe >>
|
94
|
-
(str(" ").maybe >> str(":") >> year).maybe >>
|
95
|
-
((str("/") >> stage).maybe >>
|
96
|
-
supplement).repeat.as(:supplements) >>
|
97
|
-
edition.maybe >>
|
98
|
-
language.maybe
|
175
|
+
# for French and Russian PubIDs starting with Guide type
|
176
|
+
(guide_prefix.as(:type) >> space).maybe >>
|
177
|
+
(stage.as(:stage) >> space).maybe >>
|
178
|
+
originator >> (space | str("/")) >>
|
179
|
+
(tc_document_body | std_document_body)
|
99
180
|
end
|
100
181
|
|
101
182
|
rule(:root) { identifier }
|
@@ -4,16 +4,93 @@ module Pubid::Iso
|
|
4
4
|
{ edition: "1" }
|
5
5
|
end
|
6
6
|
|
7
|
-
rule(stage: simple(:stage)) do
|
8
|
-
{ stage:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
rule(stage: simple(:stage)) do |context|
|
8
|
+
{ stage: convert_stage(context[:stage]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
rule(amendment_stage: simple(:amendment_stage)) do |context|
|
12
|
+
{ amendment_stage: convert_stage(context[:amendment_stage]) }
|
13
|
+
end
|
14
|
+
|
15
|
+
rule(corrigendum_stage: simple(:corrigendum_stage)) do |context|
|
16
|
+
{ corrigendum_stage: convert_stage(context[:corrigendum_stage]) }
|
17
|
+
end
|
18
|
+
|
19
|
+
rule(language: simple(:language)) do |context|
|
20
|
+
if context[:language].to_s.include?("/")
|
21
|
+
{ language: context[:language]
|
22
|
+
.to_s.split("/")
|
23
|
+
.map { |code| convert_language(code) }.join(",") }
|
24
|
+
else
|
25
|
+
{ language: convert_language(context[:language]) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
rule(type: simple(:type)) do
|
30
|
+
russian_type = Russian::TYPE.key(type.to_s)
|
31
|
+
{ type: russian_type&.to_s ||
|
32
|
+
case type
|
33
|
+
# XXX: can't put 2 alternative Russian translations to dictionary, temporary hack
|
34
|
+
when "GUIDE", "Руководства"
|
35
|
+
"Guide"
|
36
|
+
when "ТС"
|
37
|
+
"TS"
|
38
|
+
when "ТО"
|
39
|
+
"TR"
|
40
|
+
else
|
41
|
+
type
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
rule(copublisher: simple(:copublisher)) do
|
47
|
+
russian_copublisher = Russian::PUBLISHER.key(copublisher.to_s)
|
48
|
+
{ copublisher: russian_copublisher&.to_s ||
|
49
|
+
case copublisher
|
50
|
+
when "CEI"
|
51
|
+
"IEC"
|
52
|
+
else
|
53
|
+
copublisher
|
54
|
+
end
|
16
55
|
}
|
17
56
|
end
|
57
|
+
|
58
|
+
rule(publisher: simple(:publisher)) do
|
59
|
+
russian_publisher = Russian::PUBLISHER.key(publisher.to_s)
|
60
|
+
{ publisher: russian_publisher&.to_s || publisher }
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.convert_stage(code)
|
64
|
+
russian_code = Russian::STAGE.key(code.to_s)
|
65
|
+
return russian_code.to_s if russian_code
|
66
|
+
|
67
|
+
case code
|
68
|
+
when "D"
|
69
|
+
"DIS"
|
70
|
+
when "FD"
|
71
|
+
"FDIS"
|
72
|
+
when "Fpr"
|
73
|
+
"PRF"
|
74
|
+
when "pD", "PD"
|
75
|
+
"CD"
|
76
|
+
else
|
77
|
+
code
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.convert_language(code)
|
82
|
+
case code
|
83
|
+
when "R"
|
84
|
+
"ru"
|
85
|
+
when "F"
|
86
|
+
"fr"
|
87
|
+
when "E"
|
88
|
+
"en"
|
89
|
+
when "A"
|
90
|
+
"ar"
|
91
|
+
else
|
92
|
+
code
|
93
|
+
end
|
94
|
+
end
|
18
95
|
end
|
19
96
|
end
|
data/lib/pubid/iso/urn.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
module Pubid::Iso
|
2
|
-
class
|
3
|
-
attr_accessor :identifier
|
2
|
+
class Urn < Identifier
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
STAGES = { PWI: 0,
|
5
|
+
NP: 10,
|
6
|
+
AWI: 20,
|
7
|
+
WD: 20.20,
|
8
|
+
CD: 30,
|
9
|
+
DIS: 40,
|
10
|
+
FDIS: 50,
|
11
|
+
PRF: 50,
|
12
|
+
IS: 60 }.freeze
|
13
|
+
|
14
|
+
def initialize(**opts)
|
15
|
+
opts.each { |key, value| send("#{key}=", value) }
|
7
16
|
end
|
8
17
|
|
9
18
|
def to_s
|
@@ -11,58 +20,104 @@ module Pubid::Iso
|
|
11
20
|
# [[":" status] ":" edition]
|
12
21
|
# [":" docversion] [":" language]
|
13
22
|
|
14
|
-
|
23
|
+
if tctype
|
24
|
+
"urn:iso:doc:#{originator}:#{tctype.downcase}:#{tcnumber}#{sctype}#{wgtype}:#{number}"
|
25
|
+
else
|
26
|
+
"urn:iso:std:#{originator}#{type}:#{number}#{part}#{stage}#{edition}#{supplement}#{language}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def tctype
|
31
|
+
return @tctype.join(":") if @tctype.is_a?(Array)
|
32
|
+
|
33
|
+
@tctype
|
34
|
+
end
|
35
|
+
|
36
|
+
def sctype
|
37
|
+
return unless @sctype
|
38
|
+
|
39
|
+
":#{@sctype.downcase}:#{@scnumber}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def wgtype
|
43
|
+
return unless @wgtype
|
44
|
+
|
45
|
+
if @wgnumber
|
46
|
+
":#{@wgtype.downcase}:#{@wgnumber}"
|
47
|
+
else
|
48
|
+
":#{@wgtype.downcase}"
|
49
|
+
end
|
15
50
|
end
|
16
51
|
|
17
52
|
def part
|
18
|
-
":-#{
|
53
|
+
":-#{@part}" if @part
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_stage(stage)
|
57
|
+
":stage-#{sprintf('%05.2f', STAGES[stage.to_sym])}#{iteration}"
|
19
58
|
end
|
20
59
|
|
21
60
|
def stage
|
22
|
-
|
61
|
+
return render_stage(@stage) if @stage
|
62
|
+
|
63
|
+
return render_stage(@amendment_stage) if @amendment_stage
|
64
|
+
|
65
|
+
render_stage(@corrigendum_stage) if @corrigendum_stage
|
23
66
|
end
|
24
67
|
|
25
68
|
def originator
|
26
69
|
# originator = "iso" / "iso-iec" / "iso-cie" / "iso-astm" /
|
27
70
|
# "iso-ieee" / "iec"
|
28
71
|
|
29
|
-
if
|
30
|
-
|
72
|
+
if @copublisher
|
73
|
+
@copublisher = [@copublisher] unless @copublisher.is_a?(Array)
|
74
|
+
@publisher.downcase + @copublisher.map(&:to_s).sort.map do |copublisher|
|
75
|
+
"-#{copublisher.downcase.gsub('/', '-')}"
|
76
|
+
end.join
|
31
77
|
else
|
32
|
-
|
78
|
+
@publisher.downcase
|
33
79
|
end
|
34
80
|
end
|
35
81
|
|
36
82
|
def edition
|
37
|
-
":ed-#{
|
83
|
+
":ed-#{@edition}" if @edition
|
38
84
|
end
|
39
85
|
|
40
86
|
def iteration
|
41
|
-
".v#{
|
87
|
+
".v#{@iteration}" if @iteration
|
42
88
|
end
|
43
89
|
|
44
90
|
def type
|
45
91
|
# type = "data" / "guide" / "isp" / "iwa" /
|
46
92
|
# "pas" / "r" / "tr" / "ts" / "tta"
|
47
|
-
|
48
|
-
|
49
|
-
":#{identifier.type.downcase}"
|
93
|
+
if @type
|
94
|
+
":#{@type.downcase}"
|
50
95
|
end
|
51
96
|
end
|
52
97
|
|
53
98
|
def supplement
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
99
|
+
result = ""
|
100
|
+
if @amendment
|
101
|
+
result += if @amendment_number
|
102
|
+
":amd:#{@amendment_number}:v#{@amendment_version}"
|
103
|
+
else
|
104
|
+
":amd:#{@amendment_version}:v1"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
if @corrigendum
|
108
|
+
result += if @corrigendum_number
|
109
|
+
":cor:#{@corrigendum_number}:v#{@corrigendum_version}"
|
110
|
+
else
|
111
|
+
":cor:#{@corrigendum_version}:v1"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
result
|
61
116
|
end
|
62
117
|
|
63
118
|
def language
|
64
|
-
if
|
65
|
-
":#{
|
119
|
+
if @language
|
120
|
+
":#{@language}"
|
66
121
|
end
|
67
122
|
end
|
68
123
|
end
|
data/lib/pubid/iso/version.rb
CHANGED
data/lib/pubid/iso.rb
CHANGED
@@ -11,5 +11,7 @@ end
|
|
11
11
|
require_relative "iso/errors"
|
12
12
|
require_relative "iso/parser"
|
13
13
|
require_relative "iso/transformer"
|
14
|
-
require_relative "iso/urn"
|
15
14
|
require_relative "iso/identifier"
|
15
|
+
require_relative "iso/identifier/french"
|
16
|
+
require_relative "iso/identifier/russian"
|
17
|
+
require_relative "iso/urn"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pubid-iso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -109,6 +109,8 @@ files:
|
|
109
109
|
- lib/pubid/iso.rb
|
110
110
|
- lib/pubid/iso/errors.rb
|
111
111
|
- lib/pubid/iso/identifier.rb
|
112
|
+
- lib/pubid/iso/identifier/french.rb
|
113
|
+
- lib/pubid/iso/identifier/russian.rb
|
112
114
|
- lib/pubid/iso/parser.rb
|
113
115
|
- lib/pubid/iso/transformer.rb
|
114
116
|
- lib/pubid/iso/urn.rb
|
@@ -117,7 +119,7 @@ homepage: https://github.com/metanorma/pubid-iso
|
|
117
119
|
licenses:
|
118
120
|
- BSD-2-Clause
|
119
121
|
metadata: {}
|
120
|
-
post_install_message:
|
122
|
+
post_install_message:
|
121
123
|
rdoc_options: []
|
122
124
|
require_paths:
|
123
125
|
- lib
|
@@ -132,8 +134,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
134
|
- !ruby/object:Gem::Version
|
133
135
|
version: '0'
|
134
136
|
requirements: []
|
135
|
-
rubygems_version: 3.3.
|
136
|
-
signing_key:
|
137
|
+
rubygems_version: 3.0.3.1
|
138
|
+
signing_key:
|
137
139
|
specification_version: 4
|
138
140
|
summary: Library to generate, parse and manipulate ISO PubID.
|
139
141
|
test_files: []
|