pubid 2.0.25 → 2.0.27
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/data/parg/etsi_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/doi_pfs/builder.rb +2 -2
- data/lib/pubid/etsi_pfs/CLAUDE.md +48 -40
- data/lib/pubid/etsi_pfs/builder.rb +45 -12
- data/lib/pubid/etsi_pfs/identifier.rb +23 -41
- data/lib/pubid/etsi_pfs/identifiers/amendment.rb +20 -0
- data/lib/pubid/etsi_pfs/identifiers/corrigendum.rb +20 -0
- data/lib/pubid/etsi_pfs/identifiers/standard.rb +64 -15
- data/lib/pubid/etsi_pfs/identifiers/supplement.rb +72 -0
- data/lib/pubid/etsi_pfs/identifiers.rb +4 -1
- data/lib/pubid/etsi_pfs/pubid_urn_schema.rb +4 -2
- data/lib/pubid/etsi_pfs/renderer.rb +29 -1
- data/lib/pubid/etsi_pfs/urn_generator.rb +40 -3
- data/lib/pubid/etsi_pfs.rb +2 -1
- data/lib/pubid/version.rb +1 -1
- metadata +20 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# The synthesized Amendment wrapper (PFS supplements
|
|
5
|
+
# declaration, issue #121 feature 3): the kind face
|
|
6
|
+
# "A" is the run's dispatch token and the
|
|
7
|
+
# printed notation's face.
|
|
8
|
+
class Amendment < Supplement
|
|
9
|
+
FACE = "A".freeze
|
|
10
|
+
|
|
11
|
+
def self.face
|
|
12
|
+
FACE
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.polymorphic_name
|
|
16
|
+
"pubid:cencenelec:amendment"
|
|
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("amd", number, year)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# Concrete CEN Report identifier type (PFS type `cen_report`).
|
|
5
|
+
class CenReport < Identifier
|
|
6
|
+
TYPED_STAGES = [
|
|
7
|
+
].freeze
|
|
8
|
+
|
|
9
|
+
def self.type
|
|
10
|
+
{ key: :cr, web: :cen_report, title: "CEN Report", short: "CR" }
|
|
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: "CR")
|
|
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:cen-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 CEN Workshop Agreement identifier type (PFS type `cen_workshop_agreement`).
|
|
5
|
+
class CenWorkshopAgreement < Identifier
|
|
6
|
+
TYPED_STAGES = [
|
|
7
|
+
].freeze
|
|
8
|
+
|
|
9
|
+
def self.type
|
|
10
|
+
{ key: :cwa, web: :cen_workshop_agreement, title: "CEN Workshop Agreement", short: "CWA" }
|
|
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: "CWA")
|
|
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:cen-workshop-agreement"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# The consolidated (plus-run) bundle: the base document is
|
|
5
|
+
# the first member; the supplements carry no base.
|
|
6
|
+
class ConsolidatedIdentifier < ::Pubid::CenPfs::Identifier
|
|
7
|
+
attribute :identifiers, ::Pubid::CenPfs::Identifier,
|
|
8
|
+
polymorphic: true, collection: true
|
|
9
|
+
|
|
10
|
+
# The origin document. Members live in `identifiers`, so
|
|
11
|
+
# walk the first member to its root.
|
|
12
|
+
def root
|
|
13
|
+
identifiers&.first&.root || self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def base_document
|
|
17
|
+
identifiers&.first&.base_document || self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def drop_supplements
|
|
21
|
+
identifiers&.first || self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The base document, then each member's own supplement
|
|
25
|
+
# suffix behind the plus marker — the coded shape.
|
|
26
|
+
def to_mr_string
|
|
27
|
+
base, *supplements = identifiers
|
|
28
|
+
return "" unless base
|
|
29
|
+
|
|
30
|
+
([base.to_mr_string] +
|
|
31
|
+
supplements.map { |s| "plus-#{s.mr_supplement_suffix}" })
|
|
32
|
+
.join(::Pubid::Renderers::MrString::SEPARATOR_SUPPLEMENT)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.polymorphic_name
|
|
36
|
+
"pubid:cencenelec:consolidated-identifier"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -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
|