pubid 2.0.20 → 2.0.22
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 +73 -31
- data/data/iec/legacy-notation.md +298 -0
- data/data/iho/s4-reserved-specs.yaml +15 -0
- data/data/iso/historic-schemes.md +368 -0
- data/data/parg/bipm.json +1 -1
- data/data/parg/bipm.parg +46 -11
- data/data/parg/iec.json +1 -1
- data/data/parg/iho.json +1 -1
- data/data/parg/iho.parg +128 -11
- data/data/parg/iso.json +1 -1
- data/data/parg/iso.parg +142 -2
- data/data/parg/plateau.json +1 -1
- data/data/parg/tables/iec_typed_stages.yaml +3 -0
- data/data/parg/tables/typed_stages_ballots.yaml +6 -0
- data/data/parg/tables/typed_stages_supplements.yaml +1 -0
- data/lib/pubid/bipm/CLAUDE.md +6 -1
- data/lib/pubid/bipm/builder.rb +20 -1
- data/lib/pubid/bipm/renderer.rb +14 -2
- data/lib/pubid/bipm/urn_generator.rb +80 -14
- data/lib/pubid/bipm/urn_parser.rb +70 -6
- data/lib/pubid/ecma/CLAUDE.md +12 -0
- data/lib/pubid/ecma/identifier.rb +1 -2
- data/lib/pubid/ecma/parser.rb +49 -0
- data/lib/pubid/iec/CLAUDE.md +9 -1
- data/lib/pubid/iec/builder.rb +47 -0
- data/lib/pubid/iec/identifier.rb +19 -70
- data/lib/pubid/iec/identifiers/amendment.rb +34 -0
- data/lib/pubid/iec/identifiers/corrigendum.rb +6 -1
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +3 -3
- data/lib/pubid/iec/single_identifier.rb +69 -4
- data/lib/pubid/iec/supplement_identifier.rb +89 -83
- data/lib/pubid/iho/CLAUDE.md +54 -1
- data/lib/pubid/iho/builder.rb +105 -2
- data/lib/pubid/iho/identifiers/base.rb +52 -1
- data/lib/pubid/iho/pubid_urn_schema.rb +12 -4
- data/lib/pubid/iho/renderer.rb +39 -2
- data/lib/pubid/iho/reserved_specs.rb +54 -0
- data/lib/pubid/iho/urn_generator.rb +6 -0
- data/lib/pubid/iho/urn_parser.rb +50 -9
- data/lib/pubid/iho.rb +1 -0
- data/lib/pubid/iso/CLAUDE.md +49 -0
- data/lib/pubid/iso/builder.rb +77 -0
- data/lib/pubid/iso/identifiers/amendment.rb +1 -1
- data/lib/pubid/iso/single_identifier.rb +7 -1
- data/lib/pubid/nist/CLAUDE.md +49 -0
- data/lib/pubid/nist/builder.rb +5 -0
- data/lib/pubid/nist/identifiers/base.rb +42 -1
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +44 -5
- data/lib/pubid/nist/preprocessor.rb +18 -0
- data/lib/pubid/nist/urn_parser.rb +1 -1
- data/lib/pubid/plateau/CLAUDE.md +35 -0
- data/lib/pubid/plateau/builder.rb +4 -0
- data/lib/pubid/plateau/identifiers/handbook.rb +10 -2
- data/lib/pubid/plateau/pubid_urn_schema.rb +1 -0
- data/lib/pubid/plateau/renderer.rb +6 -1
- data/lib/pubid/sae/CLAUDE.md +11 -2
- data/lib/pubid/version.rb +1 -1
- metadata +7 -2
data/data/parg/iho.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"bindings":null,"version":"0.2.0","grammar":"PubidIho","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"IHO"}},{"Entity":{"atom":2}},{"Str":{"pattern":" "}},{"Sequence":{"atoms":[0,1]}},{"Repetition":{"atom":3,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[6,7,8,9,10]}},{"Named":{"name":"type","atom":11}},{"Entity":{"atom":14}},{"Str":{"pattern":"-"}},{"Entity":{"atom":26}},{"Entity":{"atom":17}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":16,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":23}},{"Str":{"pattern":":"}},{"Entity":{"atom":17}},{"Repetition":{"atom":21,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[20,22]}},{"Repetition":{"atom":19,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[18,24]}},{"Named":{"name":"number","atom":25}},{"Entity":{"atom":53}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[29,30,31,32,33]}},{"Entity":{"atom":14}},{"Entity":{"atom":17}},{"Repetition":{"atom":36,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[34,35,37]}},{"Entity":{"atom":17}},{"Repetition":{"atom":39,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":46}},{"Entity":{"atom":43}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Entity":{"atom":45}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[42,44]}},{"Repetition":{"atom":41,"min":0,"max":null,"tag":"Repetition"}},{"Repetition":{"atom":47,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[40,48]}},{"Entity":{"atom":43}},{"Alternative":{"atoms":[38,49,50]}},{"Named":{"name":"part","atom":51}},{"Sequence":{"atoms":[28,52]}},{"Repetition":{"atom":27,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":57}},{"Entity":{"atom":43}},{"Named":{"name":"part","atom":56}},{"Repetition":{"atom":55,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":94}},{"Str":{"pattern":"/"}},{"Entity":{"atom":17}},{"Repetition":{"atom":61,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"volume","atom":62}},{"Entity":{"atom":92}},{"Entity":{"atom":78}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":67,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Str":{"pattern":"."}},{"Entity":{"atom":17}},{"Repetition":{"atom":71,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":74,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[68,69,72,73,75]}},{"Named":{"name":"volume_edition","atom":76}},{"Sequence":{"atoms":[66,77]}},{"Entity":{"atom":90}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[82,83]}},{"Entity":{"atom":17}},{"Repetition":{"atom":85,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[84,86]}},{"Named":{"name":"volume_year","atom":87}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[80,81,88,89]}},{"Repetition":{"atom":79,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[65,91]}},{"Repetition":{"atom":64,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[60,63,93]}},{"Repetition":{"atom":59,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":137}},{"Entity":{"atom":109}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":99,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":102,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":105,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[100,101,103,104,106]}},{"Named":{"name":"edition","atom":107}},{"Sequence":{"atoms":[98,108]}},{"Entity":{"atom":122}},{"Entity":{"atom":2}},{"Str":{"pattern":"v"}},{"Entity":{"atom":17}},{"Repetition":{"atom":113,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":17}},{"Repetition":{"atom":116,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[115,117]}},{"Repetition":{"atom":118,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[114,119]}},{"Named":{"name":"edition_shorthand","atom":120}},{"Sequence":{"atoms":[111,112,121]}},{"Alternative":{"atoms":[97,110]}},{"Entity":{"atom":135}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[127,128]}},{"Entity":{"atom":17}},{"Repetition":{"atom":130,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[129,131]}},{"Named":{"name":"year","atom":132}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[125,126,133,134]}},{"Repetition":{"atom":124,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[123,136]}},{"Repetition":{"atom":96,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":177}},{"Entity":{"atom":2}},{"Str":{"pattern":"Suppl"}},{"Str":{"pattern":"Sup"}},{"Alternative":{"atoms":[141,142]}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":145,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"supplement","atom":146}},{"Entity":{"atom":175}},{"Entity":{"atom":161}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":151,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":154,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":157,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[152,153,155,156,158]}},{"Named":{"name":"supplement_edition","atom":159}},{"Sequence":{"atoms":[150,160]}},{"Entity":{"atom":173}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[165,166]}},{"Entity":{"atom":17}},{"Repetition":{"atom":168,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[167,169]}},{"Named":{"name":"supplement_year","atom":170}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[163,164,171,172]}},{"Repetition":{"atom":162,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[149,174]}},{"Repetition":{"atom":148,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[140,143,144,147,176]}},{"Repetition":{"atom":139,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":233}},{"Entity":{"atom":2}},{"Str":{"pattern":"Part"}},{"Entity":{"atom":2}},{"Entity":{"atom":203}},{"Entity":{"atom":194}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[185,186,187,188,189]}},{"Entity":{"atom":14}},{"Entity":{"atom":17}},{"Repetition":{"atom":192,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[190,191,193]}},{"Entity":{"atom":17}},{"Repetition":{"atom":195,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":46}},{"Repetition":{"atom":197,"min":0,"max":null,"tag":"Repetition"}},{"Repetition":{"atom":198,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[196,199]}},{"Entity":{"atom":43}},{"Alternative":{"atoms":[184,200,201]}},{"Named":{"name":"part","atom":202}},{"Entity":{"atom":231}},{"Entity":{"atom":217}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":207,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":210,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":213,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[208,209,211,212,214]}},{"Named":{"name":"part_edition","atom":215}},{"Sequence":{"atoms":[206,216]}},{"Entity":{"atom":229}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[221,222]}},{"Entity":{"atom":17}},{"Repetition":{"atom":224,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[223,225]}},{"Named":{"name":"part_year","atom":226}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[219,220,227,228]}},{"Repetition":{"atom":218,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[205,230]}},{"Repetition":{"atom":204,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[180,181,182,183,232]}},{"Repetition":{"atom":179,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":270}},{"Entity":{"atom":2}},{"Str":{"pattern":"Annex"}},{"Entity":{"atom":2}},{"Entity":{"atom":43}},{"Named":{"name":"annex","atom":239}},{"Entity":{"atom":268}},{"Entity":{"atom":254}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":244,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":247,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":250,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[245,246,248,249,251]}},{"Named":{"name":"annex_edition","atom":252}},{"Sequence":{"atoms":[243,253]}},{"Entity":{"atom":266}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[258,259]}},{"Entity":{"atom":17}},{"Repetition":{"atom":261,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[260,262]}},{"Named":{"name":"annex_year","atom":263}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[256,257,264,265]}},{"Repetition":{"atom":255,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[242,267]}},{"Repetition":{"atom":241,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[236,237,238,240,269]}},{"Repetition":{"atom":235,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":321}},{"Entity":{"atom":2}},{"Str":{"pattern":"Appendix"}},{"Str":{"pattern":"App"}},{"Str":{"pattern":"Ap."}},{"Alternative":{"atoms":[274,275,276]}},{"Entity":{"atom":2}},{"Entity":{"atom":284}},{"Entity":{"atom":43}},{"Entity":{"atom":17}},{"Repetition":{"atom":281,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[280,282]}},{"Named":{"name":"appendix","atom":283}},{"Entity":{"atom":290}},{"Entity":{"atom":14}},{"Entity":{"atom":17}},{"Repetition":{"atom":287,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"appendix_subnumber","atom":288}},{"Sequence":{"atoms":[286,289]}},{"Repetition":{"atom":285,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":319}},{"Entity":{"atom":305}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":295,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":298,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":70}},{"Entity":{"atom":17}},{"Repetition":{"atom":301,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[296,297,299,300,302]}},{"Named":{"name":"appendix_edition","atom":303}},{"Sequence":{"atoms":[294,304]}},{"Entity":{"atom":317}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[309,310]}},{"Entity":{"atom":17}},{"Repetition":{"atom":312,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[311,313]}},{"Named":{"name":"appendix_year","atom":314}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[307,308,315,316]}},{"Repetition":{"atom":306,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[293,318]}},{"Repetition":{"atom":292,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[273,277,278,279,291,320]}},{"Repetition":{"atom":272,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":362}},{"Entity":{"atom":348}},{"Entity":{"atom":2}},{"Str":{"pattern":"Vol."}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":328,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"volume","atom":329}},{"Entity":{"atom":346}},{"Entity":{"atom":2}},{"Str":{"pattern":"Issue"}},{"Entity":{"atom":2}},{"Entity":{"atom":17}},{"Repetition":{"atom":335,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"issue","atom":336}},{"Sequence":{"atoms":[332,333,334,337]}},{"Entity":{"atom":2}},{"Str":{"pattern":"("}},{"Entity":{"atom":17}},{"Repetition":{"atom":341,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"issue","atom":342}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[339,340,343,344]}},{"Alternative":{"atoms":[338,345]}},{"Repetition":{"atom":331,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[325,326,327,330,347]}},{"Entity":{"atom":358}},{"Entity":{"atom":2}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[351,352]}},{"Entity":{"atom":17}},{"Repetition":{"atom":354,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[353,355]}},{"Named":{"name":"volume","atom":356}},{"Sequence":{"atoms":[350,357]}},{"Alternative":{"atoms":[324,349]}},{"Entity":{"atom":92}},{"Repetition":{"atom":360,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[359,361]}},{"Repetition":{"atom":323,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":135}},{"Repetition":{"atom":364,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[4,5,13,15,54,58,95,138,178,234,271,322,363,365]}}],"root":366},"bindings":[{"capture":"type","path":"type","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":"part_edition","path":"part_edition","type":"string","card":null,"preprocess":null},{"capture":"part_year","path":"part_year","type":"string","card":null,"preprocess":null},{"capture":"annex","path":"annex","type":"string","card":null,"preprocess":null},{"capture":"annex_edition","path":"annex_edition","type":"string","card":null,"preprocess":null},{"capture":"annex_year","path":"annex_year","type":"string","card":null,"preprocess":null},{"capture":"appendix","path":"appendix","type":"string","card":null,"preprocess":null},{"capture":"appendix_subnumber","path":"appendix_subnumber","type":"string","card":null,"preprocess":null},{"capture":"appendix_edition","path":"appendix_edition","type":"string","card":null,"preprocess":null},{"capture":"appendix_year","path":"appendix_year","type":"string","card":null,"preprocess":null},{"capture":"supplement","path":"supplement","type":"string","card":null,"preprocess":null},{"capture":"supplement_edition","path":"supplement_edition","type":"string","card":null,"preprocess":null},{"capture":"supplement_year","path":"supplement_year","type":"string","card":null,"preprocess":null},{"capture":"edition","path":"edition","type":"string","card":null,"preprocess":null},{"capture":"edition_shorthand","path":"edition_shorthand","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null},{"capture":"volume","path":"volume","type":"string","card":null,"preprocess":null},{"capture":"volume_edition","path":"volume_edition","type":"string","card":null,"preprocess":null},{"capture":"volume_year","path":"volume_year","type":"string","card":null,"preprocess":null},{"capture":"issue","path":"issue","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule volume_issue: 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":"S-5","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5 Appendix 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO B-12 3.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"P-5 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5 Vol. 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5/2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO B-7 Vol. 2023","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30 (2)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30 Issue 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1/21","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1/21 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Part 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 1.0.0 Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-65 1.1.0 Annex A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-122 1.0.0 Appendix D-2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-52 4.0.0 Appendix 1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO M-2 Sup 1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO M-2 Suppl 6","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-66 2.0.0 Sup 4","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5-B","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100-1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100-1 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6-3 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5A 1.0.2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5 1.0.2 Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Part 2 (2024)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 v5.1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 v1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 1.0.0 (2024) Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-53 Ap. 1 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 Part A 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158:100 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158:100 Part 2 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-1001","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158 Part S-102 0.2.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158-S-102 0.2.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6 1.0.0 Vol. 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6 Vol. 2 1.0.1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 1.0.0 Annex A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Sup 1 2.0.0","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO B-12 3.0","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO P-5 1850","expect":{}}],"docs":{},"source":"# Port of lib/pubid/iho/parser.rb — IHO identifiers: letter series\n# (S/P/M/B/C), a number with an optional suffix, and the full component\n# tail (edition, supplement, part, annex, appendix + subnumber, volume,\n# issue, year qualifier).\n#\n# == Component model (owner rulings, 2026-11-03)\n#\n# Every component below is a first-class semantic component: its own\n# named capture, its own typed binding, independently addressable in\n# the model, URN-encodable and matchable — never a regex/string suffix.\n#\n# component face capture binding type\n# edition x.y.z (bare) edition string\n# edition v1 / v5.1 (alias) edition_shorthand string (parse-only;\n# the builder pads to\n# x.y.0 — official IHO\n# edition is dotted\n# x.y.z WITHOUT a year)\n# supplement Sup N (Suppl N) supplement string\n# part Part X / Part S-102 part string (letter,\n# number, or SERIES\n# REFERENCE)\n# part -X / -S-102 (short) part string (hyphenated)\n# annex Annex A annex string\n# appendix Appendix B appendix string\n# appendix Appendix D-2 appendix_subnumber string (the -2)\n# volume Vol. N volume string\n# volume /N (short) volume string (the slash\n# chain, P-1/21 or\n# P-5/2020)\n# volume N (bare, legacy) volume string (the yearbook\n# year IS a volume —\n# one serial-locator\n# component)\n# issue (N) / Issue N issue string\n# year (2024) year string (the with-year\n# qualifier on\n# standards; NOT a\n# serial locator)\n#\n# == Component-edition duality (owner ruling: \"this can happen with any\n# independently publishable artifacts\")\n#\n# Supplement, part, annex, appendix and volume can be published on\n# their own publication cycle, so EACH carries an optional\n# `<kind>_edition` (+ `<kind>_year` qualifier) of its own, mutually\n# exclusive with the base edition context:\n#\n# within-edition: IHO P-6 1.0.0 Vol. 2 (the volume rides\n# the base's edition)\n# separately-published: IHO P-6 Vol. 2 1.0.1 (the volume carries\n# IHO S-98 Part A 1.0.0 its own edition;\n# IHO S-158 Part S-102 0.2.0 the base is\n# cited edition-less)\n#\n# In the URN the ed- segment attaches to the node it follows, so the\n# same positional slot records both modes.\n#\n# The part has a COMPACT face, hyphenated onto the code — `IHO S-5-B`\n# (lettered part), `IHO S-100-1` (numbered part), `IHO S-158-S-102`\n# (series-reference part) — which both parses and renders; the\n# canonical expanded face stays `IHO S-100 x.y.z Part 1`. Gluing a part\n# onto the code without a separator (S-5A) is DISALLOWED as a form: it\n# cannot extend to numbered parts without ambiguity (S-1001 = series\n# 1001 vs series 100 part 1). The four lettered bases the corpus\n# records (S-5A, S-5B, S-8A, S-8B) are LEGACY data spellings: they\n# still parse as aliases (S-5A == S-5 Part A) but are never rendered;\n# the owner rules later whether to reject them outright.\n#\n# Series-reference parts: a check standard applied to another IHO\n# series cites the applied series as its part — `IHO S-158 0.2.0 Part\n# S-102` (the wild glued `S-158-102` spelling is a legacy alias whose\n# normalization to Part S-102 needs an IHO series table; the syntax\n# alone cannot tell it from S-100-1 = Part 1, so it currently parses\n# as the plain number part).\n#\n# Two main syntaxes per the owner ruling: `IHO S-100 1.0.0` (dated =\n# edition-specific) and `IHO S-100` (undated = edition-non-specific).\n# A year beside an edition is the with-year variant qualifier\n# (`IHO S-100 1.0.0 Part X (2024)`), never a year-keyed docidentifier —\n# year-keyed docidentifiers for edition-keyed products are wrong. The\n# continuously-updated series have ONE serial locator, the volume:\n# P-1 and P-6 are volume-keyed (`IHO P-1 Vol. 30 (1)`), and the\n# yearbook year IS a volume (`IHO P-5 Vol. 2020`) — the bare year\n# (`IHO P-5 2020`) and all year-faced forms are parse-only legacy\n# aliases that bind into the volume component, never rendered.\n#\n# Aliases: \"Suppl\" (canonical face Sup, the M-2 spelling — why abbreviate\n# by two letters when Annex and Appendix stay full-length), \"App\"/\"Ap.\"\n# (canonical face Appendix), the hyphenated compact part face (S-5-B ==\n# S-5 Part B, S-100-1 == S-100 Part 1), the legacy glued lettered bases\n# (S-5A, parse-only), \"S-100 v1..v5.1\" (edition shorthand), \"Issue N\"\n# (canonical (N)), the bare year (canonical Vol. N).\n#\n# == URN segment grammar (positional, containment-ordered)\n#\n# The URN mirrors the containment tree, one semantic atom per segment:\n# Part contains Annexes; Annex contains Appendices; a D-2 subnumber is\n# a child atom of Appendix D. No key.value concatenations — every\n# non-number component is a marker-prefixed segment whose marker is the\n# lowercased human-face token (edition follows ISO's ed- precedent):\n#\n# urn:iho:<type>:<number>[:ed-<x.y.z>][:year-<yyyy>]\n# [:sup-<n>[:ed-<x.y.z>][:year-<yyyy>]]\n# [:part-<X>[:ed-<x.y.z>][:year-<yyyy>]]\n# [:annex-<A>[...]]\n# [:appendix-<B>[:<sub>][...]]\n# [:vol-<n>[:issue-<n>][...]]\n# [:year-<yyyy>]\n#\n# position segment value vocabulary containment\n# -------- --------------- -------------------------- ------------------\n# 1 <type> s / p / m / b / c namespace root\n# 2 <number> digits + : suffix; may document code\n# span bare segments until\n# the first marker\n# 3 ed-<x.y.z> dotted a.b.c edition qualifier;\n# 4 year-<yyyy> 19xx/20xx ATTACHES TO THE\n# NODE IT FOLLOWS: the\n# base (no component\n# before it) or the\n# component whose\n# segment precedes\n# 5 sup-<n> 1*digit wraps the base\n# 6 part-<X> letter (case kept), contains annexes\n# digits [*letter], or a\n# series reference\n# [SPMBC]-<digits>\n# 7 annex-<A> upper letter (case kept) contains appendices\n# 8 appendix-<B> upper letter or digits contains subnumber\n# 9 <sub> 1*digit, BARE, only child of appendix\n# directly after appendix-\n# 10 vol-<n> 1*digit (incl. yearbook contains issue\n# years, Vol. 2020)\n# 11 issue-<n> 1*digit, only after vol- child of volume\n#\n# The number occupies every leading bare segment up to the first\n# marker, so a colon number (S-158:100) round-trips without escaping;\n# after the markers the only bare segment allowed is the appendix\n# subnumber in its own slot. Both the year qualifier and the volume are\n# marker-tagged so neither can collide with a colon-number segment (the\n# #637 hazard, kept under the positional scheme). Letters are\n# case-preserved: part-A and part-a are distinct documents.\n#\n# Legacy 2.0.x spellings remain decodable but are never emitted: the\n# bare a.b.c segment (edition), the dotted keys part./annex./suppl./\n# ap./appendix./vol./issue. and the single-letter y. year tag (whose\n# value decodes into the volume — the serial-locator unification).\n#\n# Edition 2: ruby#400's capture-flatten keeps text captures over\n# reference-built rules as the matched text, so the v2 tree is the v1\n# tree plus named leaves for non-captured structure.\n\ngrammar PubidIho version \"0.2.0\" edition 2 {\n digit = %x30-39\n upper = %x41-5A\n lower = %x61-7A\n letter = upper / lower\n space = \" \"\n dash = \"-\"\n dot = \".\"\n\n series = (\"S\" / \"P\" / \"M\" / \"B\" / \"C\") as type\n number_suffix = (\":\" 1*digit)\n number = (1*digit [number_suffix]) as number\n # The compact part face, hyphenated onto the code: S-5-B (lettered),\n # S-100-1 (numbered) and S-158-S-102 (series reference) — the dash\n # replaces the old bare-glued suffix, so a number like S-1001 stays a\n # whole number (the dash is what makes the part unambiguous). The\n # dash is an inlined literal: a named dash ref here collides with the\n # sequence's own dash node in the edition-2 tree.\n compact_part = \"-\" (((\"S\" / \"P\" / \"M\" / \"B\" / \"C\") dash (1*digit)) / (1*digit [*letter]) / upper) as part\n # LEGACY glued lettered bases (S-5A, S-5B, S-8A, S-8B in the corpus):\n # parse-only aliases, never rendered. Kept because the records exist;\n # the owner rules later whether to reject them.\n glued = upper as part\n\n # The official edition is the dotted x.y.z; \"v1\"/\"v5.1\" is the S-100\n # shorthand (parse-only, the builder pads to x.y.0).\n edition = space (1*digit dot 1*digit dot 1*digit) as edition\n v_edition = space \"v\" ((1*digit) [\".\" (1*digit)]) as edition_shorthand\n # The with-year qualifier on standards: a parenthesized year beside an\n # edition. This is the ONLY base-level year capture — periodical\n # years are volumes (the serial-locator unification).\n year_qualifier = space \"(\" ((\"19\" / \"20\") 2*digit) as year \")\"\n\n # The series-reference part value: a check standard applied to\n # another IHO series (S-158 checks S-102). Ordered FIRST so \"Part\n # S-102\" takes the series-reference branch, not the lone letter.\n part_series_ref = ((\"S\" / \"P\" / \"M\" / \"B\" / \"C\") dash (1*digit))\n part_value = (part_series_ref / (1*digit [*letter]) / upper) as part\n\n # Component-edition duality: each independently-publishable component\n # may carry its own edition (+ year qualifier), mutually exclusive\n # with the base edition context. The captures are position-scoped\n # (<kind>_edition / <kind>_year) so the model knows which component\n # the edition belongs to and the URN attaches ed- to the node it\n # follows.\n part = space \"Part\" space part_value [part_dated]\n part_dated = {\n part_edition_rule\n [part_year_rule]\n }\n part_edition_rule = space (1*digit dot 1*digit dot 1*digit) as part_edition\n part_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as part_year \")\"\n\n supplement = space (\"Suppl\" / \"Sup\") space (1*digit) as supplement [supplement_dated]\n supplement_dated = {\n supplement_edition_rule\n [supplement_year_rule]\n }\n supplement_edition_rule = space (1*digit dot 1*digit dot 1*digit) as supplement_edition\n supplement_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as supplement_year \")\"\n\n annex = space \"Annex\" space upper as annex [annex_dated]\n annex_dated = {\n annex_edition_rule\n [annex_year_rule]\n }\n annex_edition_rule = space (1*digit dot 1*digit dot 1*digit) as annex_edition\n annex_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as annex_year \")\"\n\n appendix_value = (upper / (1*digit)) as appendix\n appendix_subnumber = dash (1*digit) as appendix_subnumber\n appendix = space (\"Appendix\" / \"App\" / \"Ap.\") space appendix_value [appendix_subnumber] [appendix_dated]\n appendix_dated = {\n appendix_edition_rule\n [appendix_year_rule]\n }\n appendix_edition_rule = space (1*digit dot 1*digit dot 1*digit) as appendix_edition\n appendix_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as appendix_year \")\"\n\n volume = space \"Vol.\" space (1*digit) as volume [volume_issue]\n volume_issue = (space \"Issue\" space (1*digit) as issue) / (space \"(\" (1*digit) as issue \")\")\n # The volume's short face — the slash chain (\"IHO P-1/21\",\n # \"IHO P-5/2020\"). The slash no longer joins the number.\n volume_short = \"/\" ((1*digit) as volume) [volume_dated]\n # LEGACY bare year (\"IHO P-5 2024\"): the yearbook year IS a volume,\n # so a bare year binds INTO the volume component. Parse-only alias;\n # the canonical print is \"Vol. N\".\n volume_bare_year = space ((\"19\" / \"20\") 2*digit) as volume\n # The volume's own edition (+ year), shared by the Vol. and slash\n # forms.\n volume_dated = {\n volume_edition_rule\n [volume_year_rule]\n }\n volume_edition_rule = space (1*digit dot 1*digit dot 1*digit) as volume_edition\n volume_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as volume_year \")\"\n\n # The edition slot accepts the dotted form or the v-shorthand; the\n # with-year qualifier may sit right after it.\n dated = {\n (edition / v_edition)\n [year_qualifier]\n }\n\n # The serial tail picks exactly one discriminator: the long volume\n # (with its optional issue) or the legacy bare year — both bind the\n # volume component, and both may carry the volume's own edition.\n serial = {\n (volume / volume_bare_year)\n [volume_dated]\n }\n\n identifier = {\n [(\"IHO\" space)]\n series\n dash\n number\n [compact_part]\n [glued]\n [volume_short]\n [dated]\n [supplement]\n [part]\n [annex]\n [appendix]\n [serial]\n [year_qualifier]\n }\n\n entry identifier: identifier\n\n test {\n accept \"S-5\"\n accept \"IHO S-5 Appendix 2\"\n accept \"IHO B-12 3.0.0\"\n accept \"IHO P-5 2024\"\n accept \"P-5 2024\"\n accept \"IHO P-5 Vol. 2024\"\n accept \"IHO P-5/2024\"\n accept \"IHO B-7 Vol. 2023\"\n accept \"IHO P-1 Vol. 30\"\n accept \"IHO P-1 Vol. 30 (2)\"\n accept \"IHO P-1 Vol. 30 Issue 2\"\n accept \"IHO P-1/21\"\n accept \"IHO P-1/21 1.0.0\"\n accept \"IHO S-100 5.0.0 Part 2\"\n accept \"IHO S-98 1.0.0 Part A\"\n accept \"IHO S-65 1.1.0 Annex A\"\n accept \"IHO S-122 1.0.0 Appendix D-2\"\n accept \"IHO S-52 4.0.0 Appendix 1\"\n accept \"IHO M-2 Sup 1\"\n accept \"IHO M-2 Suppl 6\"\n accept \"IHO S-66 2.0.0 Sup 4\"\n accept \"IHO S-5-B\"\n accept \"IHO S-100-1\"\n accept \"IHO S-100-1 1.0.0\"\n accept \"IHO P-6-3 1.0.0\"\n accept \"IHO S-5A\"\n accept \"IHO S-5A 1.0.2\"\n accept \"IHO S-5 1.0.2 Part A\"\n accept \"IHO S-100 5.0.0 Part 2 (2024)\"\n accept \"IHO S-100 v5.1\"\n accept \"IHO S-100 v1\"\n accept \"IHO S-100 1.0.0 (2024) Part A\"\n accept \"IHO S-53 Ap. 1 1.0.0\"\n accept \"IHO S-98 Part A 1.0.0\"\n accept \"IHO S-158:100 1.0.0\"\n accept \"IHO S-158:100 Part 2 1.0.0\"\n accept \"IHO S-1001\"\n accept \"IHO S-158 Part S-102 0.2.0\"\n accept \"IHO S-158-S-102 0.2.0\"\n accept \"IHO P-6 1.0.0 Vol. 2\"\n accept \"IHO P-6 Vol. 2 1.0.1\"\n accept \"IHO S-98 1.0.0 Annex A\"\n accept \"IHO S-100 5.0.0 Sup 1 2.0.0\"\n reject \"nonsense\"\n reject \"IHO B-12 3.0\"\n reject \"IHO P-5 1850\"\n }\n\n bindings identifier {\n type -> type (string)\n number -> number (string)\n part -> part (string)\n part_edition -> part_edition (string)\n part_year -> part_year (string)\n annex -> annex (string)\n annex_edition -> annex_edition (string)\n annex_year -> annex_year (string)\n appendix -> appendix (string)\n appendix_subnumber -> appendix_subnumber (string)\n appendix_edition -> appendix_edition (string)\n appendix_year -> appendix_year (string)\n supplement -> supplement (string)\n supplement_edition -> supplement_edition (string)\n supplement_year -> supplement_year (string)\n edition -> edition (string)\n edition_shorthand -> edition_shorthand (string)\n year -> year (string)\n volume -> volume (string)\n volume_edition -> volume_edition (string)\n volume_year -> volume_year (string)\n issue -> issue (string)\n }\n}\n","source_hash":"66d50de135e5c416bfe003de604effff57ed3b556a7126262c449b5c850995ac","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:711b011976f08ffc691672fafa41f9b60e3f6024a2608451043836fd6d05eff0","checksum":"sha256:15324490896b11703cb63893072ed77fbc43f43e47dd166ae8ddb235e3c2202e"}
|
|
1
|
+
{"bindings":null,"version":"0.3.0","grammar":"PubidIho","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier_entry","grammar":{"atoms":[{"Entity":{"atom":41}},{"Str":{"pattern":"IHO"}},{"Entity":{"atom":3}},{"Str":{"pattern":" "}},{"Sequence":{"atoms":[1,2]}},{"Repetition":{"atom":4,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"B"}},{"Named":{"name":"spec_part","atom":6}},{"Entity":{"atom":9}},{"Str":{"pattern":"-"}},{"Entity":{"atom":23}},{"Entity":{"atom":22}},{"Str":{"pattern":"1"}},{"Str":{"pattern":"2"}},{"Str":{"pattern":"3"}},{"Str":{"pattern":"4"}},{"Str":{"pattern":"5"}},{"Str":{"pattern":"6"}},{"Alternative":{"atoms":[12,13,14,15,16,17]}},{"Entity":{"atom":20}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Entity":{"atom":20}},{"Sequence":{"atoms":[18,19,21]}},{"Named":{"name":"spec","atom":11}},{"Entity":{"atom":30}},{"Entity":{"atom":26}},{"Str":{"pattern":"."}},{"Entity":{"atom":20}},{"Repetition":{"atom":27,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"spec_sub","atom":28}},{"Sequence":{"atoms":[25,29]}},{"Repetition":{"atom":24,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":39}},{"Str":{"pattern":"("}},{"Entity":{"atom":35}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Repetition":{"atom":34,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"spec_variant","atom":36}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[33,37,38]}},{"Repetition":{"atom":32,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[5,7,8,10,31,40]}},{"Entity":{"atom":435}},{"Str":{"pattern":"IHO"}},{"Entity":{"atom":3}},{"Sequence":{"atoms":[43,44]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":54}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[48,49,50,51,52]}},{"Named":{"name":"type","atom":53}},{"Entity":{"atom":9}},{"Entity":{"atom":66}},{"Entity":{"atom":20}},{"Repetition":{"atom":57,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":63}},{"Str":{"pattern":":"}},{"Entity":{"atom":20}},{"Repetition":{"atom":61,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[60,62]}},{"Repetition":{"atom":59,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[58,64]}},{"Named":{"name":"number","atom":65}},{"Entity":{"atom":92}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[69,70,71,72,73]}},{"Entity":{"atom":9}},{"Entity":{"atom":20}},{"Repetition":{"atom":76,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[74,75,77]}},{"Entity":{"atom":20}},{"Repetition":{"atom":79,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":85}},{"Entity":{"atom":35}},{"Entity":{"atom":84}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[82,83]}},{"Repetition":{"atom":81,"min":0,"max":null,"tag":"Repetition"}},{"Repetition":{"atom":86,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[80,87]}},{"Entity":{"atom":35}},{"Alternative":{"atoms":[78,88,89]}},{"Named":{"name":"part","atom":90}},{"Sequence":{"atoms":[68,91]}},{"Repetition":{"atom":67,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":96}},{"Entity":{"atom":35}},{"Named":{"name":"part","atom":95}},{"Repetition":{"atom":94,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":132}},{"Str":{"pattern":"/"}},{"Entity":{"atom":20}},{"Repetition":{"atom":100,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"volume","atom":101}},{"Entity":{"atom":130}},{"Entity":{"atom":116}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":106,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":109,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":112,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[107,108,110,111,113]}},{"Named":{"name":"volume_edition","atom":114}},{"Sequence":{"atoms":[105,115]}},{"Entity":{"atom":128}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[120,121]}},{"Entity":{"atom":20}},{"Repetition":{"atom":123,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[122,124]}},{"Named":{"name":"volume_year","atom":125}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[118,119,126,127]}},{"Repetition":{"atom":117,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[104,129]}},{"Repetition":{"atom":103,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[99,102,131]}},{"Repetition":{"atom":98,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":175}},{"Entity":{"atom":147}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":137,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":140,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":143,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[138,139,141,142,144]}},{"Named":{"name":"edition","atom":145}},{"Sequence":{"atoms":[136,146]}},{"Entity":{"atom":160}},{"Entity":{"atom":3}},{"Str":{"pattern":"v"}},{"Entity":{"atom":20}},{"Repetition":{"atom":151,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":20}},{"Repetition":{"atom":154,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[153,155]}},{"Repetition":{"atom":156,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[152,157]}},{"Named":{"name":"edition_shorthand","atom":158}},{"Sequence":{"atoms":[149,150,159]}},{"Alternative":{"atoms":[135,148]}},{"Entity":{"atom":173}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[165,166]}},{"Entity":{"atom":20}},{"Repetition":{"atom":168,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[167,169]}},{"Named":{"name":"year","atom":170}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[163,164,171,172]}},{"Repetition":{"atom":162,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[161,174]}},{"Repetition":{"atom":134,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":215}},{"Entity":{"atom":3}},{"Str":{"pattern":"Suppl"}},{"Str":{"pattern":"Sup"}},{"Alternative":{"atoms":[179,180]}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":183,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"supplement","atom":184}},{"Entity":{"atom":213}},{"Entity":{"atom":199}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":189,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":192,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":195,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[190,191,193,194,196]}},{"Named":{"name":"supplement_edition","atom":197}},{"Sequence":{"atoms":[188,198]}},{"Entity":{"atom":211}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[203,204]}},{"Entity":{"atom":20}},{"Repetition":{"atom":206,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[205,207]}},{"Named":{"name":"supplement_year","atom":208}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[201,202,209,210]}},{"Repetition":{"atom":200,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[187,212]}},{"Repetition":{"atom":186,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[178,181,182,185,214]}},{"Repetition":{"atom":177,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":297}},{"Entity":{"atom":3}},{"Str":{"pattern":"Part"}},{"Entity":{"atom":3}},{"Entity":{"atom":241}},{"Entity":{"atom":232}},{"Str":{"pattern":"S"}},{"Str":{"pattern":"P"}},{"Str":{"pattern":"M"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[223,224,225,226,227]}},{"Entity":{"atom":9}},{"Entity":{"atom":20}},{"Repetition":{"atom":230,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[228,229,231]}},{"Entity":{"atom":20}},{"Repetition":{"atom":233,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":85}},{"Repetition":{"atom":235,"min":0,"max":null,"tag":"Repetition"}},{"Repetition":{"atom":236,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[234,237]}},{"Entity":{"atom":35}},{"Alternative":{"atoms":[222,238,239]}},{"Named":{"name":"part","atom":240}},{"Entity":{"atom":269}},{"Entity":{"atom":255}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":245,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":248,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":251,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[246,247,249,250,252]}},{"Named":{"name":"part_edition","atom":253}},{"Sequence":{"atoms":[244,254]}},{"Entity":{"atom":267}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[259,260]}},{"Entity":{"atom":20}},{"Repetition":{"atom":262,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[261,263]}},{"Named":{"name":"part_year","atom":264}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[257,258,265,266]}},{"Repetition":{"atom":256,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[243,268]}},{"Repetition":{"atom":242,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":295}},{"Str":{"pattern":","}},{"Entity":{"atom":3}},{"Str":{"pattern":"Section"}},{"Entity":{"atom":3}},{"Entity":{"atom":22}},{"Named":{"name":"spec_section","atom":276}},{"Str":{"pattern":","}},{"Entity":{"atom":3}},{"Entity":{"atom":292}},{"Str":{"pattern":"A"}},{"Str":{"pattern":"B"}},{"Str":{"pattern":"C"}},{"Alternative":{"atoms":[281,282,283]}},{"Named":{"name":"spec_part","atom":284}},{"Entity":{"atom":9}},{"Entity":{"atom":23}},{"Entity":{"atom":30}},{"Repetition":{"atom":288,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":39}},{"Repetition":{"atom":290,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[285,286,287,289,291]}},{"Sequence":{"atoms":[278,279,280]}},{"Repetition":{"atom":293,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[272,273,274,275,277,294]}},{"Repetition":{"atom":271,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[218,219,220,221,270,296]}},{"Repetition":{"atom":217,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":302}},{"Entity":{"atom":3}},{"Entity":{"atom":292}},{"Sequence":{"atoms":[300,301]}},{"Repetition":{"atom":299,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":339}},{"Entity":{"atom":3}},{"Str":{"pattern":"Annex"}},{"Entity":{"atom":3}},{"Entity":{"atom":35}},{"Named":{"name":"annex","atom":308}},{"Entity":{"atom":337}},{"Entity":{"atom":323}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":313,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":316,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":319,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[314,315,317,318,320]}},{"Named":{"name":"annex_edition","atom":321}},{"Sequence":{"atoms":[312,322]}},{"Entity":{"atom":335}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[327,328]}},{"Entity":{"atom":20}},{"Repetition":{"atom":330,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[329,331]}},{"Named":{"name":"annex_year","atom":332}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[325,326,333,334]}},{"Repetition":{"atom":324,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[311,336]}},{"Repetition":{"atom":310,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[305,306,307,309,338]}},{"Repetition":{"atom":304,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":390}},{"Entity":{"atom":3}},{"Str":{"pattern":"Appendix"}},{"Str":{"pattern":"App"}},{"Str":{"pattern":"Ap."}},{"Alternative":{"atoms":[343,344,345]}},{"Entity":{"atom":3}},{"Entity":{"atom":353}},{"Entity":{"atom":35}},{"Entity":{"atom":20}},{"Repetition":{"atom":350,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[349,351]}},{"Named":{"name":"appendix","atom":352}},{"Entity":{"atom":359}},{"Entity":{"atom":9}},{"Entity":{"atom":20}},{"Repetition":{"atom":356,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"appendix_subnumber","atom":357}},{"Sequence":{"atoms":[355,358]}},{"Repetition":{"atom":354,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":388}},{"Entity":{"atom":374}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":364,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":367,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":26}},{"Entity":{"atom":20}},{"Repetition":{"atom":370,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[365,366,368,369,371]}},{"Named":{"name":"appendix_edition","atom":372}},{"Sequence":{"atoms":[363,373]}},{"Entity":{"atom":386}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[378,379]}},{"Entity":{"atom":20}},{"Repetition":{"atom":381,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[380,382]}},{"Named":{"name":"appendix_year","atom":383}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[376,377,384,385]}},{"Repetition":{"atom":375,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[362,387]}},{"Repetition":{"atom":361,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[342,346,347,348,360,389]}},{"Repetition":{"atom":341,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":431}},{"Entity":{"atom":417}},{"Entity":{"atom":3}},{"Str":{"pattern":"Vol."}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":397,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"volume","atom":398}},{"Entity":{"atom":415}},{"Entity":{"atom":3}},{"Str":{"pattern":"Issue"}},{"Entity":{"atom":3}},{"Entity":{"atom":20}},{"Repetition":{"atom":404,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"issue","atom":405}},{"Sequence":{"atoms":[401,402,403,406]}},{"Entity":{"atom":3}},{"Str":{"pattern":"("}},{"Entity":{"atom":20}},{"Repetition":{"atom":410,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"issue","atom":411}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[408,409,412,413]}},{"Alternative":{"atoms":[407,414]}},{"Repetition":{"atom":400,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[394,395,396,399,416]}},{"Entity":{"atom":427}},{"Entity":{"atom":3}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[420,421]}},{"Entity":{"atom":20}},{"Repetition":{"atom":423,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[422,424]}},{"Named":{"name":"volume","atom":425}},{"Sequence":{"atoms":[419,426]}},{"Alternative":{"atoms":[393,418]}},{"Entity":{"atom":130}},{"Repetition":{"atom":429,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[428,430]}},{"Repetition":{"atom":392,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":173}},{"Repetition":{"atom":433,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[46,47,55,56,93,97,133,176,216,298,303,340,391,432,434]}},{"Alternative":{"atoms":[0,42]}}],"root":436},"bindings":[{"capture":"type","path":"type","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":"part_edition","path":"part_edition","type":"string","card":null,"preprocess":null},{"capture":"part_year","path":"part_year","type":"string","card":null,"preprocess":null},{"capture":"annex","path":"annex","type":"string","card":null,"preprocess":null},{"capture":"annex_edition","path":"annex_edition","type":"string","card":null,"preprocess":null},{"capture":"annex_year","path":"annex_year","type":"string","card":null,"preprocess":null},{"capture":"appendix","path":"appendix","type":"string","card":null,"preprocess":null},{"capture":"appendix_subnumber","path":"appendix_subnumber","type":"string","card":null,"preprocess":null},{"capture":"appendix_edition","path":"appendix_edition","type":"string","card":null,"preprocess":null},{"capture":"appendix_year","path":"appendix_year","type":"string","card":null,"preprocess":null},{"capture":"supplement","path":"supplement","type":"string","card":null,"preprocess":null},{"capture":"supplement_edition","path":"supplement_edition","type":"string","card":null,"preprocess":null},{"capture":"supplement_year","path":"supplement_year","type":"string","card":null,"preprocess":null},{"capture":"edition","path":"edition","type":"string","card":null,"preprocess":null},{"capture":"edition_shorthand","path":"edition_shorthand","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null},{"capture":"volume","path":"volume","type":"string","card":null,"preprocess":null},{"capture":"volume_edition","path":"volume_edition","type":"string","card":null,"preprocess":null},{"capture":"volume_year","path":"volume_year","type":"string","card":null,"preprocess":null},{"capture":"issue","path":"issue","type":"string","card":null,"preprocess":null},{"capture":"spec","path":"spec","type":"string","card":null,"preprocess":null},{"capture":"spec_sub","path":"spec_sub","type":"string","card":null,"preprocess":null},{"capture":"spec_variant","path":"spec_variant","type":"string","card":null,"preprocess":null},{"capture":"spec_part","path":"spec_part","type":"string","card":null,"preprocess":null},{"capture":"spec_section","path":"spec_section","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule volume_issue: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier_entry: 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":"S-5","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5 Appendix 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO B-12 3.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"P-5 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5 Vol. 2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-5/2024","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO B-7 Vol. 2023","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30 (2)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1 Vol. 30 Issue 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1/21","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-1/21 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Part 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 1.0.0 Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-65 1.1.0 Annex A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-122 1.0.0 Appendix D-2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-52 4.0.0 Appendix 1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO M-2 Sup 1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO M-2 Suppl 6","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-66 2.0.0 Sup 4","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5-B","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100-1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100-1 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6-3 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5A 1.0.2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-5 1.0.2 Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Part 2 (2024)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 v5.1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 v1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 1.0.0 (2024) Part A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-53 Ap. 1 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 Part A 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158:100 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158:100 Part 2 1.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-1001","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158 Part S-102 0.2.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-158-S-102 0.2.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6 1.0.0 Vol. 2","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO P-6 Vol. 2 1.0.1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-98 1.0.0 Annex A","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-100 5.0.0 Sup 1 2.0.0","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-401","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 4.10.0 B-401","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-122.1","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-521(I)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-351.1(I)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-400","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 B-170","expect":{}},{"entry":"identifier","kind":"accept","input":"B-401","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO B-401","expect":{}},{"entry":"identifier","kind":"accept","input":"B-122.1","expect":{}},{"entry":"identifier","kind":"accept","input":"B-521(I)","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 Part B, Section 400","expect":{}},{"entry":"identifier","kind":"accept","input":"S-4 Part B, Section 400","expect":{}},{"entry":"identifier","kind":"accept","input":"IHO S-4 Part B, Section 400, B-401","expect":{}},{"entry":"identifier","kind":"accept","input":"B-12","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO S-4 B-4","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO S-4 B-40","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO S-4 B-800","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO B-12 3.0","expect":{}},{"entry":"identifier","kind":"reject","input":"IHO P-5 1850","expect":{}}],"docs":{},"source":"# Port of lib/pubid/iho/parser.rb — IHO identifiers: letter series\n# (S/P/M/B/C), a number with an optional suffix, and the full component\n# tail (edition, supplement, part, annex, appendix + subnumber, volume,\n# issue, year qualifier).\n#\n# == Component model (owner rulings, 2026-11-03)\n#\n# Every component below is a first-class semantic component: its own\n# named capture, its own typed binding, independently addressable in\n# the model, URN-encodable and matchable — never a regex/string suffix.\n#\n# component face capture binding type\n# edition x.y.z (bare) edition string\n# edition v1 / v5.1 (alias) edition_shorthand string (parse-only;\n# the builder pads to\n# x.y.0 — official IHO\n# edition is dotted\n# x.y.z WITHOUT a year)\n# supplement Sup N (Suppl N) supplement string\n# part Part X / Part S-102 part string (letter,\n# number, or SERIES\n# REFERENCE)\n# part -X / -S-102 (short) part string (hyphenated)\n# annex Annex A annex string\n# appendix Appendix B appendix string\n# appendix Appendix D-2 appendix_subnumber string (the -2)\n# volume Vol. N volume string\n# volume /N (short) volume string (the slash\n# chain, P-1/21 or\n# P-5/2020)\n# volume N (bare, legacy) volume string (the yearbook\n# year IS a volume —\n# one serial-locator\n# component)\n# issue (N) / Issue N issue string\n# year (2024) year string (the with-year\n# qualifier on\n# standards; NOT a\n# serial locator)\n#\n# == Component-edition duality (owner ruling: \"this can happen with any\n# independently publishable artifacts\")\n#\n# Supplement, part, annex, appendix and volume can be published on\n# their own publication cycle, so EACH carries an optional\n# `<kind>_edition` (+ `<kind>_year` qualifier) of its own, mutually\n# exclusive with the base edition context:\n#\n# within-edition: IHO P-6 1.0.0 Vol. 2 (the volume rides\n# the base's edition)\n# separately-published: IHO P-6 Vol. 2 1.0.1 (the volume carries\n# IHO S-98 Part A 1.0.0 its own edition;\n# IHO S-158 Part S-102 0.2.0 the base is\n# cited edition-less)\n#\n# In the URN the ed- segment attaches to the node it follows, so the\n# same positional slot records both modes.\n#\n# The part has a COMPACT face, hyphenated onto the code — `IHO S-5-B`\n# (lettered part), `IHO S-100-1` (numbered part), `IHO S-158-S-102`\n# (series-reference part) — which both parses and renders; the\n# canonical expanded face stays `IHO S-100 x.y.z Part 1`. Gluing a part\n# onto the code without a separator (S-5A) is DISALLOWED as a form: it\n# cannot extend to numbered parts without ambiguity (S-1001 = series\n# 1001 vs series 100 part 1). The four lettered bases the corpus\n# records (S-5A, S-5B, S-8A, S-8B) are LEGACY data spellings: they\n# still parse as aliases (S-5A == S-5 Part A) but are never rendered;\n# the owner rules later whether to reject them outright.\n#\n# Series-reference parts: a check standard applied to another IHO\n# series cites the applied series as its part — `IHO S-158 0.2.0 Part\n# S-102` (the wild glued `S-158-102` spelling is a legacy alias whose\n# normalization to Part S-102 needs an IHO series table; the syntax\n# alone cannot tell it from S-100-1 = Part 1, so it currently parses\n# as the plain number part).\n#\n# Two main syntaxes per the owner ruling: `IHO S-100 1.0.0` (dated =\n# edition-specific) and `IHO S-100` (undated = edition-non-specific).\n# A year beside an edition is the with-year variant qualifier\n# (`IHO S-100 1.0.0 Part X (2024)`), never a year-keyed docidentifier —\n# year-keyed docidentifiers for edition-keyed products are wrong. The\n# continuously-updated series have ONE serial locator, the volume:\n# P-1 and P-6 are volume-keyed (`IHO P-1 Vol. 30 (1)`), and the\n# yearbook year IS a volume (`IHO P-5 Vol. 2020`) — the bare year\n# (`IHO P-5 2020`) and all year-faced forms are parse-only legacy\n# aliases that bind into the volume component, never rendered.\n#\n# Aliases: \"Suppl\" (canonical face Sup, the M-2 spelling — why abbreviate\n# by two letters when Annex and Appendix stay full-length), \"App\"/\"Ap.\"\n# (canonical face Appendix), the hyphenated compact part face (S-5-B ==\n# S-5 Part B, S-100-1 == S-100 Part 1), the legacy glued lettered bases\n# (S-5A, parse-only), \"S-100 v1..v5.1\" (edition shorthand), \"Issue N\"\n# (canonical (N)), the bare year (canonical Vol. N).\n#\n# == URN segment grammar (positional, containment-ordered)\n#\n# The URN mirrors the containment tree, one semantic atom per segment:\n# Part contains Annexes; Annex contains Appendices; a D-2 subnumber is\n# a child atom of Appendix D. No key.value concatenations — every\n# non-number component is a marker-prefixed segment whose marker is the\n# lowercased human-face token (edition follows ISO's ed- precedent).\n# An S-4 specification is a child of its Part (the citation letter rides\n# the part- atom), with the dotted sub and the parenthesized variant as\n# its own children:\n#\n# urn:iho:<type>:<number>[:ed-<x.y.z>][:year-<yyyy>]\n# [:sup-<n>[:ed-<x.y.z>][:year-<yyyy>]]\n# [:part-<X>[:ed-<x.y.z>][:year-<yyyy>]]\n# [:spec-<n>[:specsub-<n>][:specvar-<X>]]\n# [:annex-<A>[...]]\n# [:appendix-<B>[:<sub>][...]]\n# [:vol-<n>[:issue-<n>][...]]\n# [:year-<yyyy>]\n#\n# position segment value vocabulary containment\n# -------- --------------- -------------------------- ------------------\n# 1 <type> s / p / m / b / c namespace root\n# 2 <number> digits + : suffix; may document code\n# span bare segments until\n# the first marker\n# 3 ed-<x.y.z> dotted a.b.c edition qualifier;\n# 4 year-<yyyy> 19xx/20xx ATTACHES TO THE\n# NODE IT FOLLOWS: the\n# base (no component\n# before it) or the\n# component whose\n# segment precedes\n# 5 sup-<n> 1*digit wraps the base\n# 6 part-<X> letter (case kept), contains annexes\n# digits [*letter], or a and S-4 specs\n# series reference\n# [SPMBC]-<digits>\n# 7 spec-<n> [1-6]dd, only under an child of part (the\n# S-4 anchor (s:4) S-4 leaf; the\n# section is the\n# hundreds digit,\n# derivable, never\n# emitted)\n# 8 specsub-<n> 1*digit, only after spec- child of spec\n# 9 specvar-<X> upper letters, after child of spec\n# spec- or specsub-\n# 10 annex-<A> upper letter (case kept) contains appendices\n# 11 appendix-<B> upper letter or digits contains subnumber\n# 12 <sub> 1*digit, BARE, only child of appendix\n# directly after appendix-\n# 13 vol-<n> 1*digit (incl. yearbook contains issue\n# years, Vol. 2020)\n# 14 issue-<n> 1*digit, only after vol- child of volume\n#\n# The number occupies every leading bare segment up to the first\n# marker, so a colon number (S-158:100) round-trips without escaping;\n# after the markers the only bare segment allowed is the appendix\n# subnumber in its own slot. Both the year qualifier and the volume are\n# marker-tagged so neither can collide with a colon-number segment (the\n# #637 hazard, kept under the positional scheme). Letters are\n# case-preserved: part-A and part-a are distinct documents.\n#\n# Legacy 2.0.x spellings remain decodable but are never emitted: the\n# bare a.b.c segment (edition), the dotted keys part./annex./suppl./\n# ap./appendix./vol./issue. and the single-letter y. year tag (whose\n# value decodes into the volume — the serial-locator unification).\n#\n# == S-4 loose-leaf sections and specifications (issue #691; owner\n# rulings of 2026-11-11)\n#\n# The S-4 loose-leaf publication cites its regulations/specifications as\n# <letter>-<hundreds><seq>: B-401 is Part B, Section 400, item 01. ONE\n# component, not two tiers: the spec number IS the leaf; the SECTION is\n# the hundreds digit, DERIVED (never stored, never emitted). The `00`\n# slot (B-400) IS the section-level citation, so \"S-4 Part B, Section\n# 400\" and \"IHO S-4 B-400\" are one identity, two spellings.\n#\n# capture example role\n# spec B-401 -> \"401\" the leaf number (3 digits,\n# hundreds 1-6: sections 100-600)\n# spec_sub B-122.1 -> \"1\" the dotted sub\n# spec_variant B-521(I) -> \"I\" the parenthesized variant\n# spec_part B-401 -> \"B\" the citation letter (the builder\n# binds it into `part`; a Part-rule\n# capture must agree)\n# spec_section \", Section 400\" -> \"400\" the long form's spelled\n# section (becomes `spec` alone;\n# checked against a citation)\n#\n# Faces: canonical compact \"IHO S-4 B-401\" (dated: \"IHO S-4 4.10.0\n# B-401\"); long \"S-4 Part B, Section 400\" (a normalizing parse; also\n# takes a trailing citation: \"S-4 Part B, Section 400, B-401\", where the\n# spelled section only cross-checks the citation's derived section); bare\n# \"B-401\" (implicit S-4 anchor; B only — bare C-x stays the Circular\n# Letter series). The builder binds the anchor: a citation requires the\n# S-4 anchor (or synthesizes it for the bare form).\n#\n# Reserved numbers (\"NOT CURRENTLY USED\" in the S-4 contents — B-170,\n# B-230, B-305, B-323 in Ed 4.9.0 and 4.10.0) parse and resolve AS\n# RESERVED, never invalid; the edition-keyed registry lives in the pubid\n# gem (data/iho/s4-reserved-specs.yaml).\n#\n# URN atoms: part-<letter>:spec-<n>[:specsub-<n>][:specvar-<X>] — the\n# section is NOT emitted (derivable); the citation letter rides the\n# existing part- atom (case preserved: part-B).\n#\n# Edition 2: ruby#400's capture-flatten keeps text captures over\n# reference-built rules as the matched text, so the v2 tree is the v1\n# tree plus named leaves for non-captured structure.\n\ngrammar PubidIho version \"0.3.0\" edition 2 {\n digit = %x30-39\n upper = %x41-5A\n lower = %x61-7A\n letter = upper / lower\n space = \" \"\n dash = \"-\"\n dot = \".\"\n\n series = (\"S\" / \"P\" / \"M\" / \"B\" / \"C\") as type\n number_suffix = (\":\" 1*digit)\n number = (1*digit [number_suffix]) as number\n # The compact part face, hyphenated onto the code: S-5-B (lettered),\n # S-100-1 (numbered) and S-158-S-102 (series reference) — the dash\n # replaces the old bare-glued suffix, so a number like S-1001 stays a\n # whole number (the dash is what makes the part unambiguous). The\n # dash is an inlined literal: a named dash ref here collides with the\n # sequence's own dash node in the edition-2 tree.\n compact_part = \"-\" (((\"S\" / \"P\" / \"M\" / \"B\" / \"C\") dash (1*digit)) / (1*digit [*letter]) / upper) as part\n # LEGACY glued lettered bases (S-5A, S-5B, S-8A, S-8B in the corpus):\n # parse-only aliases, never rendered. Kept because the records exist;\n # the owner rules later whether to reject them.\n glued = upper as part\n\n # The official edition is the dotted x.y.z; \"v1\"/\"v5.1\" is the S-100\n # shorthand (parse-only, the builder pads to x.y.0).\n edition = space (1*digit dot 1*digit dot 1*digit) as edition\n v_edition = space \"v\" ((1*digit) [\".\" (1*digit)]) as edition_shorthand\n # The with-year qualifier on standards: a parenthesized year beside an\n # edition. This is the ONLY base-level year capture — periodical\n # years are volumes (the serial-locator unification).\n year_qualifier = space \"(\" ((\"19\" / \"20\") 2*digit) as year \")\"\n\n # The series-reference part value: a check standard applied to\n # another IHO series (S-158 checks S-102). Ordered FIRST so \"Part\n # S-102\" takes the series-reference branch, not the lone letter.\n part_series_ref = ((\"S\" / \"P\" / \"M\" / \"B\" / \"C\") dash (1*digit))\n part_value = (part_series_ref / (1*digit [*letter]) / upper) as part\n\n # Component-edition duality: each independently-publishable component\n # may carry its own edition (+ year qualifier), mutually exclusive\n # with the base edition context. The captures are position-scoped\n # (<kind>_edition / <kind>_year) so the model knows which component\n # the edition belongs to and the URN attaches ed- to the node it\n # follows.\n part = space \"Part\" space part_value [part_dated] [part_section_tail]\n part_dated = {\n part_edition_rule\n [part_year_rule]\n }\n part_edition_rule = space (1*digit dot 1*digit dot 1*digit) as part_edition\n part_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as part_year \")\"\n\n # --- S-4 loose-leaf sections and specifications (see the header) ---\n # The spec number's vocabulary: the S-4 sections run 100-600 (Part C\n # 100-500), so the leaf number is 3 digits with hundreds digit 1-6 —\n # the same shape the bare citation branch leans on to keep the B\n # Bibliographic series (B-1..B-13 style) distinct from B-4xx specs.\n spec_shape = (\"1\" / \"2\" / \"3\" / \"4\" / \"5\" / \"6\") digit digit\n spec_number = spec_shape as spec\n spec_subnumber = dot (1*digit) as spec_sub\n spec_variant = \"(\" (1*upper) as spec_variant \")\"\n # The citation letter is the spec's part (A/B/C); the builder binds it\n # into `part` and rejects a conflicting Part-rule capture.\n spec_citation_body = (\"A\" / \"B\" / \"C\") as spec_part dash spec_number [spec_subnumber] [spec_variant]\n # The compact anchor form: the citation follows the code after one\n # space (\"IHO S-4 B-401\").\n spec_citation = space spec_citation_body\n # The spelled section long form: \"Part B, Section 400\" — the spelled\n # number becomes the spec (the section-level citation), and a trailing\n # citation (\", Section 400, B-401\") makes it a cross-check only. The\n # commas are inlined literals: named comma refs collide as duplicate\n # edition-2 tree nodes under the entry's alternation (the same node\n # collision the compact_part dash-ref comment documents).\n part_section_tail = {\n \",\" space \"Section\" space (spec_shape as spec_section)\n [\",\" space spec_citation_body]\n }\n\n # The bare citation branch (the entry's FIRST alternative): \"B-401\" /\n # \"IHO B-401\" — implicit S-4 anchor (the builder synthesizes series S\n # number 4). B only: bare C-x stays the Circular Letter series, and the\n # 3-digit [1-6]xx shape keeps the B Bibliographic series (B-12) on the\n # main branch.\n bare_spec_citation = [(\"IHO\" space)] (\"B\" as spec_part) dash spec_number [spec_subnumber] [spec_variant]\n\n supplement = space (\"Suppl\" / \"Sup\") space (1*digit) as supplement [supplement_dated]\n supplement_dated = {\n supplement_edition_rule\n [supplement_year_rule]\n }\n supplement_edition_rule = space (1*digit dot 1*digit dot 1*digit) as supplement_edition\n supplement_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as supplement_year \")\"\n\n annex = space \"Annex\" space upper as annex [annex_dated]\n annex_dated = {\n annex_edition_rule\n [annex_year_rule]\n }\n annex_edition_rule = space (1*digit dot 1*digit dot 1*digit) as annex_edition\n annex_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as annex_year \")\"\n\n appendix_value = (upper / (1*digit)) as appendix\n appendix_subnumber = dash (1*digit) as appendix_subnumber\n appendix = space (\"Appendix\" / \"App\" / \"Ap.\") space appendix_value [appendix_subnumber] [appendix_dated]\n appendix_dated = {\n appendix_edition_rule\n [appendix_year_rule]\n }\n appendix_edition_rule = space (1*digit dot 1*digit dot 1*digit) as appendix_edition\n appendix_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as appendix_year \")\"\n\n volume = space \"Vol.\" space (1*digit) as volume [volume_issue]\n volume_issue = (space \"Issue\" space (1*digit) as issue) / (space \"(\" (1*digit) as issue \")\")\n # The volume's short face — the slash chain (\"IHO P-1/21\",\n # \"IHO P-5/2020\"). The slash no longer joins the number.\n volume_short = \"/\" ((1*digit) as volume) [volume_dated]\n # LEGACY bare year (\"IHO P-5 2024\"): the yearbook year IS a volume,\n # so a bare year binds INTO the volume component. Parse-only alias;\n # the canonical print is \"Vol. N\".\n volume_bare_year = space ((\"19\" / \"20\") 2*digit) as volume\n # The volume's own edition (+ year), shared by the Vol. and slash\n # forms.\n volume_dated = {\n volume_edition_rule\n [volume_year_rule]\n }\n volume_edition_rule = space (1*digit dot 1*digit dot 1*digit) as volume_edition\n volume_year_rule = space \"(\" ((\"19\" / \"20\") 2*digit) as volume_year \")\"\n\n # The edition slot accepts the dotted form or the v-shorthand; the\n # with-year qualifier may sit right after it.\n dated = {\n (edition / v_edition)\n [year_qualifier]\n }\n\n # The serial tail picks exactly one discriminator: the long volume\n # (with its optional issue) or the legacy bare year — both bind the\n # volume component, and both may carry the volume's own edition.\n serial = {\n (volume / volume_bare_year)\n [volume_dated]\n }\n\n identifier = {\n [(\"IHO\" space)]\n series\n dash\n number\n [compact_part]\n [glued]\n [volume_short]\n [dated]\n [supplement]\n [part]\n [spec_citation]\n [annex]\n [appendix]\n [serial]\n [year_qualifier]\n }\n\n # The entry dispatches the bare citation branch first (PEG order): a\n # bare \"B-401\"-shaped input takes the S-4 branch, everything else the\n # main identifier.\n identifier_entry = {\n bare_spec_citation / identifier\n }\n\n entry identifier: identifier_entry\n\n test {\n accept \"S-5\"\n accept \"IHO S-5 Appendix 2\"\n accept \"IHO B-12 3.0.0\"\n accept \"IHO P-5 2024\"\n accept \"P-5 2024\"\n accept \"IHO P-5 Vol. 2024\"\n accept \"IHO P-5/2024\"\n accept \"IHO B-7 Vol. 2023\"\n accept \"IHO P-1 Vol. 30\"\n accept \"IHO P-1 Vol. 30 (2)\"\n accept \"IHO P-1 Vol. 30 Issue 2\"\n accept \"IHO P-1/21\"\n accept \"IHO P-1/21 1.0.0\"\n accept \"IHO S-100 5.0.0 Part 2\"\n accept \"IHO S-98 1.0.0 Part A\"\n accept \"IHO S-65 1.1.0 Annex A\"\n accept \"IHO S-122 1.0.0 Appendix D-2\"\n accept \"IHO S-52 4.0.0 Appendix 1\"\n accept \"IHO M-2 Sup 1\"\n accept \"IHO M-2 Suppl 6\"\n accept \"IHO S-66 2.0.0 Sup 4\"\n accept \"IHO S-5-B\"\n accept \"IHO S-100-1\"\n accept \"IHO S-100-1 1.0.0\"\n accept \"IHO P-6-3 1.0.0\"\n accept \"IHO S-5A\"\n accept \"IHO S-5A 1.0.2\"\n accept \"IHO S-5 1.0.2 Part A\"\n accept \"IHO S-100 5.0.0 Part 2 (2024)\"\n accept \"IHO S-100 v5.1\"\n accept \"IHO S-100 v1\"\n accept \"IHO S-100 1.0.0 (2024) Part A\"\n accept \"IHO S-53 Ap. 1 1.0.0\"\n accept \"IHO S-98 Part A 1.0.0\"\n accept \"IHO S-158:100 1.0.0\"\n accept \"IHO S-158:100 Part 2 1.0.0\"\n accept \"IHO S-1001\"\n accept \"IHO S-158 Part S-102 0.2.0\"\n accept \"IHO S-158-S-102 0.2.0\"\n accept \"IHO P-6 1.0.0 Vol. 2\"\n accept \"IHO P-6 Vol. 2 1.0.1\"\n accept \"IHO S-98 1.0.0 Annex A\"\n accept \"IHO S-100 5.0.0 Sup 1 2.0.0\"\n # --- S-4 loose-leaf sections and specifications ---\n accept \"IHO S-4 B-401\"\n accept \"IHO S-4 4.10.0 B-401\"\n accept \"IHO S-4 B-122.1\"\n accept \"IHO S-4 B-521(I)\"\n accept \"IHO S-4 B-351.1(I)\"\n accept \"IHO S-4 B-400\"\n accept \"IHO S-4 B-170\"\n accept \"B-401\"\n accept \"IHO B-401\"\n accept \"B-122.1\"\n accept \"B-521(I)\"\n accept \"IHO S-4 Part B, Section 400\"\n accept \"S-4 Part B, Section 400\"\n accept \"IHO S-4 Part B, Section 400, B-401\"\n accept \"B-12\"\n reject \"IHO S-4 B-4\"\n reject \"IHO S-4 B-40\"\n reject \"IHO S-4 B-800\"\n reject \"nonsense\"\n reject \"IHO B-12 3.0\"\n reject \"IHO P-5 1850\"\n }\n\n bindings identifier_entry {\n type -> type (string)\n number -> number (string)\n part -> part (string)\n part_edition -> part_edition (string)\n part_year -> part_year (string)\n annex -> annex (string)\n annex_edition -> annex_edition (string)\n annex_year -> annex_year (string)\n appendix -> appendix (string)\n appendix_subnumber -> appendix_subnumber (string)\n appendix_edition -> appendix_edition (string)\n appendix_year -> appendix_year (string)\n supplement -> supplement (string)\n supplement_edition -> supplement_edition (string)\n supplement_year -> supplement_year (string)\n edition -> edition (string)\n edition_shorthand -> edition_shorthand (string)\n year -> year (string)\n volume -> volume (string)\n volume_edition -> volume_edition (string)\n volume_year -> volume_year (string)\n issue -> issue (string)\n spec -> spec (string)\n spec_sub -> spec_sub (string)\n spec_variant -> spec_variant (string)\n spec_part -> spec_part (string)\n spec_section -> spec_section (string)\n }\n}\n","source_hash":"2b9f7e6115555242a774cdeb356401be4085991bca0dc92fc9c8fc31ee36b842","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.126","edition":2,"semantics_hash":"sha256:eb5104d7afed4e2d261a17380e1c7ea678e354df6889cbfbbd27cd01e0442a77","checksum":"sha256:54b4f297d6fae2c2af954387ba09f87428ca42661eb170197f8791e7e3dd1c94"}
|
data/data/parg/iho.parg
CHANGED
|
@@ -98,11 +98,15 @@
|
|
|
98
98
|
# Part contains Annexes; Annex contains Appendices; a D-2 subnumber is
|
|
99
99
|
# a child atom of Appendix D. No key.value concatenations — every
|
|
100
100
|
# non-number component is a marker-prefixed segment whose marker is the
|
|
101
|
-
# lowercased human-face token (edition follows ISO's ed- precedent)
|
|
101
|
+
# lowercased human-face token (edition follows ISO's ed- precedent).
|
|
102
|
+
# An S-4 specification is a child of its Part (the citation letter rides
|
|
103
|
+
# the part- atom), with the dotted sub and the parenthesized variant as
|
|
104
|
+
# its own children:
|
|
102
105
|
#
|
|
103
106
|
# urn:iho:<type>:<number>[:ed-<x.y.z>][:year-<yyyy>]
|
|
104
107
|
# [:sup-<n>[:ed-<x.y.z>][:year-<yyyy>]]
|
|
105
108
|
# [:part-<X>[:ed-<x.y.z>][:year-<yyyy>]]
|
|
109
|
+
# [:spec-<n>[:specsub-<n>][:specvar-<X>]]
|
|
106
110
|
# [:annex-<A>[...]]
|
|
107
111
|
# [:appendix-<B>[:<sub>][...]]
|
|
108
112
|
# [:vol-<n>[:issue-<n>][...]]
|
|
@@ -123,16 +127,25 @@
|
|
|
123
127
|
# segment precedes
|
|
124
128
|
# 5 sup-<n> 1*digit wraps the base
|
|
125
129
|
# 6 part-<X> letter (case kept), contains annexes
|
|
126
|
-
# digits [*letter], or a
|
|
130
|
+
# digits [*letter], or a and S-4 specs
|
|
127
131
|
# series reference
|
|
128
132
|
# [SPMBC]-<digits>
|
|
129
|
-
# 7
|
|
130
|
-
#
|
|
131
|
-
#
|
|
133
|
+
# 7 spec-<n> [1-6]dd, only under an child of part (the
|
|
134
|
+
# S-4 anchor (s:4) S-4 leaf; the
|
|
135
|
+
# section is the
|
|
136
|
+
# hundreds digit,
|
|
137
|
+
# derivable, never
|
|
138
|
+
# emitted)
|
|
139
|
+
# 8 specsub-<n> 1*digit, only after spec- child of spec
|
|
140
|
+
# 9 specvar-<X> upper letters, after child of spec
|
|
141
|
+
# spec- or specsub-
|
|
142
|
+
# 10 annex-<A> upper letter (case kept) contains appendices
|
|
143
|
+
# 11 appendix-<B> upper letter or digits contains subnumber
|
|
144
|
+
# 12 <sub> 1*digit, BARE, only child of appendix
|
|
132
145
|
# directly after appendix-
|
|
133
|
-
#
|
|
146
|
+
# 13 vol-<n> 1*digit (incl. yearbook contains issue
|
|
134
147
|
# years, Vol. 2020)
|
|
135
|
-
#
|
|
148
|
+
# 14 issue-<n> 1*digit, only after vol- child of volume
|
|
136
149
|
#
|
|
137
150
|
# The number occupies every leading bare segment up to the first
|
|
138
151
|
# marker, so a colon number (S-158:100) round-trips without escaping;
|
|
@@ -147,11 +160,50 @@
|
|
|
147
160
|
# ap./appendix./vol./issue. and the single-letter y. year tag (whose
|
|
148
161
|
# value decodes into the volume — the serial-locator unification).
|
|
149
162
|
#
|
|
163
|
+
# == S-4 loose-leaf sections and specifications (issue #691; owner
|
|
164
|
+
# rulings of 2026-11-11)
|
|
165
|
+
#
|
|
166
|
+
# The S-4 loose-leaf publication cites its regulations/specifications as
|
|
167
|
+
# <letter>-<hundreds><seq>: B-401 is Part B, Section 400, item 01. ONE
|
|
168
|
+
# component, not two tiers: the spec number IS the leaf; the SECTION is
|
|
169
|
+
# the hundreds digit, DERIVED (never stored, never emitted). The `00`
|
|
170
|
+
# slot (B-400) IS the section-level citation, so "S-4 Part B, Section
|
|
171
|
+
# 400" and "IHO S-4 B-400" are one identity, two spellings.
|
|
172
|
+
#
|
|
173
|
+
# capture example role
|
|
174
|
+
# spec B-401 -> "401" the leaf number (3 digits,
|
|
175
|
+
# hundreds 1-6: sections 100-600)
|
|
176
|
+
# spec_sub B-122.1 -> "1" the dotted sub
|
|
177
|
+
# spec_variant B-521(I) -> "I" the parenthesized variant
|
|
178
|
+
# spec_part B-401 -> "B" the citation letter (the builder
|
|
179
|
+
# binds it into `part`; a Part-rule
|
|
180
|
+
# capture must agree)
|
|
181
|
+
# spec_section ", Section 400" -> "400" the long form's spelled
|
|
182
|
+
# section (becomes `spec` alone;
|
|
183
|
+
# checked against a citation)
|
|
184
|
+
#
|
|
185
|
+
# Faces: canonical compact "IHO S-4 B-401" (dated: "IHO S-4 4.10.0
|
|
186
|
+
# B-401"); long "S-4 Part B, Section 400" (a normalizing parse; also
|
|
187
|
+
# takes a trailing citation: "S-4 Part B, Section 400, B-401", where the
|
|
188
|
+
# spelled section only cross-checks the citation's derived section); bare
|
|
189
|
+
# "B-401" (implicit S-4 anchor; B only — bare C-x stays the Circular
|
|
190
|
+
# Letter series). The builder binds the anchor: a citation requires the
|
|
191
|
+
# S-4 anchor (or synthesizes it for the bare form).
|
|
192
|
+
#
|
|
193
|
+
# Reserved numbers ("NOT CURRENTLY USED" in the S-4 contents — B-170,
|
|
194
|
+
# B-230, B-305, B-323 in Ed 4.9.0 and 4.10.0) parse and resolve AS
|
|
195
|
+
# RESERVED, never invalid; the edition-keyed registry lives in the pubid
|
|
196
|
+
# gem (data/iho/s4-reserved-specs.yaml).
|
|
197
|
+
#
|
|
198
|
+
# URN atoms: part-<letter>:spec-<n>[:specsub-<n>][:specvar-<X>] — the
|
|
199
|
+
# section is NOT emitted (derivable); the citation letter rides the
|
|
200
|
+
# existing part- atom (case preserved: part-B).
|
|
201
|
+
#
|
|
150
202
|
# Edition 2: ruby#400's capture-flatten keeps text captures over
|
|
151
203
|
# reference-built rules as the matched text, so the v2 tree is the v1
|
|
152
204
|
# tree plus named leaves for non-captured structure.
|
|
153
205
|
|
|
154
|
-
grammar PubidIho version "0.
|
|
206
|
+
grammar PubidIho version "0.3.0" edition 2 {
|
|
155
207
|
digit = %x30-39
|
|
156
208
|
upper = %x41-5A
|
|
157
209
|
lower = %x61-7A
|
|
@@ -196,7 +248,7 @@ grammar PubidIho version "0.2.0" edition 2 {
|
|
|
196
248
|
# (<kind>_edition / <kind>_year) so the model knows which component
|
|
197
249
|
# the edition belongs to and the URN attaches ed- to the node it
|
|
198
250
|
# follows.
|
|
199
|
-
part = space "Part" space part_value [part_dated]
|
|
251
|
+
part = space "Part" space part_value [part_dated] [part_section_tail]
|
|
200
252
|
part_dated = {
|
|
201
253
|
part_edition_rule
|
|
202
254
|
[part_year_rule]
|
|
@@ -204,6 +256,39 @@ grammar PubidIho version "0.2.0" edition 2 {
|
|
|
204
256
|
part_edition_rule = space (1*digit dot 1*digit dot 1*digit) as part_edition
|
|
205
257
|
part_year_rule = space "(" (("19" / "20") 2*digit) as part_year ")"
|
|
206
258
|
|
|
259
|
+
# --- S-4 loose-leaf sections and specifications (see the header) ---
|
|
260
|
+
# The spec number's vocabulary: the S-4 sections run 100-600 (Part C
|
|
261
|
+
# 100-500), so the leaf number is 3 digits with hundreds digit 1-6 —
|
|
262
|
+
# the same shape the bare citation branch leans on to keep the B
|
|
263
|
+
# Bibliographic series (B-1..B-13 style) distinct from B-4xx specs.
|
|
264
|
+
spec_shape = ("1" / "2" / "3" / "4" / "5" / "6") digit digit
|
|
265
|
+
spec_number = spec_shape as spec
|
|
266
|
+
spec_subnumber = dot (1*digit) as spec_sub
|
|
267
|
+
spec_variant = "(" (1*upper) as spec_variant ")"
|
|
268
|
+
# The citation letter is the spec's part (A/B/C); the builder binds it
|
|
269
|
+
# into `part` and rejects a conflicting Part-rule capture.
|
|
270
|
+
spec_citation_body = ("A" / "B" / "C") as spec_part dash spec_number [spec_subnumber] [spec_variant]
|
|
271
|
+
# The compact anchor form: the citation follows the code after one
|
|
272
|
+
# space ("IHO S-4 B-401").
|
|
273
|
+
spec_citation = space spec_citation_body
|
|
274
|
+
# The spelled section long form: "Part B, Section 400" — the spelled
|
|
275
|
+
# number becomes the spec (the section-level citation), and a trailing
|
|
276
|
+
# citation (", Section 400, B-401") makes it a cross-check only. The
|
|
277
|
+
# commas are inlined literals: named comma refs collide as duplicate
|
|
278
|
+
# edition-2 tree nodes under the entry's alternation (the same node
|
|
279
|
+
# collision the compact_part dash-ref comment documents).
|
|
280
|
+
part_section_tail = {
|
|
281
|
+
"," space "Section" space (spec_shape as spec_section)
|
|
282
|
+
["," space spec_citation_body]
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
# The bare citation branch (the entry's FIRST alternative): "B-401" /
|
|
286
|
+
# "IHO B-401" — implicit S-4 anchor (the builder synthesizes series S
|
|
287
|
+
# number 4). B only: bare C-x stays the Circular Letter series, and the
|
|
288
|
+
# 3-digit [1-6]xx shape keeps the B Bibliographic series (B-12) on the
|
|
289
|
+
# main branch.
|
|
290
|
+
bare_spec_citation = [("IHO" space)] ("B" as spec_part) dash spec_number [spec_subnumber] [spec_variant]
|
|
291
|
+
|
|
207
292
|
supplement = space ("Suppl" / "Sup") space (1*digit) as supplement [supplement_dated]
|
|
208
293
|
supplement_dated = {
|
|
209
294
|
supplement_edition_rule
|
|
@@ -274,13 +359,21 @@ grammar PubidIho version "0.2.0" edition 2 {
|
|
|
274
359
|
[dated]
|
|
275
360
|
[supplement]
|
|
276
361
|
[part]
|
|
362
|
+
[spec_citation]
|
|
277
363
|
[annex]
|
|
278
364
|
[appendix]
|
|
279
365
|
[serial]
|
|
280
366
|
[year_qualifier]
|
|
281
367
|
}
|
|
282
368
|
|
|
283
|
-
entry
|
|
369
|
+
# The entry dispatches the bare citation branch first (PEG order): a
|
|
370
|
+
# bare "B-401"-shaped input takes the S-4 branch, everything else the
|
|
371
|
+
# main identifier.
|
|
372
|
+
identifier_entry = {
|
|
373
|
+
bare_spec_citation / identifier
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
entry identifier: identifier_entry
|
|
284
377
|
|
|
285
378
|
test {
|
|
286
379
|
accept "S-5"
|
|
@@ -326,12 +419,31 @@ grammar PubidIho version "0.2.0" edition 2 {
|
|
|
326
419
|
accept "IHO P-6 Vol. 2 1.0.1"
|
|
327
420
|
accept "IHO S-98 1.0.0 Annex A"
|
|
328
421
|
accept "IHO S-100 5.0.0 Sup 1 2.0.0"
|
|
422
|
+
# --- S-4 loose-leaf sections and specifications ---
|
|
423
|
+
accept "IHO S-4 B-401"
|
|
424
|
+
accept "IHO S-4 4.10.0 B-401"
|
|
425
|
+
accept "IHO S-4 B-122.1"
|
|
426
|
+
accept "IHO S-4 B-521(I)"
|
|
427
|
+
accept "IHO S-4 B-351.1(I)"
|
|
428
|
+
accept "IHO S-4 B-400"
|
|
429
|
+
accept "IHO S-4 B-170"
|
|
430
|
+
accept "B-401"
|
|
431
|
+
accept "IHO B-401"
|
|
432
|
+
accept "B-122.1"
|
|
433
|
+
accept "B-521(I)"
|
|
434
|
+
accept "IHO S-4 Part B, Section 400"
|
|
435
|
+
accept "S-4 Part B, Section 400"
|
|
436
|
+
accept "IHO S-4 Part B, Section 400, B-401"
|
|
437
|
+
accept "B-12"
|
|
438
|
+
reject "IHO S-4 B-4"
|
|
439
|
+
reject "IHO S-4 B-40"
|
|
440
|
+
reject "IHO S-4 B-800"
|
|
329
441
|
reject "nonsense"
|
|
330
442
|
reject "IHO B-12 3.0"
|
|
331
443
|
reject "IHO P-5 1850"
|
|
332
444
|
}
|
|
333
445
|
|
|
334
|
-
bindings
|
|
446
|
+
bindings identifier_entry {
|
|
335
447
|
type -> type (string)
|
|
336
448
|
number -> number (string)
|
|
337
449
|
part -> part (string)
|
|
@@ -354,5 +466,10 @@ grammar PubidIho version "0.2.0" edition 2 {
|
|
|
354
466
|
volume_edition -> volume_edition (string)
|
|
355
467
|
volume_year -> volume_year (string)
|
|
356
468
|
issue -> issue (string)
|
|
469
|
+
spec -> spec (string)
|
|
470
|
+
spec_sub -> spec_sub (string)
|
|
471
|
+
spec_variant -> spec_variant (string)
|
|
472
|
+
spec_part -> spec_part (string)
|
|
473
|
+
spec_section -> spec_section (string)
|
|
357
474
|
}
|
|
358
475
|
}
|