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 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: []