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,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Gost
5
+ # Parses GOST URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:gost:std:<number>[:<year>] (interstate)
9
+ # urn:gost:std:r:<number>[:<year>] (Russian national)
10
+ #
11
+ # Examples:
12
+ # urn:gost:std:14946:82 → GOST 14946-82
13
+ # urn:gost:std:r:34.12:2015 → GOST R 34.12-2015
14
+ class UrnParser < Pubid::UrnParser::Base
15
+ PREFIX = "urn:gost:std:".freeze
16
+
17
+ def parse_urn(urn)
18
+ body = strip_namespace(urn)
19
+ parts = split_parts(body)
20
+
21
+ if parts.first == "r"
22
+ number = parts[1]
23
+ year = parts[2]
24
+ Identifiers::NationalStandard.new(number: number, year: year)
25
+ else
26
+ number = parts[0]
27
+ year = parts[1]
28
+ Identifiers::InterstateStandard.new(number: number, year: year)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def strip_namespace(urn)
35
+ unless urn.downcase.start_with?(PREFIX)
36
+ raise Pubid::UrnParser::Errors::ParseError,
37
+ "Invalid GOST URN: #{urn.inspect}"
38
+ end
39
+
40
+ urn[PREFIX.length..]
41
+ end
42
+
43
+ def split_parts(body)
44
+ parts = body.split(":")
45
+ raise Pubid::UrnParser::Errors::ParseError,
46
+ "GOST URN missing number: #{body.inspect}" if parts.empty?
47
+
48
+ parts
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/pubid/gost.rb ADDED
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ module Pubid
5
+ module Gost
6
+ extend Pubid::PrefixesSupport
7
+
8
+ # Leading identifier tokens that a GOST document id can start with.
9
+ # Latin "GOST" and Cyrillic "ГОСТ" are both official; "R" (Russian
10
+ # national, e.g. "GOST R 34.12-2015") routes to this flavor too.
11
+ PREFIXES = ["GOST", "ГОСТ"].freeze
12
+
13
+ autoload :Builder, "#{__dir__}/gost/builder"
14
+ autoload :Identifier, "#{__dir__}/gost/identifier"
15
+ autoload :Identifiers, "#{__dir__}/gost/identifiers"
16
+ autoload :Parser, "#{__dir__}/gost/parser"
17
+ autoload :Renderer, "#{__dir__}/gost/renderer"
18
+ autoload :UrnGenerator, "#{__dir__}/gost/urn_generator"
19
+ autoload :UrnParser, "#{__dir__}/gost/urn_parser"
20
+
21
+ # Parse a GOST identifier string into an identifier object.
22
+ # @param identifier [String]
23
+ # @return [Pubid::Gost::Identifier]
24
+ def self.parse(identifier)
25
+ Identifier.parse(identifier)
26
+ end
27
+
28
+ # Per-flavor format registry: inherits global formats, overrides :human.
29
+ Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
30
+ Identifier.format_registry.register(:human, renderer: Gost::Renderer)
31
+
32
+ # Auto-discover identifier types from the Identifiers namespace.
33
+ # @return [Array<Class>]
34
+ def self.identifier_types
35
+ @identifier_types ||= Identifiers.constants
36
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
37
+ .select { |c| c.is_a?(Class) && c < Pubid::Identifier }
38
+ .reject { |c| c == Identifier }
39
+ end
40
+
41
+ # Lookup: type key → identifier class
42
+ # @param code [String, Symbol]
43
+ # @return [Class, nil]
44
+ def self.locate_type(code)
45
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
46
+ end
47
+ end
48
+ end
49
+
50
+ Pubid::Registry.register(:gost, Pubid::Gost)
@@ -10,14 +10,15 @@ module Pubid
10
10
  return build_annex(hash) if hash[:annex_marker]
11
11
 
12
12
  type_letter = stringify(hash[:type_letter])&.upcase
13
+ klass = Iala.identifier_klass_for_type_letter(type_letter)
13
14
 
14
15
  attrs = {
15
- number: build_number(hash, type_letter),
16
+ number: build_number(hash, klass),
16
17
  edition: stringify(hash.dig(:edition, :edition_value)),
17
18
  language: stringify(hash.dig(:language_group, :language))&.upcase,
18
19
  }.compact
19
20
 
20
- Iala.identifier_klass_for_type_letter(type_letter).new(**attrs)
21
+ klass.new(**attrs)
21
22
  end
22
23
 
23
24
  def self.build(parsed)
@@ -32,11 +33,11 @@ module Pubid
32
33
  def build_annex(hash)
33
34
  base_hash = hash[:base]
34
35
  base_type = stringify(base_hash[:type_letter])&.upcase
35
- base_number = build_number(base_hash, base_type)
36
- base = Iala.identifier_klass_for_type_letter(base_type).new(number: base_number)
36
+ base_klass = Iala.identifier_klass_for_type_letter(base_type)
37
+ base = base_klass.new(number: build_number(base_hash, base_klass))
37
38
 
38
39
  attrs = {
39
- base_identifier: base,
40
+ base: base,
40
41
  annex_form: stringify(hash[:annex_marker]),
41
42
  letter: stringify(hash[:annex_letter]),
42
43
  edition: stringify(hash.dig(:edition, :edition_value)),
@@ -49,43 +50,37 @@ module Pubid
49
50
  # Compose the full number string from the leading doc_number plus any
50
51
  # dotted continuation (GA01.13 → "01.13", L2.1.11 → "2.1.11") plus
51
52
  # the optional dash-separated subpart (C0103-1 → "0103-1", L2.7.1-2
52
- # → "2.7.1-2"). Padding is type-aware per IALA's canonical form:
53
- # typed S/R/G/M/C zero-pad to 4 digits; GeneralAssembly (GA) zero-
54
- # pads each segment to 2; Advices (A) and Letters (L) preserve input
55
- # (their canonical form is already what the IALA site prints).
56
- def build_number(hash, type_letter = nil)
53
+ # → "2.7.1-2"). Padding is class-driven: the resolved identifier
54
+ # class declares its canonical IALA cover-page widths via
55
+ # `canonical_number_width` / `canonical_dotted_segment_width`, so a
56
+ # new type declares its padding on its own class instead of editing
57
+ # this builder's case statement.
58
+ def build_number(hash, klass)
57
59
  base = stringify(hash[:doc_number])
58
60
  return base unless base
59
61
 
60
- base = canonical_base(base, type_letter)
62
+ base = canonical_base(base, klass)
61
63
 
62
64
  dots = hash[:doc_number_dots]
63
- dots_str = dots.is_a?(Array) ? "" : canonical_dots(stringify(dots).to_s, type_letter)
65
+ dots_str = dots.is_a?(Array) ? "" : canonical_dots(stringify(dots).to_s, klass)
64
66
 
65
67
  subpart_str = hash[:subpart] ? "-#{subpart_to_s(hash[:subpart])}" : ""
66
68
  subpart_str = "" if subpart_str == "-"
67
69
  "#{base}#{dots_str}#{subpart_str}"
68
70
  end
69
71
 
70
- # Per-type canonical width for the leading numeric run.
71
- def canonical_base(base, type_letter)
72
- case type_letter
73
- when "S", "R", "G", "M", "C", "X", "P" then base.rjust(4, "0")
74
- when "GA" then base.rjust(2, "0")
75
- else base
76
- end
72
+ def canonical_base(base, klass)
73
+ width = klass&.canonical_number_width
74
+ width ? base.rjust(width, "0") : base
77
75
  end
78
76
 
79
- # Per-type canonical width for each dotted continuation segment.
80
- # `str` looks like ".13" or ".1.11" (leading dot, then digits).
81
- def canonical_dots(str, type_letter)
77
+ def canonical_dots(str, klass)
82
78
  return "" if str.empty?
83
79
 
84
- if type_letter == "GA"
85
- str.split(".", -1).map { |seg| seg.empty? ? seg : seg.rjust(2, "0") }.join(".")
86
- else
87
- str
88
- end
80
+ width = klass&.canonical_dotted_segment_width
81
+ return str unless width
82
+
83
+ str.split(".", -1).map { |seg| seg.empty? ? seg : seg.rjust(width, "0") }.join(".")
89
84
  end
90
85
 
91
86
  # The subpart capture may be an array of {subpart_number: "1"},
@@ -4,8 +4,7 @@ module Pubid
4
4
  module Iala
5
5
  # Base class for all IALA identifiers. Canonical name
6
6
  # Pubid::Iala::Identifier; every concrete IALA identifier
7
- # (Identifiers::*) descends from it, and Identifiers::Base — aliased
8
- # at the foot of identifiers/base.rb — points back to it.
7
+ # (Identifiers::*) descends from it.
9
8
  #
10
9
  # IALA identifiers have the form:
11
10
  # [IALA ]{S|R|G|M|C|X|P}<4-digit number>[-<subpart>][ Ed <edition>][ (<LangLetter>)]
@@ -16,15 +15,18 @@ module Pubid
16
15
  # R1016:ed2.0(F)
17
16
  # C0103-1 Ed 3.0
18
17
  class Identifier < ::Pubid::Identifier
19
- # Parse an IALA identifier string into an identifier object.
18
+ # Parse an IALA identifier — human form ("IALA G1199 Ed 1.0") or
19
+ # MRN URN ("urn:mrn:iala:pub:g1199:ed1.0") — into an identifier.
20
20
  # @param identifier [String]
21
21
  # @return [Pubid::Iala::Identifier]
22
- # @raise [Parslet::ParseFailed] If parsing fails
22
+ # @raise [Pubid::Errors::ParseError] If parsing fails
23
23
  def self.parse(identifier)
24
- parsed = Parser.parse(identifier)
25
- Builder.build(parsed)
26
- rescue Parslet::ParseFailed => e
27
- raise "Failed to parse IALA identifier '#{identifier}': #{e.message}"
24
+ if FormatDetector.detect(identifier) == :urn
25
+ UrnParser.parse(identifier)
26
+ else
27
+ parsed = Parser.parse(identifier)
28
+ Builder.build(parsed)
29
+ end
28
30
  end
29
31
 
30
32
  attribute :publisher, :string, default: "IALA"
@@ -62,6 +64,32 @@ module Pubid
62
64
  def type_letter
63
65
  self.class.type[:short]
64
66
  end
67
+
68
+ class << self
69
+ # Zero-pad the leading numeric run of the document number to this
70
+ # width. nil means preserve the input verbatim. Subclasses declare
71
+ # their canonical IALA cover-page form via `number_width` (e.g.
72
+ # Standard declares 4 → M0001; GeneralAssembly declares 2 → GA01).
73
+ # The builder consults this instead of branching on type_letter.
74
+ attr_reader :canonical_number_width
75
+
76
+ # Zero-pad each dotted continuation segment of the number to this
77
+ # width. nil means preserve verbatim. Only GeneralAssembly (GA)
78
+ # sets this today — its series.index form (01.01, 01.13) is the
79
+ # canonical cover-page shape.
80
+ attr_reader :canonical_dotted_segment_width
81
+
82
+ # DSL: declare the canonical zero-pad width for the leading number.
83
+ private
84
+
85
+ def number_width(width)
86
+ @canonical_number_width = width
87
+ end
88
+
89
+ def dotted_segment_width(width)
90
+ @canonical_dotted_segment_width = width
91
+ end
92
+ end
65
93
  end
66
94
  end
67
95
  end
@@ -5,7 +5,7 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA Advices (A prefix). Numbering is dashed: A12-01, A13-04.
7
7
  # Carries no edition in the corpus.
8
- class Advice < Base
8
+ class Advice < Identifier
9
9
  def self.type
10
10
  { key: :advice, title: "Advice", short: "A" }
11
11
  end
@@ -11,19 +11,19 @@ module Pubid
11
11
  #
12
12
  # The case of the marker is preserved (Annex vs ANNEX) for round-trip
13
13
  # fidelity. Edition and language apply to the Annex itself, not the base.
14
- class Annex < Base
14
+ class Annex < Identifier
15
15
  # The publication this annex supplements. Always present; carries the
16
16
  # type letter and number (e.g. G1045).
17
- attribute :base_identifier, ::Pubid::Iala::Identifier, polymorphic: true
17
+ attribute :base, ::Pubid::Iala::Identifier, polymorphic: true
18
18
  # "Annex" or "ANNEX" — preserved verbatim for exact round-trip.
19
19
  attribute :annex_form, :string
20
20
  # "A", "B", "C", "D", or nil for the bare form.
21
21
  attribute :letter, :string
22
22
 
23
23
  key_value do
24
- map "base_identifier",
25
- with: { to: :base_identifier_to_kv,
26
- from: :base_identifier_from_kv }
24
+ map "base",
25
+ with: { to: :base_to_kv,
26
+ from: :base_from_kv }
27
27
  map "annex_form", to: :annex_form
28
28
  map "letter", to: :letter
29
29
  end
@@ -36,20 +36,20 @@ module Pubid
36
36
  # methods via public_send during (de)serialization — a `private`
37
37
  # section here raises NoMethodError on to_hash (matches the public
38
38
  # visibility of Oiml::SupplementIdentifier's identical helpers).
39
- def base_identifier_to_kv(model, doc)
40
- base = model.base_identifier
39
+ def base_to_kv(model, doc)
40
+ base = model.base
41
41
  return unless base
42
42
 
43
43
  doc.add_child(
44
- Lutaml::KeyValue::DataModel::Element.new("base_identifier",
44
+ Lutaml::KeyValue::DataModel::Element.new("base",
45
45
  base.to_hash),
46
46
  )
47
47
  end
48
48
 
49
- def base_identifier_from_kv(model, value)
49
+ def base_from_kv(model, value)
50
50
  return unless value
51
51
 
52
- model.base_identifier = ::Pubid::Iala::Identifier.from_hash(value)
52
+ model.base = ::Pubid::Iala::Identifier.from_hash(value)
53
53
  end
54
54
  end
55
55
  end
@@ -5,9 +5,12 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA General Assembly resolutions (GA prefix). Numbering is dotted
7
7
  # with a series and an index: GA01.01, GA01.13. No edition.
8
- class GeneralAssembly < Base
8
+ class GeneralAssembly < Identifier
9
+ number_width 2
10
+ dotted_segment_width 2
11
+
9
12
  def self.type
10
- { key: :"general-assembly", title: "General Assembly Resolution",
13
+ { key: :"general-assembly", title: "General Assembly Resolution",
11
14
  short: "GA" }
12
15
  end
13
16
  end
@@ -5,7 +5,9 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA Guidelines (G series).
7
7
  # Examples: G1015 Ed 2.2, G1078 Ed 2.1.
8
- class Guideline < Base
8
+ class Guideline < Identifier
9
+ number_width 4
10
+
9
11
  def self.type
10
12
  { key: :guideline, title: "Guideline", short: "G" }
11
13
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  # IALA Letters (L prefix). Numbering is dotted with a series, sub-series,
7
7
  # and item: L2.1.11, L2.7.1-2 (the trailing -2 is a sub-part on top of
8
8
  # the dotted number).
9
- class Letter < Base
9
+ class Letter < Identifier
10
10
  def self.type
11
11
  { key: :letter, title: "Letter", short: "L" }
12
12
  end
@@ -6,7 +6,9 @@ module Pubid
6
6
  # IALA Manuals (M prefix, planned).
7
7
  # Today manuals carry no code (NAVGUIDE, VTS Manual, …); M is
8
8
  # reserved for future numbered manuals.
9
- class Manual < Base
9
+ class Manual < Identifier
10
+ number_width 4
11
+
10
12
  def self.type
11
13
  { key: :manual, title: "Manual", short: "M" }
12
14
  end
@@ -5,7 +5,9 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA Model Courses (C series).
7
7
  # Examples: C0103-1 Ed 3.0, C2001-1 Ed 1.0.
8
- class ModelCourse < Base
8
+ class ModelCourse < Identifier
9
+ number_width 4
10
+
9
11
  def self.type
10
12
  { key: :"model-course", title: "Model Course", short: "C" }
11
13
  end
@@ -5,7 +5,9 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA Recommendations (R series).
7
7
  # Examples: R0103 Ed 3.1, R0126 Ed 2.0, R1024 Ed 1.0.
8
- class Recommendation < Base
8
+ class Recommendation < Identifier
9
+ number_width 4
10
+
9
11
  def self.type
10
12
  { key: :recommendation, title: "Recommendation", short: "R" }
11
13
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  # IALA Reports & Proceedings (X prefix, planned).
7
7
  # Today reports carry no code; X is reserved for future numbered
8
8
  # reports.
9
- class Report < Base
9
+ class Report < Identifier
10
10
  def self.type
11
11
  { key: :report, title: "Report", short: "X" }
12
12
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  # IALA Resolutions and other Council publications (P prefix,
7
7
  # planned). Today resolutions carry no code; P is reserved for
8
8
  # future numbered resolutions.
9
- class Resolution < Base
9
+ class Resolution < Identifier
10
10
  def self.type
11
11
  { key: :resolution, title: "Resolution", short: "P" }
12
12
  end
@@ -5,7 +5,9 @@ module Pubid
5
5
  module Identifiers
6
6
  # IALA Standards (S series).
7
7
  # Examples: S1010, S1020 Ed 2.0, S1070 Ed 2.0.
8
- class Standard < Base
8
+ class Standard < Identifier
9
+ number_width 4
10
+
9
11
  def self.type
10
12
  { key: :standard, title: "Standard", short: "S" }
11
13
  end
@@ -3,7 +3,6 @@
3
3
  module Pubid
4
4
  module Iala
5
5
  module Identifiers
6
- autoload :Base, "#{__dir__}/identifiers/base"
7
6
  autoload :Advice, "#{__dir__}/identifiers/advice"
8
7
  autoload :Annex, "#{__dir__}/identifiers/annex"
9
8
  autoload :Standard, "#{__dir__}/identifiers/standard"
@@ -15,7 +15,7 @@ module Pubid
15
15
  # R1016:ed2.0(F)
16
16
  # C0103-1
17
17
  # C0103-1 Ed 3.0
18
- class Parser < Parslet::Parser
18
+ class Parser < ::Pubid::Parser::Grammar
19
19
  include ::Pubid::Parser::CommonParseRules
20
20
 
21
21
  root :identifier
@@ -121,7 +121,15 @@ module Pubid
121
121
  # @param string [String]
122
122
  # @return [Hash]
123
123
  def self.parse(string)
124
- raise ArgumentError, "IALA identifier string exceeds maximum length" if string.length > ::Pubid::MAX_INPUT_LENGTH
124
+ unless string.is_a?(String)
125
+ raise ::Pubid::Errors::InvalidInputError,
126
+ ::Pubid::INPUT_NOT_A_STRING_MESSAGE
127
+ end
128
+
129
+ if string.length > ::Pubid::MAX_INPUT_LENGTH
130
+ raise ::Pubid::Errors::InvalidInputError,
131
+ ::Pubid::INPUT_TOO_LONG_MESSAGE
132
+ end
125
133
 
126
134
  new.parse(string.strip)
127
135
  end
@@ -24,7 +24,7 @@ module Pubid
24
24
  # the marker form is preserved verbatim ("Annex" vs "ANNEX"), then the
25
25
  # optional letter, edition, and language.
26
26
  def render_annex(id)
27
- base_str = id.base_identifier.to_s
27
+ base_str = id.base.to_s
28
28
  rendered = "#{base_str} #{id.annex_form}"
29
29
  rendered << " #{id.letter}" if id.letter
30
30
  rendered << " Ed #{id.edition}" if id.edition
@@ -31,7 +31,7 @@ module Pubid
31
31
  # G1045 Annex Ed 1 → urn:mrn:iala:pub:g1045:annex:ed1
32
32
  # G1128 ANNEX A Ed 1.6 (E) → urn:mrn:iala:pub:g1128:annex-a:ed1.6:e
33
33
  def generate_annex
34
- base = identifier.base_identifier
34
+ base = identifier.base
35
35
  parts = ["urn:mrn:iala:pub",
36
36
  "#{base.type_letter.downcase}#{base.number}"]
37
37
  annex_seg = identifier.letter ? "annex-#{identifier.letter.downcase}" : "annex"
@@ -6,11 +6,15 @@ module Pubid
6
6
  #
7
7
  # UrnGenerator emits:
8
8
  # urn:mrn:iala:pub:<type-lower><number>[:ed<edition>][:<lang-lower>]
9
+ # and for Annex identifiers:
10
+ # urn:mrn:iala:pub:<base-code>:annex[-<letter>][:ed<edition>][:<lang>]
9
11
  #
10
12
  # Examples:
11
13
  # urn:mrn:iala:pub:s1070:ed2.0 → IALA S1070 Ed 2.0
12
14
  # urn:mrn:iala:pub:r1016:ed2.0:f → IALA R1016 Ed 2.0 (F)
13
15
  # urn:mrn:iala:pub:c0103-1 → IALA C0103-1
16
+ # urn:mrn:iala:pub:g1045:annex:ed1 → IALA G1045 Annex Ed 1
17
+ # urn:mrn:iala:pub:g1128:annex-a:ed1.6 → IALA G1128 ANNEX A Ed 1.6
14
18
  class UrnParser < Pubid::UrnParser::Base
15
19
  PREFIX = "urn:mrn:iala:pub:".freeze
16
20
 
@@ -21,15 +25,32 @@ module Pubid
21
25
 
22
26
  edition = nil
23
27
  language = nil
28
+ annex_form = nil
29
+ annex_letter = nil
30
+
24
31
  parts.drop(1).each do |seg|
25
- if seg.start_with?("ed")
26
- edition = seg.sub(/\Aed/, "")
27
- elsif seg.length == 1 && seg.match?(/\A[a-z]\z/i)
32
+ case seg
33
+ when /\Aannex(-([a-z]))?\z/i
34
+ # UrnGenerator emits "annex" (bare) for the Annex-without-letter
35
+ # form and "annex-X" (lettered) for the uppercase ANNEX form.
36
+ # The human parser accepts both "Annex" and "ANNEX"; mirror the
37
+ # generator's casing so URN round-trip is exact.
38
+ annex_letter = Regexp.last_match(2)&.upcase
39
+ annex_form = annex_letter ? "ANNEX" : "Annex"
40
+ # Edition marker: case-insensitive with an optional separator dot.
41
+ # Both variants occur in published documents (R1026 prints
42
+ # "Ed1.0" and "ed.1.0"); each parses to the canonical edition
43
+ # value and re-renders as lowercase "ed<x.x>".
44
+ when /\Aed\.?/i
45
+ edition = seg.sub(/\Aed\.?/i, "")
46
+ when /\A[a-z]\z/i
28
47
  language = seg.upcase
29
48
  end
30
49
  end
31
50
 
32
51
  text = "IALA #{code.upcase}"
52
+ text += " #{annex_form}" if annex_form
53
+ text += " #{annex_letter}" if annex_letter
33
54
  text += " Ed #{edition}" if edition
34
55
  text += " (#{language})" if language
35
56
  flavor_parse(text)
data/lib/pubid/iala.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Iala
5
6
  extend Pubid::PrefixesSupport
@@ -23,8 +24,8 @@ module Pubid
23
24
  end
24
25
 
25
26
  # Per-flavor format registry: inherits global formats, overrides :human
26
- Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
27
- Identifiers::Base.format_registry.register(:human, renderer: Iala::Renderer)
27
+ Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
28
+ Identifier.format_registry.register(:human, renderer: Iala::Renderer)
28
29
 
29
30
  # Auto-discover all identifier types from the Identifiers namespace.
30
31
  # @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
@@ -32,7 +33,7 @@ module Pubid
32
33
  @identifier_types ||= Identifiers.constants
33
34
  .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
34
35
  .select { |c| c.is_a?(Class) && c < Pubid::Identifier }
35
- .reject { |c| c == Identifiers::Base }
36
+ .reject { |c| c == Identifier }
36
37
  end
37
38
 
38
39
  # Build typed stage index from identifier types
@@ -60,7 +61,7 @@ module Pubid
60
61
 
61
62
  # Look up an identifier class by its IALA type letter (S, R, G, M, C, X, P).
62
63
  # @param letter [String]
63
- # @return [Class<Identifiers::Base>]
64
+ # @return [Class<Identifier>]
64
65
  def self.identifier_klass_for_type_letter(letter)
65
66
  @by_letter ||= identifier_types.to_h { |klass| [klass.type[:short], klass] }
66
67
  @by_letter.fetch(letter.to_s.upcase)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iana
5
+ # Builds an IANA identifier object from a parse tree. There is a single
6
+ # concrete type (Registry), so the builder just extracts the slug fields.
7
+ class Builder
8
+ def self.build(parsed_data)
9
+ new.build(parsed_data)
10
+ end
11
+
12
+ def build(data)
13
+ # The top-level slug is stored as `number` — it is the relaton-index
14
+ # key; `Identifier#registry` reads it back.
15
+ Identifiers::Registry.new(
16
+ number: data[:registry].to_s,
17
+ sub_registry: data[:sub_registry]&.to_s,
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end