pubid 2.0.0.pre.alpha.64 → 2.0.0.pre.alpha.65

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/data/parg/adobe.json +1 -1
  3. data/data/parg/aiee.json +1 -1
  4. data/data/parg/amca.json +1 -1
  5. data/data/parg/ansi.json +1 -1
  6. data/data/parg/api.json +1 -1
  7. data/data/parg/ashrae.json +1 -1
  8. data/data/parg/asme.json +1 -1
  9. data/data/parg/astm.json +1 -1
  10. data/data/parg/bipm.json +1 -1
  11. data/data/parg/bsi.json +1 -1
  12. data/data/parg/calconnect.json +1 -1
  13. data/data/parg/ccsds.json +1 -1
  14. data/data/parg/cen_cenelec.json +1 -1
  15. data/data/parg/cie.json +1 -1
  16. data/data/parg/csa.json +1 -1
  17. data/data/parg/doi.json +1 -1
  18. data/data/parg/easc.json +1 -1
  19. data/data/parg/ecma.json +1 -1
  20. data/data/parg/etsi.json +1 -1
  21. data/data/parg/evs.json +1 -1
  22. data/data/parg/gb.json +1 -1
  23. data/data/parg/gost.json +1 -1
  24. data/data/parg/iala.json +1 -1
  25. data/data/parg/iana.json +1 -1
  26. data/data/parg/idf.json +1 -1
  27. data/data/parg/iec.json +1 -1
  28. data/data/parg/ieee.json +1 -1
  29. data/data/parg/ietf.json +1 -1
  30. data/data/parg/ire.json +1 -1
  31. data/data/parg/isbn.json +1 -1
  32. data/data/parg/iso.json +1 -1
  33. data/data/parg/itu.json +1 -1
  34. data/data/parg/jcgm.json +1 -1
  35. data/data/parg/jis.json +1 -1
  36. data/data/parg/nesc.json +1 -1
  37. data/data/parg/nist.json +1 -1
  38. data/data/parg/oasis.json +1 -1
  39. data/data/parg/ogc.json +1 -1
  40. data/data/parg/oiml.json +1 -1
  41. data/data/parg/omg.json +1 -1
  42. data/data/parg/parg.json +1 -1
  43. data/data/parg/plateau.json +1 -1
  44. data/data/parg/sae.json +1 -1
  45. data/data/parg/tgpp.json +1 -1
  46. data/data/parg/un.json +1 -1
  47. data/data/parg/w3c.json +1 -1
  48. data/data/parg/xsf.json +1 -1
  49. data/lib/pubid/calconnect/identifier.rb +1 -1
  50. data/lib/pubid/doi/identifier.rb +1 -1
  51. data/lib/pubid/easc/identifier.rb +1 -1
  52. data/lib/pubid/gb/identifier.rb +1 -1
  53. data/lib/pubid/ietf/identifiers/base.rb +1 -1
  54. data/lib/pubid/oasis/identifier.rb +1 -1
  55. data/lib/pubid/ogc/identifier.rb +1 -1
  56. data/lib/pubid/parg/artifact.rb +22 -3
  57. data/lib/pubid/parg/model.rb +98 -0
  58. data/lib/pubid/parg.rb +1 -0
  59. data/lib/pubid/sae/identifiers/base.rb +1 -1
  60. data/lib/pubid/version.rb +1 -1
  61. data/lib/pubid/w3c/identifier.rb +1 -1
  62. data/lib/pubid/xsf/identifier.rb +1 -1
  63. metadata +5 -4
data/data/parg/tgpp.json CHANGED
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidTgpp","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"3GPP "}},{"Repetition":{"atom":0,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":6}},{"Str":{"pattern":"TR"}},{"Str":{"pattern":"TS"}},{"Alternative":{"atoms":[3,4]}},{"Named":{"name":"type","atom":5}},{"Entity":{"atom":8}},{"Str":{"pattern":" "}},{"Entity":{"atom":17}},{"Entity":{"atom":11}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":10,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":14,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[12,13,15]}},{"Named":{"name":"number","atom":16}},{"Entity":{"atom":24}},{"Entity":{"atom":22}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[20,21]}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"suffix","atom":23}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":34}},{"Entity":{"atom":32}},{"Str":{"pattern":"-"}},{"Entity":{"atom":11}},{"Repetition":{"atom":29,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"part","atom":30}},{"Sequence":{"atoms":[28,31]}},{"Repetition":{"atom":27,"min":0,"max":null,"tag":"Repetition"}},{"Named":{"name":"parts","atom":33}},{"Entity":{"atom":36}},{"Str":{"pattern":":"}},{"Entity":{"atom":60}},{"Entity":{"atom":47}},{"Entity":{"atom":11}},{"Repetition":{"atom":39,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":42,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":45,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[40,41,43,44,46]}},{"Entity":{"atom":49}},{"Re":{"pattern":"[\\x01-\\u{10ffff}]"}},{"Lookahead":{"atom":48,"positive":false}},{"Sequence":{"atoms":[38,50]}},{"Lookahead":{"atom":51,"positive":false}},{"Entity":{"atom":57}},{"Re":{"pattern":"[\\x01-\\x2e]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[\\x3b-\\u{10ffff}]"}},{"Alternative":{"atoms":[54,55,56]}},{"Repetition":{"atom":53,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"release","atom":58}},{"Sequence":{"atoms":[52,59]}},{"Sequence":{"atoms":[35,37]}},{"Repetition":{"atom":61,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":64}},{"Str":{"pattern":"/"}},{"Entity":{"atom":67}},{"Entity":{"atom":47}},{"Named":{"name":"version","atom":66}},{"Sequence":{"atoms":[63,65]}},{"Repetition":{"atom":68,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,2,7,9,25,26,62,69]}}],"root":70},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule release_char: branches 1 and 3 are order-dependent (first set not statically known)","rule release_char: branches 2 and 3 are order-dependent (first set not statically known)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"3GPP TS 21.101","expect":{}},{"entry":"identifier","kind":"accept","input":"TS 25.999","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/tgpp/parser.rb:\n# [3GPP ]<TR|TS> <NN.NNN>[suffix][-part…][:<release>][/<version>]\n# The release excludes \"/\" and \":\" (match[\"^/:\"]), byte-wise here; the\n# mistyped-version guard (!version…!any) is ported literally.\n\ngrammar PubidTgpp version \"0.1.0\" mode \"v1\" {\n release_char = %x01-2E / %x30-39 / %x3B-10FFFF\n any_char = %x01-10FFFF\n type = (\"TR\" / \"TS\") as type\n number = (1*digit \".\" 1*digit) as number\n suffix = (1*letter) as suffix\n part = \"-\" (1*digit) as part\n parts = (*part) as parts\n version_core = 1*digit \".\" 1*digit \".\" 1*digit\n release = !(version_core !any_char) (1*release_char) as release\n version = version_core as version\n identifier = [\"3GPP \"] type space number [suffix] parts [(colon release)] [(slash version)]\n letter = %x41-5A / %x61-7A\n digit = %x30-39\n space = \" \"\n colon = \":\"\n slash = \"/\"\n entry identifier: identifier\n\n test {\n accept \"3GPP TS 21.101\"\n accept \"TS 25.999\"\n reject \"nonsense\"\n }\n}\n","source_hash":"3f3bba714488dcad3057d1a3d86f1d02b854ff34d8e2173bd0ce5b92238d034c","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.110","mode":"v1","emission":2,"checksum":"sha256:b28e6520567b826dfd127eaa81e5c9cdc0072cddb0e57af114c52c0c4c4e1a70"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidTgpp","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"3GPP "}},{"Repetition":{"atom":0,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":6}},{"Str":{"pattern":"TR"}},{"Str":{"pattern":"TS"}},{"Alternative":{"atoms":[3,4]}},{"Named":{"name":"type","atom":5}},{"Entity":{"atom":8}},{"Str":{"pattern":" "}},{"Entity":{"atom":17}},{"Entity":{"atom":11}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":10,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":14,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[12,13,15]}},{"Named":{"name":"number","atom":16}},{"Entity":{"atom":24}},{"Entity":{"atom":22}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[20,21]}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"suffix","atom":23}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":34}},{"Entity":{"atom":32}},{"Str":{"pattern":"-"}},{"Entity":{"atom":11}},{"Repetition":{"atom":29,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"part","atom":30}},{"Sequence":{"atoms":[28,31]}},{"Repetition":{"atom":27,"min":0,"max":null,"tag":"Repetition"}},{"Named":{"name":"parts","atom":33}},{"Entity":{"atom":36}},{"Str":{"pattern":":"}},{"Entity":{"atom":60}},{"Entity":{"atom":47}},{"Entity":{"atom":11}},{"Repetition":{"atom":39,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":42,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"."}},{"Entity":{"atom":11}},{"Repetition":{"atom":45,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[40,41,43,44,46]}},{"Entity":{"atom":49}},{"Re":{"pattern":"[\\x01-\\u{10ffff}]"}},{"Lookahead":{"atom":48,"positive":false}},{"Sequence":{"atoms":[38,50]}},{"Lookahead":{"atom":51,"positive":false}},{"Entity":{"atom":57}},{"Re":{"pattern":"[\\x01-\\x2e]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[\\x3b-\\u{10ffff}]"}},{"Alternative":{"atoms":[54,55,56]}},{"Repetition":{"atom":53,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"release","atom":58}},{"Sequence":{"atoms":[52,59]}},{"Sequence":{"atoms":[35,37]}},{"Repetition":{"atom":61,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":64}},{"Str":{"pattern":"/"}},{"Entity":{"atom":67}},{"Entity":{"atom":47}},{"Named":{"name":"version","atom":66}},{"Sequence":{"atoms":[63,65]}},{"Repetition":{"atom":68,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,2,7,9,25,26,62,69]}}],"root":70},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule release_char: branches 1 and 3 are order-dependent (first set not statically known)","rule release_char: branches 2 and 3 are order-dependent (first set not statically known)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"3GPP TS 21.101","expect":{}},{"entry":"identifier","kind":"accept","input":"TS 25.999","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/tgpp/parser.rb:\n# [3GPP ]<TR|TS> <NN.NNN>[suffix][-part…][:<release>][/<version>]\n# The release excludes \"/\" and \":\" (match[\"^/:\"]), byte-wise here; the\n# mistyped-version guard (!version…!any) is ported literally.\n\ngrammar PubidTgpp version \"0.1.0\" mode \"v1\" {\n release_char = %x01-2E / %x30-39 / %x3B-10FFFF\n any_char = %x01-10FFFF\n type = (\"TR\" / \"TS\") as type\n number = (1*digit \".\" 1*digit) as number\n suffix = (1*letter) as suffix\n part = \"-\" (1*digit) as part\n parts = (*part) as parts\n version_core = 1*digit \".\" 1*digit \".\" 1*digit\n release = !(version_core !any_char) (1*release_char) as release\n version = version_core as version\n identifier = [\"3GPP \"] type space number [suffix] parts [(colon release)] [(slash version)]\n letter = %x41-5A / %x61-7A\n digit = %x30-39\n space = \" \"\n colon = \":\"\n slash = \"/\"\n entry identifier: identifier\n\n test {\n accept \"3GPP TS 21.101\"\n accept \"TS 25.999\"\n reject \"nonsense\"\n }\n}\n","source_hash":"3f3bba714488dcad3057d1a3d86f1d02b854ff34d8e2173bd0ce5b92238d034c","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.114","edition":1,"checksum":"sha256:b60ab478f1cb8cb5e5bb1d5a72f709d2de8d6bbb21d24c6cc1bc609dc45dc2e0"}
data/data/parg/un.json CHANGED
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidUn","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"UN "}},{"Repetition":{"atom":0,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":9}},{"Entity":{"atom":7}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[.]"}},{"Alternative":{"atoms":[4,5,6]}},{"Repetition":{"atom":3,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"token","atom":8}},{"Entity":{"atom":11}},{"Str":{"pattern":"/"}},{"Entity":{"atom":9}},{"Sequence":{"atoms":[10,12]}},{"Repetition":{"atom":13,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[1,2,14]}}],"root":15},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"UN/CEFACT/TBG14","expect":{}},{"entry":"identifier","kind":"accept","input":"CEFACT/TBG14","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/un/parser.rb. `token` matches [A-Z0-9.] runs.\n\ngrammar PubidUn version \"0.1.0\" mode \"v1\" {\n token_char = %x41-5A / %x30-39 / %x2E\n token = (1*token_char) as token\n identifier = [\"UN \"] token 1*(slash token)\n slash = \"/\"\n entry identifier: identifier\n\n test {\n accept \"UN/CEFACT/TBG14\"\n accept \"CEFACT/TBG14\"\n reject \"nonsense\"\n }\n}\n","source_hash":"8af25923f5616b2ebe0443dc994d305d8f4390efe46bb685d8aebf89c68c66e2","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.110","mode":"v1","emission":2,"checksum":"sha256:f61608a9a7c470cfbfa5e3c7154f9db0f3ceb72643ff1204cfbccdee7e01b120"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidUn","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"UN "}},{"Repetition":{"atom":0,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":9}},{"Entity":{"atom":7}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[.]"}},{"Alternative":{"atoms":[4,5,6]}},{"Repetition":{"atom":3,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"token","atom":8}},{"Entity":{"atom":11}},{"Str":{"pattern":"/"}},{"Entity":{"atom":9}},{"Sequence":{"atoms":[10,12]}},{"Repetition":{"atom":13,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[1,2,14]}}],"root":15},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"UN/CEFACT/TBG14","expect":{}},{"entry":"identifier","kind":"accept","input":"CEFACT/TBG14","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/un/parser.rb. `token` matches [A-Z0-9.] runs.\n\ngrammar PubidUn version \"0.1.0\" mode \"v1\" {\n token_char = %x41-5A / %x30-39 / %x2E\n token = (1*token_char) as token\n identifier = [\"UN \"] token 1*(slash token)\n slash = \"/\"\n entry identifier: identifier\n\n test {\n accept \"UN/CEFACT/TBG14\"\n accept \"CEFACT/TBG14\"\n reject \"nonsense\"\n }\n}\n","source_hash":"8af25923f5616b2ebe0443dc994d305d8f4390efe46bb685d8aebf89c68c66e2","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.114","edition":1,"checksum":"sha256:634305272bf558b8cb9193a1af8e75b9cc799d75386dd4d4a53e42d4d66cce1b"}
data/data/parg/w3c.json CHANGED
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidW3c","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"W3C "}},{"Entity":{"atom":16}},{"Entity":{"atom":13}},{"Str":{"pattern":"DNOTE"}},{"Str":{"pattern":"NOTE"}},{"Str":{"pattern":"WD"}},{"Str":{"pattern":"CRD"}},{"Str":{"pattern":"CR"}},{"Str":{"pattern":"REC"}},{"Str":{"pattern":"PER"}},{"Str":{"pattern":"PR"}},{"Str":{"pattern":"SPSD"}},{"Str":{"pattern":"OBSL"}},{"Alternative":{"atoms":[3,4,5,6,7,8,9,10,11,12]}},{"Named":{"name":"type","atom":2}},{"Str":{"pattern":"-"}},{"Sequence":{"atoms":[14,15]}},{"Repetition":{"atom":1,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":22}},{"Entity":{"atom":20}},{"Re":{"pattern":"[\\x01-\\u{10ffff}]"}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"rest","atom":21}},{"Sequence":{"atoms":[0,17,18]}}],"root":23},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule type_token: branches 4 and 5 are order-dependent (shared first bytes; ordered choice is decisive)","rule type_token: branches 7 and 8 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"W3C REC-html40-19981224","expect":{}},{"entry":"identifier","kind":"accept","input":"W3C NOTE-datetime-19980827","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/w3c/parser.rb: split off the leading maturity token;\n# code/date boundary is builder-side by design. Token order matters for\n# shared prefixes (CRD before CR, PER before PR, DNOTE before NOTE).\n\ngrammar PubidW3c version \"0.1.0\" mode \"v1\" {\n any_char = %x01-10FFFF\n type_token = \"DNOTE\" / \"NOTE\" / \"WD\" / \"CRD\" / \"CR\" / \"REC\" / \"PER\" / \"PR\" / \"SPSD\" / \"OBSL\"\n type_part = type_token as type \"-\"\n rest = (1*any_char) as rest\n identifier = \"W3C \" [type_part] rest\n entry identifier: identifier\n\n test {\n accept \"W3C REC-html40-19981224\"\n accept \"W3C NOTE-datetime-19980827\"\n reject \"nonsense\"\n }\n}\n","source_hash":"d9537d5fb9de5f1026b09ba6f3b4115d9bb81e3d671410e0a68ba9a26fb5f5e1","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.110","mode":"v1","emission":2,"checksum":"sha256:5c88d37fa52aab102a4722518ae417d8b384b21eeebd9bd09b0b1fd76b4ca9bd"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidW3c","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"W3C "}},{"Entity":{"atom":16}},{"Entity":{"atom":13}},{"Str":{"pattern":"DNOTE"}},{"Str":{"pattern":"NOTE"}},{"Str":{"pattern":"WD"}},{"Str":{"pattern":"CRD"}},{"Str":{"pattern":"CR"}},{"Str":{"pattern":"REC"}},{"Str":{"pattern":"PER"}},{"Str":{"pattern":"PR"}},{"Str":{"pattern":"SPSD"}},{"Str":{"pattern":"OBSL"}},{"Alternative":{"atoms":[3,4,5,6,7,8,9,10,11,12]}},{"Named":{"name":"type","atom":2}},{"Str":{"pattern":"-"}},{"Sequence":{"atoms":[14,15]}},{"Repetition":{"atom":1,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":22}},{"Entity":{"atom":20}},{"Re":{"pattern":"[\\x01-\\u{10ffff}]"}},{"Repetition":{"atom":19,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"rest","atom":21}},{"Sequence":{"atoms":[0,17,18]}}],"root":23},"bindings":[{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"rest","path":"rest","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule type_token: branches 4 and 5 are order-dependent (shared first bytes; ordered choice is decisive)","rule type_token: branches 7 and 8 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"W3C REC-html40-19981224","expect":{}},{"entry":"identifier","kind":"accept","input":"W3C NOTE-datetime-19980827","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/w3c/parser.rb: split off the leading maturity token;\n# code/date boundary is builder-side by design. Token order matters for\n# shared prefixes (CRD before CR, PER before PR, DNOTE before NOTE).\n\ngrammar PubidW3c version \"0.1.0\" edition 2 {\n any_char = %x01-10FFFF\n type_token = \"DNOTE\" / \"NOTE\" / \"WD\" / \"CRD\" / \"CR\" / \"REC\" / \"PER\" / \"PR\" / \"SPSD\" / \"OBSL\"\n type_part = type_token as type \"-\"\n rest = (1*any_char) as rest\n identifier = \"W3C \" [type_part] rest\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 rest -> rest (string)\n }\n\n\n test {\n accept \"W3C REC-html40-19981224\"\n accept \"W3C NOTE-datetime-19980827\"\n reject \"nonsense\"\n }\n}\n","source_hash":"f1c99f42c7492c18f63f735ee29f07b25aa24442d6d899308a7af8350b83a2d9","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.114","edition":2,"checksum":"sha256:7d7f51422516dea82179ab39580f4c8ca877471c100c8d1621c6b076273c56ba"}
data/data/parg/xsf.json CHANGED
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidXsf","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"XEP "}},{"Entity":{"atom":10}},{"Entity":{"atom":3}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":2,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":8}},{"Str":{"pattern":"README"}},{"Str":{"pattern":"xxxx"}},{"Alternative":{"atoms":[6,7]}},{"Alternative":{"atoms":[4,5]}},{"Named":{"name":"number","atom":9}},{"Sequence":{"atoms":[0,1]}}],"root":11},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"XEP 0001","expect":{}},{"entry":"identifier","kind":"accept","input":"XEP README","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/xsf/parser.rb: \"XEP NNNN\" plus the two named\n# documents (README, xxxx) in SPECIAL_NUMBERS.\n grammar PubidXsf version \"0.1.0\" mode \"v1\" {\n digit = %x30-39\n special_number = \"README\" / \"xxxx\"\n number = (1*digit / special_number) as number\n identifier = \"XEP \" number\n entry identifier: identifier\n\n test {\n accept \"XEP 0001\"\n accept \"XEP README\"\n reject \"nonsense\"\n }\n}\n","source_hash":"60312ab4519e4f1710ad3335c4700eb06e38b3c99dca2390a25e06168ac2f827","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.110","mode":"v1","emission":2,"checksum":"sha256:c6c11ad1071f77a61ef17e266266f955b059b032e44ecc9e7ee0308710c550e7"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidXsf","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Str":{"pattern":"XEP "}},{"Entity":{"atom":10}},{"Entity":{"atom":3}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":2,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":8}},{"Str":{"pattern":"README"}},{"Str":{"pattern":"xxxx"}},{"Alternative":{"atoms":[6,7]}},{"Alternative":{"atoms":[4,5]}},{"Named":{"name":"number","atom":9}},{"Sequence":{"atoms":[0,1]}}],"root":11},"bindings":[{"capture":"number","path":"number","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":[]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"XEP 0001","expect":{}},{"entry":"identifier","kind":"accept","input":"XEP README","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/xsf/parser.rb: \"XEP NNNN\" plus the two named\n# documents (README, xxxx) in SPECIAL_NUMBERS.\n grammar PubidXsf version \"0.1.0\" edition 2 {\n digit = %x30-39\n special_number = \"README\" / \"xxxx\"\n number = (1*digit / special_number) as number\n identifier = \"XEP \" number\n entry identifier: identifier\n\n # Typed model bindings: every bound capture lands on the\n # consumer model's field of the same name.\n bindings identifier {\n number -> number (string)\n }\n\n\n test {\n accept \"XEP 0001\"\n accept \"XEP README\"\n reject \"nonsense\"\n }\n}\n","source_hash":"fdfa1a7c14e4430d5237cf1995240003797173c202dc8574d8c98c7f48f576d2","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.114","edition":2,"checksum":"sha256:8a983305c22e049b60a0c7c6ffdd06c36985eeb7efa4844ed6c4f3b96669ed16"}
@@ -118,7 +118,7 @@ module Pubid
118
118
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
119
119
  end
120
120
 
121
- Builder.build(Pubid::Parg::Backend.parse(:calconnect, identifier))
121
+ Pubid::Parg::Model.parse(:calconnect, Identifiers::Standard, identifier)
122
122
  end
123
123
  end
124
124
  end
@@ -41,7 +41,7 @@ module Pubid
41
41
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
42
42
  end
43
43
 
44
- parsed = Pubid::Parg::Backend.parse(:doi, identifier)
44
+ parsed = Pubid::Parg::Model.bound(:doi, identifier)
45
45
  Builder.build(parsed)
46
46
  end
47
47
  end
@@ -37,7 +37,7 @@ module Pubid
37
37
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
38
38
  end
39
39
 
40
- parsed = Pubid::Parg::Backend.parse(:easc, identifier)
40
+ parsed = Pubid::Parg::Model.bound(:easc, identifier)
41
41
  Builder.build(parsed)
42
42
  end
43
43
 
@@ -80,7 +80,7 @@ module Pubid
80
80
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
81
81
  end
82
82
 
83
- parsed = Pubid::Parg::Backend.parse(:gb, identifier)
83
+ parsed = Pubid::Parg::Model.bound(:gb, identifier)
84
84
  Builder.build(parsed)
85
85
  end
86
86
  end
@@ -64,7 +64,7 @@ module Pubid
64
64
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
65
65
  end
66
66
 
67
- parsed = Pubid::Parg::Backend.parse(:ietf, identifier)
67
+ parsed = Pubid::Parg::Model.bound(:ietf, identifier)
68
68
  Builder.build(parsed)
69
69
  end
70
70
  end
@@ -146,7 +146,7 @@ module Pubid
146
146
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
147
147
  end
148
148
 
149
- parsed = Pubid::Parg::Backend.parse(:oasis, identifier)
149
+ parsed = Pubid::Parg::Model.bound(:oasis, identifier)
150
150
  Builder.build(parsed)
151
151
  end
152
152
 
@@ -85,7 +85,7 @@ module Pubid
85
85
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
86
86
  end
87
87
 
88
- Builder.build(Pubid::Parg::Backend.parse(:ogc, identifier))
88
+ Builder.build(Pubid::Parg::Model.bound(:ogc, identifier))
89
89
  end
90
90
  end
91
91
  end
@@ -21,13 +21,19 @@ module Pubid
21
21
  def for(flavor)
22
22
  @artifacts[flavor] ||=
23
23
  begin
24
- path = File.join(DATA_DIR, "#{flavor}.json")
25
- new(Parsanol::PARG::Artifact.load(path, tables_dir: TABLES_DIR))
24
+ new(Parsanol::PARG::Artifact.load(path_for(flavor),
25
+ tables_dir: TABLES_DIR))
26
26
  rescue Parsanol::PARG::Error => e
27
27
  raise Pubid::Errors::ParseError,
28
- "PG artifact #{path} rejected: #{e.message}"
28
+ "PG artifact #{path_for(flavor)} rejected: #{e.message}"
29
29
  end
30
30
  end
31
+
32
+ # The vendored artifact's path. PG::Lutaml.register loads the file
33
+ # itself, so model registration needs the path, not the wrapper.
34
+ def path_for(flavor)
35
+ File.join(DATA_DIR, "#{flavor}.json")
36
+ end
31
37
  end
32
38
 
33
39
  def initialize(artifact)
@@ -38,6 +44,19 @@ module Pubid
38
44
  @artifact.parse(entry, input)
39
45
  end
40
46
 
47
+ # The artifact tree with the entry's declared bindings applied —
48
+ # the builder-ready attribute hash the grammar's bindings block
49
+ # declares, types cast at the engine.
50
+ def parse_and_bind(entry, input)
51
+ @artifact.parse_and_bind(entry, input)
52
+ end
53
+
54
+ # The bindings the grammar declared for +entry+, empty when it
55
+ # declares none.
56
+ def bindings(entry)
57
+ @artifact.envelope.dig("entries", entry, "bindings") || []
58
+ end
59
+
41
60
  def checksum
42
61
  @artifact.envelope["checksum"]
43
62
  end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Parg
5
+ # Typed model binding for one artifact entry point. The grammar declares
6
+ # which captures bind to which attributes (its `bindings` block); this
7
+ # module parses through those bindings — either straight into the
8
+ # flavor's model class (`parse`) or into the builder-ready hash its
9
+ # Builder consumes (`bound`) — so consumers never see the wire tree.
10
+ module Model
11
+ ALL_PARTS_SUFFIX = "(all parts)"
12
+ ALL_PARTS_PATTERN = /\s*\(all parts\)\s*\z/
13
+
14
+ @registered = {}
15
+ @mutex = Mutex.new
16
+
17
+ class << self
18
+ # Parse +input+ through the artifact's declared bindings into the
19
+ # builder-ready attribute hash, without materializing a model. For
20
+ # flavors whose Builder still owns type dispatch and component
21
+ # construction: the bindings replace tree normalization, not the
22
+ # builder. The "(all parts)" suffix keeps its contract — stripped
23
+ # before parsing, marked on the hash for the builder's AllPartsWrap.
24
+ def bound(flavor, input, entry: "identifier")
25
+ ensure_bindings!(flavor, entry)
26
+ all_parts = input.end_with?(ALL_PARTS_SUFFIX)
27
+ source = all_parts ? input.sub(ALL_PARTS_PATTERN, "") : input
28
+ hash = Artifact.for(flavor).parse_and_bind(entry, source)
29
+ all_parts ? Backend.mark_all_parts(hash) : hash
30
+ rescue Parsanol::ParseFailed => e
31
+ parse_error(e, input, flavor)
32
+ end
33
+
34
+ # Parse +input+ into +model_class+ through the artifact's declared
35
+ # bindings. The "(all parts)" suffix is stripped before parsing and
36
+ # re-applied to the model, exactly as the tree backend does.
37
+ def parse(flavor, model_class, input, entry: "identifier")
38
+ register(flavor, model_class, entry)
39
+ model, all_parts = materialize(flavor, model_class, input)
40
+ all_parts ? model.to_all_parts : model
41
+ rescue Parsanol::ParseFailed => e
42
+ parse_error(e, input, flavor)
43
+ end
44
+
45
+ private
46
+
47
+ def parse_error(error, input, flavor)
48
+ raise Pubid::Errors::ParseError.new(
49
+ error.message,
50
+ nil,
51
+ input: input,
52
+ flavor: Backend.registered_name(flavor),
53
+ )
54
+ end
55
+
56
+ def materialize(flavor, model_class, input)
57
+ all_parts = input.end_with?(ALL_PARTS_SUFFIX)
58
+ source = all_parts ? input.sub(ALL_PARTS_PATTERN, "") : input
59
+ [model_class.public_send(:"from_#{format_for(flavor)}", source),
60
+ all_parts]
61
+ end
62
+
63
+ def register(flavor, model_class, entry)
64
+ format = format_for(flavor)
65
+ @mutex.synchronize do
66
+ return if @registered[format] == model_class
67
+
68
+ ensure_bindings!(flavor, entry)
69
+ bind!(flavor, model_class, format, entry)
70
+ @registered[format] = model_class
71
+ end
72
+ end
73
+
74
+ def bind!(flavor, model_class, format, entry)
75
+ Parsanol::PARG::Lutaml.register(
76
+ model_class,
77
+ format_name: format,
78
+ artifact: Artifact.path_for(flavor),
79
+ entry: entry,
80
+ tables_dir: Artifact::TABLES_DIR,
81
+ )
82
+ end
83
+
84
+ def ensure_bindings!(flavor, entry)
85
+ return unless Artifact.for(flavor).bindings(entry).empty?
86
+
87
+ raise Pubid::Errors::ParseError,
88
+ "PG artifact for #{flavor} declares no bindings " \
89
+ "for entry #{entry}"
90
+ end
91
+
92
+ def format_for(flavor)
93
+ :"pg_#{flavor}"
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
data/lib/pubid/parg.rb CHANGED
@@ -4,5 +4,6 @@ module Pubid
4
4
  module Parg
5
5
  autoload :Artifact, "pubid/parg/artifact"
6
6
  autoload :Backend, "pubid/parg/backend"
7
+ autoload :Model, "pubid/parg/model"
7
8
  end
8
9
  end
@@ -16,7 +16,7 @@ module Pubid
16
16
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
17
17
  end
18
18
 
19
- parsed = Pubid::Parg::Backend.parse(:sae, input)
19
+ parsed = Pubid::Parg::Model.bound(:sae, input)
20
20
  Builder.build(parsed)
21
21
  end
22
22
 
data/lib/pubid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pubid
4
- VERSION = "2.0.0.pre.alpha.64"
4
+ VERSION = "2.0.0.pre.alpha.65"
5
5
  end
@@ -122,7 +122,7 @@ module Pubid
122
122
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
123
123
  end
124
124
 
125
- parsed = Pubid::Parg::Backend.parse(:w3c, identifier)
125
+ parsed = Pubid::Parg::Model.bound(:w3c, identifier)
126
126
  Builder.build(parsed)
127
127
  end
128
128
  end
@@ -58,7 +58,7 @@ module Pubid
58
58
  raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
59
59
  end
60
60
 
61
- parsed = Pubid::Parg::Backend.parse(:xsf, identifier)
61
+ parsed = Pubid::Parg::Model.bound(:xsf, identifier)
62
62
  Builder.build(parsed)
63
63
  end
64
64
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.alpha.64
4
+ version: 2.0.0.pre.alpha.65
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-28 00:00:00.000000000 Z
11
+ date: 2026-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -44,7 +44,7 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 1.3.111
47
+ version: 1.3.114
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
50
  version: '1.4'
@@ -54,7 +54,7 @@ dependencies:
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: 1.3.111
57
+ version: 1.3.114
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '1.4'
@@ -939,6 +939,7 @@ files:
939
939
  - lib/pubid/parg.rb
940
940
  - lib/pubid/parg/artifact.rb
941
941
  - lib/pubid/parg/backend.rb
942
+ - lib/pubid/parg/model.rb
942
943
  - lib/pubid/parser.rb
943
944
  - lib/pubid/parser/common_parse_methods.rb
944
945
  - lib/pubid/parser/common_parse_rules.rb