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.
- checksums.yaml +4 -4
- data/README.adoc +115 -167
- data/data/parg/cen_pfs.json +1 -1
- data/lib/pubid/cen_pfs/adopted_base.rb +114 -0
- data/lib/pubid/cen_pfs/builder.rb +157 -21
- data/lib/pubid/cen_pfs/identifier.rb +106 -48
- data/lib/pubid/cen_pfs/identifiers/adopted_european_norm.rb +55 -0
- data/lib/pubid/cen_pfs/identifiers/amendment.rb +27 -0
- data/lib/pubid/cen_pfs/identifiers/cen_report.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/cen_workshop_agreement.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/consolidated_identifier.rb +41 -0
- data/lib/pubid/cen_pfs/identifiers/corrigendum.rb +27 -0
- data/lib/pubid/cen_pfs/identifiers/european_norm.rb +43 -23
- data/lib/pubid/cen_pfs/identifiers/european_prestandard.rb +55 -0
- data/lib/pubid/cen_pfs/identifiers/european_specification.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/fragment.rb +28 -0
- data/lib/pubid/cen_pfs/identifiers/guide.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/harmonization_document.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/supplement.rb +39 -0
- data/lib/pubid/cen_pfs/identifiers/technical_report.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers/technical_specification.rb +36 -0
- data/lib/pubid/cen_pfs/identifiers.rb +15 -1
- data/lib/pubid/cen_pfs/pubid_urn_schema.rb +20 -1
- data/lib/pubid/cen_pfs/renderer.rb +50 -1
- data/lib/pubid/cen_pfs/urn_generator.rb +75 -3
- data/lib/pubid/cen_pfs.rb +7 -16
- data/lib/pubid/version.rb +1 -1
- metadata +19 -7
|
@@ -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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
4
|
-
#
|
|
5
|
-
#
|
|
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:
|
|
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
|
|
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", "
|
|
19
|
-
# The
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
|
|
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