pubid 2.0.26 → 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/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 +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7d58d221cae92c8bd336e1335298f6f5158262d694bb44f9fae687b95ea406d0
|
|
4
|
+
data.tar.gz: cdb3274979bcdc5d3d3cf32f2f374f1c1e8bb2f38b3bb54c8b0fef3090399a6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2738a496fb75d01d19e84590e311f49346542d6877aaf3d63e2a0764183fadc73e532f565014a21b0b8e8584d178e79c531914744eecd65a794d88dc351a1c6f
|
|
7
|
+
data.tar.gz: 22518fc9b9f820cd6410a51e986048b854a0a4da33151bedb4f286d90490b71ea7139164c73ed1786bccb142cffb6647394a4d710826674b20099d1d72bbe5a5
|
data/README.adoc
CHANGED
|
@@ -272,23 +272,18 @@ PubID V2 provides two-way machine-readable conversion for all identifiers, suppo
|
|
|
272
272
|
|
|
273
273
|
=== Export to Hash
|
|
274
274
|
|
|
275
|
+
(The v1 reader chain `id.to_h` is historic and was removed; pubid 2 serializes
|
|
276
|
+
through `#to_hash`.)
|
|
277
|
+
|
|
275
278
|
[source,ruby]
|
|
276
279
|
----
|
|
277
280
|
require 'pubid/iso'
|
|
278
281
|
|
|
279
282
|
id = Pubid::Iso.parse("ISO 9001:2015/Amd 1:2020")
|
|
280
|
-
id.
|
|
281
|
-
# => {
|
|
282
|
-
#
|
|
283
|
-
#
|
|
284
|
-
# publisher: "ISO",
|
|
285
|
-
# number: "9001",
|
|
286
|
-
# year: "2015",
|
|
287
|
-
# supplements: [
|
|
288
|
-
# { type: "amendment", number: "1", year: "2020" }
|
|
289
|
-
# ],
|
|
290
|
-
# urn: "urn:iso:std:iso:9001:amd:2020:v1"
|
|
291
|
-
# }
|
|
283
|
+
id.to_hash
|
|
284
|
+
# => {"_type" => "pubid:iso:amendment", "number" => "1", "year" => "2020",
|
|
285
|
+
# "base" => {"_type" => "pubid:iso:international-standard",
|
|
286
|
+
# "number" => "9001", "year" => "2015"}}
|
|
292
287
|
----
|
|
293
288
|
|
|
294
289
|
=== Export to JSON
|
|
@@ -299,7 +294,7 @@ require 'pubid/iso'
|
|
|
299
294
|
|
|
300
295
|
id = Pubid::Iso.parse("ISO 9001:2015")
|
|
301
296
|
id.to_json
|
|
302
|
-
# => '{"
|
|
297
|
+
# => '{"_type":"pubid:iso:international-standard","number":"9001","year":"2015"}'
|
|
303
298
|
----
|
|
304
299
|
|
|
305
300
|
=== Import from Hash
|
|
@@ -337,12 +332,17 @@ Pubid.from_hash({ "number" => "9001" })
|
|
|
337
332
|
|
|
338
333
|
=== Import from JSON
|
|
339
334
|
|
|
335
|
+
(The v1 `Pubid::Serializable` import surface is historic; pubid 2 imports
|
|
336
|
+
through `Pubid.from_hash`, the hash counterpart of `Pubid.parse` documented
|
|
337
|
+
above, fed with `JSON.parse`.)
|
|
338
|
+
|
|
340
339
|
[source,ruby]
|
|
341
340
|
----
|
|
341
|
+
require 'json'
|
|
342
342
|
require 'pubid/iso'
|
|
343
343
|
|
|
344
|
-
json = '{"
|
|
345
|
-
id = Pubid
|
|
344
|
+
json = '{"_type":"pubid:iso:international-standard","number":"9001","year":"2015"}'
|
|
345
|
+
id = Pubid.from_hash(JSON.parse(json))
|
|
346
346
|
id.to_s # => "ISO 9001:2015"
|
|
347
347
|
----
|
|
348
348
|
|
|
@@ -598,9 +598,10 @@ bundle exec rake export:website_data
|
|
|
598
598
|
bundle exec rake export:audit
|
|
599
599
|
----
|
|
600
600
|
|
|
601
|
-
The export task produces a JSON file covering
|
|
602
|
-
types. Each flavor's identifier classes, typed stages,
|
|
603
|
-
10 fixture examples are extracted automatically from
|
|
601
|
+
The export task produces a JSON file covering all 33 registered flavors and
|
|
602
|
+
228 identifier types (2.0.26). Each flavor's identifier classes, typed stages,
|
|
603
|
+
abbreviations, and up to 10 fixture examples are extracted automatically from
|
|
604
|
+
the library source.
|
|
604
605
|
|
|
605
606
|
=== Programmatic API
|
|
606
607
|
|
|
@@ -613,9 +614,9 @@ data = Pubid::Export::Exporter.export_all
|
|
|
613
614
|
# => { "iso" => { identifier_types: [...], attributes: [...] }, ... }
|
|
614
615
|
|
|
615
616
|
# Export a single flavor
|
|
616
|
-
exporter = Pubid::Export::
|
|
617
|
+
exporter = Pubid::Export::FlavorExporter.new(:iso)
|
|
617
618
|
result = exporter.export
|
|
618
|
-
result.to_h # => { identifier_types: [...], attributes: [...] }
|
|
619
|
+
result.to_h # => { identifier_types: [...], attributes: [...], ... }
|
|
619
620
|
----
|
|
620
621
|
|
|
621
622
|
=== Output Schema
|
|
@@ -644,7 +645,7 @@ The exported JSON follows this structure:
|
|
|
644
645
|
"examples": ["ISO 9001:2015", "ISO/IEC 17031-1:2020", ...]
|
|
645
646
|
}
|
|
646
647
|
],
|
|
647
|
-
"attributes": [
|
|
648
|
+
"attributes": []
|
|
648
649
|
}
|
|
649
650
|
}
|
|
650
651
|
----
|
|
@@ -700,50 +701,26 @@ The exported JSON follows this structure:
|
|
|
700
701
|
|
|
701
702
|
|`attributes`
|
|
702
703
|
|`string[]`
|
|
703
|
-
|Lutaml::Model attribute names on the identifier class
|
|
704
|
+
|Lutaml::Model attribute names on the identifier class (currently always
|
|
705
|
+
empty on 2.0.26)
|
|
704
706
|
|
|
705
707
|
|`wrapper_types`
|
|
706
708
|
|`object[]`
|
|
707
|
-
|Value-added overlay types (VAP, Redline, etc.) — same schema as `identifier_types
|
|
709
|
+
|Value-added overlay types (VAP, Redline, etc.) — same schema as `identifier_types`;
|
|
710
|
+
present when the flavor lists wrapper classes (`iec`, `bsi`)
|
|
708
711
|
|===
|
|
709
712
|
|
|
710
|
-
=== Extraction
|
|
711
|
-
|
|
712
|
-
Different flavors use different internal architectures. The export layer uses
|
|
713
|
-
the Strategy pattern to handle each without modifying existing code:
|
|
714
|
-
|
|
715
|
-
.Strategy classes
|
|
716
|
-
[cols="1,2,2", options="header"]
|
|
717
|
-
|===
|
|
718
|
-
|Strategy |Flavors |Pattern
|
|
719
|
-
|
|
720
|
-
|`SchemeExporter`
|
|
721
|
-
|ISO, IEC, ASTM, ASHRAE, ASME, CCSDS, CIE, CSA, JIS, JCGM, OIML, IDF, API, SAE, ANSI
|
|
722
|
-
|`Scheme.identifiers` + per-class `def self.type` + `TYPED_STAGES`
|
|
723
|
-
|
|
724
|
-
|`RegistryExporter`
|
|
725
|
-
|BSI, CEN
|
|
726
|
-
|`TYPED_STAGES_REGISTRY` on Scheme class (centralized registry)
|
|
713
|
+
=== Extraction
|
|
727
714
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
715
|
+
One extractor, `Pubid::Export::FlavorExporter`, covers every flavor: it reads
|
|
716
|
+
the flavor module's self-describing `identifier_types` interface (falling back
|
|
717
|
+
to scanning the flavor's `Identifiers` namespace), the classes' `TYPED_STAGES`,
|
|
718
|
+
and fixture examples. Wrapper (overlay) types are discovered per flavor through
|
|
719
|
+
`FlavorExporter::WRAPPER_CLASSES` (IEC `VapIdentifier`, BSI
|
|
720
|
+
`ValueAddedPublication`).
|
|
731
721
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|`Scheme.identifiers` + per-class `typed_stages` class method (not constant)
|
|
735
|
-
|
|
736
|
-
|`ItuExporter`
|
|
737
|
-
|ITU
|
|
738
|
-
|Sector-based types with transform/model pattern
|
|
739
|
-
|
|
740
|
-
|`DataClassExporter`
|
|
741
|
-
|ETSI, Plateau
|
|
742
|
-
|`Lutaml::Model::Serializable` as Scheme (no per-class identifiers)
|
|
743
|
-
|===
|
|
744
|
-
|
|
745
|
-
Adding a new flavor requires only registering it in `FLAVOR_STRATEGIES` within
|
|
746
|
-
`Exporter` — no existing strategy code changes.
|
|
722
|
+
Adding a new flavor requires only registering it in `Exporter::FLAVORS` —
|
|
723
|
+
no existing extractor code changes.
|
|
747
724
|
|
|
748
725
|
=== Adding a New Flavor to Export
|
|
749
726
|
|
|
@@ -755,42 +732,15 @@ it with the export layer:
|
|
|
755
732
|
returning `{ key: :sym, title: "Name", short: "Abbr" }`. This is the primary
|
|
756
733
|
source of metadata.
|
|
757
734
|
|
|
758
|
-
. **Choose the right strategy** — Most flavors use one of the existing strategies:
|
|
759
|
-
|
|
760
|
-
* `SchemeExporter` — if the flavor has a `Scheme` class with a class-level
|
|
761
|
-
`identifiers` method that returns identifier classes. This is the most
|
|
762
|
-
common pattern (ISO, IEC, ASTM, ASHRAE, etc.).
|
|
763
|
-
* `RegistryExporter` — if the flavor uses a centralized `TYPED_STAGES_REGISTRY`
|
|
764
|
-
on the Scheme class instead of per-class `TYPED_STAGES` (BSI, CEN).
|
|
765
|
-
* `IeeeExporter` — only for IEEE, which has a unique constant-based discovery.
|
|
766
|
-
* `NistExporter` — if typed stages come from a class method (not constant).
|
|
767
|
-
* `ItuExporter` — for sector-based types with transform/model patterns.
|
|
768
|
-
* `DataClassExporter` — for flavors where Scheme inherits from
|
|
769
|
-
`Lutaml::Model::Serializable` (ETSI, Plateau).
|
|
770
|
-
|
|
771
735
|
. **Register the flavor** in `lib/pubid/export/exporter.rb`:
|
|
772
736
|
|
|
773
737
|
[source,ruby]
|
|
774
738
|
----
|
|
775
739
|
FLAVORS = %i[iso iec ... new_flavor].freeze
|
|
776
|
-
|
|
777
|
-
FLAVOR_STRATEGIES = {
|
|
778
|
-
iso: :scheme,
|
|
779
|
-
# ...
|
|
780
|
-
new_flavor: :scheme, # or :registry, :data_class, etc.
|
|
781
|
-
}.freeze
|
|
782
|
-
----
|
|
783
|
-
|
|
784
|
-
. **Add the module mapping** in `FlavorExporter#scheme_module` (in
|
|
785
|
-
`lib/pubid/export/flavor_exporter.rb`):
|
|
786
|
-
|
|
787
|
-
[source,ruby]
|
|
788
|
-
----
|
|
789
|
-
when "new_flavor" then Pubid::NewFlavor
|
|
790
740
|
----
|
|
791
741
|
|
|
792
742
|
. **If the flavor has wrapper types** (value-added formats like VAP, Redline),
|
|
793
|
-
add them to `WRAPPER_CLASSES` in `
|
|
743
|
+
add them to `WRAPPER_CLASSES` in `lib/pubid/export/flavor_exporter.rb`:
|
|
794
744
|
|
|
795
745
|
[source,ruby]
|
|
796
746
|
----
|
|
@@ -812,7 +762,7 @@ it with the export layer:
|
|
|
812
762
|
require "spec_helper"
|
|
813
763
|
require "pubid/export"
|
|
814
764
|
|
|
815
|
-
RSpec.describe Pubid::Export::
|
|
765
|
+
RSpec.describe Pubid::Export::FlavorExporter, "for new_flavor" do
|
|
816
766
|
subject(:result) { described_class.new(:new_flavor).export }
|
|
817
767
|
|
|
818
768
|
it "exports identifier types" do
|
|
@@ -851,14 +801,8 @@ puts auditor.summary(results)
|
|
|
851
801
|
lib/pubid/export.rb # Module entry point
|
|
852
802
|
lib/pubid/export/
|
|
853
803
|
├── result.rb # Immutable value objects (IdentifierTypeResult, TypedStageResult, FlavorResult)
|
|
854
|
-
├── flavor_exporter.rb #
|
|
855
|
-
├──
|
|
856
|
-
├── registry_exporter.rb # Strategy: TYPED_STAGES_REGISTRY pattern
|
|
857
|
-
├── ieee_exporter.rb # Strategy: IEEE identifier discovery
|
|
858
|
-
├── nist_exporter.rb # Strategy: NIST per-class typed_stages
|
|
859
|
-
├── itu_exporter.rb # Strategy: ITU transform/model pattern
|
|
860
|
-
├── data_class_exporter.rb # Strategy: Lutaml::Model::Serializable Scheme
|
|
861
|
-
├── exporter.rb # Orchestrator (FLAVOR_STRATEGIES dispatch)
|
|
804
|
+
├── flavor_exporter.rb # Unified per-flavor extractor (WRAPPER_CLASSES dispatch)
|
|
805
|
+
├── exporter.rb # Orchestrator (FLAVORS list)
|
|
862
806
|
└── auditor.rb # Library vs website gap analysis
|
|
863
807
|
lib/tasks/export.rake # Rake tasks: export:website_data, export:audit
|
|
864
808
|
----
|
|
@@ -1249,16 +1193,16 @@ IEEE corrigenda are now first-class SupplementIdentifier objects with full base
|
|
|
1249
1193
|
[source,ruby]
|
|
1250
1194
|
----
|
|
1251
1195
|
cor = Pubid::Ieee.parse("IEEE Std 535-2013/Cor. 1-2017")
|
|
1252
|
-
cor.class
|
|
1253
|
-
cor.
|
|
1254
|
-
cor.
|
|
1255
|
-
cor.
|
|
1256
|
-
cor.
|
|
1257
|
-
cor.to_s
|
|
1196
|
+
cor.class # => Pubid::Ieee::Identifiers::Corrigendum
|
|
1197
|
+
cor.number # => "1"
|
|
1198
|
+
cor.year # => "2017"
|
|
1199
|
+
cor.base # => <the wrapped standard identifier>
|
|
1200
|
+
cor.base.to_s # => "IEEE Std 535-2013"
|
|
1201
|
+
cor.to_s # => "IEEE Std 535-2013/Cor. 1-2017"
|
|
1258
1202
|
|
|
1259
1203
|
# Round-trip fidelity preserved
|
|
1260
1204
|
cor2 = Pubid::Ieee.parse("IEEE Std 802.1AC-2016/Cor. 1-2018")
|
|
1261
|
-
cor2.to_s
|
|
1205
|
+
cor2.to_s # => "IEEE Std 802.1AC-2016/Cor. 1-2018"
|
|
1262
1206
|
----
|
|
1263
1207
|
|
|
1264
1208
|
**Extended Relationship Types:**
|
|
@@ -1438,34 +1382,33 @@ ASME uses 23+ multi-character codes for specialized document types:
|
|
|
1438
1382
|
----
|
|
1439
1383
|
require 'pubid/asme'
|
|
1440
1384
|
|
|
1441
|
-
# Parse standard
|
|
1385
|
+
# Parse standard (designator + number in one `number` string)
|
|
1442
1386
|
id = Pubid::Asme.parse("ASME B16.5-2020")
|
|
1443
|
-
id.
|
|
1444
|
-
id.
|
|
1445
|
-
id.
|
|
1446
|
-
id.to_s # => "ASME B16.5-2020"
|
|
1387
|
+
id.number # => "B16.5"
|
|
1388
|
+
id.year # => "2020"
|
|
1389
|
+
id.to_s # => "ASME B16.5-2020"
|
|
1447
1390
|
|
|
1448
1391
|
# Parse BPVC subdivision
|
|
1449
1392
|
bpvc = Pubid::Asme.parse("ASME BPVC.III.1.NB-2021")
|
|
1450
|
-
bpvc.
|
|
1451
|
-
bpvc.
|
|
1452
|
-
bpvc.
|
|
1453
|
-
bpvc.to_s # => "ASME BPVC.III.1.NB-2021"
|
|
1393
|
+
bpvc.number # => "BPVC.III.1.NB"
|
|
1394
|
+
bpvc.year # => "2021"
|
|
1395
|
+
bpvc.to_s # => "ASME BPVC.III.1.NB-2021"
|
|
1454
1396
|
|
|
1455
1397
|
# Parse multi-char designator
|
|
1456
1398
|
ptc = Pubid::Asme.parse("ASME PTC-1-2022")
|
|
1457
|
-
ptc.
|
|
1458
|
-
ptc.
|
|
1459
|
-
ptc.to_s # => "ASME PTC-1-2022"
|
|
1399
|
+
ptc.number # => "PTC-1"
|
|
1400
|
+
ptc.to_s # => "ASME PTC-1-2022"
|
|
1460
1401
|
|
|
1461
1402
|
# Parse CSA dual-published
|
|
1462
1403
|
dual = Pubid::Asme.parse("ASME A17.1/CSA B44-2022")
|
|
1463
|
-
dual.
|
|
1464
|
-
dual.
|
|
1465
|
-
dual.
|
|
1466
|
-
dual.to_s # => "ASME A17.1/CSA B44-2022"
|
|
1404
|
+
dual.number # => "A17.1"
|
|
1405
|
+
dual.csa_number # => "B44"
|
|
1406
|
+
dual.to_s # => "ASME A17.1/CSA B44-2022"
|
|
1467
1407
|
----
|
|
1468
1408
|
|
|
1409
|
+
(The v1 `id.code.designator` / `id.code.number` component reader is historic;
|
|
1410
|
+
v2 stores the whole designation in the `number` attribute.)
|
|
1411
|
+
|
|
1469
1412
|
**Known Limitations:**
|
|
1470
1413
|
All 731 ASME identifiers are normative (from official ASME sources). Current parser handles 75.51% (552/731) with opportunities for further enhancement in specialized patterns.
|
|
1471
1414
|
|
|
@@ -1557,16 +1500,23 @@ bsi.to_s # => "BS ISO 37101:2016"
|
|
|
1557
1500
|
|
|
1558
1501
|
# Adopted European Norm with ISO (three-level)
|
|
1559
1502
|
bsi = Pubid::Bsi.parse("BS EN ISO 13485:2016+A11:2021")
|
|
1560
|
-
bsi.
|
|
1561
|
-
bsi.
|
|
1503
|
+
bsi.class # => Pubid::Bsi::Identifiers::ConsolidatedIdentifier
|
|
1504
|
+
bsi.identifiers.map(&:to_s)
|
|
1505
|
+
# => ["BS EN ISO 13485:2016", "BS EN ISO 13485:2016+A11:2021"]
|
|
1506
|
+
bsi.identifiers.first.publisher.body # => "BS"
|
|
1507
|
+
bsi.identifiers.first.base.adopted.to_s # => "ISO 13485:2016"
|
|
1562
1508
|
# Three-level: BS wraps EN wraps ISO
|
|
1563
1509
|
|
|
1564
1510
|
# National Annex with supplements
|
|
1565
1511
|
na = Pubid::Bsi.parse("NA+A1:2012 to BS EN 1993-5:2007")
|
|
1566
|
-
na.
|
|
1567
|
-
na.
|
|
1512
|
+
na.na_supplements.first.number # => "1"
|
|
1513
|
+
na.na_supplements.first.year # => "2012"
|
|
1568
1514
|
----
|
|
1569
1515
|
|
|
1516
|
+
(The v1 `adopted_identifier` reader is historic — v2 uses the uniform `base`
|
|
1517
|
+
parent accessor on the adopted identifier and the `identifiers` collection on
|
|
1518
|
+
the consolidated wrapper.)
|
|
1519
|
+
|
|
1570
1520
|
**Features:**
|
|
1571
1521
|
- Short year expansion: `A1:15` → `A1:2015`
|
|
1572
1522
|
- Multiple supplement formats: `+A1:2021`, `+C1:2018`, `+A11:2021`
|
|
@@ -1621,24 +1571,29 @@ Features: EN documents, technical specifications/reports, joint committee public
|
|
|
1621
1571
|
[source,ruby]
|
|
1622
1572
|
----
|
|
1623
1573
|
# CEN Technical Specification (slash separator!)
|
|
1624
|
-
cen = Pubid::
|
|
1574
|
+
cen = Pubid::CenCenelec.parse("CEN/TS 14972")
|
|
1625
1575
|
cen.to_s # => "CEN/TS 14972" (slash, not space!)
|
|
1626
1576
|
|
|
1627
1577
|
# CLC Technical Report
|
|
1628
|
-
clc = Pubid::
|
|
1578
|
+
clc = Pubid::CenCenelec.parse("CLC/TR 62125:2008")
|
|
1629
1579
|
clc.to_s # => "CLC/TR 62125:2008"
|
|
1630
1580
|
|
|
1631
1581
|
# Joint committee
|
|
1632
|
-
joint = Pubid::
|
|
1633
|
-
joint.
|
|
1582
|
+
joint = Pubid::CenCenelec.parse("CEN/CLC/TR 17602-80-12:2021")
|
|
1583
|
+
joint.copublishers.map(&:to_s) # => ["CLC"]
|
|
1634
1584
|
joint.to_s # => "CEN/CLC/TR 17602-80-12:2021"
|
|
1635
1585
|
|
|
1636
|
-
# European Prestandard with ISO adoption
|
|
1637
|
-
env = Pubid::
|
|
1638
|
-
env.
|
|
1586
|
+
# European Prestandard with ISO adoption
|
|
1587
|
+
env = Pubid::CenCenelec.parse("ENV ISO 11079:1999")
|
|
1588
|
+
env.adopted.to_s # => "ISO 11079:1999"
|
|
1639
1589
|
env.to_s # => "ENV ISO 11079:1999"
|
|
1640
1590
|
----
|
|
1641
1591
|
|
|
1592
|
+
(The v1 `Pubid::Cen` module name is historic — CEN and CENELEC share the
|
|
1593
|
+
`cen_cenelec` flavor module, `Pubid::CenCenelec`; the v1
|
|
1594
|
+
`publisher.copublisher` and `adopted_identifier` readers are the v2
|
|
1595
|
+
`copublishers` collection and uniform `base`/`adopted` accessors.)
|
|
1596
|
+
|
|
1642
1597
|
**Key Architectural Decision:** CEN uses **slash separator** between publisher and type (unlike ISO's space), implemented consistently throughout all identifier classes.
|
|
1643
1598
|
|
|
1644
1599
|
==== SAE (Society of Automotive Engineers) ✨
|
|
@@ -1864,9 +1819,9 @@ id.type.abbr # => "DATA"
|
|
|
1864
1819
|
----
|
|
1865
1820
|
# Amendment
|
|
1866
1821
|
id = Pubid::Iso.parse("ISO 19110:2005/Amd 1:2011")
|
|
1867
|
-
id.class
|
|
1868
|
-
id.
|
|
1869
|
-
id.number
|
|
1822
|
+
id.class # => Pubid::Iso::Identifiers::Amendment
|
|
1823
|
+
id.base.to_s # => "ISO 19110:2005"
|
|
1824
|
+
id.number # => "1"
|
|
1870
1825
|
|
|
1871
1826
|
# Staged amendment (FDAM = Final Draft Amendment)
|
|
1872
1827
|
id = Pubid::Iso.parse("ISO/IEC 8802-3:2021/FDAM 1")
|
|
@@ -1879,9 +1834,9 @@ id.class # => Pubid::Iso::Identifiers::Corrigendum
|
|
|
1879
1834
|
|
|
1880
1835
|
# Multi-level (Amendment to Amendment gets Corrigendum)
|
|
1881
1836
|
id = Pubid::Iso.parse("ISO/IEC 13818-1:2015/Amd 3:2016/Cor 1:2017")
|
|
1882
|
-
id.class
|
|
1883
|
-
id.
|
|
1884
|
-
id.
|
|
1837
|
+
id.class # => Pubid::Iso::Identifiers::Corrigendum
|
|
1838
|
+
id.base.class # => Pubid::Iso::Identifiers::Amendment
|
|
1839
|
+
id.base.base.class # => Pubid::Iso::Identifiers::InternationalStandard
|
|
1885
1840
|
----
|
|
1886
1841
|
|
|
1887
1842
|
===== Special patterns
|
|
@@ -1890,13 +1845,13 @@ id.base_identifier.base_identifier.class # => Pubid::Iso::Identifiers::Internati
|
|
|
1890
1845
|
----
|
|
1891
1846
|
# Directives
|
|
1892
1847
|
id = Pubid::Iso.parse("ISO/IEC DIR 1:2022")
|
|
1893
|
-
id.class
|
|
1894
|
-
id.number
|
|
1848
|
+
id.class # => Pubid::Iso::Identifiers::Directives
|
|
1849
|
+
id.number # => "1"
|
|
1895
1850
|
|
|
1896
1851
|
# Directives Supplement
|
|
1897
1852
|
id = Pubid::Iso.parse("ISO/IEC DIR 1 ISO SUP:2022")
|
|
1898
|
-
id.class
|
|
1899
|
-
id.
|
|
1853
|
+
id.class # => Pubid::Iso::Identifiers::DirectivesSupplement
|
|
1854
|
+
id.base.class # => Pubid::Iso::Identifiers::Directives
|
|
1900
1855
|
id.supplement_publisher.to_s # => "ISO"
|
|
1901
1856
|
|
|
1902
1857
|
# Bundled Directives (combined document + supplement)
|
|
@@ -2270,13 +2225,13 @@ rec.to_s(format: :long) # => "OIML R 138 Edition 2007 (E)"
|
|
|
2270
2225
|
|
|
2271
2226
|
# With edition number
|
|
2272
2227
|
guide = Pubid::Oiml.parse("OIML E 5 6th Edition 2015 (E)")
|
|
2273
|
-
guide.edition # => "
|
|
2228
|
+
guide.edition # => "6th"
|
|
2274
2229
|
guide.year # => "2015"
|
|
2275
2230
|
|
|
2276
2231
|
# Amendment with recursive parsing
|
|
2277
2232
|
amd = Pubid::Oiml.parse("Amendment (2009) to OIML R 138 Edition 2007 (E)")
|
|
2278
|
-
amd.
|
|
2279
|
-
amd.year
|
|
2233
|
+
amd.base.to_s # => "OIML R 138 Edition 2007"
|
|
2234
|
+
amd.year # => "2009"
|
|
2280
2235
|
----
|
|
2281
2236
|
|
|
2282
2237
|
==== CCSDS: Space Data Systems Standards
|
|
@@ -2289,43 +2244,36 @@ require 'pubid/ccsds'
|
|
|
2289
2244
|
|
|
2290
2245
|
# Standard CCSDS document
|
|
2291
2246
|
doc = Pubid::Ccsds.parse("CCSDS 727.0-B-5")
|
|
2292
|
-
doc.
|
|
2293
|
-
doc.
|
|
2294
|
-
doc.
|
|
2295
|
-
doc.
|
|
2296
|
-
|
|
2297
|
-
# With color code
|
|
2298
|
-
doc = Pubid::Ccsds.parse("CCSDS 211.2-B-1 Magenta Book")
|
|
2299
|
-
doc.color # => "Magenta"
|
|
2300
|
-
doc.to_s # => "CCSDS 211.2-B-1 Magenta Book"
|
|
2247
|
+
doc.number # => "727"
|
|
2248
|
+
doc.part # => "0"
|
|
2249
|
+
doc.type # => "B"
|
|
2250
|
+
doc.edition # => "5"
|
|
2251
|
+
doc.to_s # => "CCSDS 727.0-B-5"
|
|
2301
2252
|
|
|
2302
2253
|
# Corrigendum supplement (with lutaml-model)
|
|
2303
2254
|
cor = Pubid::Ccsds.parse("CCSDS 727.0-B-5 Cor. 1")
|
|
2304
|
-
cor.class
|
|
2305
|
-
cor.
|
|
2306
|
-
cor.
|
|
2307
|
-
cor.to_s
|
|
2308
|
-
|
|
2309
|
-
# Language translation
|
|
2310
|
-
doc = Pubid::Ccsds.parse("CCSDS 211.0-B-5 (Chinese)")
|
|
2311
|
-
doc.language # => "Chinese"
|
|
2312
|
-
doc.to_s # => "CCSDS 211.0-B-5 (Chinese)"
|
|
2255
|
+
cor.class # => Pubid::Ccsds::Identifiers::Corrigendum
|
|
2256
|
+
cor.number # => "1"
|
|
2257
|
+
cor.base.to_s # => "CCSDS 727.0-B-5"
|
|
2258
|
+
cor.to_s # => "CCSDS 727.0-B-5 Cor. 1"
|
|
2313
2259
|
----
|
|
2314
2260
|
|
|
2261
|
+
(The color-book label (`Magenta Book`) and the bracketed translation forms of
|
|
2262
|
+
the archived pre-monogem parser are historic — they are not part of the v2
|
|
2263
|
+
CCSDS grammar and no longer parse; see the archived
|
|
2264
|
+
link:https://github.com/pubid/pubid-ccsds#readme[pubid-ccsds README].)
|
|
2265
|
+
|
|
2315
2266
|
**Architecture Quality:**
|
|
2316
2267
|
|
|
2317
2268
|
* **Lutaml::Model refactoring** - SupplementIdentifier inherits from `Identifiers::Base`
|
|
2318
|
-
* **Polymorphic attributes** -
|
|
2319
|
-
* **Type safety** -
|
|
2320
|
-
* ✅ **Serialization support** -
|
|
2321
|
-
* ✅ **Zero breaking changes** - All 16 tests passing (100%)
|
|
2269
|
+
* **Polymorphic attributes** - the wrapped document is the uniform polymorphic `base` attribute
|
|
2270
|
+
* **Type safety** - the corrigendum ordinal is the shared `number` attribute
|
|
2271
|
+
* ✅ **Serialization support** - round-trip via `#to_hash` / `Pubid.from_hash`
|
|
2322
2272
|
* ✅ **Consistent pattern** - Matches ISO, IEC, NIST architecture exactly
|
|
2323
2273
|
|
|
2324
2274
|
**Key Features:**
|
|
2325
2275
|
|
|
2326
|
-
* Version-revision numbering (e.g., B-5 = Version B,
|
|
2327
|
-
* Color book system (Green, Blue, Magenta, Yellow, Silver, Orange, Pink)
|
|
2276
|
+
* Version-revision numbering (e.g., B-5 = Version B, Edition 5, carried as `type` and `edition`)
|
|
2328
2277
|
* Corrigenda as proper supplement identifiers with recursive base parsing
|
|
2329
|
-
* Language translation support
|
|
2330
2278
|
* Round-trip fidelity preserved
|
|
2331
2279
|
|
data/data/parg/cen_pfs.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"bindings":null,"version":"0.1.0","grammar":"PubidCenPfs","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"EN"}},{"Str":{"pattern":" "}},{"Entity":{"atom":8}},{"Re":{"pattern":"[\\x31-\\x39]"}},{"Entity":{"atom":5}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":4,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[3,6]}},{"Named":{"name":"number","atom":7}},{"Str":{"pattern":"-"}},{"Entity":{"atom":13}},{"Entity":{"atom":5}},{"Repetition":{"atom":11,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"part","atom":12}},{"Sequence":{"atoms":[9,10]}},{"Repetition":{"atom":14,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":20}},{"Entity":{"atom":5}},{"Repetition":{"atom":18,"min":4,"max":null,"tag":"Repetition"}},{"Named":{"name":"year","atom":19}},{"Sequence":{"atoms":[16,17]}},{"Repetition":{"atom":21,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[0,1,2,15,22]}}],"root":23},"bindings":[{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"part","path":"part","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"EN 1325","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 12464-1:2011","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 1177:2018","expect":{}},{"entry":"identifier","kind":"reject","input":"EN","expect":{}},{"entry":"identifier","kind":"reject","input":"EN ISO 9001:2015","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"CEN/TS 12345","expect":{}},{"entry":"identifier","kind":"example","input":"EN 1325","expect":{"number":"1325"}},{"entry":"identifier","kind":"example","input":"EN 12464-1:2011","expect":{"number":"12464","part":"1","year":"2011"}},{"entry":"identifier","kind":"example","input":"EN 1177:2018","expect":{"number":"1177","year":"2018"}}],"docs":{},"source":"# PFS-generated grammar — DO NOT EDIT BY HAND.\n# Source: definitions/cen.pfs (pfs:1) sha256:bc1edd5874f8938b5f946416a2b052d9d9b9df3d99f6c20a3d88fcab9ae1d70c\n# Compiler: pubid/grammar/pfs 0.1.0\n# Flavor key: cen_pfs (grammar PubidCenPfs)\n# Regenerate: ruby scripts/pfs compile definitions/cen.pfs --as cen_pfs\n# Module: iso.inner v1 (sha256:6f04cf475f1c...)\n# Module: en.overlay v1 (sha256:851af8c5f31b...)\n# Module: national.prefix v1 (sha256:c7aa2f2442e8...)\n# Module: supplements.core v1 (sha256:9fa9656375c7...)\n\ngrammar PubidCenPfs version \"0.1.0\" edition 2 {\n\n # Grammar fragments: named lexical terms declared under `grammar:`.\n iso_space = \" \"\n iso_colon = \":\"\n iso_dash = \"-\"\n iso_year = 4*digit\n iso_part = 1*digit [\"-\" 1*digit]\n iso_number = 1*(\"0\" %x31-39) *digit [iso_dash iso_part]\n iso_document = \"ISO\" iso_space iso_number [iso_colon iso_year]\n en_space = \" \"\n en_draft = (\"pr\" / \"Fpr\")\n en_face = [en_draft] \"EN\"\n en_adoption = en_face en_space iso_document\n supplement_number = 1*digit\n supplement_year = 4*digit\n supplement_month = 2*digit\n digit = %x30-39\n space = \" \"\n slash = \"/\"\n colon = \":\"\n dash = \"-\"\n\n # Fields: one capture rule per declared field; the whole pattern\n # is the capture.\n cen_cenelec_number = ((%x31-39) *digit) as number\n cen_cenelec_part = (1*digit) as part\n cen_cenelec_year = (4*digit) as year\n\n # Identifier rule: the canonical template first, then the\n # declared alternates (parse-in spellings; they normalize to the\n # canonical render face).\n identifier = \"EN\" \" \" cen_cenelec_number [\"-\" cen_cenelec_part] [\":\" cen_cenelec_year]\n entry identifier: identifier\n\n # Typed model bindings: every bound capture lands on the\n # consumer model's field of the same name.\n bindings identifier {\n number -> number (string)\n part -> part (string)\n year -> year (string)\n }\n\n # REQUIRED examples from the definition — accepts, rejects, and\n # the capture expectations the compiler replayed at compile time.\n test {\n accept \"EN 1325\"\n accept \"EN 12464-1:2011\"\n accept \"EN 1177:2018\"\n reject \"EN\"\n reject \"EN ISO 9001:2015\"\n reject \"nonsense\"\n reject \"CEN/TS 12345\"\n example \"EN 1325\" { number: \"1325\" }\n example \"EN 12464-1:2011\" { number: \"12464\" part: \"1\" year: \"2011\" }\n example \"EN 1177:2018\" { number: \"1177\" year: \"2018\" }\n }\n}\n","source_hash":"4b84b6acda6f62fbbff60e0ff603d72e3ff00b71906914855633b6f0404869db","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:4363f170082d3242a35648e8b019037e9670c804d4ea951a51487697eb0c4cee","checksum":"sha256:e19eae585ed8ee560c88d97c8289d827384d21214db02634bc3eeff5a0296ac9"}
|
|
1
|
+
{"bindings":null,"version":"0.1.0","grammar":"PubidCenPfs","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":4}},{"Str":{"pattern":"FprEN"}},{"Str":{"pattern":"prEN"}},{"Alternative":{"atoms":[1,2]}},{"Named":{"name":"stage","atom":3}},{"Str":{"pattern":" "}},{"Entity":{"atom":15}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":7,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":" "}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":10,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[9,11]}},{"Repetition":{"atom":12,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[8,13]}},{"Named":{"name":"number","atom":14}},{"Str":{"pattern":"-"}},{"Entity":{"atom":22}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Str":{"pattern":"-"}},{"Alternative":{"atoms":[18,19]}},{"Repetition":{"atom":20,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"part","atom":21}},{"Sequence":{"atoms":[16,17]}},{"Repetition":{"atom":23,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":37}},{"Str":{"pattern":" "}},{"Str":{"pattern":"V"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":28,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":31,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":34,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[26,27,29,30,32,33,35]}},{"Named":{"name":"version","atom":36}},{"Repetition":{"atom":25,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":44}},{"Entity":{"atom":42}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":41,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"year","atom":43}},{"Sequence":{"atoms":[39,40]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[0,5,6,24,38,46]}},{"Entity":{"atom":58}},{"Str":{"pattern":"CWA"}},{"Str":{"pattern":"HD"}},{"Str":{"pattern":"ES"}},{"Str":{"pattern":"CR"}},{"Str":{"pattern":"ENV"}},{"Str":{"pattern":"EN"}},{"Str":{"pattern":"CEN"}},{"Str":{"pattern":"CLC"}},{"Alternative":{"atoms":[49,50,51,52,53,54,55,56]}},{"Named":{"name":"publisher","atom":57}},{"Entity":{"atom":68}},{"Str":{"pattern":"/"}},{"Entity":{"atom":65}},{"Str":{"pattern":"CLC"}},{"Str":{"pattern":"ETSI"}},{"Alternative":{"atoms":[62,63]}},{"Named":{"name":"copublisher","atom":64}},{"Sequence":{"atoms":[60,61]}},{"Repetition":{"atom":66,"min":0,"max":null,"tag":"Repetition"}},{"Named":{"name":"copublishers","atom":67}},{"Repetition":{"atom":59,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":73}},{"Str":{"pattern":"Guide"}},{"Named":{"name":"guide","atom":72}},{"Str":{"pattern":" "}},{"Entity":{"atom":15}},{"Str":{"pattern":"-"}},{"Entity":{"atom":22}},{"Sequence":{"atoms":[76,77]}},{"Repetition":{"atom":78,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":44}},{"Sequence":{"atoms":[80,81]}},{"Repetition":{"atom":82,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[48,69,70,71,74,75,79,83]}},{"Entity":{"atom":58}},{"Entity":{"atom":68}},{"Repetition":{"atom":86,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":148}},{"Str":{"pattern":"ISO"}},{"Str":{"pattern":"IEC"}},{"Str":{"pattern":"CISPR"}},{"Alternative":{"atoms":[90,91,92]}},{"Entity":{"atom":138}},{"Entity":{"atom":122}},{"Str":{"pattern":"/"}},{"Named":{"name":"supplements_slash","atom":96}},{"Str":{"pattern":"+"}},{"Named":{"name":"supplements_plus","atom":98}},{"Alternative":{"atoms":[97,99]}},{"Str":{"pattern":"AC"}},{"Named":{"name":"supplement_kind","atom":101}},{"Entity":{"atom":106}},{"Entity":{"atom":42}},{"Repetition":{"atom":104,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"supplement_number","atom":105}},{"Repetition":{"atom":103,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":112}},{"Entity":{"atom":42}},{"Repetition":{"atom":110,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"supplements_year","atom":111}},{"Sequence":{"atoms":[108,109]}},{"Repetition":{"atom":113,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"-"}},{"Entity":{"atom":119}},{"Entity":{"atom":42}},{"Repetition":{"atom":117,"min":2,"max":2,"tag":"Repetition"}},{"Named":{"name":"supplements_month","atom":118}},{"Sequence":{"atoms":[115,116]}},{"Repetition":{"atom":120,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[100,102,107,114,121]}},{"Entity":{"atom":136}},{"Str":{"pattern":"/"}},{"Named":{"name":"supplements_slash","atom":124}},{"Str":{"pattern":"+"}},{"Named":{"name":"supplements_plus","atom":126}},{"Alternative":{"atoms":[125,127]}},{"Str":{"pattern":"A"}},{"Named":{"name":"supplement_kind","atom":129}},{"Entity":{"atom":106}},{"Str":{"pattern":":"}},{"Entity":{"atom":112}},{"Sequence":{"atoms":[132,133]}},{"Repetition":{"atom":134,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[128,130,131,135]}},{"Alternative":{"atoms":[95,123]}},{"Named":{"name":"supplement","atom":137}},{"Lookahead":{"atom":94,"positive":false}},{"Str":{"pattern":" FRAG"}},{"Lookahead":{"atom":140,"positive":false}},{"Re":{"pattern":"[\\x01-\\x09]"}},{"Re":{"pattern":"[\\x0b-\\u{10ffff}]"}},{"Alternative":{"atoms":[142,143]}},{"Sequence":{"atoms":[139,141,144]}},{"Repetition":{"atom":145,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[93,146]}},{"Named":{"name":"adopted","atom":147}},{"Sequence":{"atoms":[85,87,88,89]}},{"Entity":{"atom":58}},{"Entity":{"atom":68}},{"Repetition":{"atom":151,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"/"}},{"Entity":{"atom":158}},{"Str":{"pattern":"TR"}},{"Str":{"pattern":"TS"}},{"Alternative":{"atoms":[155,156]}},{"Named":{"name":"type","atom":157}},{"Sequence":{"atoms":[153,154]}},{"Repetition":{"atom":159,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":15}},{"Str":{"pattern":"-"}},{"Entity":{"atom":22}},{"Sequence":{"atoms":[163,164]}},{"Repetition":{"atom":165,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":37}},{"Repetition":{"atom":167,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":44}},{"Sequence":{"atoms":[169,170]}},{"Repetition":{"atom":171,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[150,152,160,161,162,166,168,172]}},{"Alternative":{"atoms":[47,84,149,173]}},{"Entity":{"atom":178}},{"Entity":{"atom":138}},{"Repetition":{"atom":176,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"supplements","atom":177}},{"Str":{"pattern":" FRAG"}},{"Entity":{"atom":183}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":181,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"fragment_number","atom":182}},{"Sequence":{"atoms":[179,180]}},{"Repetition":{"atom":184,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[175,185]}},{"Repetition":{"atom":186,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[174,187]}},{"Entity":{"atom":58}},{"Entity":{"atom":68}},{"Repetition":{"atom":190,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":158}},{"Str":{"pattern":" "}},{"Entity":{"atom":15}},{"Str":{"pattern":"-"}},{"Entity":{"atom":22}},{"Sequence":{"atoms":[196,197]}},{"Repetition":{"atom":198,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":37}},{"Repetition":{"atom":200,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":":"}},{"Entity":{"atom":44}},{"Sequence":{"atoms":[202,203]}},{"Repetition":{"atom":204,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":178}},{"Str":{"pattern":" FRAG"}},{"Entity":{"atom":183}},{"Sequence":{"atoms":[207,208]}},{"Repetition":{"atom":209,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[206,210]}},{"Repetition":{"atom":211,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[189,191,192,193,194,195,199,201,205,212]}},{"Alternative":{"atoms":[188,213]}}],"root":214},"bindings":[{"capture":"publisher","path":"publisher","type":"string","card":null,"preprocess":null},{"capture":"copublisher","path":"copublisher","type":"string","card":null,"preprocess":null},{"capture":"copublisher","path":"copublishers[].copublisher","type":"string","card":null,"preprocess":null},{"capture":"stage","path":"stage","type":"string","card":null,"preprocess":null},{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"guide","path":"guide","type":"string","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"part","path":"part","type":"string","card":null,"preprocess":null},{"capture":"version","path":"version","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null},{"capture":"adopted","path":"adopted","type":"string","card":null,"preprocess":null},{"capture":"fragment_number","path":"fragment_number","type":"string","card":null,"preprocess":null},{"capture":"supplement","path":"supplements[].supplement","type":"raw","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule identifier: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"EN 1325","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 12464-1:2011","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 302 326-2 V2.2.1:2026","expect":{}},{"entry":"identifier","kind":"accept","input":"prEN 12464-1:2019","expect":{}},{"entry":"identifier","kind":"accept","input":"FprEN 50600-2-4","expect":{}},{"entry":"identifier","kind":"accept","input":"CEN/TR 12101-5:2005","expect":{}},{"entry":"identifier","kind":"accept","input":"CEN/CLC/ETSI/TR 101551:2026","expect":{}},{"entry":"identifier","kind":"accept","input":"CLC/TS 50701:2021","expect":{}},{"entry":"identifier","kind":"accept","input":"CR 10313:2000","expect":{}},{"entry":"identifier","kind":"accept","input":"CWA 14050-21:2000","expect":{}},{"entry":"identifier","kind":"accept","input":"ES 59008-6-1:1999","expect":{}},{"entry":"identifier","kind":"accept","input":"ENV 1613:1995","expect":{}},{"entry":"identifier","kind":"accept","input":"HD 1215-2:1988","expect":{}},{"entry":"identifier","kind":"accept","input":"CEN Guide 414:2017","expect":{}},{"entry":"identifier","kind":"accept","input":"CEN/CLC Guide 25:2023","expect":{}},{"entry":"identifier","kind":"accept","input":"EN ISO 12100:2010","expect":{}},{"entry":"identifier","kind":"accept","input":"HD IEC 60364-8-81","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 13250:2000/A1:2005","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 60335-1:2012/A1","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 13254:2000/AC:2003","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 61375-2-3:2015/AC:2016-11","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 285:2015+A1","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 285:2015+A1:2021","expect":{}},{"entry":"identifier","kind":"accept","input":"EN ISO 10077-1:2006+AC:2009+AC2:2009","expect":{}},{"entry":"identifier","kind":"accept","input":"EN 60038/A1 FRAG2","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN 300 175","expect":{}},{"entry":"identifier","kind":"reject","input":"CEN/XX 100","expect":{}},{"entry":"identifier","kind":"reject","input":"HD 1215-2:198","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 300 175 V","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 1325 EXTRA","expect":{}},{"entry":"identifier","kind":"reject","input":"EN A1","expect":{}},{"entry":"identifier","kind":"reject","input":"ISO 12100:2010","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 1325:20000","expect":{}},{"entry":"identifier","kind":"reject","input":"EN /TR 100","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 13250:2000/A1:","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 13250:2000/ACX:2003","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 285:2015+A1:","expect":{}},{"entry":"identifier","kind":"reject","input":"FRAG2","expect":{}},{"entry":"identifier","kind":"reject","input":"EN 13250:2000 FRAG2","expect":{}},{"entry":"identifier","kind":"example","input":"EN 1325","expect":{"publisher":"EN","number":"1325"}},{"entry":"identifier","kind":"example","input":"EN 12464-1:2011","expect":{"publisher":"EN","number":"12464","part":"1","year":"2011"}},{"entry":"identifier","kind":"example","input":"EN 302 326-2 V2.2.1:2026","expect":{"publisher":"EN","number":"302 326","part":"2","version":" V2.2.1","year":"2026"}},{"entry":"identifier","kind":"example","input":"prEN 12464-1:2019","expect":{"stage":"prEN","number":"12464","part":"1","year":"2019"}},{"entry":"identifier","kind":"example","input":"FprEN 50600-2-4","expect":{"stage":"FprEN","number":"50600","part":"2-4"}},{"entry":"identifier","kind":"example","input":"CEN/TR 12101-5:2005","expect":{"publisher":"CEN","type":"TR","number":"12101","part":"5","year":"2005"}},{"entry":"identifier","kind":"example","input":"CEN/CLC/ETSI/TR 101551:2026","expect":{"publisher":"CEN","copublisher":"CLC","type":"TR","number":"101551","year":"2026"}},{"entry":"identifier","kind":"example","input":"CLC/TS 50701:2021","expect":{"publisher":"CLC","type":"TS","number":"50701","year":"2021"}},{"entry":"identifier","kind":"example","input":"CR 10313:2000","expect":{"publisher":"CR","number":"10313","year":"2000"}},{"entry":"identifier","kind":"example","input":"CWA 14050-21:2000","expect":{"publisher":"CWA","number":"14050","part":"21","year":"2000"}},{"entry":"identifier","kind":"example","input":"ES 59008-6-1:1999","expect":{"publisher":"ES","number":"59008","part":"6-1","year":"1999"}},{"entry":"identifier","kind":"example","input":"ENV 1613:1995","expect":{"publisher":"ENV","number":"1613","year":"1995"}},{"entry":"identifier","kind":"example","input":"HD 1215-2:1988","expect":{"publisher":"HD","number":"1215","part":"2","year":"1988"}},{"entry":"identifier","kind":"example","input":"CEN Guide 414:2017","expect":{"publisher":"CEN","guide":"Guide","number":"414","year":"2017"}},{"entry":"identifier","kind":"example","input":"CEN/CLC Guide 25:2023","expect":{"publisher":"CEN","copublisher":"CLC","guide":"Guide","number":"25","year":"2023"}},{"entry":"identifier","kind":"example","input":"EN ISO 12100:2010","expect":{"publisher":"EN","adopted":"ISO 12100:2010"}},{"entry":"identifier","kind":"example","input":"HD IEC 60364-8-81","expect":{"publisher":"HD","adopted":"IEC 60364-8-81"}},{"entry":"identifier","kind":"example","input":"EN 13250:2000/A1:2005","expect":{"publisher":"EN","number":"13250","year":"2000"}},{"entry":"identifier","kind":"example","input":"EN 60335-1:2012/A1","expect":{"publisher":"EN","number":"60335","part":"1","year":"2012"}},{"entry":"identifier","kind":"example","input":"EN 13254:2000/AC:2003","expect":{"publisher":"EN","number":"13254","year":"2000"}},{"entry":"identifier","kind":"example","input":"EN 61375-2-3:2015/AC:2016-11","expect":{"publisher":"EN","number":"61375","part":"2-3","year":"2015"}},{"entry":"identifier","kind":"example","input":"EN 285:2015+A1","expect":{"publisher":"EN","number":"285","year":"2015"}},{"entry":"identifier","kind":"example","input":"EN 285:2015+A1:2021","expect":{"publisher":"EN","number":"285","year":"2015"}},{"entry":"identifier","kind":"example","input":"EN ISO 10077-1:2006+AC:2009+AC2:2009","expect":{"publisher":"EN","adopted":"ISO 10077-1:2006"}},{"entry":"identifier","kind":"example","input":"EN 60038/A1 FRAG2","expect":{"publisher":"EN","number":"60038","fragment_number":"2"}}],"docs":{},"source":"# PFS-generated grammar — DO NOT EDIT BY HAND.\n# Source: definitions/cen.pfs (pfs:1) sha256:b8f2c00e392dbc03c1fddedad141afa7c930c5430738721b7df0ac69a371d028\n# Compiler: pubid/grammar/pfs 0.1.0\n# Flavor key: cen_pfs (grammar PubidCenPfs)\n# Regenerate: ruby scripts/pfs compile definitions/cen.pfs --as cen_pfs\n\ngrammar PubidCenPfs version \"0.1.0\" edition 2 {\n\n # Grammar fragments: named lexical terms declared under `grammar:`.\n digit = %x30-39\n\n # Fields: one capture rule per declared field; the whole pattern\n # is the capture.\n cen_cenelec_publisher = ((\"CWA\" / \"HD\" / \"ES\" / \"CR\" / \"ENV\" / \"EN\" / \"CEN\" / \"CLC\")) as publisher\n cen_cenelec_copublisher = ((\"CLC\" / \"ETSI\")) as copublisher\n cen_cenelec_copublishers = (*( \"/\" cen_cenelec_copublisher )) as copublishers\n cen_cenelec_stage = ((\"FprEN\" / \"prEN\")) as stage\n cen_cenelec_type = ((\"TR\" / \"TS\")) as type\n cen_cenelec_guide = (\"Guide\") as guide\n cen_cenelec_number = (((1*%x30-39) (*(\" \" (1*%x30-39))))) as number\n cen_cenelec_part = (1*(%x30-39 / \"-\")) as part\n cen_cenelec_version = (\" \" \"V\" (1*%x30-39) \".\" (1*%x30-39) \".\" (1*%x30-39)) as version\n cen_cenelec_year = (4digit) as year\n cen_cenelec_adopted = ((((\"ISO\" / \"IEC\" / \"CISPR\")) *((!(cen_cenelec_supplement) !(\" FRAG\") (%x01-09 / %x0B-10FFFF))))) as adopted\n cen_cenelec_fragment_number = (1*%x30-39) as fragment_number\n\n # Supplement run (compiled from the supplements declaration):\n # each item binds its separator, kind face, ordinal and date\n # columns; the builder folds the run into the declared wrapper\n # classes (the slash run standalone, the plus run consolidated).\n cen_cenelec_supplement_number = (1*digit) as supplement_number\n cen_cenelec_supplements_year = (4digit) as supplements_year\n cen_cenelec_supplements_month = (2digit) as supplements_month\n cen_cenelec_supplement_corrigendum = {\n (\"/\" as supplements_slash / \"+\" as supplements_plus)\n \"AC\" as supplement_kind [cen_cenelec_supplement_number] [\":\" cen_cenelec_supplements_year] [\"-\" cen_cenelec_supplements_month]\n }\n cen_cenelec_supplement_amendment = {\n (\"/\" as supplements_slash / \"+\" as supplements_plus)\n \"A\" as supplement_kind cen_cenelec_supplement_number [\":\" cen_cenelec_supplements_year]\n }\n cen_cenelec_supplement = ( cen_cenelec_supplement_corrigendum / cen_cenelec_supplement_amendment ) as supplement\n cen_cenelec_supplements = (1*cen_cenelec_supplement) as supplements\n\n # Identifier rule: the canonical template first, then the\n # declared alternates (parse-in spellings; they normalize to the\n # canonical render face).\n identifier = {\n ( cen_cenelec_stage \" \" cen_cenelec_number [\"-\" cen_cenelec_part] [cen_cenelec_version] [\":\" cen_cenelec_year] / cen_cenelec_publisher [cen_cenelec_copublishers] \" \" cen_cenelec_guide \" \" cen_cenelec_number [\"-\" cen_cenelec_part] [\":\" cen_cenelec_year] / cen_cenelec_publisher [cen_cenelec_copublishers] \" \" cen_cenelec_adopted / cen_cenelec_publisher [cen_cenelec_copublishers] [\"/\" cen_cenelec_type] \" \" cen_cenelec_number [\"-\" cen_cenelec_part] [cen_cenelec_version] [\":\" cen_cenelec_year] ) [cen_cenelec_supplements [\" FRAG\" cen_cenelec_fragment_number]]\n / cen_cenelec_publisher [cen_cenelec_copublishers] \" \" cen_cenelec_type \" \" cen_cenelec_number [\"-\" cen_cenelec_part] [cen_cenelec_version] [\":\" cen_cenelec_year] [cen_cenelec_supplements [\" FRAG\" cen_cenelec_fragment_number]]\n }\n entry identifier: identifier\n\n # Typed model bindings: every bound capture lands on the\n # consumer model's field of the same name.\n bindings identifier {\n publisher -> publisher (string)\n copublisher -> copublisher (string)\n copublisher -> copublishers[].copublisher (string)\n stage -> stage (string)\n type -> type (string)\n guide -> guide (string)\n number -> number (string)\n part -> part (string)\n version -> version (string)\n year -> year (string)\n adopted -> adopted (string)\n fragment_number -> fragment_number (string)\n supplement -> supplements[].supplement (raw)\n }\n\n # REQUIRED examples from the definition — accepts, rejects, and\n # the capture expectations the compiler replayed at compile time.\n test {\n accept \"EN 1325\"\n accept \"EN 12464-1:2011\"\n accept \"EN 302 326-2 V2.2.1:2026\"\n accept \"prEN 12464-1:2019\"\n accept \"FprEN 50600-2-4\"\n accept \"CEN/TR 12101-5:2005\"\n accept \"CEN/CLC/ETSI/TR 101551:2026\"\n accept \"CLC/TS 50701:2021\"\n accept \"CR 10313:2000\"\n accept \"CWA 14050-21:2000\"\n accept \"ES 59008-6-1:1999\"\n accept \"ENV 1613:1995\"\n accept \"HD 1215-2:1988\"\n accept \"CEN Guide 414:2017\"\n accept \"CEN/CLC Guide 25:2023\"\n accept \"EN ISO 12100:2010\"\n accept \"HD IEC 60364-8-81\"\n accept \"EN 13250:2000/A1:2005\"\n accept \"EN 60335-1:2012/A1\"\n accept \"EN 13254:2000/AC:2003\"\n accept \"EN 61375-2-3:2015/AC:2016-11\"\n accept \"EN 285:2015+A1\"\n accept \"EN 285:2015+A1:2021\"\n accept \"EN ISO 10077-1:2006+AC:2009+AC2:2009\"\n accept \"EN 60038/A1 FRAG2\"\n reject \"nonsense\"\n reject \"ETSI EN 300 175\"\n reject \"CEN/XX 100\"\n reject \"HD 1215-2:198\"\n reject \"EN 300 175 V\"\n reject \"EN 1325 EXTRA\"\n reject \"EN A1\"\n reject \"ISO 12100:2010\"\n reject \"EN 1325:20000\"\n reject \"EN /TR 100\"\n reject \"EN 13250:2000/A1:\"\n reject \"EN 13250:2000/ACX:2003\"\n reject \"EN 285:2015+A1:\"\n reject \"FRAG2\"\n reject \"EN 13250:2000 FRAG2\"\n example \"EN 1325\" { publisher: \"EN\" number: \"1325\" }\n example \"EN 12464-1:2011\" { publisher: \"EN\" number: \"12464\" part: \"1\" year: \"2011\" }\n example \"EN 302 326-2 V2.2.1:2026\" { publisher: \"EN\" number: \"302 326\" part: \"2\" version: \" V2.2.1\" year: \"2026\" }\n example \"prEN 12464-1:2019\" { stage: \"prEN\" number: \"12464\" part: \"1\" year: \"2019\" }\n example \"FprEN 50600-2-4\" { stage: \"FprEN\" number: \"50600\" part: \"2-4\" }\n example \"CEN/TR 12101-5:2005\" { publisher: \"CEN\" type: \"TR\" number: \"12101\" part: \"5\" year: \"2005\" }\n example \"CEN/CLC/ETSI/TR 101551:2026\" { publisher: \"CEN\" copublisher: \"CLC\" type: \"TR\" number: \"101551\" year: \"2026\" }\n example \"CLC/TS 50701:2021\" { publisher: \"CLC\" type: \"TS\" number: \"50701\" year: \"2021\" }\n example \"CR 10313:2000\" { publisher: \"CR\" number: \"10313\" year: \"2000\" }\n example \"CWA 14050-21:2000\" { publisher: \"CWA\" number: \"14050\" part: \"21\" year: \"2000\" }\n example \"ES 59008-6-1:1999\" { publisher: \"ES\" number: \"59008\" part: \"6-1\" year: \"1999\" }\n example \"ENV 1613:1995\" { publisher: \"ENV\" number: \"1613\" year: \"1995\" }\n example \"HD 1215-2:1988\" { publisher: \"HD\" number: \"1215\" part: \"2\" year: \"1988\" }\n example \"CEN Guide 414:2017\" { publisher: \"CEN\" guide: \"Guide\" number: \"414\" year: \"2017\" }\n example \"CEN/CLC Guide 25:2023\" { publisher: \"CEN\" copublisher: \"CLC\" guide: \"Guide\" number: \"25\" year: \"2023\" }\n example \"EN ISO 12100:2010\" { publisher: \"EN\" adopted: \"ISO 12100:2010\" }\n example \"HD IEC 60364-8-81\" { publisher: \"HD\" adopted: \"IEC 60364-8-81\" }\n example \"EN 13250:2000/A1:2005\" { publisher: \"EN\" number: \"13250\" year: \"2000\" }\n example \"EN 60335-1:2012/A1\" { publisher: \"EN\" number: \"60335\" part: \"1\" year: \"2012\" }\n example \"EN 13254:2000/AC:2003\" { publisher: \"EN\" number: \"13254\" year: \"2000\" }\n example \"EN 61375-2-3:2015/AC:2016-11\" { publisher: \"EN\" number: \"61375\" part: \"2-3\" year: \"2015\" }\n example \"EN 285:2015+A1\" { publisher: \"EN\" number: \"285\" year: \"2015\" }\n example \"EN 285:2015+A1:2021\" { publisher: \"EN\" number: \"285\" year: \"2015\" }\n example \"EN ISO 10077-1:2006+AC:2009+AC2:2009\" { publisher: \"EN\" adopted: \"ISO 10077-1:2006\" }\n example \"EN 60038/A1 FRAG2\" { publisher: \"EN\" number: \"60038\" fragment_number: \"2\" }\n }\n}\n","source_hash":"af689f6d48bd5f2966cfe4fe6fee924e8af80fe2075cd1b5438b9e8dea1552f5","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:cd693464a12fefe5a83dd7621f635ca4f4432d520ef093fb7cc6f0f4e1d89142","checksum":"sha256:4eaf33574f00f7500da255feec6b63c0deb9705711fe6025f27d625a9026d4fb"}
|