pubid 2.0.23 → 2.0.25
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/data/parg/calconnect_pfs.json +1 -0
- data/data/parg/cen_pfs.json +1 -0
- data/data/parg/etsi_pfs.json +1 -0
- data/lib/pubid/calconnect_pfs/builder.rb +35 -0
- data/lib/pubid/calconnect_pfs/identifier.rb +84 -0
- data/lib/pubid/calconnect_pfs/identifiers/standard.rb +31 -0
- data/lib/pubid/calconnect_pfs/identifiers.rb +7 -0
- data/lib/pubid/calconnect_pfs/parser.rb +10 -0
- data/lib/pubid/calconnect_pfs/pubid_urn_schema.rb +17 -0
- data/lib/pubid/calconnect_pfs/renderer.rb +10 -0
- data/lib/pubid/calconnect_pfs/urn_generator.rb +30 -0
- data/lib/pubid/calconnect_pfs.rb +60 -0
- data/lib/pubid/cen_pfs/builder.rb +33 -0
- data/lib/pubid/cen_pfs/identifier.rb +64 -0
- data/lib/pubid/cen_pfs/identifiers/european_norm.rb +31 -0
- data/lib/pubid/cen_pfs/identifiers.rb +7 -0
- data/lib/pubid/cen_pfs/parser.rb +10 -0
- data/lib/pubid/cen_pfs/pubid_urn_schema.rb +15 -0
- data/lib/pubid/cen_pfs/renderer.rb +10 -0
- data/lib/pubid/cen_pfs/urn_generator.rb +12 -0
- data/lib/pubid/cen_pfs.rb +71 -0
- data/lib/pubid/doi_pfs/identifier.rb +8 -1
- data/lib/pubid/doi_pfs.rb +3 -11
- data/lib/pubid/etsi_pfs/CLAUDE.md +95 -0
- data/lib/pubid/etsi_pfs/builder.rb +25 -0
- data/lib/pubid/etsi_pfs/identifier.rb +50 -0
- data/lib/pubid/etsi_pfs/identifiers/standard.rb +22 -0
- data/lib/pubid/etsi_pfs/identifiers.rb +7 -0
- data/lib/pubid/etsi_pfs/parser.rb +10 -0
- data/lib/pubid/etsi_pfs/pubid_urn_schema.rb +19 -0
- data/lib/pubid/etsi_pfs/renderer.rb +10 -0
- data/lib/pubid/etsi_pfs/urn_generator.rb +12 -0
- data/lib/pubid/etsi_pfs.rb +59 -0
- data/lib/pubid/itu/CLAUDE.md +25 -14
- data/lib/pubid/itu/builder.rb +7 -5
- data/lib/pubid/itu/identifiers/special_publication.rb +20 -17
- data/lib/pubid/itu/urn_generator.rb +3 -4
- data/lib/pubid/jis/CLAUDE.md +35 -0
- data/lib/pubid/jis/builder.rb +33 -2
- data/lib/pubid/jis/identifier.rb +24 -4
- data/lib/pubid/jis/identifiers/welding_engineering_standard.rb +21 -2
- data/lib/pubid/jis/identifiers/welding_engineering_technical_report.rb +13 -0
- data/lib/pubid/jis/identifiers/welding_engineering_technical_specification.rb +14 -0
- data/lib/pubid/jis/identifiers.rb +5 -0
- data/lib/pubid/jis/parser.rb +30 -0
- data/lib/pubid/jis/pubid_urn_schema.rb +14 -3
- data/lib/pubid/jis/renderer.rb +1 -2
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +13 -0
- metadata +35 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4c2df973dfad39ae259a1f12504977716b523133f7ba6e98f86dc1359274206
|
|
4
|
+
data.tar.gz: c4c7e18a50914f61ca002b3ce53d00b4b7dcdfdcac33168b34e6109f8f6b2890
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1224c069ca1bc1caa4ca1968252a4686dff6a99ac99b167e65546a800f0b1067e88e807dbb87da80db18744bdde4a1c3aee630da35d4610cefa7d36d52a055fc
|
|
7
|
+
data.tar.gz: d9091695721ae3b73953f550b5515b598c7328875fc1c679f549e339d0de2daa517ed0412bcf33fe3c04568cd1522a0635f9033ba79983981cacbc04dbedd1cf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"bindings":null,"version":"0.1.0","grammar":"PubidCalconnectPfs","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"CC"}},{"Str":{"pattern":"/"}},{"Entity":{"atom":8}},{"Entity":{"atom":6}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[4,5]}},{"Repetition":{"atom":3,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"series","atom":7}},{"Sequence":{"atoms":[1,2]}},{"Repetition":{"atom":9,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":24}},{"Entity":{"atom":14}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":13,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Str":{"pattern":"-"}},{"Alternative":{"atoms":[16,17]}},{"Entity":{"atom":14}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[18,20]}},{"Repetition":{"atom":21,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[15,22]}},{"Named":{"name":"number","atom":23}},{"Str":{"pattern":":"}},{"Entity":{"atom":29}},{"Entity":{"atom":14}},{"Repetition":{"atom":27,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"year","atom":28}},{"Str":{"pattern":"-"}},{"Entity":{"atom":34}},{"Entity":{"atom":14}},{"Repetition":{"atom":32,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"month","atom":33}},{"Str":{"pattern":"-"}},{"Entity":{"atom":39}},{"Entity":{"atom":14}},{"Repetition":{"atom":37,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"day","atom":38}},{"Sequence":{"atoms":[30,31,35,36]}},{"Repetition":{"atom":40,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[25,26,41]}},{"Repetition":{"atom":42,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[0,10,11,12,43]}}],"root":44},"bindings":[{"capture":"series","path":"series","type":"string","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null},{"capture":"month","path":"month","type":"string","card":null,"preprocess":null},{"capture":"day","path":"day","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"CC 18011","expect":{}},{"entry":"identifier","kind":"accept","input":"CC 18011:2018","expect":{}},{"entry":"identifier","kind":"accept","input":"CC 11001:2024","expect":{}},{"entry":"identifier","kind":"accept","input":"CC/DIR 10006:2019","expect":{}},{"entry":"identifier","kind":"accept","input":"CC/Adv 0707.1:2007","expect":{}},{"entry":"identifier","kind":"accept","input":"CC/A 0812-1:2008","expect":{}},{"entry":"identifier","kind":"accept","input":"CC/WD 51017:2024-07-23","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"CC","expect":{}},{"entry":"identifier","kind":"reject","input":"CC/WD","expect":{}},{"entry":"identifier","kind":"reject","input":"CC 18011:","expect":{}},{"entry":"identifier","kind":"reject","input":"CC 18011:2024-","expect":{}},{"entry":"identifier","kind":"example","input":"CC 18011","expect":{"number":"18011"}},{"entry":"identifier","kind":"example","input":"CC 18011:2018","expect":{"number":"18011","year":"2018"}},{"entry":"identifier","kind":"example","input":"CC 11001:2024","expect":{"number":"11001","year":"2024"}},{"entry":"identifier","kind":"example","input":"CC/DIR 10006:2019","expect":{"series":"DIR","number":"10006","year":"2019"}},{"entry":"identifier","kind":"example","input":"CC/Adv 0707.1:2007","expect":{"series":"Adv","number":"0707.1","year":"2007"}},{"entry":"identifier","kind":"example","input":"CC/A 0812-1:2008","expect":{"series":"A","number":"0812-1","year":"2008"}},{"entry":"identifier","kind":"example","input":"CC/WD 51017:2024-07-23","expect":{"series":"WD","number":"51017","year":"2024","month":"07","day":"23"}}],"docs":{},"source":"# PFS-generated grammar — DO NOT EDIT BY HAND.\n# Source: definitions/calconnect.pfs (pfs:1) sha256:2e864f0185a1a2f18a392f2f401ad3c9d65d1f32a9ec3f3f04f7dfca9b2226c4\n# Compiler: pubid/grammar/pfs 0.1.0\n# Flavor key: calconnect_pfs (grammar PubidCalconnectPfs)\n# Regenerate: ruby scripts/pfs compile definitions/calconnect.pfs --as calconnect_pfs\n\ngrammar PubidCalconnectPfs version \"0.1.0\" edition 2 {\n\n # Grammar fragments: named lexical terms declared under `grammar:`.\n digit = %x30-39\n letter = %x41-5A / %x61-7A\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 calconnect_series = (1*letter) as series\n calconnect_number = (1*digit [(\".\" / \"-\") 1*digit]) as number\n calconnect_year = (1*digit) as year\n calconnect_month = (1*digit) as month\n calconnect_day = (1*digit) as day\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 = \"CC\" [\"/\" calconnect_series] \" \" calconnect_number [\":\" calconnect_year [\"-\" calconnect_month \"-\" calconnect_day]]\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 series -> series (string)\n number -> number (string)\n year -> year (string)\n month -> month (string)\n day -> day (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 \"CC 18011\"\n accept \"CC 18011:2018\"\n accept \"CC 11001:2024\"\n accept \"CC/DIR 10006:2019\"\n accept \"CC/Adv 0707.1:2007\"\n accept \"CC/A 0812-1:2008\"\n accept \"CC/WD 51017:2024-07-23\"\n reject \"nonsense\"\n reject \"CC\"\n reject \"CC/WD\"\n reject \"CC 18011:\"\n reject \"CC 18011:2024-\"\n example \"CC 18011\" { number: \"18011\" }\n example \"CC 18011:2018\" { number: \"18011\" year: \"2018\" }\n example \"CC 11001:2024\" { number: \"11001\" year: \"2024\" }\n example \"CC/DIR 10006:2019\" { series: \"DIR\" number: \"10006\" year: \"2019\" }\n example \"CC/Adv 0707.1:2007\" { series: \"Adv\" number: \"0707.1\" year: \"2007\" }\n example \"CC/A 0812-1:2008\" { series: \"A\" number: \"0812-1\" year: \"2008\" }\n example \"CC/WD 51017:2024-07-23\" { series: \"WD\" number: \"51017\" year: \"2024\" month: \"07\" day: \"23\" }\n }\n}\n","source_hash":"35a33d659c86202186a5e6beb8c7df58af7bd6667dd55b6cb3cecb8855713b85","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:9fbceffd1828c207a9ec854699d0801fad9e52521a972e39dc1838fb80440dc8","checksum":"sha256:6557fd4360e2deab7ca4062b72e5cd6e60b6e3cd0252cb5b1e30d66f3905f467"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"bindings":null,"version":"0.1.0","grammar":"PubidEtsiPfs","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"ETSI "}},{"Entity":{"atom":18}},{"Str":{"pattern":"I-ETS"}},{"Str":{"pattern":"TCRTR"}},{"Str":{"pattern":"GTS"}},{"Str":{"pattern":"ETR"}},{"Str":{"pattern":"ETS"}},{"Str":{"pattern":"TBR"}},{"Str":{"pattern":"NET"}},{"Str":{"pattern":"EN"}},{"Str":{"pattern":"ES"}},{"Str":{"pattern":"EG"}},{"Str":{"pattern":"TS"}},{"Str":{"pattern":"GR"}},{"Str":{"pattern":"GS"}},{"Str":{"pattern":"SR"}},{"Str":{"pattern":"TR"}},{"Alternative":{"atoms":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"Named":{"name":"type","atom":17}},{"Str":{"pattern":" "}},{"Entity":{"atom":54}},{"Str":{"pattern":"GSM"}},{"Str":{"pattern":" "}},{"Entity":{"atom":24}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":23,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":24}},{"Repetition":{"atom":27,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[21,22,25,26,28]}},{"Entity":{"atom":24}},{"Repetition":{"atom":30,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":24}},{"Repetition":{"atom":33,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[31,32,34]}},{"Entity":{"atom":40}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[37,38,39]}},{"Repetition":{"atom":36,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Entity":{"atom":40}},{"Repetition":{"atom":43,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[42,44]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":24}},{"Repetition":{"atom":48,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[41,46,47,49]}},{"Entity":{"atom":24}},{"Repetition":{"atom":51,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[29,35,50,52]}},{"Named":{"name":"number","atom":53}},{"Sequence":{"atoms":[0,1,19,20]}},{"Str":{"pattern":"ETSI "}},{"Entity":{"atom":18}},{"Str":{"pattern":" "}},{"Entity":{"atom":54}},{"Str":{"pattern":" "}},{"Entity":{"atom":64}},{"Entity":{"atom":24}},{"Repetition":{"atom":62,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"minor","atom":63}},{"Sequence":{"atoms":[60,61]}},{"Repetition":{"atom":65,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":73}},{"Str":{"pattern":"-"}},{"Entity":{"atom":40}},{"Repetition":{"atom":69,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[68,70]}},{"Repetition":{"atom":71,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"parts","atom":72}},{"Repetition":{"atom":67,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":83}},{"Str":{"pattern":"/A"}},{"Str":{"pattern":"/C"}},{"Alternative":{"atoms":[76,77]}},{"Entity":{"atom":24}},{"Repetition":{"atom":79,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[78,80]}},{"Repetition":{"atom":81,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"supplements","atom":82}},{"Repetition":{"atom":75,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" V"}},{"Entity":{"atom":92}},{"Entity":{"atom":90}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[.]"}},{"Alternative":{"atoms":[88,89]}},{"Repetition":{"atom":87,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"version","atom":91}},{"Sequence":{"atoms":[85,86]}},{"Str":{"pattern":" ed."}},{"Entity":{"atom":98}},{"Entity":{"atom":24}},{"Repetition":{"atom":96,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"edition","atom":97}},{"Sequence":{"atoms":[94,95]}},{"Alternative":{"atoms":[93,99]}},{"Repetition":{"atom":100,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" ("}},{"Entity":{"atom":106}},{"Entity":{"atom":24}},{"Repetition":{"atom":104,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"year","atom":105}},{"Str":{"pattern":"-"}},{"Entity":{"atom":111}},{"Entity":{"atom":24}},{"Repetition":{"atom":109,"min":2,"max":2,"tag":"Repetition"}},{"Named":{"name":"month","atom":110}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[102,103,107,108,112]}},{"Repetition":{"atom":113,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[56,57,58,59,66,74,84,101,114]}},{"Alternative":{"atoms":[55,115]}}],"root":116},"bindings":[{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"minor","path":"minor","type":"string","card":null,"preprocess":null},{"capture":"parts","path":"parts","type":"string","card":null,"preprocess":null},{"capture":"supplements","path":"supplements","type":"string","card":null,"preprocess":null},{"capture":"version","path":"version","type":"string","card":null,"preprocess":null},{"capture":"edition","path":"edition","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null},{"capture":"month","path":"month","type":"string","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":"ETSI EG 200 053 V1.5.1 (2004-06)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI EN 300 175","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI EN 300 175-2","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI EN 300 019-1-0 V2.1.2 (2003-09)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI TS 103 702","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI EG 201 880 V1.2.1","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI GTS GSM 02.01 V5.5.0 (1999-08)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI GR NFV-EVE 008 V3.1.1 (2017-12)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI I-ETS 300 003 ed.1 (1991-08)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI ETR 108/A1 ed.1 (1995-08)","expect":{}},{"entry":"identifier","kind":"accept","input":"ETSI ETS 300 092-1/A1/C1 ed.1 (1994-04)","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI XX 100","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN 300 175 V","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN 300 175 V1.2.x","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN 300 175 (","expect":{}},{"entry":"identifier","kind":"reject","input":"ETSI EN 300 175 (2004-6)","expect":{}},{"entry":"identifier","kind":"example","input":"ETSI EG 200 053 V1.5.1 (2004-06)","expect":{"type":"EG","number":"200 053","version":"1.5.1","year":"2004","month":"06"}},{"entry":"identifier","kind":"example","input":"ETSI EN 300 175","expect":{"type":"EN","number":"300 175"}},{"entry":"identifier","kind":"example","input":"ETSI EN 300 175-2","expect":{"type":"EN","number":"300 175","parts":"-2"}},{"entry":"identifier","kind":"example","input":"ETSI EN 300 019-1-0 V2.1.2 (2003-09)","expect":{"type":"EN","number":"300 019","parts":"-1-0","version":"2.1.2","year":"2003","month":"09"}},{"entry":"identifier","kind":"example","input":"ETSI TS 103 702","expect":{"type":"TS","number":"103 702"}},{"entry":"identifier","kind":"example","input":"ETSI EG 201 880 V1.2.1","expect":{"type":"EG","number":"201 880","version":"1.2.1"}},{"entry":"identifier","kind":"example","input":"ETSI GTS GSM 02.01 V5.5.0 (1999-08)","expect":{"type":"GTS","number":"GSM 02.01","version":"5.5.0","year":"1999","month":"08"}},{"entry":"identifier","kind":"example","input":"ETSI GR NFV-EVE 008 V3.1.1 (2017-12)","expect":{"type":"GR","number":"NFV-EVE 008","version":"3.1.1","year":"2017","month":"12"}},{"entry":"identifier","kind":"example","input":"ETSI I-ETS 300 003 ed.1 (1991-08)","expect":{"type":"I-ETS","number":"300 003","edition":"1","year":"1991","month":"08"}},{"entry":"identifier","kind":"example","input":"ETSI ETR 108/A1 ed.1 (1995-08)","expect":{"type":"ETR","number":"108","supplements":"/A1","edition":"1","year":"1995","month":"08"}},{"entry":"identifier","kind":"example","input":"ETSI ETS 300 092-1/A1/C1 ed.1 (1994-04)","expect":{"type":"ETS","number":"300 092","parts":"-1","supplements":"/A1/C1","edition":"1","year":"1994","month":"04"}}],"docs":{},"source":"# PFS-generated grammar — DO NOT EDIT BY HAND.\n# Source: definitions/etsi.pfs (pfs:1) sha256:9343088bf087b55ea790057e6be0bbebe2272407ee81f035b52e5f9a4d5c7b76\n# Compiler: pubid/grammar/pfs 0.1.0\n# Flavor key: etsi_pfs (grammar PubidEtsiPfs)\n# Regenerate: ruby scripts/pfs compile definitions/etsi.pfs --as etsi_pfs\n\ngrammar PubidEtsiPfs version \"0.1.0\" edition 2 {\n\n # Grammar fragments: named lexical terms declared under `grammar:`.\n digit = %x30-39\n alnum_char = %x41-5A / %x61-7A / %x30-39\n version_char = %x30-39 / %x2E\n\n # Fields: one capture rule per declared field; the whole pattern\n # is the capture.\n etsi_type = (\"I-ETS\" / \"TCRTR\" / \"GTS\" / \"ETR\" / \"ETS\" / \"TBR\" / \"NET\" / \"EN\" / \"ES\" / \"EG\" / \"TS\" / \"GR\" / \"GS\" / \"SR\" / \"TR\") as type\n etsi_number = ((\"GSM\" \" \" 1*digit \".\" 1*digit) / (1*digit \".\" 1*digit) / (1*alnum_char [(\"-\" 1*alnum_char)] \" \" 1*digit) / (1*digit)) as number\n etsi_minor = (1*digit) as minor\n etsi_parts = (1*(\"-\" 1*alnum_char)) as parts\n etsi_supplements = (1*((\"/A\" / \"/C\") 1*digit)) as supplements\n etsi_version = (1*version_char) as version\n etsi_edition = (1*digit) as edition\n etsi_year = (4digit) as year\n etsi_month = (2digit) as month\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 \"ETSI \" etsi_type \" \" etsi_number\n / \"ETSI \" etsi_type \" \" etsi_number [\" \" etsi_minor] [etsi_parts] [etsi_supplements] [( \" V\" etsi_version / \" ed.\" etsi_edition )] [\" (\" etsi_year \"-\" etsi_month \")\"]\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 type -> type (string)\n number -> number (string)\n minor -> minor (string)\n parts -> parts (string)\n supplements -> supplements (string)\n version -> version (string)\n edition -> edition (string)\n year -> year (string)\n month -> month (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 \"ETSI EG 200 053 V1.5.1 (2004-06)\"\n accept \"ETSI EN 300 175\"\n accept \"ETSI EN 300 175-2\"\n accept \"ETSI EN 300 019-1-0 V2.1.2 (2003-09)\"\n accept \"ETSI TS 103 702\"\n accept \"ETSI EG 201 880 V1.2.1\"\n accept \"ETSI GTS GSM 02.01 V5.5.0 (1999-08)\"\n accept \"ETSI GR NFV-EVE 008 V3.1.1 (2017-12)\"\n accept \"ETSI I-ETS 300 003 ed.1 (1991-08)\"\n accept \"ETSI ETR 108/A1 ed.1 (1995-08)\"\n accept \"ETSI ETS 300 092-1/A1/C1 ed.1 (1994-04)\"\n reject \"nonsense\"\n reject \"ETSI\"\n reject \"ETSI EN\"\n reject \"ETSI XX 100\"\n reject \"ETSI EN 300 175 V\"\n reject \"ETSI EN 300 175 V1.2.x\"\n reject \"ETSI EN 300 175 (\"\n reject \"ETSI EN 300 175 (2004-6)\"\n example \"ETSI EG 200 053 V1.5.1 (2004-06)\" { type: \"EG\" number: \"200 053\" version: \"1.5.1\" year: \"2004\" month: \"06\" }\n example \"ETSI EN 300 175\" { type: \"EN\" number: \"300 175\" }\n example \"ETSI EN 300 175-2\" { type: \"EN\" number: \"300 175\" parts: \"-2\" }\n example \"ETSI EN 300 019-1-0 V2.1.2 (2003-09)\" { type: \"EN\" number: \"300 019\" parts: \"-1-0\" version: \"2.1.2\" year: \"2003\" month: \"09\" }\n example \"ETSI TS 103 702\" { type: \"TS\" number: \"103 702\" }\n example \"ETSI EG 201 880 V1.2.1\" { type: \"EG\" number: \"201 880\" version: \"1.2.1\" }\n example \"ETSI GTS GSM 02.01 V5.5.0 (1999-08)\" { type: \"GTS\" number: \"GSM 02.01\" version: \"5.5.0\" year: \"1999\" month: \"08\" }\n example \"ETSI GR NFV-EVE 008 V3.1.1 (2017-12)\" { type: \"GR\" number: \"NFV-EVE 008\" version: \"3.1.1\" year: \"2017\" month: \"12\" }\n example \"ETSI I-ETS 300 003 ed.1 (1991-08)\" { type: \"I-ETS\" number: \"300 003\" edition: \"1\" year: \"1991\" month: \"08\" }\n example \"ETSI ETR 108/A1 ed.1 (1995-08)\" { type: \"ETR\" number: \"108\" supplements: \"/A1\" edition: \"1\" year: \"1995\" month: \"08\" }\n example \"ETSI ETS 300 092-1/A1/C1 ed.1 (1994-04)\" { type: \"ETS\" number: \"300 092\" parts: \"-1\" supplements: \"/A1/C1\" edition: \"1\" year: \"1994\" month: \"04\" }\n }\n}\n","source_hash":"f5e47bb403d9bff4737d8a200f08c71f8029df12f96c56e9774b722908bfa853","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:204a90b72aa2ea5fc2249622bd61c052b4ba5d1ebf732a2c2b57669c8de24393","checksum":"sha256:d861e040f36868dcef43c6547c5791979d4832d1ec1ca6bc310bdad82ea0e930"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
class Builder
|
|
4
|
+
def self.build(parsed_data)
|
|
5
|
+
new.build(parsed_data)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def build(data)
|
|
9
|
+
Identifiers::Standard.new(
|
|
10
|
+
series: data[:series],
|
|
11
|
+
number: data[:number],
|
|
12
|
+
date: build_date(data),
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# The publication date as the shared Components::Date, or
|
|
19
|
+
# nil when the reference omits the calendar fields (a
|
|
20
|
+
# partial reference matches by excluding the date).
|
|
21
|
+
def build_date(data)
|
|
22
|
+
values = [data[:year], data[:month], data[:day]]
|
|
23
|
+
return nil if values.compact.empty?
|
|
24
|
+
|
|
25
|
+
::Pubid::Components::Date.new(
|
|
26
|
+
year: data[:year]&.to_s,
|
|
27
|
+
month: data[:month]&.to_s,
|
|
28
|
+
day: data[:day]&.to_s,
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
Pubid::CalconnectPfs::Builder.prepend(Pubid::Builder::AllPartsWrap)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
class Identifier < ::Pubid::Identifier
|
|
4
|
+
attribute :series, :string
|
|
5
|
+
attribute :number, :string
|
|
6
|
+
attribute :date, ::Pubid::Components::Date
|
|
7
|
+
|
|
8
|
+
CC_TYPE_MAP = {
|
|
9
|
+
"pubid:calconnect:standard" => "Pubid::CalconnectPfs::Identifiers::Standard",
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
key_value do
|
|
13
|
+
map "_type", to: :_type, polymorphic_map: CC_TYPE_MAP
|
|
14
|
+
map "series", to: :series
|
|
15
|
+
map "number", to: :number
|
|
16
|
+
map "year", with: { to: :year_to_kv, from: :year_from_kv }
|
|
17
|
+
map "month", with: { to: :month_to_kv, from: :month_from_kv }
|
|
18
|
+
map "day", with: { to: :day_to_kv, from: :day_from_kv }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# --- date serialized flat (the shared flat-scalar shape) ---
|
|
22
|
+
def year_to_kv(model, doc)
|
|
23
|
+
emit_date_part(doc, "year", model.date&.year)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def year_from_kv(model, value)
|
|
27
|
+
date_for(model).year = value.to_s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# --- date serialized flat (the shared flat-scalar shape) ---
|
|
31
|
+
def month_to_kv(model, doc)
|
|
32
|
+
emit_date_part(doc, "month", model.date&.month)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def month_from_kv(model, value)
|
|
36
|
+
date_for(model).month = value.to_s
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# --- date serialized flat (the shared flat-scalar shape) ---
|
|
40
|
+
def day_to_kv(model, doc)
|
|
41
|
+
emit_date_part(doc, "day", model.date&.day)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def day_from_kv(model, value)
|
|
45
|
+
date_for(model).day = value.to_s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def emit_date_part(doc, key, val)
|
|
49
|
+
return if val.nil? || val.to_s.empty?
|
|
50
|
+
|
|
51
|
+
doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, val.to_s))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def date_for(model)
|
|
55
|
+
model.date ||= ::Pubid::Components::Date.new
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
PUBLISHER = "CC"
|
|
59
|
+
|
|
60
|
+
# The scheme's declared publisher token: the internal-form
|
|
61
|
+
# cut (to_s(with_publisher: false)) strips it from the
|
|
62
|
+
# rendered face.
|
|
63
|
+
def publisher_prefixes
|
|
64
|
+
[PUBLISHER]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.parse(identifier)
|
|
68
|
+
unless identifier.is_a?(String)
|
|
69
|
+
raise Pubid::Errors::InvalidInputError,
|
|
70
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
74
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
identifier = ::Pubid.utf8_input(identifier)
|
|
78
|
+
|
|
79
|
+
parsed = Pubid::Parg::Model.bound(:calconnect_pfs, identifier)
|
|
80
|
+
Builder.build(parsed)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# Concrete CalConnect Standard identifier type (PFS type `standard`).
|
|
5
|
+
class Standard < Identifier
|
|
6
|
+
TYPED_STAGES = [
|
|
7
|
+
Pubid::Components::TypedStage.new(
|
|
8
|
+
code: :pubcc,
|
|
9
|
+
stage_code: :published,
|
|
10
|
+
type_code: :cc,
|
|
11
|
+
abbr: ["CC"],
|
|
12
|
+
name: "CalConnect Standard",
|
|
13
|
+
harmonized_stages: [],
|
|
14
|
+
),
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
def self.type
|
|
18
|
+
{ key: :cc, web: :standard, title: "CalConnect Standard", short: "CC" }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The scheme-canonical wire tag declared in the definition:
|
|
22
|
+
# to_hash stays byte-identical with the scheme's coded
|
|
23
|
+
# flavor, and this flavor's own from_hash routes the tag
|
|
24
|
+
# to this class.
|
|
25
|
+
def self.polymorphic_name
|
|
26
|
+
"pubid:calconnect:standard"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
# PFS-generated parser shell. Parsing runs through the baked
|
|
4
|
+
# PARG artifact (data/parg/calconnect_pfs.json) via Pubid::Parg::Model.bound;
|
|
5
|
+
# the grammar source lives in pubid-grammar
|
|
6
|
+
# (grammars/calconnect_pfs.parg, compiled from definitions/calconnect.pfs).
|
|
7
|
+
class Parser
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
# The pubid-scheme URN schema, registered under the compiled
|
|
4
|
+
# flavor key. The definition's declared namespace
|
|
5
|
+
# ("calconnect") is the scheme's canonical
|
|
6
|
+
# namespace; identifiers carry the scheme's wire tag, so their
|
|
7
|
+
# pubid URNs encode through the scheme's own schema.
|
|
8
|
+
PubidUrnSchema = Pubid::PubidUrn.define("calconnect_pfs") do
|
|
9
|
+
atom "series", "series"
|
|
10
|
+
atom "year", "year"
|
|
11
|
+
atom "month", "month"
|
|
12
|
+
atom "day", "day"
|
|
13
|
+
type "pubid:calconnect:identifier", "id", core: []
|
|
14
|
+
type "pubid:calconnect:standard", "std", core: ["number"]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
# Human renderer, generated from the canonical template.
|
|
4
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
5
|
+
def render(**_opts)
|
|
6
|
+
"CC#{"/#{@id.series}" if @id.series} #{@id.number}#{":#{@id.date.year}#{"-#{@id.date.month}-#{@id.date.day}" if @id.date&.month && @id.date&.day}" if @id.date&.year}"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CalconnectPfs
|
|
3
|
+
# The official URN generator: the scheme's declared namespace
|
|
4
|
+
# ("calconnect") and the ordered segments the
|
|
5
|
+
# definition's urn.official declares — an absent field leaves no
|
|
6
|
+
# segment, a date group joins its fields with "-".
|
|
7
|
+
class UrnGenerator < ::Pubid::UrnGenerator::Base
|
|
8
|
+
def urn_namespace
|
|
9
|
+
"calconnect"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def generate
|
|
13
|
+
parts = ["urn", urn_namespace]
|
|
14
|
+
parts.concat(official_segments)
|
|
15
|
+
parts.join(":")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def official_segments
|
|
21
|
+
segments = []
|
|
22
|
+
segments << @identifier.series if @identifier.series
|
|
23
|
+
segments << @identifier.number if @identifier.number
|
|
24
|
+
date = [@identifier.date&.year, @identifier.date&.month, @identifier.date&.day].compact
|
|
25
|
+
segments << date.join("-") unless date.empty?
|
|
26
|
+
segments
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# PFS-generated flavor — DO NOT EDIT BY HAND.
|
|
4
|
+
# Source: definitions/calconnect.pfs (pfs:1) sha256:2e864f0185a1a2f18a392f2f401ad3c9d65d1f32a9ec3f3f04f7dfca9b2226c4
|
|
5
|
+
# Compiler: pubid/grammar/pfs 0.1.0 (baked with parsanol 1.3.126)
|
|
6
|
+
# Regenerate: ruby scripts/pfs compile definitions/calconnect.pfs --as calconnect_pfs --ruby-out <dir>
|
|
7
|
+
|
|
8
|
+
require "pubid"
|
|
9
|
+
|
|
10
|
+
module Pubid
|
|
11
|
+
# CalConnect Standards flavor, compiled from its PFS definition
|
|
12
|
+
# (pubid/pubid#706). A compiled flavor is a peer of the coded
|
|
13
|
+
# flavors: same registry, same input guards, same error
|
|
14
|
+
# namespace, same URN contracts.
|
|
15
|
+
module CalconnectPfs
|
|
16
|
+
extend Pubid::PrefixesSupport
|
|
17
|
+
|
|
18
|
+
PREFIXES = ["CC"].freeze
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
autoload :Builder, "#{__dir__}/calconnect_pfs/builder"
|
|
22
|
+
autoload :Identifier, "#{__dir__}/calconnect_pfs/identifier"
|
|
23
|
+
autoload :Identifiers, "#{__dir__}/calconnect_pfs/identifiers"
|
|
24
|
+
autoload :Parser, "#{__dir__}/calconnect_pfs/parser"
|
|
25
|
+
autoload :Renderer, "#{__dir__}/calconnect_pfs/renderer"
|
|
26
|
+
autoload :PubidUrnSchema, "#{__dir__}/calconnect_pfs/pubid_urn_schema"
|
|
27
|
+
autoload :UrnGenerator, "#{__dir__}/calconnect_pfs/urn_generator"
|
|
28
|
+
|
|
29
|
+
def self.parse(identifier)
|
|
30
|
+
Identifier.parse(identifier)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
34
|
+
Identifier.format_registry.register(:human, renderer: CalconnectPfs::Renderer)
|
|
35
|
+
|
|
36
|
+
def self.identifier_types
|
|
37
|
+
@identifier_types ||= Identifiers.constants
|
|
38
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
39
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
40
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.all_typed_stages
|
|
44
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
45
|
+
klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.locate_type(code)
|
|
50
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.locate_stage(abbr)
|
|
54
|
+
abbr_str = abbr.to_s.upcase
|
|
55
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
Pubid::Registry.register(:calconnect_pfs, Pubid::CalconnectPfs)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
class Builder
|
|
4
|
+
def self.build(parsed_data)
|
|
5
|
+
new.build(parsed_data)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def build(data)
|
|
9
|
+
Identifiers::EuropeanNorm.new(
|
|
10
|
+
number: data[:number],
|
|
11
|
+
part: data[:part],
|
|
12
|
+
date: build_date(data),
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# The publication date as the shared Components::Date, or
|
|
19
|
+
# nil when the reference omits the calendar fields (a
|
|
20
|
+
# partial reference matches by excluding the date).
|
|
21
|
+
def build_date(data)
|
|
22
|
+
values = [data[:year]]
|
|
23
|
+
return nil if values.compact.empty?
|
|
24
|
+
|
|
25
|
+
::Pubid::Components::Date.new(
|
|
26
|
+
year: data[:year]&.to_s,
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Pubid::CenPfs::Builder.prepend(Pubid::Builder::AllPartsWrap)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
class Identifier < ::Pubid::Identifier
|
|
4
|
+
attribute :number, :string
|
|
5
|
+
attribute :part, :string
|
|
6
|
+
attribute :date, ::Pubid::Components::Date
|
|
7
|
+
|
|
8
|
+
EN_TYPE_MAP = {
|
|
9
|
+
"pubid:cencenelec:european-norm" => "Pubid::CenPfs::Identifiers::EuropeanNorm",
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
key_value do
|
|
13
|
+
map "_type", to: :_type, polymorphic_map: EN_TYPE_MAP
|
|
14
|
+
map "number", to: :number
|
|
15
|
+
map "part", to: :part
|
|
16
|
+
map "year", with: { to: :year_to_kv, from: :year_from_kv }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# --- date serialized flat (the shared flat-scalar shape) ---
|
|
20
|
+
def year_to_kv(model, doc)
|
|
21
|
+
emit_date_part(doc, "year", model.date&.year)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def year_from_kv(model, value)
|
|
25
|
+
date_for(model).year = value.to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def emit_date_part(doc, key, val)
|
|
29
|
+
return if val.nil? || val.to_s.empty?
|
|
30
|
+
|
|
31
|
+
doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, val.to_s))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def date_for(model)
|
|
35
|
+
model.date ||= ::Pubid::Components::Date.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
PUBLISHER = "CEN"
|
|
39
|
+
|
|
40
|
+
# The scheme's declared publisher token: the internal-form
|
|
41
|
+
# cut (to_s(with_publisher: false)) strips it from the
|
|
42
|
+
# rendered face.
|
|
43
|
+
def publisher_prefixes
|
|
44
|
+
[PUBLISHER]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.parse(identifier)
|
|
48
|
+
unless identifier.is_a?(String)
|
|
49
|
+
raise Pubid::Errors::InvalidInputError,
|
|
50
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
54
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
identifier = ::Pubid.utf8_input(identifier)
|
|
58
|
+
|
|
59
|
+
parsed = Pubid::Parg::Model.bound(:cen_pfs, identifier)
|
|
60
|
+
Builder.build(parsed)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# Concrete European Norm identifier type (PFS type `european_norm`).
|
|
5
|
+
class EuropeanNorm < Identifier
|
|
6
|
+
TYPED_STAGES = [
|
|
7
|
+
Pubid::Components::TypedStage.new(
|
|
8
|
+
code: :puben,
|
|
9
|
+
stage_code: :published,
|
|
10
|
+
type_code: :en,
|
|
11
|
+
abbr: ["EN"],
|
|
12
|
+
name: "European Norm",
|
|
13
|
+
harmonized_stages: [],
|
|
14
|
+
),
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
def self.type
|
|
18
|
+
{ key: :en, web: :"european-norm", title: "European Norm", short: "EN" }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The scheme-canonical wire tag declared in the definition:
|
|
22
|
+
# to_hash stays byte-identical with the scheme's coded
|
|
23
|
+
# flavor, and this flavor's own from_hash routes the tag
|
|
24
|
+
# to this class.
|
|
25
|
+
def self.polymorphic_name
|
|
26
|
+
"pubid:cencenelec:european-norm"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
# PFS-generated parser shell. Parsing runs through the baked
|
|
4
|
+
# PARG artifact (data/parg/cen_pfs.json) via Pubid::Parg::Model.bound;
|
|
5
|
+
# the grammar source lives in pubid-grammar
|
|
6
|
+
# (grammars/cen_pfs.parg, compiled from definitions/cen.pfs).
|
|
7
|
+
class Parser
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
# The pubid-scheme URN schema, registered under the compiled
|
|
4
|
+
# flavor key. The definition's declared namespace
|
|
5
|
+
# ("cen") is the scheme's canonical
|
|
6
|
+
# namespace; identifiers carry the scheme's wire tag, so their
|
|
7
|
+
# pubid URNs encode through the scheme's own schema.
|
|
8
|
+
PubidUrnSchema = Pubid::PubidUrn.define("cen_pfs") do
|
|
9
|
+
atom "part", "part"
|
|
10
|
+
atom "year", "year"
|
|
11
|
+
type "pubid:cencenelec:identifier", "id", core: []
|
|
12
|
+
type "pubid:cencenelec:european-norm", "en", core: ["number"]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
# Human renderer, generated from the canonical template.
|
|
4
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
5
|
+
def render(**_opts)
|
|
6
|
+
"EN #{@id.number}#{"-#{@id.part}" if @id.part}#{":#{@id.date.year}" if @id.date&.year}"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module CenPfs
|
|
3
|
+
# The official URN generator, pinned to the scheme's declared
|
|
4
|
+
# namespace ("cen") so to_urn stays
|
|
5
|
+
# scheme-canonical under the compiled flavor key.
|
|
6
|
+
class UrnGenerator < ::Pubid::UrnGenerator::Base
|
|
7
|
+
def urn_namespace
|
|
8
|
+
"cen"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|