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
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ # Base class for every IETF identifier AND the flavor's parse/create entry
6
+ # point (mirrors Pubid::Jis::Identifier). Concrete identifiers under
7
+ # Pubid::Ietf::Identifiers descend from this class, so a parsed IETF id is
8
+ # an instance of Pubid::Ietf::Identifier.
9
+ #
10
+ # All families are flat, supplement-free, and use plain string attributes.
11
+ # Those attributes are declared on the LEAVES by Identifiers::Serialization
12
+ # (see the determinism note there — never re-add `attribute :number` here):
13
+ # * Rfc -> number ("2119")
14
+ # * Bcp/Std/Fyi -> number ("3") + a derived `series` reader
15
+ # * InternetDraft -> number ("draft-giuliano-treedn") + optional version
16
+ class Identifier < ::Pubid::Identifier
17
+ # Polymorphic type map for lutaml::Model key_value (de)serialization: maps
18
+ # each subclass's polymorphic_name to its class name so a stored hash
19
+ # rebuilds the correct identifier type via the shared from_hash dispatch.
20
+ IETF_TYPE_MAP = {
21
+ "pubid:ietf:rfc" => "Pubid::Ietf::Identifiers::Rfc",
22
+ "pubid:ietf:bcp" => "Pubid::Ietf::Identifiers::Bcp",
23
+ "pubid:ietf:std" => "Pubid::Ietf::Identifiers::Std",
24
+ "pubid:ietf:fyi" => "Pubid::Ietf::Identifiers::Fyi",
25
+ "pubid:ietf:internet-draft" =>
26
+ "Pubid::Ietf::Identifiers::InternetDraft",
27
+ }.freeze
28
+
29
+ # NOTE: no `key_value` block here on purpose. The mapping lives on the
30
+ # leaves (Identifiers::Serialization); a block on this shared parent would
31
+ # be inherited-and-merged by every leaf and re-emit keys the leaf did not
32
+ # declare.
33
+
34
+ # Publisher is always "IETF". A plain constant (not a `publisher` method)
35
+ # so it doesn't shadow the inherited lutaml `publisher` attribute, which
36
+ # would otherwise fail serialization type validation.
37
+ PUBLISHER = "IETF"
38
+
39
+ # Basic string representation. Delegates to the flavor renderer.
40
+ def to_s(**opts)
41
+ render(format: :human, **opts)
42
+ end
43
+
44
+ # from_hash is the shared polymorphic dispatch on Pubid::Identifier; the
45
+ # IETF_TYPE_MAP above serves as its key_value polymorphic_map.
46
+
47
+ # Parse an IETF identifier string into the appropriate identifier object.
48
+ # @param identifier [String] the IETF identifier string to parse
49
+ # @return [Identifier] the concrete identifier object
50
+ # @raise [Pubid::Errors::InvalidInputError] if the input exceeds
51
+ # Pubid::MAX_INPUT_LENGTH
52
+ # @raise [Pubid::Errors::ParseError] if parsing fails
53
+ def self.parse(identifier)
54
+ # Inline length guard (CodeQL rb/polynomial-redos barrier) — must be
55
+ # the first statement. This class-level funnel is what relaton reaches
56
+ # directly through `pubid_class: ::Pubid::Ietf::Identifier`, so it
57
+ # cannot rely on the guard in Pubid::Ietf.parse.
58
+ unless identifier.is_a?(String)
59
+ raise Pubid::Errors::InvalidInputError,
60
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
61
+ end
62
+
63
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
64
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
65
+ end
66
+
67
+ parsed = Parser.parse(identifier)
68
+ Builder.build(parsed)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # A BCP (Best Current Practice) sub-series id, e.g. "BCP 3".
7
+ class Bcp < Identifier
8
+ include Serialization
9
+
10
+ # The series token is derived from the class, not stored:
11
+ # `_type` already encodes it, so serializing `series` would
12
+ # duplicate the type in every index row.
13
+ SERIES = "BCP"
14
+
15
+ def series
16
+ SERIES
17
+ end
18
+
19
+ TYPED_STAGES = [
20
+ Pubid::Components::TypedStage.new(
21
+ code: :bcp,
22
+ stage_code: :published,
23
+ type_code: :bcp,
24
+ abbr: ["BCP"],
25
+ name: "Best Current Practice",
26
+ harmonized_stages: [],
27
+ ),
28
+ ].freeze
29
+
30
+ def self.type
31
+ { key: :bcp, web: :bcp, title: "Best Current Practice", short: "BCP" }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # An FYI (For Your Information) sub-series id, e.g. "FYI 1".
7
+ class Fyi < Identifier
8
+ include Serialization
9
+
10
+ # The series token is derived from the class, not stored:
11
+ # `_type` already encodes it, so serializing `series` would
12
+ # duplicate the type in every index row.
13
+ SERIES = "FYI"
14
+
15
+ def series
16
+ SERIES
17
+ end
18
+
19
+ TYPED_STAGES = [
20
+ Pubid::Components::TypedStage.new(
21
+ code: :fyi,
22
+ stage_code: :published,
23
+ type_code: :fyi,
24
+ abbr: ["FYI"],
25
+ name: "For Your Information",
26
+ harmonized_stages: [],
27
+ ),
28
+ ].freeze
29
+
30
+ def self.type
31
+ { key: :fyi, web: :fyi, title: "For Your Information", short: "FYI" }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # An Internet-Draft, e.g. "draft-giuliano-treedn-02" (versioned) or
7
+ # "draft-giuliano-treedn" (the unversioned "latest" sibling). The full
8
+ # slug (including the leading "draft-") is stored in `number` — it is the
9
+ # relaton-index narrowing key, shared by a draft's unversioned aggregator
10
+ # row and all of its versions; the optional trailing two-digit version is
11
+ # in `version`.
12
+ class InternetDraft < Identifier
13
+ include Serialization
14
+
15
+ # Two-digit version string, zero-pad preserved ("02"); nil for the
16
+ # unversioned "latest" sibling, in which case the canonical to_hash
17
+ # drops the key entirely.
18
+ attribute :version, :string
19
+
20
+ # Merged with the block Serialization installs (lutaml combines a
21
+ # mixin-installed key_value with a second in-class one), so the
22
+ # serialized shape is {_type, number} plus `version` when set.
23
+ key_value do
24
+ map "version", to: :version
25
+ end
26
+
27
+ TYPED_STAGES = [
28
+ Pubid::Components::TypedStage.new(
29
+ code: :internet_draft,
30
+ stage_code: :draft,
31
+ type_code: :internet_draft,
32
+ abbr: ["I-D", "Internet-Draft"],
33
+ name: "Internet-Draft",
34
+ harmonized_stages: [],
35
+ ),
36
+ ].freeze
37
+
38
+ def self.type
39
+ { key: :internet_draft, web: :internet_draft,
40
+ title: "Internet-Draft", short: "I-D" }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # An RFC (Request for Comments), e.g. "RFC 2119".
7
+ class Rfc < Identifier
8
+ include Serialization
9
+
10
+ TYPED_STAGES = [
11
+ Pubid::Components::TypedStage.new(
12
+ code: :rfc,
13
+ stage_code: :published,
14
+ type_code: :rfc,
15
+ abbr: ["RFC"],
16
+ name: "Request for Comments",
17
+ harmonized_stages: [],
18
+ ),
19
+ ].freeze
20
+
21
+ def self.type
22
+ { key: :rfc, web: :rfc, title: "Request for Comments", short: "RFC" }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # Installs the flat, index-friendly attribute set and the shared
7
+ # `key_value` block on the five concrete IETF leaves (Rfc, Bcp, Std, Fyi,
8
+ # InternetDraft).
9
+ #
10
+ # Why the leaves and not the shared Pubid::Ietf::Identifier base:
11
+ # `number` redefines the parent ::Pubid::Identifier's
12
+ # `attribute :number, Components::Code` as a plain :string. Declaring that
13
+ # on a class the concrete types INHERIT from resolves against the parent
14
+ # definition nondeterministically under multi-flavor load — it passes an
15
+ # IETF-only run and can flip `root.number` to "" under the full suite (the
16
+ # IEEE lesson; see lib/pubid/ieee/identifiers/code_number.rb and
17
+ # CLAUDE.md). Declaring `number` directly on each leaf removes the
18
+ # ambiguity at the point of use.
19
+ #
20
+ # This matters because relaton-index bsearches on `id.root.number.to_s`,
21
+ # and every IETF identifier is its own root (the flavor has no wrapper or
22
+ # supplement types), so an empty key silently defeats the search for every
23
+ # row. spec/pubid/ietf/root_number_spec.rb guards it and must run under
24
+ # the FULL suite to be meaningful.
25
+ #
26
+ # `series` is deliberately NOT an attribute here: `_type` already encodes
27
+ # it, so storing it would duplicate the type in every sub-series row. The
28
+ # three sub-series leaves expose it as a derived reader instead.
29
+ module Serialization
30
+ def self.included(base)
31
+ # Document number of an RFC or sub-series id ("2119", "66"), kept as
32
+ # a string so the printed form carries no zero-pad; for an
33
+ # Internet-Draft, the version-less slug INCLUDING the leading
34
+ # "draft-" ("draft-ietf-quic-transport"). The slug is the right index
35
+ # key for the same reason the number is for an RFC: a draft's
36
+ # unversioned aggregator row and every one of its versions share it,
37
+ # so a document and its variants cluster into one bucket.
38
+ base.attribute :number, :string
39
+
40
+ # Only these keys serialize; the inherited Pubid::Identifier
41
+ # attributes are intentionally dropped. InternetDraft merges its own
42
+ # `version` mapping on top of this block.
43
+ base.key_value do
44
+ map "_type", to: :_type, polymorphic_map: Identifier::IETF_TYPE_MAP
45
+ map "number", to: :number
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ # An STD (Internet Standard) sub-series id, e.g. "STD 66".
7
+ class Std < Identifier
8
+ include Serialization
9
+
10
+ # The series token is derived from the class, not stored:
11
+ # `_type` already encodes it, so serializing `series` would
12
+ # duplicate the type in every index row.
13
+ SERIES = "STD"
14
+
15
+ def series
16
+ SERIES
17
+ end
18
+
19
+ TYPED_STAGES = [
20
+ Pubid::Components::TypedStage.new(
21
+ code: :std,
22
+ stage_code: :published,
23
+ type_code: :std,
24
+ abbr: ["STD"],
25
+ name: "Internet Standard",
26
+ harmonized_stages: [],
27
+ ),
28
+ ].freeze
29
+
30
+ def self.type
31
+ { key: :std, web: :std, title: "Internet Standard", short: "STD" }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ module Identifiers
6
+ autoload :Serialization, "#{__dir__}/identifiers/serialization"
7
+ autoload :Rfc, "#{__dir__}/identifiers/rfc"
8
+ autoload :Bcp, "#{__dir__}/identifiers/bcp"
9
+ autoload :Std, "#{__dir__}/identifiers/std"
10
+ autoload :Fyi, "#{__dir__}/identifiers/fyi"
11
+ autoload :InternetDraft, "#{__dir__}/identifiers/internet_draft"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Ietf
7
+ # Parslet grammar for the three IETF families. The top-level alternation is
8
+ # keyed by leading token, and each alternative captures the raw fields the
9
+ # Builder needs:
10
+ # * RFC -> { number: }
11
+ # * sub-series -> { series:, number: }
12
+ # * draft -> { draft_rest: } (everything after "draft-"; the version
13
+ # split is done in the Builder to keep the digit-tail
14
+ # heuristic in one place)
15
+ class Parser < ::Pubid::Parser::Grammar
16
+ rule(:space) { str(" ") }
17
+ rule(:digit) { match["0-9"] }
18
+ rule(:digits) { digit.repeat(1) }
19
+
20
+ # "RFC 2119", and the zero-padded, space-less spelling the RFC editor's
21
+ # rfc-index.xml emits ("RFC0001"). See #subseries for why.
22
+ rule(:rfc) { str("RFC") >> space.maybe >> digits.as(:number) }
23
+
24
+ # "BCP 3" / "STD 66" / "FYI 1".
25
+ #
26
+ # The space is optional and leading zeros are allowed because
27
+ # rfc-index.xml writes the sub-series membership of an RFC in the padded,
28
+ # space-less form -- <is-also><doc-id>STD0066</doc-id></is-also> -- and
29
+ # relaton builds the STD/BCP/FYI <-> RFC cross-references from exactly
30
+ # those elements without normalizing them itself. The Builder strips the
31
+ # pad, so the printed form stays the canonical "STD 66".
32
+ rule(:subseries) do
33
+ (str("BCP") | str("STD") | str("FYI")).as(:series) >>
34
+ space.maybe >> digits.as(:number)
35
+ end
36
+
37
+ # Internet-Draft slug characters: lowercase, digits and the "-", "+", "_"
38
+ # separators, plus two historical shapes the published corpus carries --
39
+ # a dot inside a topic token ("draft-ietf-pilc-2.5g3g-12") and uppercase
40
+ # letters in protocol/organisation names ("draft-chapin-clnp-ISO8473-00").
41
+ # 50 of the 166,740 relaton-data-ids identifiers need those two
42
+ # characters; nothing else outside [a-z0-9-] occurs in the corpus.
43
+ #
44
+ # Widening the tail is unambiguous: the top-level alternation is keyed on
45
+ # the leading token (RFC / BCP|STD|FYI / draft-), so a wider draft tail
46
+ # cannot make another branch match.
47
+ #
48
+ # The whole remainder after "draft-" is captured; the Builder anchors the
49
+ # optional trailing "-NN" version.
50
+ rule(:draft_rest) { match['a-zA-Z0-9+_.\-'].repeat(1).as(:draft_rest) }
51
+ rule(:draft) { str("draft-") >> draft_rest }
52
+
53
+ rule(:identifier) { rfc | subseries | draft }
54
+ rule(:root) { identifier }
55
+
56
+ def self.parse(input)
57
+ new.parse(input)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ # Human-readable renderer for IETF identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "RFC 2119"
9
+ # "BCP 3" / "STD 66" / "FYI 1"
10
+ # "draft-giuliano-treedn-02" / "draft-giuliano-treedn"
11
+ class Renderer < ::Pubid::Renderers::Base
12
+ def render(context: nil, **_opts)
13
+ require_number!(@id)
14
+ render_identifier(@id)
15
+ end
16
+
17
+ private
18
+
19
+ # For an Internet-Draft, `number` holds the version-less slug including
20
+ # the leading "draft-"; for the sub-series, `series` is derived from the
21
+ # class rather than stored. The sub-series arm names its three classes
22
+ # explicitly instead of being a catch-all `else`, because a bare
23
+ # Pubid::Ietf::Identifier has no `series` reader at all.
24
+ def render_identifier(id)
25
+ case id
26
+ when Identifiers::Rfc then "RFC #{id.number}"
27
+ when Identifiers::InternetDraft then render_draft(id)
28
+ when Identifiers::Bcp, Identifiers::Std, Identifiers::Fyi
29
+ "#{id.series} #{id.number}"
30
+ else unsupported!(id)
31
+ end
32
+ end
33
+
34
+ def render_draft(id)
35
+ id.version ? "#{id.number}-#{id.version}" : id.number
36
+ end
37
+
38
+ # Fail loudly rather than render a nil/partial string. `number` carries
39
+ # the whole document identity for every IETF type, so a nil one means the
40
+ # object was built from something that is not a current IETF hash — most
41
+ # likely a pre-`number` index row, which stored an Internet-Draft slug
42
+ # under `name` (a key nothing reads any more; lutaml ignores it
43
+ # silently). Such a row would otherwise deserialize into an identifier
44
+ # that renders "" or "-02" and keys the index under "", with no error
45
+ # anywhere — exactly the silent-wrong-lookup failure this flavor's
46
+ # round-trip specs exist to prevent. Regenerate the
47
+ # relaton-data-{rfcs,rfcsubseries,ids} indexes instead.
48
+ def require_number!(id)
49
+ return unless id.respond_to?(:number)
50
+ return unless id.number.nil? || id.number.empty?
51
+
52
+ raise ArgumentError,
53
+ "Cannot render #{id.class} with an empty number " \
54
+ "(a pre-`number` index row stored the draft slug under `name`; " \
55
+ "regenerate the index)"
56
+ end
57
+
58
+ def unsupported!(id)
59
+ raise ArgumentError,
60
+ "Cannot render #{id.class}: not a concrete IETF identifier"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ # Emits the canonical IETF URNs:
6
+ # RFC -> urn:ietf:rfc:2119
7
+ # BCP/STD/FYI -> urn:ietf:bcp:3 / urn:ietf:std:66 / urn:ietf:fyi:1
8
+ # Internet-Draft -> urn:ietf:id:draft-giuliano-treedn[:02]
9
+ class UrnGenerator < Pubid::UrnGenerator::Base
10
+ # The sub-series arm names its three classes explicitly rather than being
11
+ # a catch-all `else`, because a bare Pubid::Ietf::Identifier has no
12
+ # `series` reader at all — `series` is derived from the concrete class.
13
+ def generate
14
+ case identifier
15
+ when Identifiers::Rfc then "urn:ietf:rfc:#{identifier.number}"
16
+ when Identifiers::InternetDraft then draft_urn
17
+ when Identifiers::Bcp, Identifiers::Std, Identifiers::Fyi
18
+ "urn:ietf:#{identifier.series.downcase}:#{identifier.number}"
19
+ else unsupported!
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def draft_urn
26
+ base = "urn:ietf:id:#{identifier.number}"
27
+ identifier.version ? "#{base}:#{identifier.version}" : base
28
+ end
29
+
30
+ def unsupported!
31
+ raise ArgumentError,
32
+ "Cannot build a URN for #{identifier.class}: " \
33
+ "not a concrete IETF identifier"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ # Parses IETF URNs back into identifiers by reconstructing the printed form
6
+ # and delegating to the flavor's text parser. Inverts UrnGenerator:
7
+ # urn:ietf:rfc:2119 -> "RFC 2119"
8
+ # urn:ietf:bcp:3 -> "BCP 3"
9
+ # urn:ietf:id:draft-giuliano-treedn:02 -> "draft-giuliano-treedn-02"
10
+ # urn:ietf:id:draft-giuliano-treedn -> "draft-giuliano-treedn"
11
+ class UrnParser < Pubid::UrnParser::Base
12
+ def parse_urn(urn)
13
+ parts = split_parts(strip_namespace(urn))
14
+ flavor_parse(human_text(parts.shift, parts))
15
+ end
16
+
17
+ private
18
+
19
+ def human_text(type, parts)
20
+ case type
21
+ when "rfc" then "RFC #{parts[0]}"
22
+ when "bcp", "std", "fyi" then "#{type.upcase} #{parts[0]}"
23
+ when "id" then draft_text(parts)
24
+ else invalid_type!(type)
25
+ end
26
+ end
27
+
28
+ # `Errors` is defined under Pubid::UrnParser (the module), which is
29
+ # neither in this class's lexical scope nor an ancestor of Base, so the
30
+ # constant must be fully qualified — a bare `Errors::ParseError` raises
31
+ # NameError instead of the intended error.
32
+ def invalid_type!(type)
33
+ raise Pubid::UrnParser::Errors::ParseError,
34
+ "Invalid IETF URN type: #{type.inspect}"
35
+ end
36
+
37
+ def draft_text(parts)
38
+ name, version = parts
39
+ version ? "#{name}-#{version}" : name
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/pubid/ietf.rb ADDED
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ module Pubid
5
+ # IETF flavor: one module covering the three IETF document families that share
6
+ # the IETF publisher and the `urn:ietf:` namespace —
7
+ # * RFC (e.g. "RFC 2119") -> Identifiers::Rfc
8
+ # * RFC sub-series (BCP/STD/FYI) -> Identifiers::Bcp/Std/Fyi
9
+ # * Internet-Drafts (e.g. "draft-...-02") -> Identifiers::InternetDraft
10
+ module Ietf
11
+ extend Pubid::PrefixesSupport
12
+
13
+ # Leading tokens a printed IETF id can begin with. "draft" covers the
14
+ # "draft-<slug>" Internet-Draft form. No joint/co-publication prefixes.
15
+ PREFIXES = ["RFC", "BCP", "STD", "FYI", "draft"].freeze
16
+
17
+ autoload :Builder, "#{__dir__}/ietf/builder"
18
+ autoload :Identifier, "#{__dir__}/ietf/identifiers/base"
19
+ autoload :Identifiers, "#{__dir__}/ietf/identifiers"
20
+ autoload :Parser, "#{__dir__}/ietf/parser"
21
+ autoload :Renderer, "#{__dir__}/ietf/renderer"
22
+ autoload :UrnGenerator, "#{__dir__}/ietf/urn_generator"
23
+ autoload :UrnParser, "#{__dir__}/ietf/urn_parser"
24
+
25
+ # Parse an IETF identifier string
26
+ def self.parse(identifier)
27
+ # Inline length guard (CodeQL rb/polynomial-redos barrier) before the
28
+ # normalization/parse path. The type check goes above it because it is
29
+ # what makes `.length` safe to call; the length check itself must still
30
+ # be the first thing the input string meets.
31
+ unless identifier.is_a?(String)
32
+ raise Pubid::Errors::InvalidInputError,
33
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
34
+ end
35
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
36
+ raise Pubid::Errors::InvalidInputError,
37
+ Pubid::INPUT_TOO_LONG_MESSAGE
38
+ end
39
+
40
+ Identifier.parse(identifier)
41
+ end
42
+
43
+ # Per-flavor format registry: inherits global formats, overrides :human
44
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
45
+ Identifier.format_registry.register(:human, renderer: Ietf::Renderer)
46
+
47
+ # Auto-discover all identifier types from the Identifiers namespace
48
+ # @return [Array<Class>] identifier classes that define a self.type Hash
49
+ def self.identifier_types
50
+ @identifier_types ||= Identifiers.constants
51
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
52
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
53
+ .select { |c| c.type.is_a?(Hash) }
54
+ end
55
+
56
+ # Build typed stage index from identifier types
57
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
58
+ def self.all_typed_stages
59
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
60
+ if klass.const_defined?(:TYPED_STAGES)
61
+ klass.const_get(:TYPED_STAGES)
62
+ else
63
+ []
64
+ end
65
+ end
66
+ end
67
+
68
+ # Lookup: type code -> identifier class
69
+ # @param code [String, Symbol] the type key to find
70
+ # @return [Class, nil] the matching identifier class
71
+ def self.locate_type(code)
72
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
73
+ end
74
+
75
+ # Lookup: abbreviation -> typed stage
76
+ # @param abbr [String, Symbol] the abbreviation to find
77
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
78
+ def self.locate_stage(abbr)
79
+ abbr_str = abbr.to_s.upcase
80
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
81
+ end
82
+ end
83
+ end
84
+
85
+ # Register IETF flavor with the registry
86
+ Pubid::Registry.register(:ietf, Pubid::Ietf)
@@ -3,7 +3,5 @@
3
3
  # The IHO flavor base class is Pubid::Iho::Identifier — a real Pubid::Identifier
4
4
  # subclass that every concrete IHO identifier descends from, so `is_a?` identity
5
5
  # and the shared polymorphic `from_hash` work natively (no facade needed). Its
6
- # body, `.parse`, and the Identifiers::Base back-compat alias live in
7
- # identifiers/base.rb; this file just ensures it is loaded when a consumer
6
+ # body and `.parse` live in identifiers/base.rb; this file just ensures it is loaded when a consumer
8
7
  # references Pubid::Iho::Identifier directly.
9
- require_relative "identifiers/base"
@@ -3,8 +3,7 @@
3
3
  module Pubid
4
4
  module Iho
5
5
  # Base class for all IHO identifiers. Canonical name Pubid::Iho::Identifier;
6
- # every concrete IHO identifier (Identifiers::*) descends from it, and
7
- # Identifiers::Base — aliased at the foot of this file — points back to it.
6
+ # every concrete IHO identifier (Identifiers::*) descends from it.
8
7
  #
9
8
  # IHO identifiers have the form:
10
9
  # IHO {S|P|M|B|C}-{number}[ Ap. {appendix}][ Part {part}][ Annex {annex}][ Suppl {supplement}][ {version}]
@@ -15,12 +14,19 @@ module Pubid
15
14
  # Parse an IHO identifier string into an identifier object
16
15
  # @param identifier [String] The IHO identifier string to parse
17
16
  # @return [Pubid::Iho::Identifier] The appropriate identifier object
18
- # @raise [Parslet::ParseFailed] If parsing fails
17
+ # @raise [Pubid::Errors::ParseError] If parsing fails
19
18
  def self.parse(identifier)
19
+ unless identifier.is_a?(String)
20
+ raise Pubid::Errors::InvalidInputError,
21
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
22
+ end
23
+
24
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
25
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
26
+ end
27
+
20
28
  parsed = Parser.parse(identifier)
21
29
  Builder.build(parsed)
22
- rescue Parslet::ParseFailed => e
23
- raise "Failed to parse IHO identifier '#{identifier}': #{e.message}"
24
30
  end
25
31
 
26
32
  # `number` overrides the generic Components::Code attribute with a plain
@@ -65,10 +71,5 @@ module Pubid
65
71
  # IHO_TYPE_MAP remains as the key_value polymorphic_map.
66
72
  end
67
73
 
68
- module Identifiers
69
- # Backward-compatible alias: IHO's base class used to be
70
- # Pubid::Iho::Identifiers::Base. It is now Pubid::Iho::Identifier.
71
- Base = Pubid::Iho::Identifier
72
- end
73
74
  end
74
75
  end