pubid 2.0.0.pre.alpha.8 → 2.0.0.pre.alpha.11

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 (672) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +33 -11
  3. data/conformance/pending.yaml +4 -0
  4. data/data/bipm/update_codes.yaml +9 -0
  5. data/data/iec/update_codes.yaml +3 -0
  6. data/data/ieee/update_codes.yaml +107 -1
  7. data/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
  8. data/data/nist/update_codes.yaml +8 -0
  9. data/lib/pubid/adobe/builder.rb +52 -0
  10. data/lib/pubid/adobe/identifier.rb +47 -0
  11. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  12. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  13. data/lib/pubid/adobe/identifiers.rb +10 -0
  14. data/lib/pubid/adobe/parser.rb +136 -0
  15. data/lib/pubid/adobe/renderer.rb +39 -0
  16. data/lib/pubid/adobe/urn_generator.rb +42 -0
  17. data/lib/pubid/adobe/urn_parser.rb +69 -0
  18. data/lib/pubid/adobe.rb +61 -0
  19. data/lib/pubid/amca/builder.rb +4 -4
  20. data/lib/pubid/amca/identifier.rb +1 -3
  21. data/lib/pubid/amca/identifiers/base.rb +50 -33
  22. data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
  23. data/lib/pubid/amca/identifiers/publication.rb +14 -10
  24. data/lib/pubid/amca/identifiers/standard.rb +3 -1
  25. data/lib/pubid/amca/identifiers.rb +0 -1
  26. data/lib/pubid/amca/parser.rb +1 -1
  27. data/lib/pubid/amca/renderer.rb +4 -4
  28. data/lib/pubid/amca/single_identifier.rb +1 -1
  29. data/lib/pubid/amca/urn_generator.rb +2 -2
  30. data/lib/pubid/amca.rb +5 -4
  31. data/lib/pubid/ansi/builder.rb +2 -2
  32. data/lib/pubid/ansi/identifier.rb +18 -0
  33. data/lib/pubid/ansi/parser.rb +1 -1
  34. data/lib/pubid/ansi/renderer.rb +2 -2
  35. data/lib/pubid/ansi.rb +5 -5
  36. data/lib/pubid/api/builder.rb +16 -2
  37. data/lib/pubid/api/identifier.rb +25 -4
  38. data/lib/pubid/api/identifiers/mpms.rb +10 -8
  39. data/lib/pubid/api/parser.rb +1 -1
  40. data/lib/pubid/api/renderer.rb +16 -7
  41. data/lib/pubid/api/single_identifier.rb +5 -12
  42. data/lib/pubid/api.rb +1 -0
  43. data/lib/pubid/ashrae/builder.rb +53 -32
  44. data/lib/pubid/ashrae/identifier.rb +3 -4
  45. data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
  46. data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
  47. data/lib/pubid/ashrae/identifiers/base.rb +94 -12
  48. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
  49. data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
  50. data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
  51. data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
  52. data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
  53. data/lib/pubid/ashrae/identifiers.rb +0 -1
  54. data/lib/pubid/ashrae/parser.rb +37 -17
  55. data/lib/pubid/ashrae/renderer.rb +20 -20
  56. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  57. data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
  58. data/lib/pubid/ashrae/urn_generator.rb +8 -2
  59. data/lib/pubid/ashrae.rb +10 -4
  60. data/lib/pubid/asme/builder.rb +11 -2
  61. data/lib/pubid/asme/identifier.rb +9 -0
  62. data/lib/pubid/asme/identifiers/standard.rb +86 -2
  63. data/lib/pubid/asme/parser.rb +1 -1
  64. data/lib/pubid/asme/renderer.rb +3 -3
  65. data/lib/pubid/asme/single_identifier.rb +8 -1
  66. data/lib/pubid/asme/urn_generator.rb +2 -2
  67. data/lib/pubid/asme.rb +1 -0
  68. data/lib/pubid/astm/builder.rb +10 -3
  69. data/lib/pubid/astm/identifier.rb +9 -0
  70. data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
  71. data/lib/pubid/astm/identifiers/code_number.rb +81 -0
  72. data/lib/pubid/astm/identifiers/data_series.rb +2 -0
  73. data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
  74. data/lib/pubid/astm/identifiers/manual.rb +10 -0
  75. data/lib/pubid/astm/identifiers/monograph.rb +2 -0
  76. data/lib/pubid/astm/identifiers/research_report.rb +10 -0
  77. data/lib/pubid/astm/identifiers/standard.rb +10 -0
  78. data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
  79. data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
  80. data/lib/pubid/astm/identifiers.rb +1 -0
  81. data/lib/pubid/astm/parser.rb +1 -1
  82. data/lib/pubid/astm/renderer.rb +1 -1
  83. data/lib/pubid/astm/single_identifier.rb +31 -1
  84. data/lib/pubid/astm/urn_generator.rb +7 -5
  85. data/lib/pubid/astm.rb +1 -0
  86. data/lib/pubid/bipm/builder.rb +163 -0
  87. data/lib/pubid/bipm/identifier.rb +285 -0
  88. data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
  89. data/lib/pubid/bipm/identifiers/guide.rb +35 -0
  90. data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
  91. data/lib/pubid/bipm/identifiers/mep.rb +33 -0
  92. data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
  93. data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
  94. data/lib/pubid/bipm/identifiers.rb +15 -0
  95. data/lib/pubid/bipm/parser.rb +237 -0
  96. data/lib/pubid/bipm/renderer.rb +118 -0
  97. data/lib/pubid/bipm/urn_generator.rb +58 -0
  98. data/lib/pubid/bipm/urn_parser.rb +60 -0
  99. data/lib/pubid/bipm.rb +92 -0
  100. data/lib/pubid/bsi/builder.rb +62 -52
  101. data/lib/pubid/bsi/identifier.rb +0 -1
  102. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  103. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
  104. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
  105. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  106. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
  107. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
  108. data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
  109. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  110. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  111. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  112. data/lib/pubid/bsi/identifiers/handbook.rb +0 -2
  113. data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
  114. data/lib/pubid/bsi/identifiers/set.rb +11 -0
  115. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
  116. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  117. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  118. data/lib/pubid/bsi/parser.rb +1 -1
  119. data/lib/pubid/bsi/renderer.rb +71 -59
  120. data/lib/pubid/bsi/single_identifier.rb +64 -7
  121. data/lib/pubid/bsi/urn_generator.rb +11 -2
  122. data/lib/pubid/bsi.rb +7 -1
  123. data/lib/pubid/builder/base.rb +23 -11
  124. data/lib/pubid/bundled_identifier.rb +19 -9
  125. data/lib/pubid/calconnect/builder.rb +38 -0
  126. data/lib/pubid/calconnect/identifier.rb +121 -0
  127. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  128. data/lib/pubid/calconnect/identifiers.rb +9 -0
  129. data/lib/pubid/calconnect/parser.rb +54 -0
  130. data/lib/pubid/calconnect/renderer.rb +36 -0
  131. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  132. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  133. data/lib/pubid/calconnect.rb +83 -0
  134. data/lib/pubid/ccsds/builder.rb +1 -1
  135. data/lib/pubid/ccsds/identifier.rb +10 -3
  136. data/lib/pubid/ccsds/identifiers/base.rb +4 -2
  137. data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
  138. data/lib/pubid/ccsds/parser.rb +1 -1
  139. data/lib/pubid/ccsds/single_identifier.rb +2 -2
  140. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  141. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  142. data/lib/pubid/ccsds.rb +1 -0
  143. data/lib/pubid/cen_cenelec/builder.rb +131 -72
  144. data/lib/pubid/cen_cenelec/identifier.rb +115 -3
  145. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
  146. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
  147. data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
  148. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
  149. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
  150. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
  151. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -14
  152. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
  153. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  154. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
  155. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
  156. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
  157. data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
  158. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
  159. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
  160. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
  161. data/lib/pubid/cen_cenelec/parser.rb +1 -1
  162. data/lib/pubid/cen_cenelec/renderer.rb +55 -60
  163. data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
  164. data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
  165. data/lib/pubid/cen_cenelec.rb +104 -82
  166. data/lib/pubid/cie/builder.rb +149 -24
  167. data/lib/pubid/cie/identifier.rb +13 -4
  168. data/lib/pubid/cie/identifiers/bundle.rb +35 -5
  169. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  170. data/lib/pubid/cie/identifiers/conference.rb +11 -6
  171. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  172. data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
  173. data/lib/pubid/cie/identifiers/identical.rb +9 -9
  174. data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
  175. data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
  176. data/lib/pubid/cie/identifiers/standard.rb +43 -8
  177. data/lib/pubid/cie/identifiers/supplement.rb +27 -25
  178. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
  179. data/lib/pubid/cie/identifiers.rb +2 -0
  180. data/lib/pubid/cie/parser.rb +55 -6
  181. data/lib/pubid/cie/single_identifier.rb +40 -1
  182. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  183. data/lib/pubid/cie/urn_generator.rb +11 -8
  184. data/lib/pubid/cie.rb +7 -2
  185. data/lib/pubid/components/date.rb +21 -5
  186. data/lib/pubid/conformance/checks.rb +72 -0
  187. data/lib/pubid/conformance/corpus/case.rb +55 -0
  188. data/lib/pubid/conformance/corpus.rb +36 -0
  189. data/lib/pubid/conformance/generator.rb +212 -0
  190. data/lib/pubid/conformance/pending.rb +63 -0
  191. data/lib/pubid/conformance/runner.rb +153 -0
  192. data/lib/pubid/conformance.rb +55 -0
  193. data/lib/pubid/core.rb +2 -0
  194. data/lib/pubid/csa/builder.rb +48 -48
  195. data/lib/pubid/csa/composite_identifier.rb +18 -7
  196. data/lib/pubid/csa/identifier.rb +187 -80
  197. data/lib/pubid/csa/identifiers/bundled.rb +25 -9
  198. data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
  199. data/lib/pubid/csa/identifiers/cec.rb +44 -4
  200. data/lib/pubid/csa/identifiers/combined.rb +97 -69
  201. data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
  202. data/lib/pubid/csa/identifiers/package.rb +4 -4
  203. data/lib/pubid/csa/parser.rb +12 -8
  204. data/lib/pubid/csa/renderer.rb +13 -5
  205. data/lib/pubid/csa/single_identifier.rb +93 -4
  206. data/lib/pubid/csa/urn_generator.rb +9 -2
  207. data/lib/pubid/csa/wrapper_identifier.rb +43 -10
  208. data/lib/pubid/csa.rb +7 -1
  209. data/lib/pubid/doi/builder.rb +18 -0
  210. data/lib/pubid/doi/identifier.rb +49 -0
  211. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  212. data/lib/pubid/doi/identifiers.rb +9 -0
  213. data/lib/pubid/doi/parser.rb +52 -0
  214. data/lib/pubid/doi/renderer.rb +13 -0
  215. data/lib/pubid/doi.rb +56 -0
  216. data/lib/pubid/easc/builder.rb +55 -0
  217. data/lib/pubid/easc/identifier.rb +59 -0
  218. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  219. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  220. data/lib/pubid/easc/identifiers.rb +10 -0
  221. data/lib/pubid/easc/parser.rb +88 -0
  222. data/lib/pubid/easc/renderer.rb +48 -0
  223. data/lib/pubid/easc/urn_generator.rb +46 -0
  224. data/lib/pubid/easc/urn_parser.rb +57 -0
  225. data/lib/pubid/easc.rb +53 -0
  226. data/lib/pubid/ecma/builder.rb +45 -0
  227. data/lib/pubid/ecma/identifier.rb +147 -0
  228. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  229. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  230. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  231. data/lib/pubid/ecma/identifiers.rb +11 -0
  232. data/lib/pubid/ecma/parser.rb +76 -0
  233. data/lib/pubid/ecma/renderer.rb +67 -0
  234. data/lib/pubid/ecma/urn_generator.rb +46 -0
  235. data/lib/pubid/ecma/urn_parser.rb +51 -0
  236. data/lib/pubid/ecma.rb +68 -0
  237. data/lib/pubid/errors.rb +80 -0
  238. data/lib/pubid/etsi/builder.rb +13 -4
  239. data/lib/pubid/etsi/identifier.rb +1 -3
  240. data/lib/pubid/etsi/identifiers/base.rb +43 -11
  241. data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
  242. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
  243. data/lib/pubid/etsi/identifiers.rb +0 -1
  244. data/lib/pubid/etsi/parser.rb +9 -3
  245. data/lib/pubid/etsi/renderer.rb +8 -2
  246. data/lib/pubid/etsi.rb +6 -5
  247. data/lib/pubid/evs/builder.rb +26 -0
  248. data/lib/pubid/evs/identifier.rb +37 -0
  249. data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
  250. data/lib/pubid/evs/identifiers.rb +9 -0
  251. data/lib/pubid/evs/parser.rb +27 -0
  252. data/lib/pubid/evs/renderer.rb +30 -0
  253. data/lib/pubid/evs/urn_generator.rb +30 -0
  254. data/lib/pubid/evs/urn_parser.rb +80 -0
  255. data/lib/pubid/evs.rb +90 -0
  256. data/lib/pubid/export/exporter.rb +2 -1
  257. data/lib/pubid/export/flavor_exporter.rb +18 -3
  258. data/lib/pubid/export.rb +1 -0
  259. data/lib/pubid/format_detector.rb +1 -0
  260. data/lib/pubid/gb/builder.rb +45 -0
  261. data/lib/pubid/gb/identifier.rb +67 -0
  262. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  263. data/lib/pubid/gb/identifiers.rb +9 -0
  264. data/lib/pubid/gb/parser.rb +63 -0
  265. data/lib/pubid/gb/renderer.rb +35 -0
  266. data/lib/pubid/gb.rb +88 -0
  267. data/lib/pubid/gost/builder.rb +185 -0
  268. data/lib/pubid/gost/identifier.rb +47 -0
  269. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  270. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  271. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  272. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  273. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  274. data/lib/pubid/gost/identifiers.rb +13 -0
  275. data/lib/pubid/gost/parser.rb +105 -0
  276. data/lib/pubid/gost/renderer.rb +48 -0
  277. data/lib/pubid/gost/urn_generator.rb +46 -0
  278. data/lib/pubid/gost/urn_parser.rb +52 -0
  279. data/lib/pubid/gost.rb +50 -0
  280. data/lib/pubid/iala/builder.rb +22 -27
  281. data/lib/pubid/iala/identifier.rb +36 -8
  282. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  283. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  284. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  285. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  286. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  287. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  288. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  289. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  290. data/lib/pubid/iala/identifiers/report.rb +1 -1
  291. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  292. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  293. data/lib/pubid/iala/identifiers.rb +0 -1
  294. data/lib/pubid/iala/parser.rb +10 -2
  295. data/lib/pubid/iala/renderer.rb +1 -1
  296. data/lib/pubid/iala/urn_generator.rb +1 -1
  297. data/lib/pubid/iala/urn_parser.rb +24 -3
  298. data/lib/pubid/iala.rb +5 -4
  299. data/lib/pubid/iana/builder.rb +22 -0
  300. data/lib/pubid/iana/identifier.rb +140 -0
  301. data/lib/pubid/iana/identifiers/registry.rb +69 -0
  302. data/lib/pubid/iana/identifiers.rb +9 -0
  303. data/lib/pubid/iana/parser.rb +38 -0
  304. data/lib/pubid/iana/renderer.rb +32 -0
  305. data/lib/pubid/iana/urn_generator.rb +19 -0
  306. data/lib/pubid/iana/urn_parser.rb +24 -0
  307. data/lib/pubid/iana.rb +70 -0
  308. data/lib/pubid/identifier.rb +797 -26
  309. data/lib/pubid/identifier_metadata.rb +1 -0
  310. data/lib/pubid/idf/builder.rb +4 -4
  311. data/lib/pubid/idf/identifier.rb +18 -9
  312. data/lib/pubid/idf/parser.rb +3 -3
  313. data/lib/pubid/idf/renderer.rb +5 -5
  314. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  315. data/lib/pubid/idf/urn_generator.rb +1 -1
  316. data/lib/pubid/idf.rb +7 -1
  317. data/lib/pubid/iec/builder.rb +49 -32
  318. data/lib/pubid/iec/components.rb +0 -1
  319. data/lib/pubid/iec/identifier.rb +112 -77
  320. data/lib/pubid/iec/identifiers/amendment.rb +6 -2
  321. data/lib/pubid/iec/identifiers/base.rb +2 -2
  322. data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
  323. data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
  324. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  325. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
  326. data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
  327. data/lib/pubid/iec/identifiers/guide.rb +0 -16
  328. data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
  329. data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
  330. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
  331. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  332. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
  333. data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
  334. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  335. data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
  336. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
  337. data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
  338. data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
  339. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  340. data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
  341. data/lib/pubid/iec/identifiers/working_document.rb +24 -10
  342. data/lib/pubid/iec/identifiers.rb +1 -0
  343. data/lib/pubid/iec/parser.rb +53 -28
  344. data/lib/pubid/iec/renderer.rb +31 -18
  345. data/lib/pubid/iec/single_identifier.rb +34 -11
  346. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  347. data/lib/pubid/iec/urn_generator.rb +227 -61
  348. data/lib/pubid/iec/urn_parser.rb +42 -4
  349. data/lib/pubid/iec.rb +2 -6
  350. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  351. data/lib/pubid/ieee/aiee/identifier.rb +46 -62
  352. data/lib/pubid/ieee/aiee/parser.rb +1 -1
  353. data/lib/pubid/ieee/builder.rb +386 -69
  354. data/lib/pubid/ieee/compaction.rb +121 -0
  355. data/lib/pubid/ieee/components/draft.rb +47 -7
  356. data/lib/pubid/ieee/identifier.rb +1 -3
  357. data/lib/pubid/ieee/identifiers/adopted_standard.rb +62 -5
  358. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  359. data/lib/pubid/ieee/identifiers/base.rb +148 -18
  360. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  361. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  362. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  363. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +24 -3
  364. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  365. data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
  366. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  367. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
  368. data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
  369. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
  370. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  371. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  372. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  373. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  374. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  375. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  376. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  377. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  378. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  379. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  380. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  381. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  382. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  383. data/lib/pubid/ieee/identifiers.rb +2 -1
  384. data/lib/pubid/ieee/ire/builder.rb +7 -6
  385. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  386. data/lib/pubid/ieee/ire/parser.rb +1 -1
  387. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  388. data/lib/pubid/ieee/nesc/parser.rb +16 -15
  389. data/lib/pubid/ieee/parser.rb +462 -44
  390. data/lib/pubid/ieee/pre_parser.rb +1 -1
  391. data/lib/pubid/ieee/renderer.rb +158 -57
  392. data/lib/pubid/ieee/typed_stages.rb +12 -1
  393. data/lib/pubid/ieee/urn_generator.rb +35 -8
  394. data/lib/pubid/ieee.rb +63 -4
  395. data/lib/pubid/ieee_debug.rb +1 -0
  396. data/lib/pubid/ietf/builder.rb +78 -0
  397. data/lib/pubid/ietf/identifier.rb +5 -0
  398. data/lib/pubid/ietf/identifiers/base.rb +72 -0
  399. data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
  400. data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
  401. data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
  402. data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
  403. data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
  404. data/lib/pubid/ietf/identifiers/std.rb +36 -0
  405. data/lib/pubid/ietf/identifiers.rb +14 -0
  406. data/lib/pubid/ietf/parser.rb +61 -0
  407. data/lib/pubid/ietf/renderer.rb +64 -0
  408. data/lib/pubid/ietf/urn_generator.rb +37 -0
  409. data/lib/pubid/ietf/urn_parser.rb +43 -0
  410. data/lib/pubid/ietf.rb +86 -0
  411. data/lib/pubid/iho/identifier.rb +1 -3
  412. data/lib/pubid/iho/identifiers/base.rb +11 -10
  413. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  414. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  415. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  416. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  417. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  418. data/lib/pubid/iho/identifiers.rb +0 -1
  419. data/lib/pubid/iho/parser.rb +1 -1
  420. data/lib/pubid/iho.rb +8 -7
  421. data/lib/pubid/isbn/builder.rb +44 -0
  422. data/lib/pubid/isbn/check_digit.rb +53 -0
  423. data/lib/pubid/isbn/identifier.rb +81 -0
  424. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  425. data/lib/pubid/isbn/identifiers.rb +9 -0
  426. data/lib/pubid/isbn/parser.rb +45 -0
  427. data/lib/pubid/isbn/renderer.rb +16 -0
  428. data/lib/pubid/isbn.rb +53 -0
  429. data/lib/pubid/iso/builder.rb +9 -4
  430. data/lib/pubid/iso/bundled_identifier.rb +5 -3
  431. data/lib/pubid/iso/combined_identifier.rb +6 -4
  432. data/lib/pubid/iso/identifier.rb +29 -8
  433. data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
  434. data/lib/pubid/iso/normalizer.rb +2 -2
  435. data/lib/pubid/iso/parser.rb +17 -13
  436. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  437. data/lib/pubid/iso/urn_generator.rb +4 -1
  438. data/lib/pubid/iso/urn_parser.rb +1 -1
  439. data/lib/pubid/iso.rb +7 -1
  440. data/lib/pubid/itu/builder.rb +230 -29
  441. data/lib/pubid/itu/components/code.rb +48 -5
  442. data/lib/pubid/itu/components/designation.rb +35 -0
  443. data/lib/pubid/itu/components.rb +1 -0
  444. data/lib/pubid/itu/identifier.rb +1 -3
  445. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  446. data/lib/pubid/itu/identifiers/amendment.rb +7 -29
  447. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  448. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  449. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  450. data/lib/pubid/itu/identifiers/base.rb +357 -25
  451. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  452. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  453. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  454. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  455. data/lib/pubid/itu/identifiers/question.rb +63 -0
  456. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  457. data/lib/pubid/itu/identifiers/report.rb +39 -0
  458. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  459. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  460. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  461. data/lib/pubid/itu/identifiers.rb +10 -1
  462. data/lib/pubid/itu/model.rb +1 -1
  463. data/lib/pubid/itu/parser.rb +481 -27
  464. data/lib/pubid/itu/urn_generator.rb +36 -6
  465. data/lib/pubid/itu/urn_parser.rb +8 -0
  466. data/lib/pubid/itu.rb +12 -3
  467. data/lib/pubid/jcgm/builder.rb +24 -14
  468. data/lib/pubid/jcgm/identifier.rb +10 -0
  469. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  470. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  471. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  472. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  473. data/lib/pubid/jcgm/identifiers.rb +2 -0
  474. data/lib/pubid/jcgm/parser.rb +74 -7
  475. data/lib/pubid/jcgm/renderer.rb +33 -12
  476. data/lib/pubid/jcgm/single_identifier.rb +84 -6
  477. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  478. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  479. data/lib/pubid/jcgm/urn_parser.rb +164 -10
  480. data/lib/pubid/jcgm.rb +10 -0
  481. data/lib/pubid/jis/identifier.rb +62 -3
  482. data/lib/pubid/jis/parser.rb +1 -1
  483. data/lib/pubid/jis.rb +1 -0
  484. data/lib/pubid/nist/builder.rb +29 -9
  485. data/lib/pubid/nist/caster.rb +7 -45
  486. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  487. data/lib/pubid/nist/components/stage.rb +2 -2
  488. data/lib/pubid/nist/components/supplement.rb +5 -2
  489. data/lib/pubid/nist/configuration.rb +6 -2
  490. data/lib/pubid/nist/identifier.rb +1 -3
  491. data/lib/pubid/nist/identifiers/base.rb +133 -39
  492. data/lib/pubid/nist/identifiers/circular.rb +10 -3
  493. data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
  494. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  495. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  496. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +8 -2
  497. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
  498. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  499. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  500. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  501. data/lib/pubid/nist/identifiers/handbook.rb +10 -3
  502. data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
  503. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  504. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
  505. data/lib/pubid/nist/identifiers/monograph.rb +15 -8
  506. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  507. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  508. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  509. data/lib/pubid/nist/identifiers/report.rb +15 -7
  510. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  511. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  512. data/lib/pubid/nist/identifiers.rb +0 -1
  513. data/lib/pubid/nist/parser.rb +27 -4
  514. data/lib/pubid/nist/preprocessor.rb +15 -0
  515. data/lib/pubid/nist/router.rb +2 -2
  516. data/lib/pubid/nist/series/ir.rb +0 -3
  517. data/lib/pubid/nist/supplement_identifier.rb +24 -9
  518. data/lib/pubid/nist.rb +19 -13
  519. data/lib/pubid/oasis/builder.rb +79 -0
  520. data/lib/pubid/oasis/identifier.rb +160 -0
  521. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  522. data/lib/pubid/oasis/identifiers.rb +9 -0
  523. data/lib/pubid/oasis/parser.rb +34 -0
  524. data/lib/pubid/oasis/renderer.rb +29 -0
  525. data/lib/pubid/oasis/urn_generator.rb +25 -0
  526. data/lib/pubid/oasis/urn_parser.rb +22 -0
  527. data/lib/pubid/oasis.rb +80 -0
  528. data/lib/pubid/ogc/builder.rb +33 -0
  529. data/lib/pubid/ogc/identifier.rb +81 -0
  530. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  531. data/lib/pubid/ogc/identifiers.rb +10 -0
  532. data/lib/pubid/ogc/parser.rb +40 -0
  533. data/lib/pubid/ogc/renderer.rb +33 -0
  534. data/lib/pubid/ogc/urn_generator.rb +14 -0
  535. data/lib/pubid/ogc/urn_parser.rb +22 -0
  536. data/lib/pubid/ogc.rb +72 -0
  537. data/lib/pubid/oiml/builder.rb +36 -8
  538. data/lib/pubid/oiml/identifier.rb +9 -1
  539. data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
  540. data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
  541. data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
  542. data/lib/pubid/oiml/identifiers/document.rb +2 -0
  543. data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
  544. data/lib/pubid/oiml/identifiers/guide.rb +2 -0
  545. data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
  546. data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
  547. data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
  548. data/lib/pubid/oiml/identifiers.rb +1 -0
  549. data/lib/pubid/oiml/parser.rb +12 -13
  550. data/lib/pubid/oiml/renderer.rb +13 -13
  551. data/lib/pubid/oiml/single_identifier.rb +41 -37
  552. data/lib/pubid/oiml/supplement_identifier.rb +36 -9
  553. data/lib/pubid/oiml/urn_parser.rb +23 -6
  554. data/lib/pubid/oiml.rb +10 -0
  555. data/lib/pubid/omg/builder.rb +20 -0
  556. data/lib/pubid/omg/identifier.rb +61 -0
  557. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  558. data/lib/pubid/omg/identifiers.rb +9 -0
  559. data/lib/pubid/omg/parser.rb +93 -0
  560. data/lib/pubid/omg/renderer.rb +31 -0
  561. data/lib/pubid/omg.rb +52 -0
  562. data/lib/pubid/parser/grammar.rb +74 -0
  563. data/lib/pubid/parser.rb +2 -0
  564. data/lib/pubid/parsers/mr_string.rb +120 -7
  565. data/lib/pubid/plateau/builder.rb +8 -4
  566. data/lib/pubid/plateau/identifier.rb +1 -3
  567. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  568. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  569. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  570. data/lib/pubid/plateau/identifiers.rb +0 -1
  571. data/lib/pubid/plateau/parser.rb +16 -6
  572. data/lib/pubid/plateau/renderer.rb +1 -1
  573. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  574. data/lib/pubid/plateau.rb +14 -4
  575. data/lib/pubid/prefixes_support.rb +1 -0
  576. data/lib/pubid/renderers/annotator.rb +233 -0
  577. data/lib/pubid/renderers/base.rb +13 -0
  578. data/lib/pubid/renderers/directives_renderer.rb +3 -3
  579. data/lib/pubid/renderers/human_readable.rb +6 -4
  580. data/lib/pubid/renderers/mr_string.rb +54 -6
  581. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  582. data/lib/pubid/renderers.rb +1 -0
  583. data/lib/pubid/rendering/numbering.rb +25 -7
  584. data/lib/pubid/rendering/supplement.rb +4 -4
  585. data/lib/pubid/rendering.rb +1 -0
  586. data/lib/pubid/sae/builder.rb +1 -1
  587. data/lib/pubid/sae/identifier.rb +1 -3
  588. data/lib/pubid/sae/identifiers/base.rb +19 -9
  589. data/lib/pubid/sae/identifiers.rb +0 -1
  590. data/lib/pubid/sae/parser.rb +1 -1
  591. data/lib/pubid/sae.rb +4 -3
  592. data/lib/pubid/schema/declaration.rb +33 -0
  593. data/lib/pubid/schema/error.rb +14 -0
  594. data/lib/pubid/schema/identifier_type.rb +23 -0
  595. data/lib/pubid/schema/loader.rb +117 -0
  596. data/lib/pubid/schema/typed_stage.rb +24 -0
  597. data/lib/pubid/schema.rb +25 -0
  598. data/lib/pubid/tgpp/builder.rb +41 -0
  599. data/lib/pubid/tgpp/identifier.rb +107 -0
  600. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  601. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  602. data/lib/pubid/tgpp/identifiers.rb +11 -0
  603. data/lib/pubid/tgpp/parser.rb +78 -0
  604. data/lib/pubid/tgpp/renderer.rb +52 -0
  605. data/lib/pubid/tgpp/urn_generator.rb +39 -0
  606. data/lib/pubid/tgpp/urn_parser.rb +30 -0
  607. data/lib/pubid/tgpp.rb +84 -0
  608. data/lib/pubid/type_resolver.rb +74 -0
  609. data/lib/pubid/un/builder.rb +42 -0
  610. data/lib/pubid/un/identifier.rb +40 -0
  611. data/lib/pubid/un/identifiers/document.rb +24 -0
  612. data/lib/pubid/un/identifiers.rb +9 -0
  613. data/lib/pubid/un/parser.rb +25 -0
  614. data/lib/pubid/un/renderer.rb +11 -0
  615. data/lib/pubid/un.rb +47 -0
  616. data/lib/pubid/urn_parser/errors.rb +8 -1
  617. data/lib/pubid/urn_parser.rb +1 -0
  618. data/lib/pubid/utils.rb +1 -0
  619. data/lib/pubid/version.rb +1 -1
  620. data/lib/pubid/w3c/builder.rb +55 -0
  621. data/lib/pubid/w3c/identifier.rb +130 -0
  622. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  623. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  624. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  625. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  626. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  627. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  628. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  629. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  630. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  631. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  632. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  633. data/lib/pubid/w3c/identifiers.rb +25 -0
  634. data/lib/pubid/w3c/parser.rb +43 -0
  635. data/lib/pubid/w3c/renderer.rb +35 -0
  636. data/lib/pubid/w3c/urn_generator.rb +18 -0
  637. data/lib/pubid/w3c/urn_parser.rb +36 -0
  638. data/lib/pubid/w3c.rb +68 -0
  639. data/lib/pubid/xsf/builder.rb +17 -0
  640. data/lib/pubid/xsf/identifier.rb +66 -0
  641. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  642. data/lib/pubid/xsf/identifiers.rb +9 -0
  643. data/lib/pubid/xsf/parser.rb +38 -0
  644. data/lib/pubid/xsf/renderer.rb +23 -0
  645. data/lib/pubid/xsf/urn_generator.rb +13 -0
  646. data/lib/pubid/xsf/urn_parser.rb +18 -0
  647. data/lib/pubid/xsf.rb +82 -0
  648. data/lib/pubid.rb +424 -22
  649. data/lib/tasks/conformance.rake +34 -0
  650. data/lib/tasks/docs.rake +3 -3
  651. data/lib/tasks/schema.rake +88 -0
  652. data/schema/core/joint_prefixes.yaml +24 -0
  653. data/schema/iec.yaml +1017 -0
  654. data/schema/iso.yaml +1586 -0
  655. data/schema/schema.schema.yaml +96 -0
  656. metadata +241 -19
  657. data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
  658. data/archived-gems/pubid-iec/stages.yaml +0 -129
  659. data/archived-gems/pubid-iec/update_codes.yaml +0 -67
  660. data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
  661. data/archived-gems/pubid-iso/stages.yaml +0 -106
  662. data/archived-gems/pubid-iso/update_codes.yaml +0 -4
  663. data/archived-gems/pubid-itu/i18n.yaml +0 -13
  664. data/archived-gems/pubid-itu/series.yaml +0 -42
  665. data/archived-gems/pubid-nist/publishers.yaml +0 -6
  666. data/archived-gems/pubid-nist/update_codes.yaml +0 -93
  667. data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
  668. data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
  669. data/lib/pubid/cie/components/code.rb +0 -80
  670. data/lib/pubid/iala/identifiers/base.rb +0 -14
  671. data/lib/pubid/iec/components/code.rb +0 -36
  672. /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
@@ -5,7 +5,6 @@ module Pubid
5
5
  class SingleIdentifier < Identifier
6
6
  # Base class for OIML single identifiers (non-supplements)
7
7
  attribute :publisher, :string
8
- attribute :code, Oiml::Components::Code
9
8
  attribute :date, Pubid::Components::Date
10
9
  attribute :edition, :string
11
10
  attribute :stage, :string
@@ -16,46 +15,24 @@ module Pubid
16
15
  } # Track parsed format
17
16
 
18
17
  # Serialization delta on top of Oiml::Identifier's shared block. The
19
- # `code` (number/part/subpart/suffix) and `date` (year) components are
20
- # flattened to top-level keys rather than nested hashes, mirroring ISO
21
- # (lib/pubid/iso/identifier.rb). `type` is intentionally omitted
22
- # (recomputed from the class on load).
18
+ # `date` (year) component is flattened to a top-level key rather than a
19
+ # nested hash, mirroring ISO (lib/pubid/iso/identifier.rb). `type` is
20
+ # intentionally omitted (recomputed from the class on load).
21
+ #
22
+ # The code columns (number/part/subpart/suffix/space_suffix) are NOT
23
+ # here: they are declared, and mapped, by Identifiers::CodeNumber on each
24
+ # concrete leaf, because redefining the inherited `number` on this class
25
+ # — which every leaf inherits — is the multi-flavor determinism landmine.
26
+ # Keeping the mapping with the attribute is also what lets Bulletin, the
27
+ # one leaf with no code, omit both.
23
28
  key_value do
24
29
  map "publisher", to: :publisher
25
- map "number", with: { to: :number_to_kv, from: :number_from_kv }
26
- map "part", with: { to: :part_to_kv, from: :part_from_kv }
27
- map "subpart", with: { to: :subpart_to_kv, from: :subpart_from_kv }
28
- map "suffix", with: { to: :suffix_to_kv, from: :suffix_from_kv }
29
- map "space_suffix",
30
- with: { to: :space_suffix_to_kv, from: :space_suffix_from_kv }
31
30
  map "year", with: { to: :year_to_kv, from: :year_from_kv }
32
31
  map "edition", to: :edition
33
32
  map "stage", to: :stage
34
33
  map "iteration", to: :iteration
35
34
  end
36
35
 
37
- # --- code components flattened to top-level keys ---
38
- def number_to_kv(model, doc) = emit_kv(doc, "number", model.code&.number)
39
- def number_from_kv(model, value) = code_for(model).number = value.to_s
40
- def part_to_kv(model, doc) = emit_kv(doc, "part", model.code&.part)
41
- def part_from_kv(model, value) = code_for(model).part = value.to_s
42
- def subpart_to_kv(model, doc) = emit_kv(doc, "subpart", model.code&.subpart)
43
- def subpart_from_kv(model, value) = code_for(model).subpart = value.to_s
44
- def suffix_to_kv(model, doc) = emit_kv(doc, "suffix", model.code&.suffix)
45
- def suffix_from_kv(model, value) = code_for(model).suffix = value.to_s
46
-
47
- def space_suffix_to_kv(model, doc)
48
- return unless model.code&.space_suffix
49
-
50
- doc.add_child(
51
- Lutaml::KeyValue::DataModel::Element.new("space_suffix", true),
52
- )
53
- end
54
-
55
- def space_suffix_from_kv(model, value)
56
- code_for(model).space_suffix = value
57
- end
58
-
59
36
  # --- date flattened to a top-level year ---
60
37
  def year_to_kv(model, doc) = emit_kv(doc, "year", model.date&.year)
61
38
 
@@ -69,10 +46,6 @@ module Pubid
69
46
  doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, value.to_s))
70
47
  end
71
48
 
72
- def code_for(model)
73
- model.code ||= Components::Code.new
74
- end
75
-
76
49
  attr_reader :requested_format
77
50
 
78
51
  # Type is determined by the subclass
@@ -103,6 +76,37 @@ module Pubid
103
76
  raise NotImplementedError, "Subclasses must implement type_string"
104
77
  end
105
78
 
79
+ # OIML keeps identity in the code columns and `type_string` (e.g. "R",
80
+ # "V", "D"), not in the inherited `typed_stage` — the generic MrString
81
+ # renderer would otherwise drop both and produce `OIML.<year>`.
82
+ # Losslessness for issue #142 requires the type letter and document
83
+ # number to appear in MR.
84
+ #
85
+ # Reads through `code`, which every code-bearing leaf composes from its
86
+ # split columns (Identifiers::CodeNumber); Bulletin has no code and
87
+ # returns nil here, keeping its (year, issue, sequence) slug.
88
+ def mr_number_with_part
89
+ segments = []
90
+ segments << code&.number&.to_s if code&.number
91
+ segments << code&.part&.to_s if code&.part
92
+ segments << code&.subpart&.to_s if code&.subpart
93
+ segments << code&.suffix&.to_s if code&.suffix
94
+ return nil if segments.empty?
95
+
96
+ segments.join("-")
97
+ end
98
+
99
+ # Bulletin overrides `code`; every other leaf gets it from
100
+ # Identifiers::CodeNumber. Returning nil here keeps #== , the renderer
101
+ # and the URN generator total for the abstract class itself.
102
+ def code
103
+ nil
104
+ end
105
+
106
+ def mr_type
107
+ type_string&.downcase
108
+ end
109
+
106
110
  # Subclasses override this
107
111
  end
108
112
  end
@@ -5,9 +5,36 @@ module Pubid
5
5
  class SupplementIdentifier < Identifier
6
6
  # Base class for OIML supplements (amendments, annexes)
7
7
  # These wrap a base identifier like ISO amendments
8
- attribute :base_identifier, Oiml::Identifier, polymorphic: true
8
+ attribute :base, Oiml::Identifier, polymorphic: true
9
9
  attribute :year, :string
10
10
  attribute :language, :string
11
+
12
+ # Delegate the document code to the wrapped standard, mirroring
13
+ # Pubid::Etsi::Identifiers::SupplementIdentifier#code.
14
+ #
15
+ # PRE-EXISTING BUG this closes: `UrnGenerator#urn_number` calls
16
+ # `identifier.code` for every non-Bulletin type, but a supplement
17
+ # descends from Oiml::Identifier directly — it is a SIBLING of
18
+ # SingleIdentifier, which is where `code` used to live — so it inherited
19
+ # no `code` at all and `to_urn` raised NoMethodError for every Amendment,
20
+ # Errata and Annex. Verified against a baseline captured on main: all
21
+ # five supplement fixtures already raised there, so this is a fix, not a
22
+ # regression introduced by the move to split index columns.
23
+ #
24
+ # It stayed hidden because spec/pubid/oiml/urn_spec.rb only exercises a
25
+ # bare Recommendation and spec/pubid/oiml/fixtures_spec.rb globs a bad
26
+ # path and runs 0 examples (hand-off: ten-dead-fixture-specs).
27
+ # `iteration` is the same story: declared on SingleIdentifier, read
28
+ # unconditionally by UrnGenerator#urn_iteration, absent from the
29
+ # supplement branch of the hierarchy. (`stage` escapes because
30
+ # ::Pubid::Identifier declares one, so it merely returns nil.)
31
+ def code
32
+ base&.code
33
+ end
34
+
35
+ def iteration
36
+ base&.iteration
37
+ end
11
38
  # True for the trailing-word shorthand ("OIML R 138:2009 Amendment"),
12
39
  # where the supplement word is appended after a dated base instead of the
13
40
  # "Amendment (YYYY) to BASE" prose form. The word itself comes from the
@@ -21,28 +48,28 @@ module Pubid
21
48
  } # Track supplement's parsed format
22
49
 
23
50
  # Serialization delta on top of Oiml::Identifier's shared block. The
24
- # nested base_identifier is (de)serialized recursively through the
51
+ # nested base is (de)serialized recursively through the
25
52
  # polymorphic router so its own `_type` selects the right subclass.
26
53
  key_value do
27
- map "base_identifier",
28
- with: { to: :base_identifier_to_kv, from: :base_identifier_from_kv }
54
+ map "base",
55
+ with: { to: :base_to_kv, from: :base_from_kv }
29
56
  map "year", to: :year
30
57
  map "trailing", to: :trailing
31
58
  map "joined", to: :joined
32
59
  end
33
60
 
34
- def base_identifier_to_kv(model, doc)
35
- base = model.base_identifier
61
+ def base_to_kv(model, doc)
62
+ base = model.base
36
63
  return unless base
37
64
 
38
65
  doc.add_child(
39
- Lutaml::KeyValue::DataModel::Element.new("base_identifier",
66
+ Lutaml::KeyValue::DataModel::Element.new("base",
40
67
  base.to_hash),
41
68
  )
42
69
  end
43
70
 
44
- def base_identifier_from_kv(model, value)
45
- model.base_identifier = ::Pubid::Oiml::Identifier.from_hash(value) if value
71
+ def base_from_kv(model, value)
72
+ model.base = ::Pubid::Oiml::Identifier.from_hash(value) if value
46
73
  end
47
74
 
48
75
  attr_reader :requested_format
@@ -4,18 +4,35 @@ module Pubid
4
4
  module Oiml
5
5
  # Parses OIML URNs back into identifiers.
6
6
  #
7
- # UrnGenerator emits: `urn:oiml:{type}:{number}[-{part}]` where type
8
- # is the lowercase document class (r for Recommendation, d for Document).
7
+ # UrnGenerator emits: `urn:oiml:{type}:{locator}` where type is the
8
+ # lowercase document class — single letter for typed documents
9
+ # (r, d, b, g, …) or the word "bulletin" for Bulletin issues. The
10
+ # locator is the number-part-subpart for typed documents and the
11
+ # YYYY-II-SS tuple for Bulletins.
9
12
  #
10
13
  # Examples:
11
- # - urn:oiml:r:111-1 → OIML R 111-1
12
- # - urn:oiml:d:1 → OIML D 1
14
+ # - urn:oiml:r:111-1 → OIML R 111-1
15
+ # - urn:oiml:d:1 → OIML D 1
16
+ # - urn:oiml:bulletin:2026-02-11 → OIML Bulletin 2026-02-11
13
17
  class UrnParser < Pubid::UrnParser::Base
14
18
  def parse_urn(urn)
15
19
  body = strip_namespace(urn)
16
20
  parts = split_parts(body)
17
- type_token, number = parts
18
- flavor_parse("OIML #{type_token.upcase} #{number}")
21
+ type_token = parts.fetch(0)
22
+ number = parts[1]
23
+
24
+ text = "OIML #{display_type(type_token)}"
25
+ text += " #{number}" if number
26
+ flavor_parse(text)
27
+ end
28
+
29
+ private
30
+
31
+ # URN type tokens are lowercase. Typed documents use a single letter
32
+ # that maps cleanly via upcase; Bulletin is the multi-letter word
33
+ # that the human parser expects capitalized.
34
+ def display_type(token)
35
+ token.downcase == "bulletin" ? "Bulletin" : token.upcase
19
36
  end
20
37
  end
21
38
  end
data/lib/pubid/oiml.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Oiml
5
6
  extend Pubid::PrefixesSupport
@@ -19,6 +20,15 @@ module Pubid
19
20
  autoload :UrnParser, "#{__dir__}/oiml/urn_parser"
20
21
 
21
22
  def self.parse(identifier)
23
+ unless identifier.is_a?(String)
24
+ raise Pubid::Errors::InvalidInputError,
25
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
26
+ end
27
+
28
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
29
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
30
+ end
31
+
22
32
  parser = Parser.new
23
33
  builder = Builder.new
24
34
 
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ # Builds a Pubid::Omg::Identifier from a parse tree.
6
+ class Builder
7
+ def self.build(parsed_data)
8
+ new.build(parsed_data)
9
+ end
10
+
11
+ def build(data)
12
+ Identifiers::Specification.new(
13
+ acronym: data[:acronym].to_s,
14
+ version: data[:version]&.to_s,
15
+ part: data[:part]&.to_s,
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ # Base class for every OMG identifier AND the flavor's parse/create
6
+ # entry point.
7
+ class Identifier < ::Pubid::Identifier
8
+ # The spec family acronym, e.g. "AMI4CCM", "UML", "CORBA".
9
+ attribute :acronym, :string
10
+
11
+ # Free-form version string. Stored verbatim because OMG versioning is
12
+ # loose ("1.0", "2.5.1", "5 beta 3", "1.1"). Use Version#to_s for
13
+ # rendering.
14
+ attribute :version, :string
15
+
16
+ # The document part: the volume or format segment after the version,
17
+ # e.g. "Superstructure", "Infrastructure", "PDF".
18
+ #
19
+ # This retypes the `part` that ::Pubid::Identifier declares as a
20
+ # Components::Code, because an OMG part is a name and not a numbered
21
+ # part. Reusing the inherited name is what gives relaton `remove_part!`
22
+ # as `exclude(:part)`, and what lets Renderers::Annotator wrap the value
23
+ # from its own TOKENS table. The declaration sits once, on the class
24
+ # every OMG identifier inherits from, whose body lives in this one file
25
+ # and is never reopened — the placement the number-retype tranches
26
+ # require.
27
+ attribute :part, :string
28
+
29
+ OMG_TYPE_MAP = {
30
+ "pubid:omg:specification" => "Pubid::Omg::Identifiers::Specification",
31
+ }.freeze
32
+
33
+ key_value do
34
+ map "_type", to: :_type, polymorphic_map: OMG_TYPE_MAP
35
+ map "acronym", to: :acronym
36
+ map "version", to: :version
37
+ map "part", to: :part
38
+ end
39
+
40
+ PUBLISHER = "OMG"
41
+
42
+ def to_s(**opts)
43
+ render(format: :human, **opts)
44
+ end
45
+
46
+ def self.parse(identifier)
47
+ unless identifier.is_a?(String)
48
+ raise Pubid::Errors::InvalidInputError,
49
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
50
+ end
51
+
52
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
53
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
54
+ end
55
+
56
+ parsed = Parser.parse(identifier)
57
+ Builder.build(parsed)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ module Identifiers
6
+ # OMG specification identifier.
7
+ #
8
+ # Examples:
9
+ # OMG AMI4CCM 1.0
10
+ # OMG UML 2.5.1
11
+ # OMG DDS 5 beta 3
12
+ # OMG CORBA
13
+ class Specification < Identifier
14
+ TYPED_STAGES = [
15
+ Pubid::Components::TypedStage.new(
16
+ code: :pubomg,
17
+ stage_code: :published,
18
+ type_code: :omg,
19
+ abbr: ["OMG"],
20
+ name: "OMG Specification",
21
+ harmonized_stages: %w[60.00 60.60],
22
+ ),
23
+ ].freeze
24
+
25
+ def self.type
26
+ { key: :omg, web: :specification, title: "OMG Specification",
27
+ short: "OMG" }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ module Identifiers
6
+ autoload :Specification, "#{__dir__}/identifiers/specification"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Omg
7
+ # Parslet grammar for OMG specification identifiers.
8
+ #
9
+ # Accepts:
10
+ # OMG {ACRONYM}[ {VERSION}][ {PART}]
11
+ #
12
+ # ACRONYM is the URL segment of https://www.omg.org/spec/<ACRONYM>/, e.g.
13
+ # "UML", "DDS-XTypes", "EDMC-FIBO/BE", "VSIPL++", "smartant".
14
+ # VERSION is digits/dots, optionally followed by a beta label, e.g. "1.0",
15
+ # "2.5.1", "5 beta 3", "2.5 beta".
16
+ # PART is the volume or format segment, e.g. "Superstructure", "PDF". A
17
+ # space or a slash separates it.
18
+ class Parser < ::Pubid::Parser::Grammar
19
+ rule(:space) { str(" ") }
20
+
21
+ # Acronym: the URL segment OMG gives the specification, kept verbatim,
22
+ # because a consumer builds the URL from it. It starts with a letter,
23
+ # which may be lower case ("smartant"). Letters, digits and "+" follow
24
+ # ("SysML", "AMI4CCM", "VSIPL++"). A hyphen or a slash joins further
25
+ # segments ("DDS-PSM-Cxx", "EDMC-FIBO/BE"). Each segment is non-empty,
26
+ # so a hyphen or a slash never ends the acronym.
27
+ #
28
+ # The slash in "EDMC-FIBO/BE" belongs to the acronym: OMG serves the
29
+ # document at /spec/EDMC-FIBO/BE/. A slash after the version separates
30
+ # the document part instead (see the identifier rule).
31
+ rule(:acronym_char) { match("[A-Za-z0-9+]") }
32
+
33
+ rule(:acronym) do
34
+ (match("[A-Za-z]") >> acronym_char.repeat >>
35
+ (match("[-/]") >> acronym_char.repeat(1)).repeat).as(:acronym)
36
+ end
37
+
38
+ # Version: digits with optional dots, optionally followed by " beta" and
39
+ # an optional beta number. OMG writes the label both ways: the document
40
+ # at /spec/UML/2.5/Beta1 gives its own version as "2.5 beta", and DDS 1.4
41
+ # supersedes /spec/DDS/1.4/Beta2.
42
+ #
43
+ # The beta number must stay optional here. The document part below would
44
+ # otherwise swallow a bare "beta" and report the version as "2.5" — a
45
+ # silent wrong answer, not a parse failure.
46
+ #
47
+ # Both halves of the beta label end at a word boundary. Parslet never
48
+ # backtracks into a `.maybe` that already succeeded, so an unanchored
49
+ # literal makes the version eat the front of a document part and then
50
+ # reject the whole identifier: "OMG DDS 1.4 beta2" and
51
+ # "OMG DDS 1.4 betawave" would raise instead of reading the part.
52
+ rule(:word_boundary) { match("[A-Za-z0-9]").absent? }
53
+
54
+ rule(:beta) do
55
+ str(" beta") >> word_boundary >>
56
+ (space >> match("[0-9]").repeat(1) >> word_boundary).maybe
57
+ end
58
+
59
+ rule(:version) do
60
+ (match("[0-9]").repeat(1) >>
61
+ (str(".") >> match("[0-9]").repeat(1)).repeat >>
62
+ beta.maybe).as(:version)
63
+ end
64
+
65
+ # After the version, OMG separates the document part with either a
66
+ # space or a slash. The renderer prints a space, so the two spellings of
67
+ # one document stay equal.
68
+ rule(:part_separator) { space | str("/") }
69
+
70
+ # Document part: the volume or format segment OMG puts after the
71
+ # version. UML 2.1.1 is two documents, Superstructure and
72
+ # Infrastructure, and the URL carries the same segment
73
+ # (/spec/UML/2.1.1/Superstructure). A format name (/spec/DDS/1.4/PDF)
74
+ # occupies the same position.
75
+ rule(:part) { match("[A-Za-z0-9]").repeat(1).as(:part) }
76
+
77
+ # Only a space separates a part that follows the acronym directly. The
78
+ # acronym rule takes a slash there, so a slash separator is legal only
79
+ # after a version.
80
+ rule(:identifier) do
81
+ str("OMG") >> space >> acronym >>
82
+ ((space >> version >> (part_separator >> part).maybe) |
83
+ (space >> part)).maybe
84
+ end
85
+
86
+ rule(:root) { identifier }
87
+
88
+ def self.parse(input)
89
+ new.parse(input)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ # Human-readable renderer for OMG specification identifiers.
6
+ #
7
+ # Produces:
8
+ # "OMG AMI4CCM 1.0"
9
+ # "OMG UML 2.5.1"
10
+ # "OMG UML 2.1.1 Superstructure"
11
+ # "OMG CORBA"
12
+ #
13
+ # The document part always prints behind a space. OMG writes it behind
14
+ # either a space or a slash, and the parser takes both, so normalizing
15
+ # here is what keeps the two spellings of one document equal.
16
+ class Renderer < ::Pubid::Renderers::Base
17
+ def render(**_opts)
18
+ result = "OMG #{@id.acronym}"
19
+ result += " #{@id.version}" if present?(@id.version)
20
+ result += " #{@id.part}" if present?(@id.part)
21
+ result
22
+ end
23
+
24
+ private
25
+
26
+ def present?(value)
27
+ value && !value.empty?
28
+ end
29
+ end
30
+ end
31
+ end
data/lib/pubid/omg.rb ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ module Pubid
5
+ # OMG (Object Management Group) specification flavor.
6
+ #
7
+ # Covers formal OMG specifications identified by an acronym (UML, SysML,
8
+ # CORBA, DDS-XTypes, EDMC-FIBO/BE, ...) with optional version (`1.0`, `2.5.1`,
9
+ # `5 beta 3`).
10
+ module Omg
11
+ extend Pubid::PrefixesSupport
12
+
13
+ PREFIXES = ["OMG"].freeze
14
+
15
+ autoload :Builder, "#{__dir__}/omg/builder"
16
+ autoload :Identifier, "#{__dir__}/omg/identifier"
17
+ autoload :Identifiers, "#{__dir__}/omg/identifiers"
18
+ autoload :Parser, "#{__dir__}/omg/parser"
19
+ autoload :Renderer, "#{__dir__}/omg/renderer"
20
+
21
+ def self.parse(identifier)
22
+ Identifier.parse(identifier)
23
+ end
24
+
25
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
26
+ Identifier.format_registry.register(:human, renderer: Omg::Renderer)
27
+
28
+ def self.identifier_types
29
+ @identifier_types ||= Identifiers.constants
30
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
31
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
32
+ .select { |c| c.type.is_a?(Hash) }
33
+ end
34
+
35
+ def self.all_typed_stages
36
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
37
+ klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
38
+ end
39
+ end
40
+
41
+ def self.locate_type(code)
42
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
43
+ end
44
+
45
+ def self.locate_stage(abbr)
46
+ abbr_str = abbr.to_s.upcase
47
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
48
+ end
49
+ end
50
+ end
51
+
52
+ Pubid::Registry.register(:omg, Pubid::Omg)
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+ require_relative "../errors"
5
+
6
+ module Pubid
7
+ module Parser
8
+ # The superclass of every flavor grammar.
9
+ #
10
+ # Its only job is to keep parslet out of pubid's public contract. Every
11
+ # grammar failure originates in `Parslet::Atoms::Base#parse`, which
12
+ # `Parslet::Parser` does not override, so one override here covers all 46
13
+ # grammars, both public entry points of every flavor, and the cross-flavor
14
+ # delegation routes (`Pubid::Iso.parse("ITU-T G.711")` runs ITU's grammar)
15
+ # — without touching the 131 `parse` methods.
16
+ #
17
+ # The name is `Grammar`, not `Base`, because {Pubid::Parsers::Base} already
18
+ # exists and means something unrelated (the MR-string parser).
19
+ #
20
+ # Known limit: a rule atom parsed directly, `Parser.new.<rule>.parse(str)`,
21
+ # bypasses this and raises a bare `Parslet::ParseFailed`. Nothing in the
22
+ # gem does that.
23
+ class Grammar < ::Parslet::Parser
24
+ # @param io [String, IO]
25
+ # @param options [Hash] passed through to parslet
26
+ # @raise [Pubid::Errors::ParseError]
27
+ def parse(io, options = {})
28
+ super
29
+ rescue ::Pubid::Errors::ParseError
30
+ # A nested grammar already wrapped it. Keep the inner flavor and input.
31
+ raise
32
+ rescue ::Parslet::ParseFailed => e
33
+ raise wrap_parse_failure(e, io)
34
+ end
35
+
36
+ private
37
+
38
+ # @param error [Parslet::ParseFailed]
39
+ # @param io [String, IO] what was handed to {#parse}
40
+ # @return [Pubid::Errors::ParseError]
41
+ def wrap_parse_failure(error, io)
42
+ ::Pubid::Errors::ParseError.new(
43
+ error.message,
44
+ error.parse_failure_cause,
45
+ input: io.is_a?(String) ? io : nil,
46
+ flavor: pubid_flavor_name,
47
+ )
48
+ end
49
+
50
+ # "Pubid::Iso::Parser" -> "iso"; "Pubid::Ieee::Aiee::Parser" -> "ieee".
51
+ #
52
+ # Resolved through {Pubid::Registry} rather than taken from the module
53
+ # name, because the two disagree: `Pubid::Tgpp` registers as `"3gpp"`,
54
+ # and `Pubid::CenCenelec` registers twice (`"cen_cenelec"` first, then
55
+ # the `"cen"` alias). Reporting the registered name is what lets a caller
56
+ # feed `error.flavor` straight back to `Pubid::Registry.get`.
57
+ # @return [String, nil]
58
+ def pubid_flavor_name
59
+ parts = self.class.name.to_s.split("::")
60
+ return nil unless parts[0] == "Pubid" && parts.length > 1
61
+
62
+ registered_flavor_name(parts[1]) || parts[1].downcase
63
+ end
64
+
65
+ # @param module_name [String] e.g. "Tgpp"
66
+ # @return [String, nil] the registered name, nil if not registered
67
+ def registered_flavor_name(module_name)
68
+ ::Pubid::Registry.canonical_name(::Pubid.const_get(module_name))
69
+ rescue ::NameError
70
+ nil
71
+ end
72
+ end
73
+ end
74
+ end
data/lib/pubid/parser.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Parser
6
+ autoload :Grammar, "pubid/parser/grammar"
5
7
  autoload :CommonParseMethods, "pubid/parser/common_parse_methods"
6
8
  autoload :CommonParseRules, "pubid/parser/common_parse_rules"
7
9
  end