pubid 2.0.0.pre.alpha.5 → 2.0.0.pre.alpha.7

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +40 -0
  3. data/lib/pubid/amca.rb +6 -0
  4. data/lib/pubid/ansi.rb +7 -0
  5. data/lib/pubid/api.rb +5 -0
  6. data/lib/pubid/ashrae.rb +6 -0
  7. data/lib/pubid/asme.rb +5 -0
  8. data/lib/pubid/astm.rb +5 -0
  9. data/lib/pubid/bsi/builder.rb +41 -48
  10. data/lib/pubid/bsi/identifiers/amendment.rb +28 -0
  11. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +11 -1
  12. data/lib/pubid/bsi/identifiers/corrigendum.rb +24 -0
  13. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -0
  14. data/lib/pubid/bsi/identifiers/flex.rb +4 -0
  15. data/lib/pubid/bsi/parser.rb +19 -5
  16. data/lib/pubid/bsi/renderer.rb +19 -17
  17. data/lib/pubid/bsi.rb +15 -0
  18. data/lib/pubid/ccsds.rb +5 -0
  19. data/lib/pubid/cen_cenelec.rb +7 -0
  20. data/lib/pubid/cie.rb +5 -0
  21. data/lib/pubid/csa.rb +5 -0
  22. data/lib/pubid/etsi.rb +7 -0
  23. data/lib/pubid/iala/builder.rb +107 -0
  24. data/lib/pubid/iala/identifier.rb +67 -0
  25. data/lib/pubid/iala/identifiers/advice.rb +15 -0
  26. data/lib/pubid/iala/identifiers/annex.rb +55 -0
  27. data/lib/pubid/iala/identifiers/base.rb +14 -0
  28. data/lib/pubid/iala/identifiers/general_assembly.rb +16 -0
  29. data/lib/pubid/iala/identifiers/guideline.rb +15 -0
  30. data/lib/pubid/iala/identifiers/letter.rb +16 -0
  31. data/lib/pubid/iala/identifiers/manual.rb +16 -0
  32. data/lib/pubid/iala/identifiers/model_course.rb +15 -0
  33. data/lib/pubid/iala/identifiers/recommendation.rb +15 -0
  34. data/lib/pubid/iala/identifiers/report.rb +16 -0
  35. data/lib/pubid/iala/identifiers/resolution.rb +16 -0
  36. data/lib/pubid/iala/identifiers/standard.rb +15 -0
  37. data/lib/pubid/iala/identifiers.rb +20 -0
  38. data/lib/pubid/iala/parser.rb +130 -0
  39. data/lib/pubid/iala/renderer.rb +36 -0
  40. data/lib/pubid/iala/urn_generator.rb +49 -0
  41. data/lib/pubid/iala/urn_parser.rb +50 -0
  42. data/lib/pubid/iala.rb +71 -0
  43. data/lib/pubid/identifier.rb +54 -1
  44. data/lib/pubid/idf.rb +5 -0
  45. data/lib/pubid/iec.rb +8 -0
  46. data/lib/pubid/ieee.rb +8 -0
  47. data/lib/pubid/iho.rb +5 -0
  48. data/lib/pubid/iso.rb +6 -0
  49. data/lib/pubid/itu.rb +5 -0
  50. data/lib/pubid/jcgm.rb +5 -0
  51. data/lib/pubid/jis.rb +6 -0
  52. data/lib/pubid/nist.rb +13 -0
  53. data/lib/pubid/oiml/builder.rb +33 -0
  54. data/lib/pubid/oiml/identifier.rb +1 -0
  55. data/lib/pubid/oiml/identifiers/bulletin.rb +101 -0
  56. data/lib/pubid/oiml/identifiers.rb +1 -0
  57. data/lib/pubid/oiml/parser.rb +43 -1
  58. data/lib/pubid/oiml/renderer.rb +51 -0
  59. data/lib/pubid/oiml/urn_generator.rb +22 -0
  60. data/lib/pubid/oiml.rb +5 -0
  61. data/lib/pubid/plateau.rb +5 -0
  62. data/lib/pubid/prefixes_support.rb +51 -0
  63. data/lib/pubid/sae.rb +6 -0
  64. data/lib/pubid/version.rb +1 -1
  65. data/lib/pubid.rb +69 -0
  66. metadata +24 -2
@@ -28,6 +28,17 @@ module Pubid
28
28
  end
29
29
 
30
30
  def generate
31
+ # Bulletin issues carry no code; the (year, issue, sequence) tuple
32
+ # is the locator. URNs are canonical regardless of how the input was
33
+ # formatted, so we always emit the structured YYYY-II-SS form even
34
+ # when the identifier was parsed from a citation string.
35
+ if identifier.is_a?(Identifiers::Bulletin)
36
+ parts = ["urn", "oiml", "bulletin"]
37
+ parts << bulletin_locator if identifier.date&.present?
38
+ parts << urn_language if urn_language
39
+ return parts.join(":")
40
+ end
41
+
31
42
  parts = ["urn", "oiml"]
32
43
  parts << urn_type
33
44
  parts << urn_number if urn_number
@@ -51,6 +62,17 @@ module Pubid
51
62
 
52
63
  parts.join(":")
53
64
  end
65
+
66
+ # Structured locator "YYYY-II-SS" (or "YYYY-II" / "YYYY") for a Bulletin.
67
+ # Built directly from the date year and the issue/sequence attributes so
68
+ # the URN is identical regardless of whether the input was the structured
69
+ # or citation form.
70
+ def bulletin_locator
71
+ locator = identifier.date.year.to_s
72
+ locator += "-#{identifier.issue}" if identifier.issue
73
+ locator += "-#{identifier.sequence}" if identifier.sequence
74
+ locator
75
+ end
54
76
  end
55
77
  end
56
78
  end
data/lib/pubid/oiml.rb CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  module Pubid
4
4
  module Oiml
5
+ extend Pubid::PrefixesSupport
6
+
7
+ # Sole OIML publisher token (see the parser's `publisher` rule).
8
+ PREFIXES = ["OIML"].freeze
9
+
5
10
  autoload :Builder, "#{__dir__}/oiml/builder"
6
11
  autoload :Components, "#{__dir__}/oiml/components"
7
12
  autoload :Identifier, "#{__dir__}/oiml/identifier"
data/lib/pubid/plateau.rb CHANGED
@@ -4,6 +4,11 @@ require "parslet"
4
4
 
5
5
  module Pubid
6
6
  module Plateau
7
+ extend Pubid::PrefixesSupport
8
+
9
+ # Sole PLATEAU publisher token (see the parser's `publisher` rule).
10
+ PREFIXES = ["PLATEAU"].freeze
11
+
7
12
  autoload :Builder, "#{__dir__}/plateau/builder"
8
13
  autoload :Identifier, "#{__dir__}/plateau/identifier"
9
14
  autoload :Identifiers, "#{__dir__}/plateau/identifiers"
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ # Mixin providing the uniform, static +prefixes+ class method that every
5
+ # registered flavor exposes. relaton uses this to build a global prefix
6
+ # register that routes a printed reference string (e.g. +"DD 1234"+,
7
+ # +"ISO/IEC 8802"+) to the flavor(s) that own it.
8
+ #
9
+ # A flavor +extend+s this module and defines a frozen +PREFIXES+ array holding
10
+ # only *its own* leading tokens. Joint / co-publication tokens are injected
11
+ # centrally from {Pubid::JOINT_PREFIXES} so that a co-published prefix
12
+ # (e.g. +"ISO/IEC"+) is listed symmetrically by every co-publisher without
13
+ # being duplicated by hand in two files.
14
+ #
15
+ # == Inclusion policy
16
+ # +prefixes+ returns the set of *leading identifier prefix tokens* — the
17
+ # tokens a printed identifier can start with such that the string belongs to
18
+ # this SDO. Concretely it INCLUDES:
19
+ # * publisher prefixes (e.g. +ISO+, +IEC+, +NIST+, +NBS+, +BS+, +BSI+);
20
+ # * leading series/type tokens that can *begin* a printed reference on their
21
+ # own (e.g. BSI +DD+/+PD+, NIST +FIPS+/+SP+);
22
+ # * joint / co-publication forms (e.g. +ISO/IEC+, +ISO/IEC/IEEE+).
23
+ # It EXCLUDES:
24
+ # * pure sub-series that never appear without a publisher prefix;
25
+ # * dangerously-ambiguous single letters (e.g. BSI aerospace +A+/+B+/+C+),
26
+ # which would cause false routing.
27
+ module PrefixesSupport
28
+ # The static set of leading prefix tokens this flavor recognizes.
29
+ #
30
+ # Static: callable without parsing any identifier string. Strings are
31
+ # returned in canonical case exactly as printed (e.g. +"BS EN ISO"+,
32
+ # +"ISO/IEC"+); consumers fold case themselves.
33
+ #
34
+ # @return [Array<String>] frozen, de-duplicated list of prefix tokens
35
+ def prefixes
36
+ own = const_defined?(:PREFIXES) ? const_get(:PREFIXES) : []
37
+ joint = Pubid::JOINT_PREFIXES.fetch(prefix_flavor_key, [])
38
+ (own + joint).uniq.freeze
39
+ end
40
+
41
+ # The registry key for this flavor, derived from the module name
42
+ # (e.g. +Pubid::CenCenelec+ => +:cen_cenelec+). Used to look this flavor up
43
+ # in {Pubid::JOINT_PREFIXES} and to label it in {Pubid.prefix_flavors}.
44
+ #
45
+ # @return [Symbol]
46
+ def prefix_flavor_key
47
+ name.split("::").last
48
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
49
+ end
50
+ end
51
+ end
data/lib/pubid/sae.rb CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  module Pubid
4
4
  module Sae
5
+ extend Pubid::PrefixesSupport
6
+
7
+ # Sole SAE publisher token (see the parser's `publisher` rule). Document
8
+ # types (AMS/AIR/ARP/AS/J/MA) follow the SAE prefix and are excluded.
9
+ PREFIXES = ["SAE"].freeze
10
+
5
11
  autoload :Builder, "#{__dir__}/sae/builder"
6
12
  autoload :Components, "#{__dir__}/sae/components"
7
13
  autoload :Identifier, "#{__dir__}/sae/identifier"
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.0.pre.alpha.5"
4
+ VERSION = "2.0.0.pre.alpha.7"
5
5
  end
data/lib/pubid.rb CHANGED
@@ -9,6 +9,11 @@ require "parslet"
9
9
  # code runs.
10
10
  require "pubid/lutaml/no_store_registration"
11
11
 
12
+ # Uniform, static per-flavor prefix API (Pubid::<Flavor>.prefixes). Required
13
+ # before the flavor autoloads below so each flavor file can `extend` it and the
14
+ # central JOINT_PREFIXES constant is visible when its PREFIXES is defined.
15
+ require "pubid/prefixes_support"
16
+
12
17
  module Pubid
13
18
  # Upper bound on the length of an identifier string accepted by any +parse+
14
19
  # entry point. Real-world standards identifiers are well under 200 characters;
@@ -61,6 +66,21 @@ module Pubid
61
66
  end
62
67
  end
63
68
 
69
+ # Canonical joint / co-publication leading tokens, injected symmetrically into
70
+ # every participating flavor's +prefixes+ (see {PrefixesSupport}). Single
71
+ # source of truth: editing an entry here updates both sides at once
72
+ # (e.g. +"ISO/IEC"+ appears in +Pubid::Iso.prefixes+ and +Pubid::Iec.prefixes+),
73
+ # so co-publication symmetry can never drift. Keyed by
74
+ # {PrefixesSupport#prefix_flavor_key}.
75
+ JOINT_PREFIXES = {
76
+ iso: ["ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"],
77
+ iec: ["ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"],
78
+ ieee: ["ISO/IEC/IEEE"],
79
+ ansi: ["ANSI/ASHRAE", "ANSI/AMCA"],
80
+ ashrae: ["ANSI/ASHRAE"],
81
+ amca: ["ANSI/AMCA"],
82
+ }.freeze
83
+
64
84
  autoload :Parser, "pubid/parser"
65
85
  autoload :Components, "pubid/components"
66
86
  autoload :BundledIdentifier, "pubid/bundled_identifier"
@@ -95,6 +115,7 @@ module Pubid
95
115
  autoload :Idf, "pubid/idf"
96
116
  autoload :Iec, "pubid/iec"
97
117
  autoload :Ieee, "pubid/ieee"
118
+ autoload :Iala, "pubid/iala"
98
119
  autoload :Iho, "pubid/iho"
99
120
  autoload :Iso, "pubid/iso"
100
121
  autoload :Itu, "pubid/itu"
@@ -174,4 +195,52 @@ module Pubid
174
195
  end
175
196
  @flavors_loaded = true
176
197
  end
198
+
199
+ # Static leading prefix tokens for a single flavor.
200
+ #
201
+ # @param flavor [Symbol, String] a registered flavor name (e.g. +:iso+)
202
+ # @return [Array<String>] the flavor's prefixes (see {PrefixesSupport})
203
+ # @raise [ArgumentError] if the flavor is not registered
204
+ def self.prefixes(flavor)
205
+ mod = Registry.get(flavor)
206
+ raise ArgumentError, "unknown flavor: #{flavor.inspect}" unless mod
207
+
208
+ mod.prefixes
209
+ end
210
+
211
+ # Reverse index mapping every canonical prefix token to the flavor(s) that
212
+ # own it — the exact routing table relaton needs. Co-published prefixes list
213
+ # every co-publisher (e.g. +"ISO/IEC" => [:iec, :iso]+); see the inclusion /
214
+ # exclusion policy documented on {PrefixesSupport}.
215
+ #
216
+ # The +:cen+ alias of +:cen_cenelec+ is de-duplicated by module identity, so a
217
+ # prefix is attributed to a flavor's canonical
218
+ # {PrefixesSupport#prefix_flavor_key} exactly once.
219
+ #
220
+ # @return [Hash{String => Array<Symbol>}] prefix token => sorted flavor keys,
221
+ # e.g. +{ "ISO" => [:iso], "ISO/IEC" => [:iec, :iso], ... }+
222
+ def self.prefix_flavors
223
+ index = Hash.new { |h, k| h[k] = [] }
224
+ each_prefix_flavor_module do |mod|
225
+ key = mod.prefix_flavor_key
226
+ mod.prefixes.each { |prefix| index[prefix] |= [key] }
227
+ end
228
+ index.transform_values(&:sort).sort.to_h
229
+ end
230
+
231
+ # Yields each unique flavor module that exposes +prefixes+ exactly once,
232
+ # collapsing alias registrations (e.g. +:cen+ and +:cen_cenelec+ both point to
233
+ # +Pubid::CenCenelec+) by module identity.
234
+ # @yieldparam mod [Module] a flavor module
235
+ def self.each_prefix_flavor_module
236
+ eager_load_flavors!
237
+ seen = {}
238
+ Registry.flavor_names.each do |flavor_name|
239
+ mod = Registry.get(flavor_name)
240
+ next if seen.key?(mod) || !mod.respond_to?(:prefixes)
241
+
242
+ seen[mod] = true
243
+ yield mod
244
+ end
245
+ end
177
246
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.alpha.5
4
+ version: 2.0.0.pre.alpha.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-06 00:00:00.000000000 Z
11
+ date: 2026-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -335,6 +335,26 @@ files:
335
335
  - lib/pubid/export/result.rb
336
336
  - lib/pubid/format_detector.rb
337
337
  - lib/pubid/format_registry.rb
338
+ - lib/pubid/iala.rb
339
+ - lib/pubid/iala/builder.rb
340
+ - lib/pubid/iala/identifier.rb
341
+ - lib/pubid/iala/identifiers.rb
342
+ - lib/pubid/iala/identifiers/advice.rb
343
+ - lib/pubid/iala/identifiers/annex.rb
344
+ - lib/pubid/iala/identifiers/base.rb
345
+ - lib/pubid/iala/identifiers/general_assembly.rb
346
+ - lib/pubid/iala/identifiers/guideline.rb
347
+ - lib/pubid/iala/identifiers/letter.rb
348
+ - lib/pubid/iala/identifiers/manual.rb
349
+ - lib/pubid/iala/identifiers/model_course.rb
350
+ - lib/pubid/iala/identifiers/recommendation.rb
351
+ - lib/pubid/iala/identifiers/report.rb
352
+ - lib/pubid/iala/identifiers/resolution.rb
353
+ - lib/pubid/iala/identifiers/standard.rb
354
+ - lib/pubid/iala/parser.rb
355
+ - lib/pubid/iala/renderer.rb
356
+ - lib/pubid/iala/urn_generator.rb
357
+ - lib/pubid/iala/urn_parser.rb
338
358
  - lib/pubid/identifier.rb
339
359
  - lib/pubid/identifier_metadata.rb
340
360
  - lib/pubid/idf.rb
@@ -609,6 +629,7 @@ files:
609
629
  - lib/pubid/oiml/identifiers/amendment.rb
610
630
  - lib/pubid/oiml/identifiers/annex.rb
611
631
  - lib/pubid/oiml/identifiers/basic_publication.rb
632
+ - lib/pubid/oiml/identifiers/bulletin.rb
612
633
  - lib/pubid/oiml/identifiers/document.rb
613
634
  - lib/pubid/oiml/identifiers/errata.rb
614
635
  - lib/pubid/oiml/identifiers/expert_report.rb
@@ -640,6 +661,7 @@ files:
640
661
  - lib/pubid/plateau/supplement_identifier.rb
641
662
  - lib/pubid/plateau/urn_generator.rb
642
663
  - lib/pubid/plateau/urn_parser.rb
664
+ - lib/pubid/prefixes_support.rb
643
665
  - lib/pubid/renderers.rb
644
666
  - lib/pubid/renderers/base.rb
645
667
  - lib/pubid/renderers/directives_renderer.rb