pubid-iec 1.15.10 → 1.15.11

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: e9e654ca4504342d555dec629448cd79724e9cd7f5f9d929161cee733598f655
4
- data.tar.gz: ad9af0eac552a1c13a27d3047e91aaa797826b5218ce6c63f02e59874953b443
3
+ metadata.gz: efe5ce834b34e6bf882c6865106c3bb907785d6170a08d02d0a9890bc01c0529
4
+ data.tar.gz: c4dd107ef92b86593b096f0e159cc14e4291ffc57b92274db7cad8b04ec99b78
5
5
  SHA512:
6
- metadata.gz: 48e9553910b266e31d698cd7813b7c87e9a31bd7649a6b099047bccfd0af1e0b6417b2dd37b3a2320c0a47a842f2a15005442f9522bb735695b75c37e7566b1c
7
- data.tar.gz: 1575c4d703b71f0e8a63a3265c04fa5adfcb8601f519671eaf675d215f3b8bf7818ad0f42b8bf2b9ee487c051f1f2073b09040fa03fab21553c966d33b2621bb
6
+ metadata.gz: 12e1dfab360df93395240121cbc5442e31c717d7cb585b32984d00cb19f0202c5269a4d66a25d14c004513ee26875e7dbc738d499eea4c67e0017e179e3bafda
7
+ data.tar.gz: 806193bedb59a705cbcfe73b883a31b9b3284ecba2c47c6b110c7ceebcc40404bcbe71d74125c3536af4e8d4c388e210b6c4626e5b0602c15a81af0112e4125b
@@ -69,7 +69,9 @@ module Pubid::Iec
69
69
  end
70
70
 
71
71
  def to_s(with_edition_month_date: false, annotated: false)
72
- self.class.get_renderer_class.new(renderer_data).render(with_edition_month_date: with_edition_month_date, annotated: annotated)
72
+ result = self.class.get_renderer_class.new(renderer_data).render(with_edition_month_date: with_edition_month_date, annotated: annotated)
73
+ result += " (all parts)" if all_parts
74
+ result
73
75
  end
74
76
 
75
77
  def to_yaml
@@ -111,7 +113,7 @@ module Pubid::Iec
111
113
 
112
114
  def transform(params)
113
115
  identifier_params = transform_hash(params)
114
-
116
+ normalize_urn_params!(identifier_params) if identifier_params[:publisher].to_s.match?(/\A[a-z]+\z/)
115
117
  if identifier_params[:interpretation_sheet]
116
118
  return Identifier.create(
117
119
  type: :ish,
@@ -125,6 +127,27 @@ module Pubid::Iec
125
127
  Identifier.create(**identifier_params)
126
128
  end
127
129
 
130
+ def normalize_urn_params!(params)
131
+ params[:publisher] = params[:publisher].to_s.upcase
132
+ params[:copublisher] = params[:copublisher].to_s.upcase if params[:copublisher]
133
+ params[:type] = params[:type].to_s.upcase if params[:type]
134
+ params[:number] = params[:number].to_s.upcase
135
+
136
+ # Map fuzzy URN stages to abbreviations that resolve correctly
137
+ if params[:stage]
138
+ stage_str = params[:stage].to_s
139
+ case stage_str
140
+ when "draft" then params[:stage] = "CD"
141
+ when "published" then params[:stage] = "60.60"
142
+ end
143
+ end
144
+
145
+ # Remove amendments/corrigendums parsed as bare strings from URN
146
+ # (full supplement round-trip support to be added later)
147
+ params.delete(:amendments) if params[:amendments].is_a?(String)
148
+ params.delete(:corrigendums) if params[:corrigendums].is_a?(String)
149
+ end
150
+
128
151
  def get_amendment_class
129
152
  Amendment
130
153
  end
@@ -1,7 +1,9 @@
1
1
  require "pubid-core"
2
+ require_relative "parser_urn"
2
3
 
3
4
  module Pubid::Iec
4
5
  class Parser < Pubid::Core::Parser
6
+ include Pubid::Iec::ParserUrn
5
7
  rule(:organization) do
6
8
  str("IECEE") | str("IECEx") | str("IECQ") | str("IEC") | str("ISO") |
7
9
  str("IEEE") | str("CISPR") | str("ASTM")
@@ -106,6 +108,6 @@ module Pubid::Iec
106
108
  language.maybe)
107
109
  end
108
110
 
109
- rule(:root) { identifier }
111
+ rule(:root) { urn_identifier | identifier }
110
112
  end
111
113
  end
@@ -0,0 +1,110 @@
1
+ module Pubid
2
+ module Iec
3
+ module ParserUrn
4
+ LANGUAGES = %w[en fr es ar ru zh ja de].freeze
5
+ VAP_CODES = %w[csv ser rlv cmv exv pac prv].freeze
6
+
7
+ def self.included(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
8
+ base.class_eval do # rubocop:disable Metrics/BlockLength
9
+ rule(:colon) { str(":") }
10
+
11
+ rule(:urn_organization) do
12
+ str("iecee") | str("iecex") | str("iecq") |
13
+ str("iec") | str("iso") | str("ieee") | str("cispr") | str("astm")
14
+ end
15
+
16
+ rule(:urn_publisher_copublisher) do
17
+ urn_organization.as(:publisher) >> (dash >> urn_organization.as(:copublisher)).repeat >> colon
18
+ end
19
+
20
+ rule(:urn_type) do
21
+ (array_to_str(
22
+ Identifier.config.types.map { |t| t.type[:short] }.flatten.compact.map(&:downcase),
23
+ ).as(:type) >> colon).maybe
24
+ end
25
+
26
+ rule(:urn_number) do
27
+ # Alpha-prefix numbers like ca:01 or plain alpha like syccomm
28
+ (match('[a-z]').repeat(1) >> (str(":") >> match('[a-z0-9]').repeat(1)).maybe |
29
+ # Numeric numbers, optionally followed by a letter (15k)
30
+ match('[0-9]').repeat(1) >> match('[a-z]').maybe).as(:number)
31
+ end
32
+
33
+ rule(:urn_part) do
34
+ # Accept both new format (colon-dash, e.g. ":-6") and legacy API
35
+ # format (dash only, e.g. "-6") for part numbers in URNs
36
+ (colon.maybe >> dash >> (match('[a-z0-9]') | dash).repeat(1).as(:part)).maybe
37
+ end
38
+
39
+ rule(:urn_conjuction_part) do
40
+ (str(",") >> digits.as(:conjuction_part)).repeat
41
+ end
42
+
43
+ rule(:urn_year) do
44
+ # Accept optional month suffix (e.g. "2008-03") for legacy API URNs
45
+ (year_digits.as(:year) >> (dash >> month_digits.as(:month)).maybe).maybe
46
+ end
47
+
48
+ rule(:urn_iteration) do
49
+ (str(".v") >> digits.as(:iteration)).maybe
50
+ end
51
+
52
+ rule(:urn_stage_digits) do
53
+ match('\d').repeat(1, 2) >> str(".") >> match('\d').repeat(2, 2)
54
+ end
55
+
56
+ rule(:urn_stage) do
57
+ str("stage-") >> (str("draft") | str("published") | urn_stage_digits).as(:stage) >>
58
+ urn_iteration
59
+ end
60
+
61
+ rule(:urn_vap) do
62
+ array_to_str(VAP_CODES).as(:vap) >>
63
+ (dash >> array_to_str(VAP_CODES).as(:vap)).repeat
64
+ end
65
+
66
+ rule(:urn_edition) do
67
+ (str("ed-") >> digits.as(:edition)).maybe
68
+ end
69
+
70
+ rule(:urn_amendment) do
71
+ colon >> str("amd").as(:amendments) >>
72
+ (colon >> (year_digits | digits).as(:number)).maybe >>
73
+ (colon >> str("v") >> digits.as(:iteration)).maybe
74
+ end
75
+
76
+ rule(:urn_corrigendum) do
77
+ colon >> str("cor").as(:corrigendums) >>
78
+ (colon >> (year_digits | digits).as(:number)).maybe >>
79
+ (colon >> str("v") >> digits.as(:iteration)).maybe
80
+ end
81
+
82
+ rule(:urn_supplements) do
83
+ (urn_amendment | urn_corrigendum).repeat
84
+ end
85
+
86
+ rule(:urn_fragment) do
87
+ (colon >> str("frag") >> colon >> match('[a-z0-9]').repeat(1).as(:fragment)).maybe
88
+ end
89
+
90
+ rule(:urn_language) do
91
+ (array_to_str(LANGUAGES) >> (dash >> array_to_str(LANGUAGES)).repeat).as(:language)
92
+ end
93
+
94
+ rule(:urn_identifier) do
95
+ str("urn:iec:std:") >> urn_publisher_copublisher >> urn_type >>
96
+ urn_number >> urn_part >> urn_conjuction_part >>
97
+ (colon >> urn_year >>
98
+ (colon >> (urn_stage | urn_vap).maybe >>
99
+ (colon >> urn_edition >>
100
+ urn_supplements >> urn_fragment >>
101
+ (colon >> urn_language.maybe).maybe
102
+ ).maybe
103
+ ).maybe
104
+ ).maybe
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -53,10 +53,38 @@ module Pubid::Iec::Renderer
53
53
  }.freeze
54
54
 
55
55
  def render_identifier(params)
56
- "urn:iec:std:%{publisher}%{copublisher}%{type}:%{number}"\
57
- "%{part}%{conjuction_part}%{year}%{stage}%{vap}"\
58
- "%{urn_stage}%{corrigendum_stage}%{iteration}%{version}%{part_version}"\
59
- "%{edition}%{amendments}%{corrigendums}%{fragment}" % params
56
+ result = "urn:iec:std:#{params[:publisher]}#{params[:copublisher]}" \
57
+ "#{params[:type]}:#{params[:number]}" \
58
+ "#{params[:part]}#{params[:conjuction_part]}"
59
+
60
+ # Positional fields — always colon-separated even when empty
61
+ result += ":#{strip_leading_colon(params[:year])}"
62
+
63
+ stage_value = [params[:stage], params[:vap], params[:urn_stage],
64
+ params[:corrigendum_stage], params[:iteration],
65
+ params[:version], params[:part_version]].map(&:to_s).join
66
+ result += ":#{strip_leading_colon(stage_value)}"
67
+
68
+ result += ":#{strip_leading_colon(params[:edition])}"
69
+
70
+ # Non-positional suffixes
71
+ result += params[:amendments].to_s
72
+ result += params[:corrigendums].to_s
73
+ result += params[:fragment].to_s
74
+
75
+ result
76
+ end
77
+
78
+ def render(with_date: true, with_language_code: :iso, annotated: false, **args)
79
+ base = render_base_identifier(**args.merge(
80
+ with_date: with_date, with_language_code: with_language_code, annotated: annotated,
81
+ ))
82
+ lang = strip_leading_colon(@prerendered_params[:language].to_s)
83
+ if @prerendered_params.key?(:all_parts)
84
+ "#{base}ser"
85
+ else
86
+ "#{base}:#{lang}"
87
+ end
60
88
  end
61
89
 
62
90
  def render_number(number, _opts, _params)
@@ -111,5 +139,12 @@ module Pubid::Iec::Renderer
111
139
  "-" + Array(copublisher).map { |c| c.to_s.downcase }.join("-")
112
140
  end
113
141
 
142
+ private
143
+
144
+ def strip_leading_colon(value)
145
+ s = value.to_s
146
+ s.start_with?(":") ? s[1..] : s
147
+ end
148
+
114
149
  end
115
150
  end
@@ -12,5 +12,11 @@ module Pubid::Iec::Renderer
12
12
  def render_stage(stage, _opts, _params)
13
13
  ":stage-#{stage.to_s.downcase}"
14
14
  end
15
+
16
+ def render(with_date: true, with_language_code: :iso, annotated: false, **args)
17
+ render_base_identifier(**args.merge(
18
+ with_date: with_date, with_language_code: with_language_code, annotated: annotated,
19
+ )) + @prerendered_params[:language].to_s
20
+ end
15
21
  end
16
22
  end
@@ -1,5 +1,5 @@
1
1
  module Pubid
2
2
  module Iec
3
- VERSION = "1.15.10".freeze
3
+ VERSION = "1.15.11".freeze
4
4
  end
5
5
  end
data/lib/pubid/iec.rb CHANGED
@@ -11,6 +11,7 @@ require "pubid-core"
11
11
  require_relative "iec/errors"
12
12
  require_relative "iec/stage"
13
13
  require_relative "iec/typed_project_stage"
14
+ require_relative "iec/parser_urn"
14
15
  require_relative "iec/parser"
15
16
  require_relative "iec/trf_parser"
16
17
  require_relative "iec/renderer/pubid"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubid-iec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.10
4
+ version: 1.15.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-03-26 00:00:00.000000000 Z
11
+ date: 2026-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 1.15.10
33
+ version: 1.15.11
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 1.15.10
40
+ version: 1.15.11
41
41
  description: Library to generate, parse and manipulate IEC PubID.
42
42
  email:
43
43
  - open.source@ribose.com
@@ -75,6 +75,7 @@ files:
75
75
  - lib/pubid/iec/identifier/white_paper.rb
76
76
  - lib/pubid/iec/identifier/working_document.rb
77
77
  - lib/pubid/iec/parser.rb
78
+ - lib/pubid/iec/parser_urn.rb
78
79
  - lib/pubid/iec/renderer/amendment.rb
79
80
  - lib/pubid/iec/renderer/corrigendum.rb
80
81
  - lib/pubid/iec/renderer/interpretation_sheet.rb