pubid 2.0.26 → 2.0.28

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.
@@ -0,0 +1,27 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # The synthesized Corrigendum wrapper (PFS supplements
5
+ # declaration, issue #121 feature 3): the kind face
6
+ # "AC" is the run's dispatch token and the
7
+ # printed notation's face.
8
+ class Corrigendum < Supplement
9
+ FACE = "AC".freeze
10
+
11
+ def self.face
12
+ FACE
13
+ end
14
+
15
+ def self.polymorphic_name
16
+ "pubid:cencenelec:corrigendum"
17
+ end
18
+
19
+ # The MR slug's supplement suffix: the shared MrString
20
+ # recurses into base and appends this.
21
+ def mr_supplement_suffix
22
+ mr_join_segments("cor", number, supplement_date)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,31 +1,51 @@
1
- module Pubid
2
- module CenPfs
3
- module Identifiers
4
- # Concrete European Norm identifier type (PFS type `european_norm`).
5
- class EuropeanNorm < Identifier
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete European Norm identifier type (PFS type `european_norm`).
5
+ class EuropeanNorm < Identifier
6
6
  TYPED_STAGES = [
7
- Pubid::Components::TypedStage.new(
8
- code: :puben,
9
- stage_code: :published,
10
- type_code: :en,
11
- abbr: ["EN"],
12
- name: "European Norm",
13
- harmonized_stages: [],
14
- ),
7
+ ::Pubid::Components::TypedStage.new(
8
+ code: :puben, stage_code: :published,
9
+ type_code: :en, abbr: ["EN"],
10
+ name: "European Norm", harmonized_stages: [],
11
+ ),
12
+ ::Pubid::Components::TypedStage.new(
13
+ code: :pren, stage_code: :proposal,
14
+ type_code: :en, abbr: ["prEN"],
15
+ name: "pren", harmonized_stages: [],
16
+ ),
17
+ ::Pubid::Components::TypedStage.new(
18
+ code: :fpren, stage_code: :final_proposal,
19
+ type_code: :en, abbr: ["FprEN"],
20
+ name: "fpren", harmonized_stages: [],
21
+ ),
15
22
  ].freeze
16
23
 
17
- def self.type
18
- { key: :en, web: :"european-norm", title: "European Norm", short: "EN" }
19
- end
24
+ def self.type
25
+ { key: :en, web: :"european-norm", title: "European Norm", short: "EN" }
26
+ end
27
+
28
+ # The publisher default (feature 5): the type's own token
29
+ # when the type is its designation, else the scheme default.
30
+ def self.default_publisher
31
+ ::Pubid::Components::Publisher.new(body: "EN")
32
+ end
33
+
34
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
35
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
36
+
37
+ def self.default_type
38
+ ::Pubid::Components::Type.new(abbr: type[:short])
39
+ end
20
40
 
21
- # The scheme-canonical wire tag declared in the definition:
22
- # to_hash stays byte-identical with the scheme's coded
23
- # flavor, and this flavor's own from_hash routes the tag
24
- # to this class.
25
- def self.polymorphic_name
26
- "pubid:cencenelec:european-norm"
27
- end
41
+ # The scheme-canonical wire tag declared in the definition:
42
+ # to_hash stays byte-identical with the scheme's coded
43
+ # flavor, and this flavor's own from_hash routes the tag
44
+ # to this class.
45
+ def self.polymorphic_name
46
+ "pubid:cencenelec:european-norm"
28
47
  end
29
48
  end
30
49
  end
31
50
  end
51
+ end
@@ -0,0 +1,55 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete European Prestandard identifier type (PFS type `european_prestandard`).
5
+ class EuropeanPrestandard < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :env, web: :european_prestandard, title: "European Prestandard", short: "ENV" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "ENV")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The adopted document (feature 4): the whole identity lives
27
+ # on the nested ISO/IEC identifier.
28
+ attribute :adopted, ::Pubid::Identifier, polymorphic: true
29
+
30
+ def root
31
+ adopted ? adopted.root : self
32
+ end
33
+
34
+ # MR "cen.iso.ts.21003-7": the publisher group fused, then the
35
+ # adopted document's own MR string in place of a number.
36
+ def mr_publisher
37
+ mr_join(*([publisher] + Array(copublishers)).compact
38
+ .map { |p| p.to_s.downcase })
39
+ end
40
+
41
+ def mr_number_with_part
42
+ adopted ? adopted.to_mr_string : super
43
+ end
44
+
45
+ # The scheme-canonical wire tag declared in the definition:
46
+ # to_hash stays byte-identical with the scheme's coded
47
+ # flavor, and this flavor's own from_hash routes the tag
48
+ # to this class.
49
+ def self.polymorphic_name
50
+ "pubid:cencenelec:european-prestandard"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete European Specification identifier type (PFS type `european_specification`).
5
+ class EuropeanSpecification < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :es, web: :european_specification, title: "European Specification", short: "ES" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "ES")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The scheme-canonical wire tag declared in the definition:
27
+ # to_hash stays byte-identical with the scheme's coded
28
+ # flavor, and this flavor's own from_hash routes the tag
29
+ # to this class.
30
+ def self.polymorphic_name
31
+ "pubid:cencenelec:european-specification"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # The fragment wrapper: a fragment of the amendment it
5
+ # wraps; the fragment ordinal is its own `number`.
6
+ class Fragment < ::Pubid::CenPfs::Identifier
7
+ attribute :base, ::Pubid::CenPfs::Identifier
8
+ attribute :number, :string
9
+
10
+ def base_document
11
+ base&.base_document || self
12
+ end
13
+
14
+ def drop_supplements
15
+ base || self
16
+ end
17
+
18
+ def mr_supplement_suffix
19
+ mr_join_segments("frag", number)
20
+ end
21
+
22
+ def self.polymorphic_name
23
+ "pubid:cencenelec:fragment"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete Guide identifier type (PFS type `guide`).
5
+ class Guide < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :guide, web: :guide, title: "Guide", short: "Guide" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "EN")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The scheme-canonical wire tag declared in the definition:
27
+ # to_hash stays byte-identical with the scheme's coded
28
+ # flavor, and this flavor's own from_hash routes the tag
29
+ # to this class.
30
+ def self.polymorphic_name
31
+ "pubid:cencenelec:guide"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete Harmonization Document identifier type (PFS type `harmonization_document`).
5
+ class HarmonizationDocument < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :hd, web: :harmonization_document, title: "Harmonization Document", short: "HD" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "HD")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The scheme-canonical wire tag declared in the definition:
27
+ # to_hash stays byte-identical with the scheme's coded
28
+ # flavor, and this flavor's own from_hash routes the tag
29
+ # to this class.
30
+ def self.polymorphic_name
31
+ "pubid:cencenelec:harmonization-document"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # The supplement wrapper base: the wrapper owns its ordinal
5
+ # and the base identifier; every delegated attribute reads
6
+ # through (the coded SupplementIdentifier shape).
7
+ class Supplement < ::Pubid::CenPfs::Identifier
8
+ attribute :base, ::Pubid::CenPfs::Identifier
9
+ attribute :number, :string
10
+ attribute :year, :string
11
+ attribute :month, :string
12
+
13
+ def base_document
14
+ base&.base_document || self
15
+ end
16
+
17
+ def drop_supplements
18
+ base || self
19
+ end
20
+
21
+ # The wrapper's date: "2016-11", "2003", or nil.
22
+ def supplement_date
23
+ return nil unless year
24
+
25
+ [year, month].compact.reject(&:empty?).join("-")
26
+ end
27
+
28
+ # The printed notation: the kind face, the ordinal (absent
29
+ # for an unnumbered corrigendum) and the declared date tail.
30
+ # The bare notation; the renderer's walkers add the
31
+ # standalone slash and the consolidated plus themselves.
32
+ def supplement_notation
33
+ "#{self.class.face}#{number}#{year ? ":#{year}" : ''}#{month ? "-#{month}" : ''}"
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete Technical Report identifier type (PFS type `technical_report`).
5
+ class TechnicalReport < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :tr, web: :technical_report, title: "Technical Report", short: "TR" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "EN")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The scheme-canonical wire tag declared in the definition:
27
+ # to_hash stays byte-identical with the scheme's coded
28
+ # flavor, and this flavor's own from_hash routes the tag
29
+ # to this class.
30
+ def self.polymorphic_name
31
+ "pubid:cencenelec:technical-report"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module Pubid
2
+ module CenPfs
3
+ module Identifiers
4
+ # Concrete Technical Specification identifier type (PFS type `technical_specification`).
5
+ class TechnicalSpecification < Identifier
6
+ TYPED_STAGES = [
7
+ ].freeze
8
+
9
+ def self.type
10
+ { key: :ts, web: :technical_specification, title: "Technical Specification", short: "TS" }
11
+ end
12
+
13
+ # The publisher default (feature 5): the type's own token
14
+ # when the type is its designation, else the scheme default.
15
+ def self.default_publisher
16
+ ::Pubid::Components::Publisher.new(body: "EN")
17
+ end
18
+
19
+ attribute :publisher, ::Pubid::Components::Publisher, default: -> { self.class.default_publisher }
20
+ attribute :type, ::Pubid::Components::Type, default: -> { self.class.default_type }
21
+
22
+ def self.default_type
23
+ ::Pubid::Components::Type.new(abbr: type[:short])
24
+ end
25
+
26
+ # The scheme-canonical wire tag declared in the definition:
27
+ # to_hash stays byte-identical with the scheme's coded
28
+ # flavor, and this flavor's own from_hash routes the tag
29
+ # to this class.
30
+ def self.polymorphic_name
31
+ "pubid:cencenelec:technical-specification"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,7 +1,21 @@
1
1
  module Pubid
2
2
  module CenPfs
3
3
  module Identifiers
4
- autoload :EuropeanNorm, "#{__dir__}/identifiers/european_norm"
4
+ autoload :EuropeanNorm, "#{__dir__}/identifiers/european_norm"
5
+ autoload :AdoptedEuropeanNorm, "#{__dir__}/identifiers/adopted_european_norm"
6
+ autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
7
+ autoload :TechnicalSpecification, "#{__dir__}/identifiers/technical_specification"
8
+ autoload :Guide, "#{__dir__}/identifiers/guide"
9
+ autoload :CenReport, "#{__dir__}/identifiers/cen_report"
10
+ autoload :CenWorkshopAgreement, "#{__dir__}/identifiers/cen_workshop_agreement"
11
+ autoload :EuropeanSpecification, "#{__dir__}/identifiers/european_specification"
12
+ autoload :EuropeanPrestandard, "#{__dir__}/identifiers/european_prestandard"
13
+ autoload :HarmonizationDocument, "#{__dir__}/identifiers/harmonization_document"
14
+ autoload :Supplement, "#{__dir__}/identifiers/supplement"
15
+ autoload :Amendment, "#{__dir__}/identifiers/amendment"
16
+ autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
17
+ autoload :ConsolidatedIdentifier, "#{__dir__}/identifiers/consolidated_identifier"
18
+ autoload :Fragment, "#{__dir__}/identifiers/fragment"
5
19
  end
6
20
  end
7
21
  end
@@ -6,10 +6,29 @@
6
6
  # namespace; identifiers carry the scheme's wire tag, so their
7
7
  # pubid URNs encode through the scheme's own schema.
8
8
  PubidUrnSchema = Pubid::PubidUrn.define("cen_pfs") do
9
+ atom "publisher", "pub"
10
+ atom "copublishers", "co", kind: :list
9
11
  atom "part", "part"
10
12
  atom "year", "year"
13
+ atom "version", "v"
14
+ atom "stage", "stage"
15
+ atom "adopted", "adopted", kind: :id
16
+ atom "identifiers", "ids", kind: :ids
17
+ type "pubid:cencenelec:adopted-european-norm", "aen", core: []
18
+ type "pubid:cencenelec:amendment", "amd", core: []
19
+ type "pubid:cencenelec:cen-report", "cr", core: []
20
+ type "pubid:cencenelec:cen-workshop-agreement", "cwa", core: []
21
+ type "pubid:cencenelec:consolidated-identifier", "consol", core: []
22
+ type "pubid:cencenelec:corrigendum", "cor", core: []
23
+ type "pubid:cencenelec:european-norm", "en", core: []
24
+ type "pubid:cencenelec:european-prestandard", "ep", core: []
25
+ type "pubid:cencenelec:european-specification", "es", core: []
26
+ type "pubid:cencenelec:fragment", "fragment", core: []
27
+ type "pubid:cencenelec:guide", "guide", core: []
28
+ type "pubid:cencenelec:harmonization-document", "hd", core: []
11
29
  type "pubid:cencenelec:identifier", "id", core: []
12
- type "pubid:cencenelec:european-norm", "en", core: ["number"]
30
+ type "pubid:cencenelec:technical-report", "tr", core: []
31
+ type "pubid:cencenelec:technical-specification", "ts", core: []
13
32
  end
14
33
  end
15
34
  end
@@ -2,8 +2,57 @@ module Pubid
2
2
  module CenPfs
3
3
  # Human renderer, generated from the canonical template.
4
4
  class Renderer < ::Pubid::Renderers::Base
5
+ FACE_stage = {
6
+ "fpren" => "FprEN",
7
+ "pren" => "prEN",
8
+ }.freeze
5
9
  def render(**_opts)
6
- "EN #{@id.number}#{"-#{@id.part}" if @id.part}#{":#{@id.date.year}" if @id.date&.year}"
10
+ f = render_fields(@id)
11
+ "#{if f[:stage] && f[:number]; "#{f[:stage]} #{f[:number]}#{("-#{f[:part]}") if f[:part]}#{("#{f[:version]}") if f[:version]}#{(":#{f[:year]}") if f[:year]}" elsif f[:publisher] && f[:guide] && f[:number]; "#{f[:publisher]}#{("#{f[:copublishers]}") if f[:copublishers]} #{f[:guide]} #{f[:number]}#{("-#{f[:part]}") if f[:part]}#{(":#{f[:year]}") if f[:year]}" elsif f[:publisher] && f[:adopted]; "#{f[:publisher]}#{("#{f[:copublishers]}") if f[:copublishers]} #{f[:adopted]}" elsif f[:publisher] && f[:number]; "#{f[:publisher]}#{("#{f[:copublishers]}") if f[:copublishers]}#{("/#{f[:type]}") if f[:type]} #{f[:number]}#{("-#{f[:part]}") if f[:part]}#{("#{f[:version]}") if f[:version]}#{(":#{f[:year]}") if f[:year]}"; end}#{("#{f[:supplements]}#{(" FRAG#{f[:fragment_number]}") if f[:fragment_number]}") if f[:supplements]}"
12
+ end
13
+
14
+ private
15
+
16
+ # The field view: a wrapper reads through to the wrapped
17
+ # standard and composes the printed run once — the standalone
18
+ # chain behind its slash, the consolidated members behind the
19
+ # plus — and the fragment face follows its base.
20
+ def render_fields(id)
21
+ root = id
22
+ run = +""
23
+ members = nil
24
+ frag = nil
25
+ if root.is_a?(Identifiers::Fragment)
26
+ frag = root.number
27
+ root = root.base
28
+ end
29
+ if root.is_a?(Identifiers::ConsolidatedIdentifier)
30
+ base, *consolidated = root.identifiers
31
+ members = consolidated
32
+ root = base
33
+ end
34
+ while root.is_a?(Identifiers::Supplement)
35
+ run.prepend("/#{root.supplement_notation}")
36
+ root = root.base
37
+ end
38
+ members&.each do |member|
39
+ run << "+#{member.supplement_notation}"
40
+ end
41
+ view = {
42
+ publisher: root.publisher&.respond_to?(:body) ? root.publisher.body : root.publisher,
43
+ copublishers: root.copublishers.to_a.any? ? root.copublishers.map { |item| "/#{item.respond_to?(:body) ? item.body : item}" }.join : nil,
44
+ stage: FACE_stage.fetch(root.typed_stage&.code&.to_s, root.typed_stage&.code&.to_s),
45
+ type: (v = root.type&.abbr) && ["TR", "TS"].include?(v) ? v : nil,
46
+ guide: (v = root.type&.abbr) && ["Guide"].include?(v) ? v : nil,
47
+ number: root.number,
48
+ part: root.part,
49
+ version: root.version,
50
+ year: root.date&.year,
51
+ adopted: root.respond_to?(:adopted) ? root.adopted : nil,
52
+ }
53
+ view[:supplements] = run.empty? ? nil : run
54
+ view[:fragment_number] = frag
55
+ view
7
56
  end
8
57
  end
9
58
  end
@@ -1,12 +1,84 @@
1
1
  module Pubid
2
2
  module CenPfs
3
- # The official URN generator, pinned to the scheme's declared
4
- # namespace ("cen") so to_urn stays
5
- # scheme-canonical under the compiled flavor key.
3
+ # The official URN generator: the scheme's declared namespace
4
+ # ("cen") and the ordered fused segments
5
+ # (feature 6) — the publisher group, the adopted document's
6
+ # fused MR string, the composed code, the year, the draft
7
+ # stage. A wrapper reads through to its subject and appends
8
+ # its declared chain; the consolidated bundle marks each
9
+ # member with the plus marker.
6
10
  class UrnGenerator < ::Pubid::UrnGenerator::Base
7
11
  def urn_namespace
8
12
  "cen"
9
13
  end
14
+
15
+ def generate
16
+ id = @identifier
17
+ members = nil
18
+ frag_segments = []
19
+ wrapper = []
20
+ if id.is_a?(Identifiers::Fragment)
21
+ frag_segments = wrapper_segments(id)
22
+ id = id.base
23
+ end
24
+ if id.is_a?(Identifiers::ConsolidatedIdentifier)
25
+ base, *consolidated = id.identifiers
26
+ members = consolidated
27
+ id = base
28
+ end
29
+ while id.is_a?(Identifiers::Supplement)
30
+ wrapper.prepend(*wrapper_segments(id))
31
+ id = id.base
32
+ end
33
+ @identifier = id
34
+ parts = ["urn", urn_namespace]
35
+ parts.concat(official_segments)
36
+ parts.concat(wrapper)
37
+ members&.each do |member|
38
+ parts << "plus"
39
+ parts.concat(wrapper_segments(member))
40
+ end
41
+ parts.concat(frag_segments)
42
+ parts.join(":")
43
+ end
44
+
45
+ private
46
+
47
+ def official_segments
48
+ segments = []
49
+ group = [@identifier.publisher&.respond_to?(:body) ? @identifier.publisher.body : @identifier.publisher,
50
+ *Array(@identifier.copublishers).map { |p| p.respond_to?(:body) ? p.body : p }].compact.map(&:to_s)
51
+ segments << group.map(&:downcase).join("-") unless group.empty?
52
+ adopted = @identifier.respond_to?(:adopted) ? @identifier.adopted : nil
53
+ mr = adopted&.to_mr_string
54
+ segments << mr.tr("._", "::") unless mr.nil? || mr.empty?
55
+ code = []
56
+ code << @identifier.number.to_s if @identifier.number
57
+ code << "-" + @identifier.part.to_s if @identifier.part
58
+ segments << code.join unless code.empty?
59
+ date = [@identifier.date&.year].compact
60
+ segments << date.join("-") unless date.empty?
61
+ stage = @identifier.typed_stage
62
+ code = stage&.stage_code
63
+ segments << "stage." + code.to_s if code && code.to_s != "published"
64
+ segments
65
+ end
66
+
67
+ # One wrapper's declared URN chain: the kind word, then the
68
+ # wrapper's columns (the ordinal, the year-month date).
69
+ def wrapper_segments(id)
70
+ segments = case id
71
+ when Identifiers::Amendment
72
+ ["amd", id.number, id.year]
73
+ when Identifiers::Corrigendum
74
+ ["cor", id.number, (id.respond_to?(:supplement_date) ? id.supplement_date : [id.year, id.month].compact.join("-") )]
75
+ when Identifiers::Fragment
76
+ ["frag", id.number]
77
+ else
78
+ []
79
+ end
80
+ segments.map(&:to_s).reject(&:empty?)
81
+ end
10
82
  end
11
83
  end
12
84
  end
data/lib/pubid/cen_pfs.rb CHANGED
@@ -1,34 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # PFS-generated flavor — DO NOT EDIT BY HAND.
4
- # Source: definitions/cen.pfs (pfs:1) sha256:bc1edd5874f8938b5f946416a2b052d9d9b9df3d99f6c20a3d88fcab9ae1d70c
4
+ # Source: definitions/cen.pfs (pfs:1) sha256:b8f2c00e392dbc03c1fddedad141afa7c930c5430738721b7df0ac69a371d028
5
5
  # Compiler: pubid/grammar/pfs 0.1.0 (baked with parsanol 1.3.126)
6
6
  # Regenerate: ruby scripts/pfs compile definitions/cen.pfs --as cen_pfs --ruby-out <dir>
7
7
 
8
8
  require "pubid"
9
9
 
10
10
  module Pubid
11
- # CEN/CENELEC European Norms (module composition) flavor, compiled from its PFS definition
11
+ # CEN/CENELEC flavor, compiled from its PFS definition
12
12
  # (pubid/pubid#706). A compiled flavor is a peer of the coded
13
13
  # flavors: same registry, same input guards, same error
14
14
  # namespace, same URN contracts.
15
15
  module CenPfs
16
16
  extend Pubid::PrefixesSupport
17
17
 
18
- PREFIXES = ["EN", "CEN/", "CLC/"].freeze
19
- # The module composition the definition binds (issue #706 §4):
20
- # each entry names the library module, the version it was bound
21
- # at, and — where the module declares one — its IDENTITY
22
- # composition (wrapper-with-adopted: the adopted document is
23
- # the base). Carried so consumers and the wizard can
24
- # introspect what the flavor is composed of.
25
- MODULES = [
26
- { name: "iso.inner", version: 1, identity: { composition: "wrapper-with-adopted", base_module: "iso.inner", adopted_field: :adopted } },
27
- { name: "en.overlay", version: 1, identity: { composition: "wrapper-with-adopted", base_module: "iso.inner", adopted_field: :adopted } },
28
- { name: "national.prefix", version: 1, identity: { composition: "wrapper-with-adopted", base_module: "iso.inner", adopted_field: :adopted } },
29
- { name: "supplements.core", version: 1, identity: { composition: "wrapper-with-adopted", adopted_field: :base } },
30
- ].freeze
31
-
18
+ PREFIXES = ["CEN", "CLC", "CENELEC", "EN", "CWA", "HD", "ES", "CR", "ENV"].freeze
19
+ # The adopted-base dispatch hook (the §4 coded escape hatch):
20
+ # vendored beside the generated classes — a missing hook file
21
+ # fails loudly on the first adoption, never silently.
22
+ autoload :AdoptedBase, "#{__dir__}/cen_pfs/adopted_base"
32
23
  autoload :Builder, "#{__dir__}/cen_pfs/builder"
33
24
  autoload :Identifier, "#{__dir__}/cen_pfs/identifier"
34
25
  autoload :Identifiers, "#{__dir__}/cen_pfs/identifiers"
data/lib/pubid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pubid
4
- VERSION = "2.0.26"
4
+ VERSION = "2.0.28"
5
5
  end