pubid 2.0.7 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +2 -1
  3. data/data/parg/sae.json +1 -1
  4. data/lib/pubid/api/pubid_urn_schema.rb +31 -0
  5. data/lib/pubid/api.rb +1 -0
  6. data/lib/pubid/ashrae/pubid_urn_schema.rb +37 -0
  7. data/lib/pubid/ashrae.rb +1 -0
  8. data/lib/pubid/asme/pubid_urn_schema.rb +34 -0
  9. data/lib/pubid/asme.rb +1 -0
  10. data/lib/pubid/cen_cenelec/CLAUDE.md +17 -0
  11. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +4 -1
  12. data/lib/pubid/cen_cenelec/identifiers.rb +1 -1
  13. data/lib/pubid/cen_cenelec/pubid_urn_schema.rb +35 -0
  14. data/lib/pubid/cen_cenelec.rb +1 -0
  15. data/lib/pubid/etsi/CLAUDE.md +9 -0
  16. data/lib/pubid/etsi/pubid_urn_schema.rb +36 -0
  17. data/lib/pubid/etsi.rb +1 -0
  18. data/lib/pubid/gost/CLAUDE.md +12 -0
  19. data/lib/pubid/gost/pubid_urn_schema.rb +34 -0
  20. data/lib/pubid/gost.rb +1 -0
  21. data/lib/pubid/identifier.rb +7 -1
  22. data/lib/pubid/iec/pubid_urn_schema.rb +11 -4
  23. data/lib/pubid/jcgm/pubid_urn_schema.rb +29 -0
  24. data/lib/pubid/jcgm.rb +1 -0
  25. data/lib/pubid/oiml/pubid_urn_schema.rb +46 -0
  26. data/lib/pubid/oiml.rb +1 -0
  27. data/lib/pubid/plateau/CLAUDE.md +13 -0
  28. data/lib/pubid/plateau/pubid_urn_schema.rb +25 -0
  29. data/lib/pubid/plateau.rb +1 -0
  30. data/lib/pubid/pubid_urn/decoder.rb +8 -2
  31. data/lib/pubid/pubid_urn/encoder.rb +14 -2
  32. data/lib/pubid/pubid_urn/schema.rb +18 -4
  33. data/lib/pubid/pubid_urn.rb +40 -0
  34. data/lib/pubid/sae/CLAUDE.md +78 -0
  35. data/lib/pubid/sae/builder.rb +89 -11
  36. data/lib/pubid/sae/components/date.rb +12 -3
  37. data/lib/pubid/sae/components/type.rb +54 -2
  38. data/lib/pubid/sae/identifiers/base.rb +54 -1
  39. data/lib/pubid/sae/renderer.rb +17 -20
  40. data/lib/pubid/sae/urn_generator.rb +6 -1
  41. data/lib/pubid/sae/urn_parser.rb +8 -3
  42. data/lib/pubid/version.rb +1 -1
  43. data/lib/pubid.rb +20 -0
  44. metadata +13 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5558c63d94ec7b763262f3a00bbd5b996d51faee1f99b79636578d3d3938d89
4
- data.tar.gz: 98b831396d0d862a6b4693663e8b225126bac0a2c6a0aaf1776be3fbc6732c64
3
+ metadata.gz: 014b932f4ce8d6a4da07b23e611467dc460afc19aa73f9be3af191cab1007a02
4
+ data.tar.gz: 284a4f85f2adcdabe735a20c5f427bf15a242c8b660c66d2ebde54f1938a2665
5
5
  SHA512:
6
- metadata.gz: dbed0fc963d50e98df37f687090df28345a038390fe110fd44687b258de13e11c22b76c008aa6a2e0be7c2a481d4e2d52e95fe49051b245da1b6afc89159a05c
7
- data.tar.gz: 1520252a6c0154937f2175aeecc80086349bb0bc8c0a76b6d32d73b55efdafaef14809edd2dc8a0bf9a147ea03d665e32478fbc1c6eb3a77843ae4fe030f7d96
6
+ metadata.gz: bdecc7d28c6b0bc0c2550d9a643e48324f5f40c8feb3faf3e931c6b2928f573f1c07e01db60d30c016fab9e60bca035e4cf9f4b064c9a47a973b1aa5e500cea3
7
+ data.tar.gz: 112284d94ca1994025773f8de8ba04840e3560fc339a955c07241e1c0def5bae291f7285aef723ee370669cc8682d7ef88a1d1afd21a37d1c2cb2e890bc965eb
data/README.adoc CHANGED
@@ -93,7 +93,8 @@ id.to_urn # => "urn:iso:std:iso:9001:amd:2020:v1"
93
93
  `#to_urn` follows the registered grammar of the organization, which can
94
94
  drop values (RFC 5141 has no year). `#to_pubid_urn` is pubid's own URN: it
95
95
  carries every value, always round-trips through `Pubid.parse_urn`, and is
96
- safe to use as an HTTP path. ISO, IEEE, ANSI, ITU, NIST and ASTM support it now; the other flavors follow
96
+ safe to use as an HTTP path. ISO, IEEE, ANSI, ITU, NIST, ASTM, API, ASHRAE,
97
+ ASME, JCGM, OIML, ETSI, GOST and PLATEAU support it now; the other flavors follow
97
98
  (link:docs/URN-SCHEMES.adoc[URN schemes]).
98
99
 
99
100
  [source,ruby]
data/data/parg/sae.json CHANGED
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidSae","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"SAE"}},{"Named":{"name":"publisher","atom":0}},{"Entity":{"atom":3}},{"Str":{"pattern":" "}},{"Entity":{"atom":12}},{"Str":{"pattern":"AMS"}},{"Str":{"pattern":"AIR"}},{"Str":{"pattern":"ARP"}},{"Str":{"pattern":"AS"}},{"Str":{"pattern":"J"}},{"Str":{"pattern":"MA"}},{"Alternative":{"atoms":[5,6,7,8,9,10]}},{"Named":{"name":"type","atom":11}},{"Entity":{"atom":3}},{"Repetition":{"atom":13,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":29}},{"Entity":{"atom":17}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Repetition":{"atom":16,"min":1,"max":1,"tag":"Repetition"}},{"Entity":{"atom":20}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[18,21]}},{"Entity":{"atom":20}},{"Repetition":{"atom":23,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":17}},{"Repetition":{"atom":25,"min":0,"max":1,"tag":"Repetition"}},{"Sequence":{"atoms":[24,26]}},{"Alternative":{"atoms":[22,27]}},{"Named":{"name":"number","atom":28}},{"Entity":{"atom":31}},{"Str":{"pattern":":"}},{"Named":{"name":"colon","atom":30}},{"Entity":{"atom":36}},{"Entity":{"atom":20}},{"Repetition":{"atom":34,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"year","atom":35}},{"Sequence":{"atoms":[32,33]}},{"Repetition":{"atom":37,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,2,4,14,15,38]}}],"root":39},"bindings":[{"capture":"type","path":"type","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":"publisher","path":"publisher","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"SAE J1939","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE AMS2430","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE ARP4754A:2010","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/sae/parser.rb: SAE <AMS|AIR|ARP|AS|J|MA> <number>[:year]\n\ngrammar PubidSae version \"0.1.0\" edition 2 {\n doc_type = (\"AMS\" / \"AIR\" / \"ARP\" / \"AS\" / \"J\" / \"MA\") as type\n number = ((1*1letter 1*digit) / (1*digit *1letter)) as number\n year = (4digit) as year\n identifier = \"SAE\" as publisher space doc_type [space] number [(colon year)]\n letter = %x41-5A\n digit = %x30-39\n space = \" \"\n colon = \":\"\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 year -> year (string)\n publisher -> publisher (string)\n }\n\n\n test {\n accept \"SAE J1939\"\n accept \"SAE AMS2430\"\n accept \"SAE ARP4754A:2010\"\n reject \"nonsense\"\n }\n}\n","source_hash":"2d3a161caeb9c059ce2600050b823aea373712c16cfa662e5f82166c6f7ee01a","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.114","edition":2,"checksum":"sha256:cdcc10602aa864cbccccd23ab6baaeed8e7edc4e4a8075c6c7a8f90324d7b5e1"}
1
+ {"bindings":null,"version":"0.2.0","grammar":"PubidSae","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"SAE"}},{"Named":{"name":"publisher","atom":0}},{"Entity":{"atom":3}},{"Str":{"pattern":" "}},{"Entity":{"atom":86}},{"Str":{"pattern":"AMS-QQ-A"}},{"Str":{"pattern":"AMS-QQ-C"}},{"Str":{"pattern":"AMS-QQ-N"}},{"Str":{"pattern":"AMS-QQ-P"}},{"Str":{"pattern":"AMS-QQ-S"}},{"Str":{"pattern":"AMS-QQ-W"}},{"Str":{"pattern":"AMS-WW-T"}},{"Str":{"pattern":"GEIA-STD"}},{"Str":{"pattern":"AMS-DTL"}},{"Str":{"pattern":"AMS-PRF"}},{"Str":{"pattern":"AMS-STD"}},{"Str":{"pattern":"EIA-STD"}},{"Str":{"pattern":"GEIA-HB"}},{"Str":{"pattern":"GEIA-OP"}},{"Str":{"pattern":"GEIA-TB"}},{"Str":{"pattern":"GEIASTD"}},{"Str":{"pattern":"AMSDTL"}},{"Str":{"pattern":"AMSPRF"}},{"Str":{"pattern":"AMSQQA"}},{"Str":{"pattern":"AMSQQC"}},{"Str":{"pattern":"AMSQQN"}},{"Str":{"pattern":"AMSQQP"}},{"Str":{"pattern":"AMSQQS"}},{"Str":{"pattern":"AMSQQW"}},{"Str":{"pattern":"AMSSTD"}},{"Str":{"pattern":"AMSWWT"}},{"Str":{"pattern":"EIA-IS"}},{"Str":{"pattern":"EIASTD"}},{"Str":{"pattern":"GEIAHB"}},{"Str":{"pattern":"GEIAOP"}},{"Str":{"pattern":"GEIATB"}},{"Str":{"pattern":"AMS-A"}},{"Str":{"pattern":"AMS-B"}},{"Str":{"pattern":"AMS-C"}},{"Str":{"pattern":"AMS-D"}},{"Str":{"pattern":"AMS-F"}},{"Str":{"pattern":"AMS-G"}},{"Str":{"pattern":"AMS-H"}},{"Str":{"pattern":"AMS-I"}},{"Str":{"pattern":"AMS-L"}},{"Str":{"pattern":"AMS-M"}},{"Str":{"pattern":"AMS-P"}},{"Str":{"pattern":"AMS-R"}},{"Str":{"pattern":"AMS-S"}},{"Str":{"pattern":"AMS-T"}},{"Str":{"pattern":"AMS-W"}},{"Str":{"pattern":"EIAIS"}},{"Str":{"pattern":"USCAR"}},{"Str":{"pattern":"AMSA"}},{"Str":{"pattern":"AMSB"}},{"Str":{"pattern":"AMSC"}},{"Str":{"pattern":"AMSD"}},{"Str":{"pattern":"AMSF"}},{"Str":{"pattern":"AMSG"}},{"Str":{"pattern":"AMSH"}},{"Str":{"pattern":"AMSI"}},{"Str":{"pattern":"AMSL"}},{"Str":{"pattern":"AMSM"}},{"Str":{"pattern":"AMSP"}},{"Str":{"pattern":"AMSR"}},{"Str":{"pattern":"AMSS"}},{"Str":{"pattern":"AMST"}},{"Str":{"pattern":"AMSW"}},{"Str":{"pattern":"GEIA"}},{"Str":{"pattern":"AIR"}},{"Str":{"pattern":"AMS"}},{"Str":{"pattern":"ARD"}},{"Str":{"pattern":"ARP"}},{"Str":{"pattern":"CMB"}},{"Str":{"pattern":"CRP"}},{"Str":{"pattern":"EIA"}},{"Str":{"pattern":"MAM"}},{"Str":{"pattern":"MAP"}},{"Str":{"pattern":"SSB"}},{"Str":{"pattern":"TSB"}},{"Str":{"pattern":"AS"}},{"Str":{"pattern":"JA"}},{"Str":{"pattern":"MA"}},{"Str":{"pattern":"MS"}},{"Str":{"pattern":"J"}},{"Alternative":{"atoms":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84]}},{"Named":{"name":"type","atom":85}},{"Entity":{"atom":90}},{"Entity":{"atom":3}},{"Str":{"pattern":"-"}},{"Alternative":{"atoms":[88,89]}},{"Named":{"name":"type_sep","atom":87}},{"Repetition":{"atom":91,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":97}},{"Entity":{"atom":95}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":94,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":96}},{"Entity":{"atom":107}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"_"}},{"Alternative":{"atoms":[99,100]}},{"Entity":{"atom":95}},{"Repetition":{"atom":102,"min":1,"max":3,"tag":"Repetition"}},{"Named":{"name":"dash","atom":103}},{"Entity":{"atom":95}},{"Lookahead":{"atom":105,"positive":false}},{"Sequence":{"atoms":[101,104,106]}},{"Repetition":{"atom":98,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":113}},{"Entity":{"atom":111}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Repetition":{"atom":110,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"tail","atom":112}},{"Repetition":{"atom":109,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":130}},{"Str":{"pattern":"/"}},{"Entity":{"atom":111}},{"Repetition":{"atom":117,"min":0,"max":null,"tag":"Repetition"}},{"Entity":{"atom":95}},{"Repetition":{"atom":119,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[118,120]}},{"Entity":{"atom":111}},{"Repetition":{"atom":122,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[121,123]}},{"Named":{"name":"part","atom":124}},{"Entity":{"atom":111}},{"Repetition":{"atom":126,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"part_tail","atom":127}},{"Repetition":{"atom":128,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[116,125,129]}},{"Repetition":{"atom":115,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":137}},{"Str":{"pattern":"_A"}},{"Entity":{"atom":95}},{"Repetition":{"atom":134,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"amendment","atom":135}},{"Sequence":{"atoms":[133,136]}},{"Repetition":{"atom":132,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":153}},{"Str":{"pattern":":"}},{"Entity":{"atom":95}},{"Repetition":{"atom":141,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"year","atom":142}},{"Sequence":{"atoms":[140,143]}},{"Str":{"pattern":"_"}},{"Entity":{"atom":95}},{"Repetition":{"atom":146,"min":4,"max":4,"tag":"Repetition"}},{"Named":{"name":"year","atom":147}},{"Entity":{"atom":95}},{"Repetition":{"atom":149,"min":2,"max":2,"tag":"Repetition"}},{"Named":{"name":"month","atom":150}},{"Sequence":{"atoms":[145,148,151]}},{"Alternative":{"atoms":[144,152]}},{"Repetition":{"atom":139,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,2,4,92,93,108,114,131,138,154]}}],"root":155},"bindings":[{"capture":"publisher","path":"publisher","type":"string","card":null,"preprocess":null},{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"dash","path":"dash","type":"string","card":null,"preprocess":null},{"capture":"tail","path":"tail","type":"string","card":null,"preprocess":null},{"capture":"part","path":"part","type":"string","card":null,"preprocess":null},{"capture":"part_tail","path":"part_tail","type":"string","card":null,"preprocess":null},{"capture":"amendment","path":"amendment","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":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"SAE J1939","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE J 3016","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE AMS2430","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE ARP4754A:2010","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE AMS-QQ-A-250/4B","expect":{}},{"entry":"identifier","kind":"accept","input":"SAE AMSQQA250/4B","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"SAE J3016_2021","expect":{}},{"entry":"identifier","kind":"reject","input":"SAE XYZ1","expect":{}},{"entry":"identifier","kind":"example","input":"SAE J3016_202104","expect":{"type":"J","number":"3016","year":"2021","month":"04"}},{"entry":"identifier","kind":"example","input":"SAE AMS4121J","expect":{"type":"AMS","number":"4121","tail":"J"}},{"entry":"identifier","kind":"example","input":"SAE AS22520/45A","expect":{"type":"AS","number":"22520","part":"45","part_tail":"A"}},{"entry":"identifier","kind":"example","input":"SAE AMS5622/H1025","expect":{"type":"AMS","number":"5622","part":"H1025"}},{"entry":"identifier","kind":"example","input":"SAE J2945/AS","expect":{"type":"J","number":"2945","part":"AS"}},{"entry":"identifier","kind":"example","input":"SAE J1939-71:2020","expect":{"type":"J","number":"1939","dash":"71","year":"2020"}},{"entry":"identifier","kind":"example","input":"SAE EIA649_1A","expect":{"type":"EIA","number":"649","dash":"1","tail":"A"}},{"entry":"identifier","kind":"example","input":"SAE AS5259/7A_A1","expect":{"type":"AS","number":"5259","part":"7","part_tail":"A","amendment":"1"}},{"entry":"identifier","kind":"example","input":"SAE AMSSTD595","expect":{"type":"AMSSTD","number":"595"}},{"entry":"identifier","kind":"example","input":"SAE GEIA-STD-0001","expect":{"type":"GEIA-STD","number":"0001"}}],"docs":{},"source":"# SAE identifiers, in SAE's printed form and in the hyphen-free form of its\n# Crossref DOI suffixes (10.4271/<code>):\n#\n# SAE <type>[ |-]<number>[-<dash>][<tail>][/<part>[<part_tail>]][_A<n>][:yyyy|_yyyymm]\n#\n# The grammar only segments. What a letter tail means (a revision, the\n# metric M of a J report, a digital-annex DA) and which spelling of the type\n# is printed is decided by pubid's lib/pubid/sae/builder.rb, which owns the\n# type table (Pubid::Sae::Components::Type::TYPES). The doc_type\n# alternatives are that table's keys plus their hyphen-free spellings,\n# longest first: PEG commits to the first alternative that matches, so\n# \"AMS\" must come after every \"AMS...\" family.\n\ngrammar PubidSae version \"0.2.0\" edition 2 {\n doc_type = (\"AMS-QQ-A\" / \"AMS-QQ-C\" / \"AMS-QQ-N\" / \"AMS-QQ-P\" / \"AMS-QQ-S\" / \"AMS-QQ-W\" / \"AMS-WW-T\" / \"GEIA-STD\" / \"AMS-DTL\" / \"AMS-PRF\" / \"AMS-STD\" / \"EIA-STD\" / \"GEIA-HB\" / \"GEIA-OP\" / \"GEIA-TB\" / \"GEIASTD\" / \"AMSDTL\" / \"AMSPRF\" / \"AMSQQA\" / \"AMSQQC\" / \"AMSQQN\" / \"AMSQQP\" / \"AMSQQS\" / \"AMSQQW\" / \"AMSSTD\" / \"AMSWWT\" / \"EIA-IS\" / \"EIASTD\" / \"GEIAHB\" / \"GEIAOP\" / \"GEIATB\" / \"AMS-A\" / \"AMS-B\" / \"AMS-C\" / \"AMS-D\" / \"AMS-F\" / \"AMS-G\" / \"AMS-H\" / \"AMS-I\" / \"AMS-L\" / \"AMS-M\" / \"AMS-P\" / \"AMS-R\" / \"AMS-S\" / \"AMS-T\" / \"AMS-W\" / \"EIAIS\" / \"USCAR\" / \"AMSA\" / \"AMSB\" / \"AMSC\" / \"AMSD\" / \"AMSF\" / \"AMSG\" / \"AMSH\" / \"AMSI\" / \"AMSL\" / \"AMSM\" / \"AMSP\" / \"AMSR\" / \"AMSS\" / \"AMST\" / \"AMSW\" / \"GEIA\" / \"AIR\" / \"AMS\" / \"ARD\" / \"ARP\" / \"CMB\" / \"CRP\" / \"EIA\" / \"MAM\" / \"MAP\" / \"SSB\" / \"TSB\" / \"AS\" / \"JA\" / \"MA\" / \"MS\" / \"J\") as type\n type_sep = space / \"-\"\n number = (1*digit) as number\n # A dash number: J1939-71, EIA649-2, and the DOI's EIA649_1. At most three\n # digits and no digit after, so \"_202104\" stays a date.\n dash = (\"-\" / \"_\") (1*3digit) as dash !digit\n tail = (1*letter) as tail\n part = \"/\" ((*letter 1*digit) / 1*letter) as part [(1*letter) as part_tail]\n amendment = \"_A\" (1*digit) as amendment\n date = (\":\" (4digit) as year) / (\"_\" (4digit) as year (2digit) as month)\n identifier = \"SAE\" as publisher space doc_type [type_sep] number [dash] [tail] [part] [amendment] [date]\n letter = %x41-5A\n digit = %x30-39\n space = \" \"\n entry identifier: identifier\n\n bindings identifier {\n publisher -> publisher (string)\n type -> type (string)\n number -> number (string)\n dash -> dash (string)\n tail -> tail (string)\n part -> part (string)\n part_tail -> part_tail (string)\n amendment -> amendment (string)\n year -> year (string)\n month -> month (string)\n }\n\n test {\n accept \"SAE J1939\"\n accept \"SAE J 3016\"\n accept \"SAE AMS2430\"\n accept \"SAE ARP4754A:2010\"\n accept \"SAE AMS-QQ-A-250/4B\"\n accept \"SAE AMSQQA250/4B\"\n reject \"nonsense\"\n reject \"SAE J3016_2021\"\n reject \"SAE XYZ1\"\n example \"SAE J3016_202104\" { type: \"J\", number: \"3016\", year: \"2021\", month: \"04\" }\n example \"SAE AMS4121J\" { type: \"AMS\", number: \"4121\", tail: \"J\" }\n example \"SAE AS22520/45A\" { type: \"AS\", number: \"22520\", part: \"45\", part_tail: \"A\" }\n example \"SAE AMS5622/H1025\" { type: \"AMS\", number: \"5622\", part: \"H1025\" }\n example \"SAE J2945/AS\" { type: \"J\", number: \"2945\", part: \"AS\" }\n example \"SAE J1939-71:2020\" { type: \"J\", number: \"1939\", dash: \"71\", year: \"2020\" }\n example \"SAE EIA649_1A\" { type: \"EIA\", number: \"649\", dash: \"1\", tail: \"A\" }\n example \"SAE AS5259/7A_A1\" { type: \"AS\", number: \"5259\", part: \"7\", part_tail: \"A\", amendment: \"1\" }\n example \"SAE AMSSTD595\" { type: \"AMSSTD\", number: \"595\" }\n example \"SAE GEIA-STD-0001\" { type: \"GEIA-STD\", number: \"0001\" }\n }\n}\n","source_hash":"204b7183faedf1026e76016e92d3e9904d81930ed04d7a9d54849ac78f1ad6e7","unicode_tables":"onigmo (Ruby 3.4.10)","compiler_version":"1.3.129","edition":2,"semantics_hash":"sha256:58d95b3087380a9ddb6598898095eac06e5cf639bc63d699c0db8d51c88c15f0","checksum":"sha256:ea9c116c71abfbf523abb94e20bede94a0b9613621dd2d4cae1990aad6f3e774"}
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Api
5
+ # The pubid-scheme URN of API (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # API MPMS Ch. 10.10 -> urn:pubid:api:mpms:10.10:subsec-...
8
+ #
9
+ # The number is the core of every type; +part+, +section+ and
10
+ # +subsection+ are atoms, in the doc's canonical order.
11
+ PubidUrnSchema = Pubid::PubidUrn.define("api") do
12
+ atom "part", "part"
13
+ atom "section", "section"
14
+ atom "subsection", "subsection"
15
+ # typeless standards date themselves ("API 650:2020")
16
+ atom "year", "year"
17
+
18
+ type "pubid:api:base", "base"
19
+ type "pubid:api:bulletin", "bulletin"
20
+ type "pubid:api:continuous-operations-standard", "cos"
21
+ type "pubid:api:identifier", "id"
22
+ type "pubid:api:mpms", "mpms"
23
+ type "pubid:api:publication", "pub"
24
+ type "pubid:api:recommended-practice", "rp"
25
+ type "pubid:api:specification", "spec"
26
+ type "pubid:api:standard", "std"
27
+ type "pubid:api:technical-report", "tr"
28
+ type "pubid:api:typeless-standard", "ts"
29
+ end
30
+ end
31
+ end
data/lib/pubid/api.rb CHANGED
@@ -16,6 +16,7 @@ module Pubid
16
16
  autoload :SingleIdentifier, "#{__dir__}/api/single_identifier"
17
17
  autoload :UrnGenerator, "#{__dir__}/api/urn_generator"
18
18
  autoload :UrnParser, "#{__dir__}/api/urn_parser"
19
+ autoload :PubidUrnSchema, "#{__dir__}/api/pubid_urn_schema"
19
20
 
20
21
  def self.parse(input)
21
22
  Identifier.parse(input)
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ashrae
5
+ # The pubid-scheme URN of ASHRAE (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # ASHRAE Standard 15-2007 (RA 2010)
8
+ # urn:pubid:ashrae:std:15:year-2007:reaffirmed-2010
9
+ #
10
+ # The number is the core of every type (the base-anchored ones emit
11
+ # it as NULL when absent — the errata and the package carry their
12
+ # identity in the base chain). The atoms follow the doc's canonical
13
+ # order; the date internals stay placed until the Components::Code
14
+ # reduction lands (docs/URN-SCHEMES.adoc, ashrae finding).
15
+ PubidUrnSchema = Pubid::PubidUrn.define("ashrae") do
16
+ atom "copublisher", "co"
17
+ atom "year", "year"
18
+ atom "date.day", "dateday"
19
+ atom "date.month", "datemonth"
20
+ atom "date.year", "dateyear"
21
+ atom "addendum_code", "addendumcode"
22
+ atom "addendum_codes", "addendumcodes"
23
+ atom "package_description", "packagedescription"
24
+ atom "reaffirmed", "reaffirmed"
25
+ atom "suffix", "suffix"
26
+
27
+ type "pubid:ashrae:addenda-package", "ap"
28
+ type "pubid:ashrae:addendum", "add"
29
+ type "pubid:ashrae:combined-addenda", "ca"
30
+ type "pubid:ashrae:errata", "err"
31
+ type "pubid:ashrae:guideline", "g"
32
+ type "pubid:ashrae:identifier", "id"
33
+ type "pubid:ashrae:interpretation", "interp"
34
+ type "pubid:ashrae:standard", "std"
35
+ end
36
+ end
37
+ end
data/lib/pubid/ashrae.rb CHANGED
@@ -18,6 +18,7 @@ module Pubid
18
18
  autoload :SupplementIdentifier, "#{__dir__}/ashrae/supplement_identifier"
19
19
  autoload :UrnGenerator, "#{__dir__}/ashrae/urn_generator"
20
20
  autoload :UrnParser, "#{__dir__}/ashrae/urn_parser"
21
+ autoload :PubidUrnSchema, "#{__dir__}/ashrae/pubid_urn_schema"
21
22
 
22
23
  def self.parse(identifier)
23
24
  unless identifier.is_a?(String)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Asme
5
+ # The pubid-scheme URN of ASME (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # ASME B30.3-20XX (Revision of ASME B30.1-2020)
8
+ # urn:pubid:asme:std:B30.3:pub-ASME:draftyear-20XX
9
+ # :parentheticalrevision-...
10
+ #
11
+ # The number is the core; the atoms follow the doc's canonical order.
12
+ # +parenthetical_revision+ and +revision_note+ are the two verbatim
13
+ # bracket notes, case-kept.
14
+ PubidUrnSchema = Pubid::PubidUrn.define("asme") do
15
+ atom "publisher", "pub"
16
+ atom "year", "year"
17
+ atom "language", "lang"
18
+ atom "csa_number", "csanumber"
19
+ atom "draft_year", "draftyear"
20
+ atom "first_code", "firstcode"
21
+ atom "first_publisher", "firstpublisher"
22
+ atom "handbook", "handbook", kind: :bool
23
+ atom "joint_publisher", "jointpublisher"
24
+ atom "parenthetical_revision", "parentheticalrevision"
25
+ atom "ptc_suffix", "ptcsuffix"
26
+ atom "revision_note", "revisionnote"
27
+ atom "second_publisher", "secondpublisher"
28
+
29
+ type "pubid:asme:base", "base"
30
+ type "pubid:asme:identifier", "id"
31
+ type "pubid:asme:standard", "std"
32
+ end
33
+ end
34
+ end
data/lib/pubid/asme.rb CHANGED
@@ -17,6 +17,7 @@ module Pubid
17
17
  autoload :SingleIdentifier, "#{__dir__}/asme/single_identifier"
18
18
  autoload :UrnGenerator, "#{__dir__}/asme/urn_generator"
19
19
  autoload :UrnParser, "#{__dir__}/asme/urn_parser"
20
+ autoload :PubidUrnSchema, "#{__dir__}/asme/pubid_urn_schema"
20
21
 
21
22
  def self.parse(str)
22
23
  Identifier.parse(str)
@@ -57,3 +57,20 @@ keeps `#matches?(other, ignore:)`.
57
57
  decision, on the reading that a published norm should carry a published
58
58
  stage by default. It is fixed at the matching layer instead: no grammar
59
59
  change, no index re-crawl.
60
+
61
+ ## `locate_type` and `CenelecHarmonizationDocument`
62
+
63
+ `CenCenelec.locate_type` returns the **first** class in `identifier_types`
64
+ whose `type[:key]` matches, and `identifier_types` reads
65
+ `Identifiers.constants`, whose order Ruby does not guarantee.
66
+ `CenelecHarmonizationDocument` shared the key `:hd` with
67
+ `HarmonizationDocument`, and its autoload was misspelled
68
+ (`CENelecHarmonizationDocument`), so it joined the list only when something
69
+ else had loaded its file before the list was memoized. Then `HD 123:2020`
70
+ could build the CENELEC class: 6 CEN examples failed in one spec order only,
71
+ exposed by the pubid-URN GOST wave, not caused by it. The autoload is fixed
72
+ and the class has its own key `:chd` (the token `docs/URN-SCHEMES.adoc`
73
+ gives it); `spec/pubid/cen_cenelec/type_key_spec.rb` loads the class and
74
+ rebuilds the list, so it does not depend on order. **Every type key in a
75
+ flavor must be unique**; ANSI has the same shape (`Standard` and
76
+ `AmericanNationalStandard` both declare `ans`) and is not checked here.
@@ -19,8 +19,11 @@ module Pubid
19
19
  ),
20
20
  ].freeze
21
21
 
22
+ # Its own key: CenCenelec.locate_type returns the first class with
23
+ # a matching key, and HarmonizationDocument owns :hd ("HD 123:2020").
24
+ # A shared key made the class choice depend on load order.
22
25
  def self.type
23
- { key: :hd, title: "CENELEC Harmonization Document", short: "HD" }
26
+ { key: :chd, title: "CENELEC Harmonization Document", short: "HD" }
24
27
  end
25
28
  end
26
29
  end
@@ -7,7 +7,7 @@ module Pubid
7
7
  "#{__dir__}/identifiers/adopted_european_norm"
8
8
  autoload :Amendment, "#{__dir__}/identifiers/amendment"
9
9
  autoload :Base, "#{__dir__}/identifiers/base"
10
- autoload :CENelecHarmonizationDocument,
10
+ autoload :CenelecHarmonizationDocument,
11
11
  "#{__dir__}/identifiers/cenelec_harmonization_document"
12
12
  autoload :CenReport, "#{__dir__}/identifiers/cen_report"
13
13
  autoload :CenWorkshopAgreement,
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module CenCenelec
5
+ # The pubid-scheme URN of CEN/CENELEC — PARTIAL (issue #656;
6
+ # docs/URN-SCHEMES.adoc).
7
+ #
8
+ # Only the types a GOST adoption can name are declared: an EN, an
9
+ # adopted EN ("EN ISO 12100:2010", no number of its own), its amendment
10
+ # and corrigendum, a CEN TS or TR, and the consolidated
11
+ # "EN 14988:2017+A1:2020". The atoms keep the doc's canonical order; an
12
+ # absent atom writes nothing, so the CEN wave can add types and atoms
13
+ # without changing these URNs. Until then cen_cenelec stays pending in
14
+ # the contract spec.
15
+ PubidUrnSchema = Pubid::PubidUrn.define("cencenelec") do
16
+ atom "publisher", "pub"
17
+ atom "copublishers", "co", kind: :list
18
+ atom "part", "part"
19
+ atom "year", "year"
20
+ atom "month", "month"
21
+ atom "version", "v"
22
+ atom "stage", "stage"
23
+ atom "adopted", "adopted", kind: :id
24
+ atom "identifiers", "ids", kind: :ids
25
+
26
+ type "pubid:cencenelec:adopted-european-norm", "aen", core: []
27
+ type "pubid:cencenelec:amendment", "amd"
28
+ type "pubid:cencenelec:consolidated-identifier", "consol", core: []
29
+ type "pubid:cencenelec:corrigendum", "cor"
30
+ type "pubid:cencenelec:european-norm", "en"
31
+ type "pubid:cencenelec:technical-report", "tr"
32
+ type "pubid:cencenelec:technical-specification", "ts"
33
+ end
34
+ end
35
+ end
@@ -19,6 +19,7 @@ module Pubid
19
19
  autoload :Identifier, "#{__dir__}/cen_cenelec/identifier"
20
20
  autoload :Identifiers, "#{__dir__}/cen_cenelec/identifiers"
21
21
  autoload :Parser, "#{__dir__}/cen_cenelec/parser"
22
+ autoload :PubidUrnSchema, "#{__dir__}/cen_cenelec/pubid_urn_schema"
22
23
  autoload :Renderer, "#{__dir__}/cen_cenelec/renderer"
23
24
  autoload :SingleIdentifier, "#{__dir__}/cen_cenelec/single_identifier"
24
25
  autoload :UrnGenerator, "#{__dir__}/cen_cenelec/urn_generator"
@@ -32,3 +32,12 @@ keeps `#matches?(other, ignore:)`.
32
32
  - `SUBSET_PAIRS["etsi"]` in `spec/pubid/subset_match_spec.rb` moved from
33
33
  `ETSI EN 300 175` to `ETSI EN 300 175-1`: the reference now states its
34
34
  part, and the version and the date are what it omits.
35
+
36
+ ## pubid-scheme URN (issue #656)
37
+
38
+ `lib/pubid/etsi/pubid_urn_schema.rb`; rulings in `docs/URN-SCHEMES.adoc`
39
+ (`[[urn-etsi]]`). A supplement's `number` is an Integer ordinal, so its core
40
+ is `:int` (`core: [["number", :int]]`), and the codec refuses a String there.
41
+ `minor` and `day` are placed although no pass fixture sets them, because
42
+ `EtsiStandard`'s `key_value` block maps them: a schema must place every key
43
+ the mapping can write, not only the keys the corpus shows.
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Etsi
5
+ # The pubid-scheme URN of ETSI (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # ETSI EN 300 175-1 V2.9.1 (2022-01)
8
+ # urn:pubid:etsi:es:300~20175:type-EN:part-1:year-2022:month-01:v-2.9.1
9
+ #
10
+ # ETSI ETR 108/A1 ed.1 (1995-08)
11
+ # urn:pubid:etsi:es:108:type-ETR:year-1995:month-08:v-1:isedition-true:
12
+ # amd:1
13
+ #
14
+ # The number is the core of every type. A supplement's number is its
15
+ # Integer ordinal, so it is an :int core; the document it supplements
16
+ # comes first, along +base+. The official urn:etsi: form (RFC 8515)
17
+ # stays on #to_urn.
18
+ PubidUrnSchema = Pubid::PubidUrn.define("etsi") do
19
+ atom "type", "type"
20
+ atom "parts", "part", kind: :list
21
+ atom "minor", "minor"
22
+ atom "year", "year"
23
+ atom "month", "month"
24
+ atom "day", "day"
25
+ atom "version", "v"
26
+ atom "is_edition", "isedition", kind: :bool
27
+
28
+ supplement = [["number", :int]]
29
+ type "pubid:etsi:amendment", "amd", core: supplement
30
+ type "pubid:etsi:corrigendum", "cor", core: supplement
31
+ type "pubid:etsi:etsi-standard", "es"
32
+ type "pubid:etsi:identifier", "id"
33
+ type "pubid:etsi:supplement-identifier", "si", core: supplement
34
+ end
35
+ end
36
+ end
data/lib/pubid/etsi.rb CHANGED
@@ -17,6 +17,7 @@ module Pubid
17
17
  autoload :Identifier, "#{__dir__}/etsi/identifiers/base"
18
18
  autoload :Identifiers, "#{__dir__}/etsi/identifiers"
19
19
  autoload :Parser, "#{__dir__}/etsi/parser"
20
+ autoload :PubidUrnSchema, "#{__dir__}/etsi/pubid_urn_schema"
20
21
  autoload :Renderer, "#{__dir__}/etsi/renderer"
21
22
  autoload :UrnGenerator, "#{__dir__}/etsi/urn_generator"
22
23
  autoload :UrnParser, "#{__dir__}/etsi/urn_parser"
@@ -62,3 +62,15 @@ a deterministic reproduction of the race (not a reliance on catching the rare
62
62
  full-suite failure): it temporarily `Registry.unregister(:bsi)`s the usual
63
63
  race winner and asserts routing still resolves to `Pubid::Iso` correctly —
64
64
  proving the fix is prefix routing, not a lucky alphabetical ordering.
65
+
66
+ ## pubid-scheme URN (issue #656)
67
+
68
+ `lib/pubid/gost/pubid_urn_schema.rb`; rulings in `docs/URN-SCHEMES.adoc`
69
+ (`[[urn-gost]]`). The adopted documents nest with their own flavor's schema,
70
+ so this wave added a partial `lib/pubid/cen_cenelec/pubid_urn_schema.rb`.
71
+ **Open gap:** `ForeignReference#raw` is not mapped in `key_value`, so
72
+ `to_hash` drops the text of an adopted document of an unknown flavor
73
+ (`(OECD 460:2017)`): two such adoptions share one hash and one URN, and
74
+ `from_hash` loses the parenthesis. Mapping `raw` changes `to_hash`, and the
75
+ `pubid-testsuite` GOST cases store the hash without it, so the fix must land
76
+ together with a testsuite update. The schema's `raw-` atom is ready for it.
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Gost
5
+ # The pubid-scheme URN of GOST (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # ГОСТ ISO 6848 -> urn:pubid:gost:is:6848:co-ISO
8
+ #
9
+ # ГОСТ Р 58904-2020/ISO/TR 25901-1:2016
10
+ # urn:pubid:gost:ns:58904:year-2020:ia:58904:year-2020:
11
+ # adopted-(iso:tr:25901:part-1:year-2016)
12
+ #
13
+ # A harmonized or identical adoption wraps the GOST standard in +base+
14
+ # (written first) and repeats its number and year, as #to_hash does.
15
+ # The adopted documents are nested with their own flavor's schema
16
+ # (cencenelec, iec, iso, ieee, astm).
17
+ PubidUrnSchema = Pubid::PubidUrn.define("gost") do
18
+ atom "publisher", "pub"
19
+ atom "copublisher", "co"
20
+ atom "year", "year"
21
+ atom "subtype", "subtype"
22
+ atom "raw", "raw"
23
+ atom "adopted_identifiers", "adoptedidentifiers", kind: :ids
24
+ atom "adopted", "adopted", kind: :id
25
+
26
+ type "pubid:gost:foreign-reference", "fr"
27
+ type "pubid:gost:harmonized", "h"
28
+ type "pubid:gost:identical-adoption", "ia"
29
+ type "pubid:gost:identifier", "id"
30
+ type "pubid:gost:interstate-standard", "is"
31
+ type "pubid:gost:national-standard", "ns"
32
+ end
33
+ end
34
+ end
data/lib/pubid/gost.rb CHANGED
@@ -14,6 +14,7 @@ module Pubid
14
14
  autoload :Identifier, "#{__dir__}/gost/identifier"
15
15
  autoload :Identifiers, "#{__dir__}/gost/identifiers"
16
16
  autoload :Parser, "#{__dir__}/gost/parser"
17
+ autoload :PubidUrnSchema, "#{__dir__}/gost/pubid_urn_schema"
17
18
  autoload :Renderer, "#{__dir__}/gost/renderer"
18
19
  autoload :UrnGenerator, "#{__dir__}/gost/urn_generator"
19
20
  autoload :UrnParser, "#{__dir__}/gost/urn_parser"
@@ -1468,7 +1468,13 @@ module Pubid
1468
1468
  @hash ||= compute_hash
1469
1469
  end
1470
1470
 
1471
- def eql?(other)
1471
+ # The second parameter is lutaml's: ComparableModel#== (an alias of its
1472
+ # #eql?(other, compared_objects = {})) recurses with two arguments when
1473
+ # an attribute holds a model of the SAME class, such as the standard
1474
+ # an IEEE "Revision of" id revises. A one-parameter override made #==
1475
+ # raise ArgumentError there. The cycle guard is lutaml's; this method
1476
+ # keeps its own semantics and does not need it.
1477
+ def eql?(other, _compared_objects = nil)
1472
1478
  return false unless other.is_a?(self.class)
1473
1479
 
1474
1480
  hash == other.hash && self == other
@@ -5,10 +5,12 @@ module Pubid
5
5
  # The pubid-scheme URN of IEC — PARTIAL (issue #656;
6
6
  # docs/URN-SCHEMES.adoc).
7
7
  #
8
- # Only +pubid:iec:international-standard+ is declared, because IEEE
9
- # identifiers nest it (IEC/IEEE co-publications). IEC's own wave declares
10
- # the rest of the flavor; until then IEC stays pending in the contract
11
- # spec. The official RFC 5141-style urn:iec:std: form stays on #to_urn.
8
+ # Only the types other flavors nest are declared: the International
9
+ # Standard (IEC/IEEE co-publications, GOST adoptions), and the TS, TR,
10
+ # amendment and consolidated identifier a GOST adoption can name
11
+ # ("IEC 60079-0:2017+AMD1:2020"). IEC's own wave declares the rest of the
12
+ # flavor; until then IEC stays pending in the contract spec. The official
13
+ # RFC 5141-style urn:iec:std: form stays on #to_urn.
12
14
  PubidUrnSchema = Pubid::PubidUrn.define("iec") do
13
15
  atom "publisher", "pub"
14
16
  atom "copublishers", "co", kind: :list
@@ -23,10 +25,15 @@ module Pubid
23
25
  atom "stage_iteration", "iter"
24
26
  atom "database", "database"
25
27
  atom "languages.*.code", "lang"
28
+ atom "identifiers", "ids", kind: :ids
26
29
 
27
30
  facet "languages.*.original_code", "langsrc"
28
31
 
32
+ type "pubid:iec:amendment", "amd"
33
+ type "pubid:iec:consolidated-identifier", "consol", core: []
29
34
  type "pubid:iec:international-standard", "is"
35
+ type "pubid:iec:technical-report", "tr"
36
+ type "pubid:iec:technical-specification", "ts"
30
37
  end
31
38
  end
32
39
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Jcgm
5
+ # The pubid-scheme URN of JCGM (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # JCGM 100:2008/Amd 1:2026
8
+ # urn:pubid:jcgm:guide:100:year-2008:lang-en:amd:1:year-2026
9
+ #
10
+ # The number is the core of every type; the year, the month/day of a
11
+ # dated meeting or amendment and the languages are atoms, in the
12
+ # doc's canonical order. The original language code is a facet.
13
+ PubidUrnSchema = Pubid::PubidUrn.define("jcgm") do
14
+ atom "year", "year"
15
+ atom "month", "month"
16
+ atom "day", "day"
17
+ atom "languages.*.code", "lang"
18
+
19
+ facet "languages.*.original_code", "langsrc"
20
+
21
+ type "pubid:jcgm:amendment", "amd"
22
+ type "pubid:jcgm:corrigendum", "cor"
23
+ type "pubid:jcgm:guide", "guide"
24
+ type "pubid:jcgm:gum-guide", "gumguide"
25
+ type "pubid:jcgm:identifier", "id"
26
+ type "pubid:jcgm:meeting", "meeting"
27
+ end
28
+ end
29
+ end
data/lib/pubid/jcgm.rb CHANGED
@@ -18,6 +18,7 @@ module Pubid
18
18
  autoload :SupplementIdentifier, "#{__dir__}/jcgm/supplement_identifier"
19
19
  autoload :UrnGenerator, "#{__dir__}/jcgm/urn_generator"
20
20
  autoload :UrnParser, "#{__dir__}/jcgm/urn_parser"
21
+ autoload :PubidUrnSchema, "#{__dir__}/jcgm/pubid_urn_schema"
21
22
 
22
23
  # Parse a JCGM identifier string
23
24
  # @param identifier [String] the identifier string to parse
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ # The pubid-scheme URN of OIML (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # OIML D 2 (E) -> urn:pubid:oiml:document:2:pub-OIML:lang-E:format-...
8
+ #
9
+ # The number is the core of every type except the dual-published (no
10
+ # core; its two nested identifiers ride +first-/second-). The atoms
11
+ # follow the doc's canonical order; details in docs/URN-SCHEMES.adoc.
12
+ PubidUrnSchema = Pubid::PubidUrn.define("oiml") do
13
+ atom "publisher", "pub"
14
+ atom "part", "part"
15
+ atom "year", "year"
16
+ atom "edition", "ed"
17
+ atom "stage", "stage"
18
+ atom "language", "lang"
19
+ atom "amendment", "amendment"
20
+ atom "family", "family"
21
+ atom "iteration", "iteration"
22
+ atom "letter", "letter"
23
+ atom "trailing", "trailing", kind: :bool
24
+ atom "first", "first", kind: :id
25
+ atom "second", "second", kind: :id
26
+
27
+ facet "parsed_format", "format"
28
+ facet "space_separator", "sp", kind: :bool
29
+
30
+ type "pubid:oiml:amendment", "amd"
31
+ type "pubid:oiml:annex", "annex"
32
+ type "pubid:oiml:basic-publication", "bp"
33
+ type "pubid:oiml:bulletin", "bulletin"
34
+ type "pubid:oiml:certification-system", "cs"
35
+ type "pubid:oiml:document", "document"
36
+ type "pubid:oiml:dual-published", "dp", core: []
37
+ type "pubid:oiml:errata", "err"
38
+ type "pubid:oiml:expert-report", "er"
39
+ type "pubid:oiml:guide", "guide"
40
+ type "pubid:oiml:identifier", "id", core: []
41
+ type "pubid:oiml:recommendation", "rec"
42
+ type "pubid:oiml:seminar-report", "sr"
43
+ type "pubid:oiml:vocabulary", "v"
44
+ end
45
+ end
46
+ end
data/lib/pubid/oiml.rb CHANGED
@@ -18,6 +18,7 @@ module Pubid
18
18
  autoload :SupplementIdentifier, "#{__dir__}/oiml/supplement_identifier"
19
19
  autoload :UrnGenerator, "#{__dir__}/oiml/urn_generator"
20
20
  autoload :UrnParser, "#{__dir__}/oiml/urn_parser"
21
+ autoload :PubidUrnSchema, "#{__dir__}/oiml/pubid_urn_schema"
21
22
 
22
23
  def self.parse(identifier)
23
24
  unless identifier.is_a?(String)
@@ -0,0 +1,13 @@
1
+ # PLATEAU flavor notes
2
+
3
+ Read this before you change `lib/pubid/plateau/` or `spec/pubid/plateau/`. The
4
+ root `CLAUDE.md` keeps the cross-flavor contract that every flavor obeys.
5
+
6
+ ## pubid-scheme URN (issue #656)
7
+
8
+ `lib/pubid/plateau/pubid_urn_schema.rb`; rulings in `docs/URN-SCHEMES.adoc`
9
+ (`[[urn-plateau]]`). PLATEAU is the one flavor whose `number` stays an
10
+ Integer, so its core is `:int` (`core: [["number", :int]]`): `#00` is the core
11
+ `0`, and `00` in a URN is not canonical. The Annex type has no `number`; it
12
+ has no core, its document comes first along `base`, and its `letter` is an
13
+ atom. No input makes an Annex today, so the spec builds one by hand.
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Plateau
5
+ # The pubid-scheme URN of PLATEAU (issue #656; docs/URN-SCHEMES.adoc).
6
+ #
7
+ # PLATEAU Handbook #00 第1.0版 -> urn:pubid:plateau:hb:0:ed-1.0
8
+ #
9
+ # PLATEAU keeps +number+ as an Integer (the one flavor the String retype
10
+ # left out), so it is an :int core. An Annex has no number of its own:
11
+ # its document comes first, along +base+, and its letter is an atom.
12
+ PubidUrnSchema = Pubid::PubidUrn.define("plateau") do
13
+ atom "publisher", "pub"
14
+ atom "edition", "ed"
15
+ atom "annex", "annex", kind: :int
16
+
17
+ number = [["number", :int]]
18
+ type "pubid:plateau:annex", "annex", core: [],
19
+ atoms: [%w[letter letter]]
20
+ type "pubid:plateau:handbook", "hb", core: number
21
+ type "pubid:plateau:identifier", "id", core: number
22
+ type "pubid:plateau:technical-report", "tr", core: number
23
+ end
24
+ end
25
+ end
data/lib/pubid/plateau.rb CHANGED
@@ -13,6 +13,7 @@ module Pubid
13
13
  autoload :Identifier, "#{__dir__}/plateau/identifiers/base"
14
14
  autoload :Identifiers, "#{__dir__}/plateau/identifiers"
15
15
  autoload :Parser, "#{__dir__}/plateau/parser"
16
+ autoload :PubidUrnSchema, "#{__dir__}/plateau/pubid_urn_schema"
16
17
  autoload :Renderer, "#{__dir__}/plateau/renderer"
17
18
  autoload :SupplementIdentifier, "#{__dir__}/plateau/supplement_identifier"
18
19
  autoload :UrnGenerator, "#{__dir__}/plateau/urn_generator"