pubid 2.0.0.pre.alpha.3 → 2.0.0.pre.alpha.4
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/lib/pubid/amca/identifier.rb +4 -23
- data/lib/pubid/amca/identifiers/base.rb +67 -30
- data/lib/pubid/amca/identifiers/interpretation.rb +0 -4
- data/lib/pubid/amca/identifiers/publication.rb +0 -4
- data/lib/pubid/amca/identifiers/standard.rb +0 -4
- data/lib/pubid/amca/renderer.rb +1 -1
- data/lib/pubid/amca/urn_generator.rb +2 -1
- data/lib/pubid/api/builder.rb +4 -0
- data/lib/pubid/api/identifier.rb +5 -1
- data/lib/pubid/api/identifiers/base.rb +2 -12
- data/lib/pubid/api/identifiers/mpms.rb +0 -4
- data/lib/pubid/api/identifiers/typeless_standard.rb +0 -3
- data/lib/pubid/api/single_identifier.rb +5 -8
- data/lib/pubid/ashrae/identifier.rb +7 -22
- data/lib/pubid/ashrae/identifiers/base.rb +28 -17
- data/lib/pubid/ashrae/parser.rb +4 -0
- data/lib/pubid/ashrae.rb +4 -0
- data/lib/pubid/asme/single_identifier.rb +3 -1
- data/lib/pubid/astm/single_identifier.rb +3 -1
- data/lib/pubid/bsi/identifier.rb +5 -31
- data/lib/pubid/bsi/identifiers/addendum_document.rb +0 -4
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +0 -4
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +0 -4
- data/lib/pubid/bsi/identifiers/aerospace_standard.rb +0 -3
- data/lib/pubid/bsi/identifiers/amendment.rb +0 -4
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -3
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +2 -5
- data/lib/pubid/bsi/identifiers/committee_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +2 -5
- data/lib/pubid/bsi/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/bsi/identifiers/detailed_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/disc.rb +0 -3
- data/lib/pubid/bsi/identifiers/draft_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/electronic_book.rb +0 -3
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +0 -4
- data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +0 -3
- data/lib/pubid/bsi/identifiers/flex.rb +0 -3
- data/lib/pubid/bsi/identifiers/handbook.rb +0 -3
- data/lib/pubid/bsi/identifiers/index.rb +0 -3
- data/lib/pubid/bsi/identifiers/method.rb +0 -3
- data/lib/pubid/bsi/identifiers/national_annex.rb +0 -3
- data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -3
- data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/published_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/section.rb +0 -3
- data/lib/pubid/bsi/identifiers/set.rb +2 -5
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +0 -3
- data/lib/pubid/bsi/identifiers/supplement_document.rb +0 -4
- data/lib/pubid/bsi/identifiers/supplementary_index.rb +0 -3
- data/lib/pubid/bsi/identifiers/technical_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/test_method.rb +0 -3
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +0 -4
- data/lib/pubid/bsi/single_identifier.rb +32 -13
- data/lib/pubid/bsi.rb +8 -1
- data/lib/pubid/ccsds/identifier.rb +2 -14
- data/lib/pubid/cen_cenelec/identifier.rb +10 -8
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/base.rb +2 -9
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +0 -3
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +0 -4
- data/lib/pubid/cen_cenelec/single_identifier.rb +4 -7
- data/lib/pubid/cen_cenelec.rb +4 -0
- data/lib/pubid/cie/identifier.rb +4 -0
- data/lib/pubid/cie/single_identifier.rb +4 -4
- data/lib/pubid/cie.rb +4 -0
- data/lib/pubid/csa/identifier.rb +10 -1
- data/lib/pubid/csa/identifiers/base.rb +0 -3
- data/lib/pubid/csa/identifiers/cec.rb +0 -4
- data/lib/pubid/csa/identifiers/series.rb +0 -4
- data/lib/pubid/csa/single_identifier.rb +1 -1
- data/lib/pubid/csa.rb +4 -0
- data/lib/pubid/etsi/components/code.rb +1 -7
- data/lib/pubid/etsi/components/version.rb +0 -5
- data/lib/pubid/etsi/identifier.rb +4 -12
- data/lib/pubid/etsi/identifiers/base.rb +31 -24
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +0 -3
- data/lib/pubid/etsi.rb +3 -1
- data/lib/pubid/identifier.rb +90 -1
- data/lib/pubid/idf/identifier.rb +4 -0
- data/lib/pubid/idf.rb +4 -0
- data/lib/pubid/iec/identifier.rb +14 -14
- data/lib/pubid/iec/identifiers/base.rb +0 -4
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +0 -4
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/test_report_form.rb +0 -3
- data/lib/pubid/iec/identifiers/vap_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/working_document.rb +0 -4
- data/lib/pubid/iec.rb +4 -0
- data/lib/pubid/ieee/identifier.rb +5 -17
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +0 -4
- data/lib/pubid/ieee/identifiers/base.rb +223 -201
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +0 -4
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/dual_published.rb +0 -4
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +0 -4
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +0 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +0 -4
- data/lib/pubid/ieee.rb +4 -0
- data/lib/pubid/iho/identifier.rb +7 -25
- data/lib/pubid/iho/identifiers/base.rb +62 -68
- data/lib/pubid/iho.rb +3 -1
- data/lib/pubid/iso/identifier.rb +15 -14
- data/lib/pubid/iso/single_identifier.rb +0 -4
- data/lib/pubid/iso.rb +4 -0
- data/lib/pubid/itu/components/code.rb +1 -7
- data/lib/pubid/itu/components/sector.rb +15 -4
- data/lib/pubid/itu/components/series.rb +0 -4
- data/lib/pubid/itu/identifier.rb +4 -18
- data/lib/pubid/itu/identifiers/base.rb +124 -122
- data/lib/pubid/itu.rb +3 -1
- data/lib/pubid/jcgm/identifiers/amendment.rb +0 -4
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +0 -4
- data/lib/pubid/jcgm/single_identifier.rb +0 -4
- data/lib/pubid/jis/identifier.rb +2 -14
- data/lib/pubid/nist/identifier.rb +8 -23
- data/lib/pubid/nist/identifiers/base.rb +553 -544
- data/lib/pubid/nist/preprocessor.rb +12 -0
- data/lib/pubid/nist.rb +4 -0
- data/lib/pubid/oiml/builder.rb +21 -3
- data/lib/pubid/oiml/components/code.rb +7 -0
- data/lib/pubid/oiml/identifier.rb +44 -0
- data/lib/pubid/oiml/identifiers/annex.rb +10 -1
- data/lib/pubid/oiml/identifiers/errata.rb +15 -0
- data/lib/pubid/oiml/identifiers.rb +1 -1
- data/lib/pubid/oiml/parser.rb +59 -12
- data/lib/pubid/oiml/renderer.rb +27 -17
- data/lib/pubid/oiml/single_identifier.rb +58 -0
- data/lib/pubid/oiml/supplement_identifier.rb +30 -1
- data/lib/pubid/plateau/identifier.rb +4 -21
- data/lib/pubid/plateau/identifiers/base.rb +45 -36
- data/lib/pubid/plateau/identifiers/handbook.rb +0 -4
- data/lib/pubid/plateau/identifiers/technical_report.rb +0 -4
- data/lib/pubid/plateau/supplement_identifier.rb +0 -4
- data/lib/pubid/sae/identifier.rb +4 -12
- data/lib/pubid/sae/identifiers/base.rb +26 -17
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +18 -2
- data/lib/tasks/export.rake +6 -5
- metadata +3 -4
- data/lib/pubid/identifier_facade.rb +0 -114
- data/lib/pubid/oiml/identifiers/base.rb +0 -21
|
@@ -2,79 +2,73 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Iho
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
attribute :annex, :string
|
|
26
|
-
attribute :supplement, :string
|
|
27
|
-
attribute :version, :string
|
|
5
|
+
# Base class for all IHO identifiers. Canonical name Pubid::Iho::Identifier;
|
|
6
|
+
# every concrete IHO identifier (Identifiers::*) descends from it, and
|
|
7
|
+
# Identifiers::Base — aliased at the foot of this file — points back to it.
|
|
8
|
+
#
|
|
9
|
+
# IHO identifiers have the form:
|
|
10
|
+
# IHO {S|P|M|B|C}-{number}[ Ap. {appendix}][ Part {part}][ Annex {annex}][ Suppl {supplement}][ {version}]
|
|
11
|
+
#
|
|
12
|
+
# The leading IHO publisher prefix is optional on input but always
|
|
13
|
+
# emitted on output.
|
|
14
|
+
class Identifier < ::Pubid::Identifier
|
|
15
|
+
# Parse an IHO identifier string into an identifier object
|
|
16
|
+
# @param identifier [String] The IHO identifier string to parse
|
|
17
|
+
# @return [Pubid::Iho::Identifier] The appropriate identifier object
|
|
18
|
+
# @raise [Parslet::ParseFailed] If parsing fails
|
|
19
|
+
def self.parse(identifier)
|
|
20
|
+
parsed = Parser.parse(identifier)
|
|
21
|
+
Builder.build(parsed)
|
|
22
|
+
rescue Parslet::ParseFailed => e
|
|
23
|
+
raise "Failed to parse IHO identifier '#{identifier}': #{e.message}"
|
|
24
|
+
end
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
# `number` overrides the generic Components::Code attribute with a plain
|
|
27
|
+
# string (same pattern as `part` below); it holds the IHO document
|
|
28
|
+
# number (e.g. "100", "1/21"). Kept as the generic `number` so the
|
|
29
|
+
# relaton index sorts/binary-searches on it natively via `id.number`.
|
|
30
|
+
attribute :number, :string
|
|
31
|
+
attribute :publisher, :string, default: "IHO"
|
|
32
|
+
attribute :appendix, :string
|
|
33
|
+
attribute :part, :string
|
|
34
|
+
attribute :annex, :string
|
|
35
|
+
attribute :supplement, :string
|
|
36
|
+
attribute :version, :string
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
map "annex", to: :annex
|
|
51
|
-
map "supplement", to: :supplement
|
|
52
|
-
map "version", to: :version
|
|
53
|
-
end
|
|
38
|
+
# Polymorphic type map for lutaml::Model key_value serialization: maps
|
|
39
|
+
# each subclass's polymorphic_name to its class name so `from_hash` can
|
|
40
|
+
# re-instantiate the concrete type from `_type`.
|
|
41
|
+
IHO_TYPE_MAP = {
|
|
42
|
+
"pubid:iho:standard" => "Pubid::Iho::Identifiers::Standard",
|
|
43
|
+
"pubid:iho:publication" => "Pubid::Iho::Identifiers::Publication",
|
|
44
|
+
"pubid:iho:miscellaneous" => "Pubid::Iho::Identifiers::Miscellaneous",
|
|
45
|
+
"pubid:iho:bibliographic" => "Pubid::Iho::Identifiers::Bibliographic",
|
|
46
|
+
"pubid:iho:circular-letter" => "Pubid::Iho::Identifiers::CircularLetter",
|
|
47
|
+
}.freeze
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
# The base Pubid::Identifier no longer auto-maps attributes, so each
|
|
50
|
+
# flavor's top class must declare its own key_value mapping. IHO
|
|
51
|
+
# attributes are plain strings, so they map directly. `publisher` is
|
|
52
|
+
# intentionally omitted: it is always the "IHO" default and is restored
|
|
53
|
+
# on load.
|
|
54
|
+
key_value do
|
|
55
|
+
map "_type", to: :_type, polymorphic_map: IHO_TYPE_MAP
|
|
56
|
+
map "number", to: :number
|
|
57
|
+
map "appendix", to: :appendix
|
|
58
|
+
map "part", to: :part
|
|
59
|
+
map "annex", to: :annex
|
|
60
|
+
map "supplement", to: :supplement
|
|
61
|
+
map "version", to: :version
|
|
62
|
+
end
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
# from_hash is the shared polymorphic dispatch on Pubid::Identifier.
|
|
65
|
+
# IHO_TYPE_MAP remains as the key_value polymorphic_map.
|
|
66
|
+
end
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
end
|
|
77
|
-
end
|
|
68
|
+
module Identifiers
|
|
69
|
+
# Backward-compatible alias: IHO's base class used to be
|
|
70
|
+
# Pubid::Iho::Identifiers::Base. It is now Pubid::Iho::Identifier.
|
|
71
|
+
Base = Pubid::Iho::Identifier
|
|
78
72
|
end
|
|
79
73
|
end
|
|
80
74
|
end
|
data/lib/pubid/iho.rb
CHANGED
|
@@ -27,7 +27,9 @@ module Pubid
|
|
|
27
27
|
@identifier_types ||= Identifiers.constants
|
|
28
28
|
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
29
29
|
.select { |c| c.is_a?(Class) && c < Pubid::Identifier }
|
|
30
|
-
|
|
30
|
+
# Exclude the flavor base itself by identity (Identifiers::Base is now an
|
|
31
|
+
# alias for Pubid::Iho::Identifier, so name-based matching misses it).
|
|
32
|
+
.reject { |c| c == Identifiers::Base }
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
# Build typed stage index from identifier types
|
data/lib/pubid/iso/identifier.rb
CHANGED
|
@@ -85,6 +85,14 @@ module Pubid
|
|
|
85
85
|
"pubid:iso:bundled-identifier" => "Pubid::Iso::BundledIdentifier",
|
|
86
86
|
}.freeze
|
|
87
87
|
|
|
88
|
+
# BundledIdentifier lives outside Pubid::Iso::Identifiers but carries a
|
|
89
|
+
# polymorphic `_type`, so the shared polymorphic_type_map needs it
|
|
90
|
+
# explicitly (see Pubid::Identifier#additional_identifier_classes).
|
|
91
|
+
def self.additional_identifier_classes
|
|
92
|
+
[Pubid::Iso::BundledIdentifier]
|
|
93
|
+
end
|
|
94
|
+
private_class_method :additional_identifier_classes
|
|
95
|
+
|
|
88
96
|
# Build type map from Pubid::Iso.identifier_types for validation
|
|
89
97
|
def self.build_type_map
|
|
90
98
|
Pubid::Iso.identifier_types.to_h do |klass|
|
|
@@ -259,6 +267,10 @@ module Pubid
|
|
|
259
267
|
end
|
|
260
268
|
|
|
261
269
|
def self.parse(string, format: :auto)
|
|
270
|
+
if string.length > Pubid::MAX_INPUT_LENGTH
|
|
271
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
272
|
+
end
|
|
273
|
+
|
|
262
274
|
format = Pubid::FormatDetector.detect(string) if format == :auto
|
|
263
275
|
|
|
264
276
|
case format
|
|
@@ -277,20 +289,9 @@ module Pubid
|
|
|
277
289
|
end
|
|
278
290
|
end
|
|
279
291
|
|
|
280
|
-
#
|
|
281
|
-
#
|
|
282
|
-
#
|
|
283
|
-
# and drop `base_identifier`. Route by `_type` to the right subclass and
|
|
284
|
-
# let its (inherited) from_hash do the real work, mirroring JIS.
|
|
285
|
-
def self.from_hash(data, options = {})
|
|
286
|
-
type = data["_type"] || data[:_type]
|
|
287
|
-
klass_name = ISO_TYPE_MAP[type]
|
|
288
|
-
if klass_name
|
|
289
|
-
klass = Object.const_get(klass_name)
|
|
290
|
-
return klass.from_hash(data, options) unless klass == self
|
|
291
|
-
end
|
|
292
|
-
super
|
|
293
|
-
end
|
|
292
|
+
# from_hash is the shared polymorphic dispatch on Pubid::Identifier, which
|
|
293
|
+
# routes `_type` through polymorphic_type_map (ISO_TYPE_MAP's dynamic
|
|
294
|
+
# equivalent). ISO_TYPE_MAP remains as the key_value polymorphic_map.
|
|
294
295
|
end
|
|
295
296
|
end
|
|
296
297
|
end
|
data/lib/pubid/iso.rb
CHANGED
|
@@ -25,6 +25,10 @@ module Pubid
|
|
|
25
25
|
# @param format [Symbol] :auto, :human, :mr_string, or :urn
|
|
26
26
|
# @return [Identifier] the parsed identifier
|
|
27
27
|
def self.parse(identifier, format: :auto)
|
|
28
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
29
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
format = Pubid::FormatDetector.detect(identifier) if format == :auto
|
|
29
33
|
|
|
30
34
|
case format
|
|
@@ -15,13 +15,7 @@ module Pubid
|
|
|
15
15
|
class Code < Lutaml::Model::Serializable
|
|
16
16
|
attribute :number, :string
|
|
17
17
|
attribute :subseries, :string
|
|
18
|
-
attribute :parts, :string, collection: true
|
|
19
|
-
|
|
20
|
-
def initialize(number:, subseries: nil, parts: nil)
|
|
21
|
-
@number = number
|
|
22
|
-
@subseries = subseries
|
|
23
|
-
@parts = parts || []
|
|
24
|
-
end
|
|
18
|
+
attribute :parts, :string, collection: true, default: []
|
|
25
19
|
|
|
26
20
|
def to_s
|
|
27
21
|
result = number.to_s
|
|
@@ -12,12 +12,23 @@ module Pubid
|
|
|
12
12
|
|
|
13
13
|
VALID_SECTORS = %w[R T D].freeze
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
# Accept either a positional Hash (lutaml-model's call style:
|
|
16
|
+
# `Sector.new({lutaml_register: :default})` then attribute assignment)
|
|
17
|
+
# or a literal `sector:` kwarg (`Sector.new(sector: "R")`). Both call
|
|
18
|
+
# paths funnel through the same validate-then-set flow so the attribute
|
|
19
|
+
# stays lutaml-tracked and round-trips through to_hash/from_hash.
|
|
20
|
+
def initialize(attrs = {}, options = {})
|
|
21
|
+
super
|
|
22
|
+
sector_val = attrs[:sector] || attrs["sector"]
|
|
23
|
+
return if sector_val.nil?
|
|
24
|
+
|
|
25
|
+
normalized = sector_val.to_s.upcase
|
|
26
|
+
unless VALID_SECTORS.include?(normalized)
|
|
27
|
+
raise ArgumentError,
|
|
28
|
+
"Invalid sector: #{sector_val}. Must be R, T, or D"
|
|
18
29
|
end
|
|
19
30
|
|
|
20
|
-
|
|
31
|
+
self.sector = normalized
|
|
21
32
|
end
|
|
22
33
|
|
|
23
34
|
def to_s
|
data/lib/pubid/itu/identifier.rb
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# component), so enabling the facade's identity check would route ITU ids
|
|
8
|
-
# through a consumer's `to_hash` (e.g. relaton-index#save) and crash.
|
|
9
|
-
# Re-enable once ITU serialization round-trips cleanly. See
|
|
10
|
-
# identifier_facade.rb.
|
|
11
|
-
module Identifier
|
|
12
|
-
def self.parse(identifier)
|
|
13
|
-
parsed = Parser.parse(identifier)
|
|
14
|
-
Builder.build(parsed)
|
|
15
|
-
rescue Parslet::ParseFailed => e
|
|
16
|
-
raise "Failed to parse ITU identifier '#{identifier}': #{e.message}"
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
3
|
+
# Pubid::Itu::Identifier is the ITU base class (a real Pubid::Identifier
|
|
4
|
+
# subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
|
|
5
|
+
# live in identifiers/base.rb. This file just ensures it is loaded.
|
|
6
|
+
require_relative "identifiers/base"
|
|
@@ -2,147 +2,149 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Itu
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"ar" => "A", "zh" => "C", "en" => "E",
|
|
16
|
-
"F" => "F", "S" => "S", "R" => "R",
|
|
17
|
-
"A" => "A", "C" => "C", "E" => "E"
|
|
18
|
-
}.freeze
|
|
19
|
-
|
|
20
|
-
attribute :sector, Pubid::Itu::Components::Sector
|
|
21
|
-
attribute :series, Pubid::Itu::Components::Series
|
|
22
|
-
attribute :code, Pubid::Itu::Components::Code
|
|
23
|
-
attribute :date, Pubid::Components::Date
|
|
24
|
-
attribute :language, :string
|
|
25
|
-
|
|
26
|
-
def initialize(**kwargs)
|
|
27
|
-
if kwargs[:language]
|
|
28
|
-
kwargs = kwargs.merge(language: normalize_language(kwargs[:language]))
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
super
|
|
32
|
-
|
|
33
|
-
validate_ob_no_sector!
|
|
34
|
-
end
|
|
5
|
+
# Base class for all ITU identifiers. Canonical name Pubid::Itu::Identifier
|
|
6
|
+
# (Identifiers::Base is a back-compat alias).
|
|
7
|
+
class Identifier < ::Pubid::Identifier
|
|
8
|
+
# Parse an ITU identifier string into an identifier object.
|
|
9
|
+
def self.parse(identifier)
|
|
10
|
+
parsed = Parser.parse(identifier)
|
|
11
|
+
Builder.build(parsed)
|
|
12
|
+
rescue Parslet::ParseFailed => e
|
|
13
|
+
raise "Failed to parse ITU identifier '#{identifier}': #{e.message}"
|
|
14
|
+
end
|
|
35
15
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
16
|
+
# Long-form ↔ ITU single-letter language code map. The parser produces
|
|
17
|
+
# single-letter codes (E/F/S/R/A/C); API callers (e.g. metanorma-itu)
|
|
18
|
+
# pass long-form (en/fr/es/ru/ar/zh). Storage is normalized to the
|
|
19
|
+
# single-letter form. Languages with no canonical letter (e.g. "de")
|
|
20
|
+
# pass through unchanged and produce no trailing suffix.
|
|
21
|
+
LANGUAGES = {
|
|
22
|
+
"fr" => "F", "es" => "S", "ru" => "R",
|
|
23
|
+
"ar" => "A", "zh" => "C", "en" => "E",
|
|
24
|
+
"F" => "F", "S" => "S", "R" => "R",
|
|
25
|
+
"A" => "A", "C" => "C", "E" => "E"
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
attribute :sector, Pubid::Itu::Components::Sector
|
|
29
|
+
attribute :series, Pubid::Itu::Components::Series
|
|
30
|
+
attribute :code, Pubid::Itu::Components::Code
|
|
31
|
+
attribute :date, Pubid::Components::Date
|
|
32
|
+
attribute :language, :string
|
|
33
|
+
|
|
34
|
+
def initialize(**kwargs)
|
|
35
|
+
if kwargs[:language]
|
|
36
|
+
kwargs = kwargs.merge(language: normalize_language(kwargs[:language]))
|
|
50
37
|
end
|
|
51
38
|
|
|
52
|
-
|
|
53
|
-
"ITU"
|
|
54
|
-
end
|
|
39
|
+
super
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# @param i18n_lang [Symbol, String] language for identifier text
|
|
59
|
-
# translation (e.g. :fr renders "Annex to" as "Annexe au"). Distinct
|
|
60
|
-
# from the identifier's `language` attribute, which is the document's
|
|
61
|
-
# own language and produces the trailing suffix like "-F".
|
|
62
|
-
# @param language [Symbol, String] deprecated alias for i18n_lang.
|
|
63
|
-
# @param format [Symbol] :long for title-style rendering of supported
|
|
64
|
-
# identifiers, otherwise the default short form.
|
|
65
|
-
def to_s(**opts)
|
|
66
|
-
opts = self.class.normalize_to_s_opts(opts)
|
|
67
|
-
render_base(**opts) + render_language_suffix
|
|
68
|
-
end
|
|
41
|
+
validate_ob_no_sector!
|
|
42
|
+
end
|
|
69
43
|
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
# Generate URN for this identifier
|
|
45
|
+
#
|
|
46
|
+
# @return [String] URN representation
|
|
47
|
+
|
|
48
|
+
# Stored as a plain string (always "ITU") so it round-trips through
|
|
49
|
+
# to_hash/from_hash. Was a `def publisher` method, which made lutaml
|
|
50
|
+
# serialize a String against the Components::Publisher attribute.
|
|
51
|
+
attribute :publisher, :string, default: -> { "ITU" }
|
|
52
|
+
|
|
53
|
+
# Render identifier as a string.
|
|
54
|
+
#
|
|
55
|
+
# @param i18n_lang [Symbol, String] language for identifier text
|
|
56
|
+
# translation (e.g. :fr renders "Annex to" as "Annexe au"). Distinct
|
|
57
|
+
# from the identifier's `language` attribute, which is the document's
|
|
58
|
+
# own language and produces the trailing suffix like "-F".
|
|
59
|
+
# @param language [Symbol, String] deprecated alias for i18n_lang.
|
|
60
|
+
# @param format [Symbol] :long for title-style rendering of supported
|
|
61
|
+
# identifiers, otherwise the default short form.
|
|
62
|
+
def to_s(**opts)
|
|
63
|
+
opts = self.class.normalize_to_s_opts(opts)
|
|
64
|
+
render_base(**opts) + render_language_suffix
|
|
65
|
+
end
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
" #{series}.#{code}"
|
|
76
|
-
else
|
|
77
|
-
" #{code}"
|
|
78
|
-
end
|
|
67
|
+
def render_base(**_opts)
|
|
68
|
+
result = "#{publisher}-#{sector}"
|
|
79
69
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
end
|
|
87
|
-
end
|
|
70
|
+
# Add series and code
|
|
71
|
+
result += if series
|
|
72
|
+
" #{series}.#{code}"
|
|
73
|
+
else
|
|
74
|
+
" #{code}"
|
|
75
|
+
end
|
|
88
76
|
|
|
89
|
-
|
|
77
|
+
# Add date if present
|
|
78
|
+
if date
|
|
79
|
+
result += if date.month
|
|
80
|
+
" (#{date.month}/#{date.year})"
|
|
81
|
+
else
|
|
82
|
+
" (#{date.year})"
|
|
83
|
+
end
|
|
90
84
|
end
|
|
91
85
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
result
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def render_language_suffix
|
|
90
|
+
return "" unless language
|
|
91
|
+
# Only render canonical single-letter ITU language codes
|
|
92
|
+
# (e.g. "F", "S"). Languages with no mapping (e.g. "de") get
|
|
93
|
+
# no suffix — matches v1 PR #38 render_language behavior.
|
|
94
|
+
return "" unless LANGUAGES.value?(language)
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
"-#{language}"
|
|
97
|
+
end
|
|
101
98
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
end
|
|
112
|
-
opts
|
|
99
|
+
# Translate `language:` opt to `i18n_lang:` opt. v1 PR #38 introduced
|
|
100
|
+
# `i18n_lang:` to disambiguate "rendering language" from the document
|
|
101
|
+
# language attribute; `language:` remains a deprecated alias.
|
|
102
|
+
def self.normalize_to_s_opts(opts)
|
|
103
|
+
opts = opts.dup
|
|
104
|
+
if opts.key?(:language) && !opts.key?(:i18n_lang)
|
|
105
|
+
opts[:i18n_lang] = opts.delete(:language)
|
|
106
|
+
else
|
|
107
|
+
opts.delete(:language)
|
|
113
108
|
end
|
|
109
|
+
opts
|
|
110
|
+
end
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
def ==(other)
|
|
113
|
+
return false unless other.is_a?(Pubid::Itu::Identifier)
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
sector == other.sector &&
|
|
116
|
+
series == other.series &&
|
|
117
|
+
code == other.code &&
|
|
118
|
+
date == other.date &&
|
|
119
|
+
language == other.language
|
|
120
|
+
end
|
|
124
121
|
|
|
125
|
-
|
|
122
|
+
private
|
|
126
123
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
def normalize_language(value)
|
|
125
|
+
str = value.to_s
|
|
126
|
+
LANGUAGES[str] || str
|
|
127
|
+
end
|
|
131
128
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
end
|
|
129
|
+
# OB (Operational Bulletin) is a cross-bureau ITU publication and
|
|
130
|
+
# must not have a sector. Direct construction with both raises;
|
|
131
|
+
# the parser silently drops sector for legacy strings like
|
|
132
|
+
# "ITU-T OB.X" (handled in Builder).
|
|
133
|
+
def validate_ob_no_sector!
|
|
134
|
+
return unless series&.series == "OB"
|
|
135
|
+
return if sector.nil?
|
|
136
|
+
return if sector.is_a?(Components::Sector) && (sector.sector.nil? || sector.sector.to_s.empty?)
|
|
137
|
+
|
|
138
|
+
raise ArgumentError,
|
|
139
|
+
"OB (Operational Bulletin) is a cross-bureau ITU publication; " \
|
|
140
|
+
"sector must not be set"
|
|
145
141
|
end
|
|
146
142
|
end
|
|
143
|
+
|
|
144
|
+
module Identifiers
|
|
145
|
+
# Backward-compatible alias: ITU's base class used to be
|
|
146
|
+
# Pubid::Itu::Identifiers::Base. It is now Pubid::Itu::Identifier.
|
|
147
|
+
Base = Pubid::Itu::Identifier
|
|
148
|
+
end
|
|
147
149
|
end
|
|
148
150
|
end
|
data/lib/pubid/itu.rb
CHANGED
|
@@ -27,7 +27,9 @@ module Pubid
|
|
|
27
27
|
@identifier_types ||= Identifiers.constants
|
|
28
28
|
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
29
29
|
.select { |c| c.is_a?(Class) && c < Pubid::Identifier }
|
|
30
|
-
|
|
30
|
+
# Exclude the flavor base itself by identity (Identifiers::Base is now an
|
|
31
|
+
# alias for Pubid::Itu::Identifier, so name-based matching misses it).
|
|
32
|
+
.reject { |c| c == Identifiers::Base }
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
# Build typed stage index from identifier types
|