pubid-iso 0.1.1 → 0.1.2
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 +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 +142 -30
- data/lib/pubid/iso/parser.rb +61 -19
- data/lib/pubid/iso/transformer.rb +86 -9
- data/lib/pubid/iso/urn.rb +59 -23
- data/lib/pubid/iso/version.rb +1 -1
- data/lib/pubid/iso.rb +2 -0
- 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: b4b3d52e0c0c000893b1ed556782f8ad349a54c2d70fe2e1f81942b4699e67a9
|
4
|
+
data.tar.gz: 3d82f5403447fe7a816a4913efd3fea16c37cc7c3e20ea8168ef21ab415996b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad4e1d604590a74fe504b7b5036cfe3bfe2696a7a145486470011ddfc148ca41265d79d8c2c0b171d9b26f8a0fb20186648a40d749ab9470afcf2f32cc9bb98d
|
7
|
+
data.tar.gz: 62b3e37a7b82df4fdd5ca160e71380c15e4c28999b26b5eb6699cc1abdd1611182d38f66841d4cb0980bf21e25feefe4059e7c5860e773cbbcd312eb536ab317
|
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 && 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 && 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,158 @@
|
|
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
|
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
|
14
8
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
28
|
-
|
29
|
-
@supplements = supplements
|
9
|
+
LANGUAGES = {
|
10
|
+
"ru" => "R",
|
11
|
+
"fr" => "F",
|
12
|
+
"en" => "E",
|
13
|
+
"ar" => "A",
|
14
|
+
}.freeze
|
30
15
|
|
16
|
+
def initialize(**opts)
|
31
17
|
opts.each { |key, value| send("#{key}=", value.is_a?(Array) && value || value.to_s) }
|
32
18
|
end
|
33
19
|
|
20
|
+
def get_params
|
21
|
+
instance_variables.map { |var| [var.to_s.gsub("@", "").to_sym, instance_variable_get(var)] }.to_h
|
22
|
+
end
|
23
|
+
|
34
24
|
def urn
|
35
|
-
|
25
|
+
Urn.new(**get_params)
|
36
26
|
end
|
37
27
|
|
38
|
-
def self.parse(
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
def self.parse(code_or_params)
|
29
|
+
params = code_or_params.is_a?(String) ? Parser.new.parse(code_or_params) : code_or_params
|
30
|
+
# Parslet returns an array when match any copublisher
|
31
|
+
# otherwise it's hash
|
32
|
+
if params.is_a?(Array)
|
33
|
+
new(
|
34
|
+
**(
|
35
|
+
params.inject({}) do |r, i|
|
36
|
+
result = r
|
37
|
+
i.map {|k, v| Transformer.new.apply(k => v).to_a.first }.each do |k, v|
|
38
|
+
result = result.merge(k => r.key?(k) ? [v, r[k]] : v)
|
39
|
+
end
|
40
|
+
result
|
41
|
+
end
|
42
|
+
)
|
43
|
+
)
|
44
|
+
else
|
45
|
+
new(**params.map do |k, v|
|
46
|
+
Transformer.new.apply(k => v).to_a.first
|
47
|
+
end.to_h)
|
48
|
+
end
|
49
|
+
# merge values repeating keys into array (for copublishers)
|
50
|
+
|
51
|
+
|
52
|
+
# params.to_h)
|
42
53
|
rescue Parslet::ParseFailed => failure
|
43
54
|
raise Pubid::Iso::Errors::ParseError, "#{failure.message}\ncause: #{failure.parse_failure_cause.ascii_tree}"
|
44
55
|
end
|
56
|
+
|
57
|
+
def to_s(lang: nil, with_date: true, with_language_code: :iso)
|
58
|
+
# @pubid_language = lang
|
59
|
+
case lang
|
60
|
+
when :french
|
61
|
+
French.new(**get_params)
|
62
|
+
when :russian
|
63
|
+
Russian.new(**get_params)
|
64
|
+
else
|
65
|
+
self
|
66
|
+
end.identifier(with_date, with_language_code) + (@joint_document && "|#{@joint_document}").to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
def identifier(with_date, with_language_code)
|
70
|
+
"#{originator}#{type}#{stage} #{number}#{part}#{iteration}"\
|
71
|
+
"#{with_date && year || ''}#{edition}#{supplements}#{language(with_language_code)}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def copublisher
|
75
|
+
return nil unless @copublisher
|
76
|
+
|
77
|
+
(!@copublisher.is_a?(Array) && [@copublisher]) || @copublisher
|
78
|
+
end
|
79
|
+
|
80
|
+
def originator
|
81
|
+
if copublisher
|
82
|
+
# @copublisher = [@copublisher] unless @copublisher.is_a?(Array)
|
83
|
+
# @copublisher.map! { |copublisher| copublisher.sub("IEC", "CEI") } if @french
|
84
|
+
publisher + copublisher.map(&:to_s).sort.map do |copublisher|
|
85
|
+
"/#{copublisher.gsub('-', '/')}"
|
86
|
+
end.join
|
87
|
+
else
|
88
|
+
publisher
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def stage
|
93
|
+
"#{(@copublisher && ' ') || '/'}#{@stage}" if @stage
|
94
|
+
end
|
95
|
+
|
96
|
+
def part
|
97
|
+
"-#{@part}" if @part
|
98
|
+
end
|
99
|
+
|
100
|
+
def year
|
101
|
+
":#{@year}" if @year
|
102
|
+
end
|
103
|
+
|
104
|
+
def type
|
105
|
+
"#{(@copublisher && ' ') || '/'}#{@type}" if @type
|
106
|
+
end
|
107
|
+
|
108
|
+
def edition
|
109
|
+
" ED#{@edition}" if @edition
|
110
|
+
end
|
111
|
+
|
112
|
+
def iteration
|
113
|
+
".#{@iteration}" if @iteration
|
114
|
+
end
|
115
|
+
|
116
|
+
def amendment
|
117
|
+
if @amendment_number
|
118
|
+
"Amd #{@amendment_version}:#{@amendment_number}"
|
119
|
+
else
|
120
|
+
"Amd #{@amendment_version}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def corrigendum
|
125
|
+
if @corrigendum_number
|
126
|
+
"Cor #{@corrigendum_version}:#{@corrigendum_number}"
|
127
|
+
else
|
128
|
+
"Cor #{@corrigendum_version}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def supplements
|
133
|
+
result = ""
|
134
|
+
if @amendment
|
135
|
+
result += (@amendment_stage && "/#{@amendment_stage} ") || "/"
|
136
|
+
result += amendment
|
137
|
+
end
|
138
|
+
|
139
|
+
if @corrigendum
|
140
|
+
result += (@corrigendum_stage && "/#{@corrigendum_stage} ") || "/"
|
141
|
+
result += corrigendum
|
142
|
+
end
|
143
|
+
|
144
|
+
result
|
145
|
+
end
|
146
|
+
|
147
|
+
def language(with_language_code = :iso)
|
148
|
+
if @language
|
149
|
+
if with_language_code == :single
|
150
|
+
"(#{LANGUAGES[@language]})"
|
151
|
+
else
|
152
|
+
"(#{@language})"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
45
157
|
end
|
46
158
|
end
|
data/lib/pubid/iso/parser.rb
CHANGED
@@ -22,8 +22,14 @@ module Pubid::Iso
|
|
22
22
|
end
|
23
23
|
|
24
24
|
rule(:stage) do
|
25
|
-
(
|
26
|
-
|
25
|
+
Russian::STAGE.values.reduce(
|
26
|
+
# other stages
|
27
|
+
str("NP") | str("WD") | str("CD") | str("DIS") | str("FDIS") | str("PRF") |
|
28
|
+
str("IS") | str("AWI") | str("PWI") |
|
29
|
+
# AMD and COR stages
|
30
|
+
str("FPD") | str("pD") | str("PD") | str("FD") | str("D")) do |acc, stage|
|
31
|
+
acc | str(stage)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
# TYPES = {
|
@@ -36,12 +42,17 @@ module Pubid::Iso
|
|
36
42
|
# # type = "data" / "guide" / "isp" / "iwa" /
|
37
43
|
# # "pas" / "r" / "tr" / "ts" / "tta"
|
38
44
|
rule(:type) do
|
39
|
-
(
|
40
|
-
|
45
|
+
(
|
46
|
+
Russian::TYPE.values.reduce(
|
47
|
+
str("DATA") | str("ISP") | str("IWA") | str("R") | str("TTA") |
|
48
|
+
str("TS") | str("TR") | str("PAS") | str("Guide") | str("GUIDE")) do |acc, type|
|
49
|
+
acc | str(type)
|
50
|
+
end
|
51
|
+
).as(:type)
|
41
52
|
end
|
42
53
|
|
43
54
|
rule(:year) do
|
44
|
-
match('\d').repeat(4, 4)
|
55
|
+
match('\d').repeat(4, 4).as(:year)
|
45
56
|
end
|
46
57
|
|
47
58
|
rule(:part) do
|
@@ -51,13 +62,16 @@ module Pubid::Iso
|
|
51
62
|
|
52
63
|
rule(:originator) do
|
53
64
|
organization.as(:publisher) >>
|
54
|
-
(str(" ").maybe >> str("/") >> organization.as(:copublisher)).
|
65
|
+
(str(" ").maybe >> str("/") >> organization.as(:copublisher)).repeat
|
55
66
|
end
|
56
67
|
|
57
68
|
rule(:organization) do
|
58
|
-
|
69
|
+
Russian::PUBLISHER.values.reduce(
|
70
|
+
str("IEC") | str("IEEE") | str("CIW") | str("SAE") |
|
59
71
|
str("CIE") | str("ASME") | str("ASTM") | str("OECD") | str("ISO") |
|
60
|
-
str("IWA") | str("HL7")
|
72
|
+
str("IWA") | str("HL7") | str("CEI")) do |acc, publisher|
|
73
|
+
acc | str(publisher)
|
74
|
+
end
|
61
75
|
end
|
62
76
|
|
63
77
|
rule(:edition) do
|
@@ -69,31 +83,59 @@ module Pubid::Iso
|
|
69
83
|
str(".") >> digits.as(:iteration)
|
70
84
|
end
|
71
85
|
|
72
|
-
rule(:
|
86
|
+
rule(:amendment) do
|
87
|
+
(str("/") >> stage.as(:amendment_stage)).maybe >>
|
73
88
|
(str("/") | str(" ")).maybe >>
|
74
|
-
(str("Amd") | str("AMD") | str("
|
75
|
-
str(" ") >>
|
76
|
-
digits.as(:
|
77
|
-
(str(":") >> digits.as(:
|
89
|
+
(str("Amd") | str("AMD") | str("AM")).as(:amendment) >>
|
90
|
+
(str(" ") | str(".")) >>
|
91
|
+
digits.as(:amendment_version) >>
|
92
|
+
(str(":") >> digits.as(:amendment_number)).maybe
|
93
|
+
end
|
94
|
+
|
95
|
+
rule(:corrigendum) do
|
96
|
+
(str("/") >> stage.as(:corrigendum_stage)).maybe >>
|
97
|
+
(str("/") | str(" ")).maybe >>
|
98
|
+
(str("Cor") | str("COR")).as(:corrigendum) >>
|
99
|
+
(str(" ") | str(".")) >>
|
100
|
+
digits.as(:corrigendum_version) >>
|
101
|
+
(str(":") >> digits.as(:corrigendum_number)).maybe
|
78
102
|
end
|
79
103
|
|
80
104
|
rule(:language) do
|
81
|
-
str("(") >>
|
105
|
+
str("(") >> (
|
106
|
+
( # parse ru,en,fr
|
107
|
+
(match["a-z"].repeat(1) >> str(",").maybe) |
|
108
|
+
# parse R/E/F
|
109
|
+
((str("E") | str("F") | str("A") | str("R")) >> str("/").maybe)
|
110
|
+
).repeat.as(:language)
|
111
|
+
) >> str(")")
|
112
|
+
end
|
113
|
+
|
114
|
+
rule(:guide_prefix) do
|
115
|
+
str("Guide") | str("GUIDE") | str("Руководство") | str("Руководства")
|
82
116
|
end
|
83
117
|
|
84
118
|
rule(:identifier) do
|
85
119
|
str("Fpr").as(:stage).maybe >>
|
86
120
|
# Withdrawn e.g: WD/ISO 10360-5:2000
|
87
121
|
str("WD/").maybe >>
|
122
|
+
# for French and Russian PubIDs starting with Guide type
|
123
|
+
(guide_prefix.as(:type) >> str(" ")).maybe >>
|
124
|
+
(stage.as(:stage) >> str(" ")).maybe >>
|
88
125
|
originator >> ((str(" ") | str("/")) >>
|
89
126
|
# for ISO/FDIS
|
90
|
-
(type | stage)).maybe >>
|
127
|
+
(type | stage.as(:stage))).maybe >>
|
91
128
|
# for ISO/IEC WD TS 25025
|
92
|
-
str(" ").maybe >> ((stage | type) >> str(" ")).maybe >>
|
93
|
-
digits.as(:number) >>
|
129
|
+
str(" ").maybe >> ((stage.as(:stage) | type) >> str(" ")).maybe >>
|
130
|
+
digits.as(:number) >>
|
131
|
+
# for identifiers like ISO 5537/IDF 26
|
132
|
+
(str("|") >> (str("IDF") >> str(" ") >> digits).as(:joint_document)).maybe >>
|
133
|
+
part.maybe >> iteration.maybe >>
|
94
134
|
(str(" ").maybe >> str(":") >> year).maybe >>
|
95
|
-
|
96
|
-
|
135
|
+
# stage before amendment
|
136
|
+
(
|
137
|
+
# stage before corrigendum
|
138
|
+
((amendment >> corrigendum.maybe) | corrigendum).maybe) >>
|
97
139
|
edition.maybe >>
|
98
140
|
language.maybe
|
99
141
|
end
|
@@ -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,24 @@
|
|
1
1
|
module Pubid::Iso
|
2
|
-
class
|
3
|
-
attr_accessor :
|
2
|
+
class Urn
|
3
|
+
attr_accessor :number, :publisher, :copublisher, :stage, :substage, :part,
|
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
|
4
8
|
|
5
|
-
|
6
|
-
|
9
|
+
|
10
|
+
STAGES = { PWI: 0,
|
11
|
+
NP: 10,
|
12
|
+
AWI: 20,
|
13
|
+
WD: 20.20,
|
14
|
+
CD: 30,
|
15
|
+
DIS: 40,
|
16
|
+
FDIS: 50,
|
17
|
+
PRF: 50,
|
18
|
+
IS: 60 }.freeze
|
19
|
+
|
20
|
+
def initialize(**opts)
|
21
|
+
opts.each { |key, value| send("#{key}=", value) }
|
7
22
|
end
|
8
23
|
|
9
24
|
def to_s
|
@@ -11,58 +26,79 @@ module Pubid::Iso
|
|
11
26
|
# [[":" status] ":" edition]
|
12
27
|
# [":" docversion] [":" language]
|
13
28
|
|
14
|
-
"urn:iso:std:#{originator}#{type}:#{
|
29
|
+
"urn:iso:std:#{originator}#{type}:#{number}#{part}#{stage}#{edition}#{supplement}#{language}"
|
15
30
|
end
|
16
31
|
|
17
32
|
def part
|
18
|
-
":-#{
|
33
|
+
":-#{@part}" if @part
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_stage(stage)
|
37
|
+
":stage-#{sprintf('%05.2f', STAGES[stage.to_sym])}#{iteration}"
|
19
38
|
end
|
20
39
|
|
21
40
|
def stage
|
22
|
-
|
41
|
+
return render_stage(@stage) if @stage
|
42
|
+
|
43
|
+
return render_stage(@amendment_stage) if @amendment_stage
|
44
|
+
|
45
|
+
render_stage(@corrigendum_stage) if @corrigendum_stage
|
23
46
|
end
|
24
47
|
|
25
48
|
def originator
|
26
49
|
# originator = "iso" / "iso-iec" / "iso-cie" / "iso-astm" /
|
27
50
|
# "iso-ieee" / "iec"
|
28
51
|
|
29
|
-
if
|
30
|
-
|
52
|
+
if @copublisher
|
53
|
+
@copublisher = [@copublisher] unless @copublisher.is_a?(Array)
|
54
|
+
@publisher.downcase + @copublisher.map(&:to_s).sort.map do |copublisher|
|
55
|
+
"-#{copublisher.downcase.gsub('/', '-')}"
|
56
|
+
end.join
|
31
57
|
else
|
32
|
-
|
58
|
+
@publisher.downcase
|
33
59
|
end
|
34
60
|
end
|
35
61
|
|
36
62
|
def edition
|
37
|
-
":ed-#{
|
63
|
+
":ed-#{@edition}" if @edition
|
38
64
|
end
|
39
65
|
|
40
66
|
def iteration
|
41
|
-
".v#{
|
67
|
+
".v#{@iteration}" if @iteration
|
42
68
|
end
|
43
69
|
|
44
70
|
def type
|
45
71
|
# type = "data" / "guide" / "isp" / "iwa" /
|
46
72
|
# "pas" / "r" / "tr" / "ts" / "tta"
|
47
73
|
|
48
|
-
if
|
49
|
-
":#{
|
74
|
+
if @type
|
75
|
+
":#{@type.downcase}"
|
50
76
|
end
|
51
77
|
end
|
52
78
|
|
53
79
|
def supplement
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
80
|
+
result = ""
|
81
|
+
if @amendment
|
82
|
+
result += if @amendment_number
|
83
|
+
":amd:#{@amendment_number}:v#{@amendment_version}"
|
84
|
+
else
|
85
|
+
":amd:#{@amendment_version}:v1"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
if @corrigendum
|
89
|
+
result += if @corrigendum_number
|
90
|
+
":cor:#{@corrigendum_number}:v#{@corrigendum_version}"
|
91
|
+
else
|
92
|
+
":cor:#{@corrigendum_version}:v1"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
result
|
61
97
|
end
|
62
98
|
|
63
99
|
def language
|
64
|
-
if
|
65
|
-
":#{
|
100
|
+
if @language
|
101
|
+
":#{@language}"
|
66
102
|
end
|
67
103
|
end
|
68
104
|
end
|
data/lib/pubid/iso/version.rb
CHANGED
data/lib/pubid/iso.rb
CHANGED
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.2
|
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-04-09 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: []
|