pubid-iso 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1f95297e422efe82291fd2570ba264ca9daf1b6304dc3050ae7aebcff532739
4
- data.tar.gz: '08f400bc76e43847ae0ae0b7d0c516de05a6a9bdc1dce60abd9b69ca9745b05e'
3
+ metadata.gz: b4b3d52e0c0c000893b1ed556782f8ad349a54c2d70fe2e1f81942b4699e67a9
4
+ data.tar.gz: 3d82f5403447fe7a816a4913efd3fea16c37cc7c3e20ea8168ef21ab415996b2
5
5
  SHA512:
6
- metadata.gz: 6d2f14cbb013fc0e9097178bc9cf7c3b5255f21699c0e904cbd8bb4aec159464f451c679e5d2f4a24aee9c3c3397d8b882f3fbb89c096104c17da51bfe6cf4f7
7
- data.tar.gz: 3d263a1fad953c7e508b2d1936fda41fd4d827f09eb81fecc6b3379acb23502d6852cdaa99860717714934af262eb01a13039b00871af2ef8f11cf97b738e3df
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
@@ -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
- def initialize(stage: nil, supplements: nil, **opts)
16
- if stage
17
- @stage = STAGES[stage.to_sym]
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
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
- URN.new(self)
25
+ Urn.new(**get_params)
36
26
  end
37
27
 
38
- def self.parse(code)
39
- new(**Parser.new.parse(code).map do |k, v|
40
- Transformer.new.apply(k => v).to_a.first
41
- end.to_h)
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
@@ -22,8 +22,14 @@ module Pubid::Iso
22
22
  end
23
23
 
24
24
  rule(:stage) do
25
- (str("NP") | str("WD") | str("CD") | str("DIS") | str("FDIS") | str("PRF") |
26
- str("IS") | str("AWI") | str("FD") | str("D")).as(:stage)
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
- (str("DATA") | str("ISP") | str("IWA") | str("R") | str("TTA") |
40
- str("TS") | str("TR") | str("PAS") | str("Guide")).as(:type)
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)).maybe
65
+ (str(" ").maybe >> str("/") >> organization.as(:copublisher)).repeat
55
66
  end
56
67
 
57
68
  rule(:organization) do
58
- str("IEC/IEEE") | str("IEC") | str("IEEE") | str("CIW") | str("SAE") |
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(:supplement) do
86
+ rule(:amendment) do
87
+ (str("/") >> stage.as(:amendment_stage)).maybe >>
73
88
  (str("/") | str(" ")).maybe >>
74
- (str("Amd") | str("AMD") | str("Cor") | str("COR")).as(:supplement) >>
75
- str(" ") >>
76
- digits.as(:supplement_version) >>
77
- (str(":") >> digits.as(:supplement_number)).maybe
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("(") >> match["a-z"].repeat(1).as(:language) >> 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) >> part.maybe >> iteration.maybe >>
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
- ((str("/") >> stage).maybe >>
96
- supplement).repeat.as(:supplements) >>
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: case stage
9
- when "D"
10
- "DIS"
11
- when "FD"
12
- "FDIS"
13
- else
14
- stage
15
- end
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 URN
3
- attr_accessor :identifier
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
- def initialize(identifier)
6
- @identifier = identifier
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}:#{identifier.number}#{part}#{stage}#{edition}#{supplement}#{language}"
29
+ "urn:iso:std:#{originator}#{type}:#{number}#{part}#{stage}#{edition}#{supplement}#{language}"
15
30
  end
16
31
 
17
32
  def part
18
- ":-#{identifier.part}" if identifier.part
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
- ":stage-#{identifier.stage}.#{sprintf('%02d', identifier.substage)}#{iteration}" if identifier.stage
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 identifier.copublisher
30
- "#{identifier.publisher.downcase}-#{identifier.copublisher.downcase.gsub('/', '-')}"
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
- identifier.publisher.downcase
58
+ @publisher.downcase
33
59
  end
34
60
  end
35
61
 
36
62
  def edition
37
- ":ed-#{identifier.edition}" if identifier.edition
63
+ ":ed-#{@edition}" if @edition
38
64
  end
39
65
 
40
66
  def iteration
41
- ".v#{identifier.iteration}" if identifier.iteration
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 identifier.type
49
- ":#{identifier.type.downcase}"
74
+ if @type
75
+ ":#{@type.downcase}"
50
76
  end
51
77
  end
52
78
 
53
79
  def supplement
54
- identifier.supplements&.map do |supplement|
55
- if supplement[:supplement_number]
56
- ":#{supplement[:supplement].to_s.downcase}:#{supplement[:supplement_number]}:v#{supplement[:supplement_version]}"
57
- else
58
- ":#{supplement[:supplement].to_s.downcase}:v#{supplement[:supplement_version]}"
59
- end
60
- end&.join
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 identifier.language
65
- ":#{identifier.language}"
100
+ if @language
101
+ ":#{@language}"
66
102
  end
67
103
  end
68
104
  end
@@ -1,5 +1,5 @@
1
1
  module Pubid
2
2
  module Iso
3
- VERSION = "0.1.1".freeze
3
+ VERSION = "0.1.2".freeze
4
4
  end
5
5
  end
data/lib/pubid/iso.rb CHANGED
@@ -13,3 +13,5 @@ require_relative "iso/parser"
13
13
  require_relative "iso/transformer"
14
14
  require_relative "iso/urn"
15
15
  require_relative "iso/identifier"
16
+ require_relative "iso/identifier/french"
17
+ require_relative "iso/identifier/russian"
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.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-03-06 00:00:00.000000000 Z
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.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: []