pubid 1.15.19 → 2.0.0.pre.alpha.2

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 (604) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.adoc +2041 -53
  4. data/archived-gems/pubid-ccsds/update_codes.yaml +1 -0
  5. data/archived-gems/pubid-iec/stages.yaml +129 -0
  6. data/archived-gems/pubid-iec/update_codes.yaml +67 -0
  7. data/archived-gems/pubid-ieee/update_codes.yaml +104 -0
  8. data/archived-gems/pubid-iso/stages.yaml +106 -0
  9. data/archived-gems/pubid-iso/update_codes.yaml +4 -0
  10. data/archived-gems/pubid-itu/i18n.yaml +13 -0
  11. data/archived-gems/pubid-itu/series.yaml +42 -0
  12. data/archived-gems/pubid-nist/publishers.yaml +6 -0
  13. data/archived-gems/pubid-nist/series.yaml +121 -0
  14. data/archived-gems/pubid-nist/stages.yaml +16 -0
  15. data/archived-gems/pubid-nist/update_codes.yaml +93 -0
  16. data/archived-gems/pubid-plateau/update_codes.yaml +6 -0
  17. data/data/ccsds/update_codes.yaml +1 -0
  18. data/data/iec/update_codes.yaml +67 -0
  19. data/data/ieee/update_codes.yaml +104 -0
  20. data/data/iso/update_codes.yaml +21 -0
  21. data/data/nist/update_codes.yaml +89 -0
  22. data/data/plateau/update_codes.yaml +6 -0
  23. data/lib/pubid/amca/builder.rb +176 -0
  24. data/lib/pubid/amca/identifier.rb +57 -0
  25. data/lib/pubid/amca/identifiers/base.rb +64 -0
  26. data/lib/pubid/amca/identifiers/interpretation.rb +51 -0
  27. data/lib/pubid/amca/identifiers/publication.rb +47 -0
  28. data/lib/pubid/amca/identifiers/standard.rb +22 -0
  29. data/lib/pubid/amca/identifiers.rb +12 -0
  30. data/lib/pubid/amca/parser.rb +153 -0
  31. data/lib/pubid/amca/scheme.rb +16 -0
  32. data/lib/pubid/amca/single_identifier.rb +33 -0
  33. data/lib/pubid/amca/urn_generator.rb +50 -0
  34. data/lib/pubid/amca.rb +26 -0
  35. data/lib/pubid/ansi/builder.rb +52 -0
  36. data/lib/pubid/ansi/identifier.rb +55 -0
  37. data/lib/pubid/ansi/identifiers/american_national_standard.rb +12 -0
  38. data/lib/pubid/ansi/identifiers/standard.rb +16 -0
  39. data/lib/pubid/ansi/identifiers.rb +11 -0
  40. data/lib/pubid/ansi/parser.rb +91 -0
  41. data/lib/pubid/ansi/scheme.rb +15 -0
  42. data/lib/pubid/ansi/single_identifier.rb +45 -0
  43. data/lib/pubid/ansi/urn_generator.rb +76 -0
  44. data/lib/pubid/ansi.rb +27 -0
  45. data/lib/pubid/api/builder.rb +85 -0
  46. data/lib/pubid/api/components/code.rb +9 -0
  47. data/lib/pubid/api/identifier.rb +68 -0
  48. data/lib/pubid/api/identifiers/base.rb +24 -0
  49. data/lib/pubid/api/identifiers/bulletin.rb +15 -0
  50. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +15 -0
  51. data/lib/pubid/api/identifiers/mpms.rb +44 -0
  52. data/lib/pubid/api/identifiers/publication.rb +15 -0
  53. data/lib/pubid/api/identifiers/recommended_practice.rb +15 -0
  54. data/lib/pubid/api/identifiers/specification.rb +15 -0
  55. data/lib/pubid/api/identifiers/standard.rb +15 -0
  56. data/lib/pubid/api/identifiers/technical_report.rb +15 -0
  57. data/lib/pubid/api/identifiers/typeless_standard.rb +27 -0
  58. data/lib/pubid/api/parser.rb +140 -0
  59. data/lib/pubid/api/scheme.rb +66 -0
  60. data/lib/pubid/api/single_identifier.rb +46 -0
  61. data/lib/pubid/api/urn_generator.rb +41 -0
  62. data/lib/pubid/api.rb +17 -0
  63. data/lib/pubid/ashrae/builder.rb +498 -0
  64. data/lib/pubid/ashrae/identifier.rb +57 -0
  65. data/lib/pubid/ashrae/identifiers/addenda_package.rb +46 -0
  66. data/lib/pubid/ashrae/identifiers/addendum.rb +55 -0
  67. data/lib/pubid/ashrae/identifiers/base.rb +23 -0
  68. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +51 -0
  69. data/lib/pubid/ashrae/identifiers/errata.rb +40 -0
  70. data/lib/pubid/ashrae/identifiers/guideline.rb +38 -0
  71. data/lib/pubid/ashrae/identifiers/interpretation.rb +39 -0
  72. data/lib/pubid/ashrae/identifiers/standard.rb +38 -0
  73. data/lib/pubid/ashrae/identifiers.rb +16 -0
  74. data/lib/pubid/ashrae/parser.rb +724 -0
  75. data/lib/pubid/ashrae/scheme.rb +53 -0
  76. data/lib/pubid/ashrae/single_identifier.rb +23 -0
  77. data/lib/pubid/ashrae/supplement_identifier.rb +23 -0
  78. data/lib/pubid/ashrae/urn_generator.rb +59 -0
  79. data/lib/pubid/ashrae.rb +21 -0
  80. data/lib/pubid/asme/builder.rb +153 -0
  81. data/lib/pubid/asme/components/code.rb +18 -0
  82. data/lib/pubid/asme/identifier.rb +61 -0
  83. data/lib/pubid/asme/identifiers/base.rb +70 -0
  84. data/lib/pubid/asme/identifiers/standard.rb +12 -0
  85. data/lib/pubid/asme/identifiers.rb +10 -0
  86. data/lib/pubid/asme/parser.rb +308 -0
  87. data/lib/pubid/asme/scheme.rb +37 -0
  88. data/lib/pubid/asme/single_identifier.rb +29 -0
  89. data/lib/pubid/asme/urn_generator.rb +133 -0
  90. data/lib/pubid/asme.rb +21 -0
  91. data/lib/pubid/astm/builder.rb +159 -0
  92. data/lib/pubid/astm/components/code.rb +33 -0
  93. data/lib/pubid/astm/identifier.rb +92 -0
  94. data/lib/pubid/astm/identifiers/adjunct.rb +21 -0
  95. data/lib/pubid/astm/identifiers/base.rb +13 -0
  96. data/lib/pubid/astm/identifiers/data_series.rb +25 -0
  97. data/lib/pubid/astm/identifiers/iso_dual_published.rb +74 -0
  98. data/lib/pubid/astm/identifiers/manual.rb +40 -0
  99. data/lib/pubid/astm/identifiers/monograph.rb +25 -0
  100. data/lib/pubid/astm/identifiers/research_report.rb +18 -0
  101. data/lib/pubid/astm/identifiers/standard.rb +52 -0
  102. data/lib/pubid/astm/identifiers/technical_report.rb +23 -0
  103. data/lib/pubid/astm/identifiers/work_in_progress.rb +21 -0
  104. data/lib/pubid/astm/parser.rb +244 -0
  105. data/lib/pubid/astm/scheme.rb +55 -0
  106. data/lib/pubid/astm/single_identifier.rb +25 -0
  107. data/lib/pubid/astm/urn_generator.rb +99 -0
  108. data/lib/pubid/astm.rb +38 -0
  109. data/lib/pubid/bsi/builder.rb +1483 -0
  110. data/lib/pubid/bsi/components/code.rb +11 -0
  111. data/lib/pubid/bsi/components/date.rb +11 -0
  112. data/lib/pubid/bsi/components/publisher.rb +11 -0
  113. data/lib/pubid/bsi/components/type.rb +11 -0
  114. data/lib/pubid/bsi/identifier.rb +87 -0
  115. data/lib/pubid/bsi/identifiers/addendum_document.rb +64 -0
  116. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +95 -0
  117. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +82 -0
  118. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +118 -0
  119. data/lib/pubid/bsi/identifiers/amendment.rb +40 -0
  120. data/lib/pubid/bsi/identifiers/base.rb +11 -0
  121. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +27 -0
  122. data/lib/pubid/bsi/identifiers/british_standard.rb +33 -0
  123. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +114 -0
  124. data/lib/pubid/bsi/identifiers/committee_document.rb +51 -0
  125. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +152 -0
  126. data/lib/pubid/bsi/identifiers/corrigendum.rb +28 -0
  127. data/lib/pubid/bsi/identifiers/detailed_specification.rb +69 -0
  128. data/lib/pubid/bsi/identifiers/disc.rb +56 -0
  129. data/lib/pubid/bsi/identifiers/draft_document.rb +71 -0
  130. data/lib/pubid/bsi/identifiers/electronic_book.rb +52 -0
  131. data/lib/pubid/bsi/identifiers/expert_commentary.rb +47 -0
  132. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +82 -0
  133. data/lib/pubid/bsi/identifiers/flex.rb +61 -0
  134. data/lib/pubid/bsi/identifiers/handbook.rb +39 -0
  135. data/lib/pubid/bsi/identifiers/index.rb +62 -0
  136. data/lib/pubid/bsi/identifiers/method.rb +76 -0
  137. data/lib/pubid/bsi/identifiers/national_annex.rb +73 -0
  138. data/lib/pubid/bsi/identifiers/practice_guide.rb +27 -0
  139. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +79 -0
  140. data/lib/pubid/bsi/identifiers/published_document.rb +79 -0
  141. data/lib/pubid/bsi/identifiers/section.rb +62 -0
  142. data/lib/pubid/bsi/identifiers/set.rb +46 -0
  143. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +40 -0
  144. data/lib/pubid/bsi/identifiers/supplement_document.rb +51 -0
  145. data/lib/pubid/bsi/identifiers/supplementary_index.rb +81 -0
  146. data/lib/pubid/bsi/identifiers/technical_specification.rb +79 -0
  147. data/lib/pubid/bsi/identifiers/test_method.rb +67 -0
  148. data/lib/pubid/bsi/identifiers/value_added_publication.rb +52 -0
  149. data/lib/pubid/bsi/identifiers.rb +52 -0
  150. data/lib/pubid/bsi/model.rb +196 -0
  151. data/lib/pubid/bsi/parser.rb +659 -0
  152. data/lib/pubid/bsi/scheme.rb +243 -0
  153. data/lib/pubid/bsi/single_identifier.rb +129 -0
  154. data/lib/pubid/bsi/urn_generator.rb +84 -0
  155. data/lib/pubid/bsi.rb +32 -0
  156. data/lib/pubid/builder/base.rb +138 -0
  157. data/lib/pubid/bundled_identifier.rb +126 -0
  158. data/lib/pubid/ccsds/builder.rb +56 -0
  159. data/lib/pubid/ccsds/identifier.rb +84 -0
  160. data/lib/pubid/ccsds/identifiers/base.rb +89 -0
  161. data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +70 -0
  162. data/lib/pubid/ccsds/identifiers/corrigendum.rb +39 -0
  163. data/lib/pubid/ccsds/identifiers.rb +10 -0
  164. data/lib/pubid/ccsds/parser.rb +71 -0
  165. data/lib/pubid/ccsds/scheme.rb +57 -0
  166. data/lib/pubid/ccsds/single_identifier.rb +77 -0
  167. data/lib/pubid/ccsds/supplement_identifier.rb +33 -0
  168. data/lib/pubid/ccsds/urn_generator.rb +115 -0
  169. data/lib/pubid/ccsds.rb +21 -0
  170. data/lib/pubid/cen_cenelec/builder.rb +330 -0
  171. data/lib/pubid/cen_cenelec/identifier.rb +52 -0
  172. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +40 -0
  173. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +29 -0
  174. data/lib/pubid/cen_cenelec/identifiers/base.rb +75 -0
  175. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +28 -0
  176. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +27 -0
  177. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +28 -0
  178. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +61 -0
  179. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +35 -0
  180. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +41 -0
  181. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +37 -0
  182. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +28 -0
  183. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +22 -0
  184. data/lib/pubid/cen_cenelec/identifiers/guide.rb +27 -0
  185. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +27 -0
  186. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +27 -0
  187. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +35 -0
  188. data/lib/pubid/cen_cenelec/identifiers.rb +32 -0
  189. data/lib/pubid/cen_cenelec/parser.rb +144 -0
  190. data/lib/pubid/cen_cenelec/scheme.rb +164 -0
  191. data/lib/pubid/cen_cenelec/single_identifier.rb +130 -0
  192. data/lib/pubid/cen_cenelec/supplement_identifier.rb +48 -0
  193. data/lib/pubid/cen_cenelec/urn_generator.rb +129 -0
  194. data/lib/pubid/cen_cenelec.rb +21 -0
  195. data/lib/pubid/cie/builder.rb +399 -0
  196. data/lib/pubid/cie/components/code.rb +72 -0
  197. data/lib/pubid/cie/components/language.rb +58 -0
  198. data/lib/pubid/cie/identifier.rb +71 -0
  199. data/lib/pubid/cie/identifiers/bundle.rb +20 -0
  200. data/lib/pubid/cie/identifiers/conference.rb +32 -0
  201. data/lib/pubid/cie/identifiers/corrigendum.rb +40 -0
  202. data/lib/pubid/cie/identifiers/dual_published.rb +41 -0
  203. data/lib/pubid/cie/identifiers/identical.rb +64 -0
  204. data/lib/pubid/cie/identifiers/joint_published.rb +52 -0
  205. data/lib/pubid/cie/identifiers/standard.rb +58 -0
  206. data/lib/pubid/cie/identifiers/supplement.rb +45 -0
  207. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +20 -0
  208. data/lib/pubid/cie/identifiers.rb +17 -0
  209. data/lib/pubid/cie/parser.rb +347 -0
  210. data/lib/pubid/cie/scheme.rb +64 -0
  211. data/lib/pubid/cie/single_identifier.rb +30 -0
  212. data/lib/pubid/cie/supplement_identifier.rb +26 -0
  213. data/lib/pubid/cie/urn_generator.rb +123 -0
  214. data/lib/pubid/cie.rb +28 -0
  215. data/lib/pubid/components/code.rb +33 -0
  216. data/lib/pubid/components/date.rb +49 -0
  217. data/lib/pubid/components/edition.rb +32 -0
  218. data/lib/pubid/components/factory.rb +50 -0
  219. data/lib/pubid/components/language.rb +37 -0
  220. data/lib/pubid/components/locality.rb +10 -0
  221. data/lib/pubid/components/publisher.rb +36 -0
  222. data/lib/pubid/components/stage.rb +54 -0
  223. data/lib/pubid/components/type.rb +58 -0
  224. data/lib/pubid/components/typed_stage.rb +59 -0
  225. data/lib/pubid/components.rb +16 -0
  226. data/lib/pubid/core/pattern_doc_generator.rb +272 -0
  227. data/lib/pubid/core/update_codes.rb +77 -0
  228. data/lib/pubid/core.rb +8 -0
  229. data/lib/pubid/csa/builder.rb +671 -0
  230. data/lib/pubid/csa/components/code.rb +9 -0
  231. data/lib/pubid/csa/components.rb +9 -0
  232. data/lib/pubid/csa/composite_identifier.rb +27 -0
  233. data/lib/pubid/csa/identifier.rb +513 -0
  234. data/lib/pubid/csa/identifiers/base.rb +133 -0
  235. data/lib/pubid/csa/identifiers/bundled.rb +125 -0
  236. data/lib/pubid/csa/identifiers/canadian_adopted.rb +82 -0
  237. data/lib/pubid/csa/identifiers/cec.rb +129 -0
  238. data/lib/pubid/csa/identifiers/combined.rb +130 -0
  239. data/lib/pubid/csa/identifiers/csa_adopted.rb +78 -0
  240. data/lib/pubid/csa/identifiers/package.rb +65 -0
  241. data/lib/pubid/csa/identifiers/series.rb +127 -0
  242. data/lib/pubid/csa/identifiers/standard.rb +10 -0
  243. data/lib/pubid/csa/identifiers.rb +17 -0
  244. data/lib/pubid/csa/parser.rb +445 -0
  245. data/lib/pubid/csa/scheme.rb +44 -0
  246. data/lib/pubid/csa/single_identifier.rb +30 -0
  247. data/lib/pubid/csa/urn_generator.rb +80 -0
  248. data/lib/pubid/csa/wrapper_identifier.rb +31 -0
  249. data/lib/pubid/csa.rb +25 -0
  250. data/lib/pubid/etsi/builder.rb +133 -0
  251. data/lib/pubid/etsi/components/code.rb +42 -0
  252. data/lib/pubid/etsi/components/version.rb +37 -0
  253. data/lib/pubid/etsi/components.rb +10 -0
  254. data/lib/pubid/etsi/identifier.rb +57 -0
  255. data/lib/pubid/etsi/identifiers/amendment.rb +15 -0
  256. data/lib/pubid/etsi/identifiers/base.rb +38 -0
  257. data/lib/pubid/etsi/identifiers/corrigendum.rb +15 -0
  258. data/lib/pubid/etsi/identifiers/etsi_standard.rb +19 -0
  259. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +91 -0
  260. data/lib/pubid/etsi/identifiers.rb +14 -0
  261. data/lib/pubid/etsi/parser.rb +133 -0
  262. data/lib/pubid/etsi/scheme.rb +42 -0
  263. data/lib/pubid/etsi/urn_generator.rb +76 -0
  264. data/lib/pubid/etsi.rb +21 -0
  265. data/lib/pubid/export/auditor.rb +89 -0
  266. data/lib/pubid/export/data_class_exporter.rb +59 -0
  267. data/lib/pubid/export/exporter.rb +74 -0
  268. data/lib/pubid/export/flavor_exporter.rb +402 -0
  269. data/lib/pubid/export/ieee_exporter.rb +78 -0
  270. data/lib/pubid/export/itu_exporter.rb +66 -0
  271. data/lib/pubid/export/nist_exporter.rb +64 -0
  272. data/lib/pubid/export/registry_exporter.rb +90 -0
  273. data/lib/pubid/export/result.rb +97 -0
  274. data/lib/pubid/export/scheme_exporter.rb +70 -0
  275. data/lib/pubid/export.rb +18 -0
  276. data/lib/pubid/format_detector.rb +16 -0
  277. data/lib/pubid/format_registry.rb +42 -0
  278. data/lib/pubid/identifier.rb +242 -0
  279. data/lib/pubid/identifier_metadata.rb +148 -0
  280. data/lib/pubid/identifier_registry.rb +198 -0
  281. data/lib/pubid/idf/builder.rb +82 -0
  282. data/lib/pubid/idf/identifier.rb +129 -0
  283. data/lib/pubid/idf/identifiers/amendment.rb +27 -0
  284. data/lib/pubid/idf/identifiers/corrigendum.rb +27 -0
  285. data/lib/pubid/idf/identifiers/international_standard.rb +123 -0
  286. data/lib/pubid/idf/identifiers/reviewed_method.rb +100 -0
  287. data/lib/pubid/idf/identifiers.rb +13 -0
  288. data/lib/pubid/idf/parser.rb +143 -0
  289. data/lib/pubid/idf/scheme.rb +61 -0
  290. data/lib/pubid/idf/single_identifier.rb +19 -0
  291. data/lib/pubid/idf/supplement_identifier.rb +43 -0
  292. data/lib/pubid/idf/urn_generator.rb +84 -0
  293. data/lib/pubid/idf.rb +25 -0
  294. data/lib/pubid/iec/builder.rb +458 -0
  295. data/lib/pubid/iec/components/code.rb +60 -0
  296. data/lib/pubid/iec/components/consolidated_amendment.rb +59 -0
  297. data/lib/pubid/iec/components/publisher.rb +36 -0
  298. data/lib/pubid/iec/components/sheet.rb +32 -0
  299. data/lib/pubid/iec/components/trf_info.rb +38 -0
  300. data/lib/pubid/iec/components/vap_suffix.rb +41 -0
  301. data/lib/pubid/iec/identifier.rb +256 -0
  302. data/lib/pubid/iec/identifiers/amendment.rb +94 -0
  303. data/lib/pubid/iec/identifiers/base.rb +82 -0
  304. data/lib/pubid/iec/identifiers/component_specification.rb +39 -0
  305. data/lib/pubid/iec/identifiers/conformity_assessment.rb +39 -0
  306. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +82 -0
  307. data/lib/pubid/iec/identifiers/corrigendum.rb +94 -0
  308. data/lib/pubid/iec/identifiers/fragment_identifier.rb +137 -0
  309. data/lib/pubid/iec/identifiers/guide.rb +104 -0
  310. data/lib/pubid/iec/identifiers/international_standard.rb +147 -0
  311. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +104 -0
  312. data/lib/pubid/iec/identifiers/operational_document.rb +39 -0
  313. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +101 -0
  314. data/lib/pubid/iec/identifiers/sheet_identifier.rb +62 -0
  315. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +40 -0
  316. data/lib/pubid/iec/identifiers/systems_reference_document.rb +40 -0
  317. data/lib/pubid/iec/identifiers/technical_report.rb +132 -0
  318. data/lib/pubid/iec/identifiers/technical_specification.rb +132 -0
  319. data/lib/pubid/iec/identifiers/technology_report.rb +39 -0
  320. data/lib/pubid/iec/identifiers/test_report_form.rb +78 -0
  321. data/lib/pubid/iec/identifiers/vap_identifier.rb +73 -0
  322. data/lib/pubid/iec/identifiers/white_paper.rb +39 -0
  323. data/lib/pubid/iec/identifiers/working_document.rb +96 -0
  324. data/lib/pubid/iec/parser.rb +417 -0
  325. data/lib/pubid/iec/rendering_style.rb +113 -0
  326. data/lib/pubid/iec/scheme.rb +71 -0
  327. data/lib/pubid/iec/single_identifier.rb +80 -0
  328. data/lib/pubid/iec/supplement_identifier.rb +161 -0
  329. data/lib/pubid/iec/urn_generator.rb +79 -0
  330. data/lib/pubid/iec/urn_parser.rb +90 -0
  331. data/lib/pubid/iec.rb +85 -0
  332. data/lib/pubid/ieee/aiee/builder.rb +71 -0
  333. data/lib/pubid/ieee/aiee/identifier.rb +105 -0
  334. data/lib/pubid/ieee/aiee/parser.rb +130 -0
  335. data/lib/pubid/ieee/aiee.rb +11 -0
  336. data/lib/pubid/ieee/builder.rb +1237 -0
  337. data/lib/pubid/ieee/components/code.rb +102 -0
  338. data/lib/pubid/ieee/components/draft.rb +93 -0
  339. data/lib/pubid/ieee/components/relationship.rb +157 -0
  340. data/lib/pubid/ieee/components/typed_stage.rb +100 -0
  341. data/lib/pubid/ieee/identifier.rb +54 -0
  342. data/lib/pubid/ieee/identifiers/adopted_standard.rb +33 -0
  343. data/lib/pubid/ieee/identifiers/base.rb +591 -0
  344. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +35 -0
  345. data/lib/pubid/ieee/identifiers/corrigendum.rb +37 -0
  346. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +51 -0
  347. data/lib/pubid/ieee/identifiers/dual_identifier.rb +18 -0
  348. data/lib/pubid/ieee/identifiers/dual_published.rb +28 -0
  349. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +27 -0
  350. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +34 -0
  351. data/lib/pubid/ieee/identifiers/joint_development.rb +172 -0
  352. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +51 -0
  353. data/lib/pubid/ieee/identifiers/nesc/base.rb +56 -0
  354. data/lib/pubid/ieee/identifiers/nesc/draft.rb +28 -0
  355. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +32 -0
  356. data/lib/pubid/ieee/identifiers/nesc/redline.rb +26 -0
  357. data/lib/pubid/ieee/identifiers/nesc/standard.rb +26 -0
  358. data/lib/pubid/ieee/identifiers/nesc.rb +15 -0
  359. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +20 -0
  360. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +26 -0
  361. data/lib/pubid/ieee/identifiers/redlined_standard.rb +33 -0
  362. data/lib/pubid/ieee/identifiers/si_standard.rb +73 -0
  363. data/lib/pubid/ieee/identifiers/standard.rb +41 -0
  364. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +23 -0
  365. data/lib/pubid/ieee/identifiers.rb +33 -0
  366. data/lib/pubid/ieee/ire/builder.rb +61 -0
  367. data/lib/pubid/ieee/ire/identifier.rb +58 -0
  368. data/lib/pubid/ieee/ire/parser.rb +91 -0
  369. data/lib/pubid/ieee/ire.rb +11 -0
  370. data/lib/pubid/ieee/nesc/builder.rb +101 -0
  371. data/lib/pubid/ieee/nesc/parser.rb +154 -0
  372. data/lib/pubid/ieee/nesc.rb +10 -0
  373. data/lib/pubid/ieee/parser.rb +1226 -0
  374. data/lib/pubid/ieee/scheme.rb +90 -0
  375. data/lib/pubid/ieee/typed_stages.rb +172 -0
  376. data/lib/pubid/ieee/urn_generator.rb +188 -0
  377. data/lib/pubid/ieee.rb +32 -0
  378. data/lib/pubid/ieee_debug.rb +31 -0
  379. data/lib/pubid/iho/builder.rb +37 -0
  380. data/lib/pubid/iho/identifier.rb +61 -0
  381. data/lib/pubid/iho/identifiers/base.rb +41 -0
  382. data/lib/pubid/iho/identifiers/bibliographic.rb +16 -0
  383. data/lib/pubid/iho/identifiers/circular_letter.rb +15 -0
  384. data/lib/pubid/iho/identifiers/miscellaneous.rb +16 -0
  385. data/lib/pubid/iho/identifiers/publication.rb +15 -0
  386. data/lib/pubid/iho/identifiers/standard.rb +15 -0
  387. data/lib/pubid/iho/identifiers.rb +14 -0
  388. data/lib/pubid/iho/parser.rb +68 -0
  389. data/lib/pubid/iho/scheme.rb +29 -0
  390. data/lib/pubid/iho/urn_generator.rb +29 -0
  391. data/lib/pubid/iho.rb +21 -0
  392. data/lib/pubid/iso/builder.rb +309 -0
  393. data/lib/pubid/iso/bundled_identifier.rb +85 -0
  394. data/lib/pubid/iso/combined_identifier.rb +22 -0
  395. data/lib/pubid/iso/components/code.rb +36 -0
  396. data/lib/pubid/iso/components/publisher.rb +60 -0
  397. data/lib/pubid/iso/components.rb +12 -0
  398. data/lib/pubid/iso/format_resolver.rb +45 -0
  399. data/lib/pubid/iso/identifier.rb +330 -0
  400. data/lib/pubid/iso/identifiers/addendum.rb +104 -0
  401. data/lib/pubid/iso/identifiers/amendment.rb +128 -0
  402. data/lib/pubid/iso/identifiers/base.rb +115 -0
  403. data/lib/pubid/iso/identifiers/corrigendum.rb +108 -0
  404. data/lib/pubid/iso/identifiers/data.rb +76 -0
  405. data/lib/pubid/iso/identifiers/directives.rb +59 -0
  406. data/lib/pubid/iso/identifiers/directives_supplement.rb +119 -0
  407. data/lib/pubid/iso/identifiers/extract.rb +30 -0
  408. data/lib/pubid/iso/identifiers/guide.rb +100 -0
  409. data/lib/pubid/iso/identifiers/international_standard.rb +168 -0
  410. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +94 -0
  411. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +89 -0
  412. data/lib/pubid/iso/identifiers/pas.rb +93 -0
  413. data/lib/pubid/iso/identifiers/recommendation.rb +45 -0
  414. data/lib/pubid/iso/identifiers/supplement.rb +87 -0
  415. data/lib/pubid/iso/identifiers/tc_document.rb +108 -0
  416. data/lib/pubid/iso/identifiers/technical_report.rb +103 -0
  417. data/lib/pubid/iso/identifiers/technical_specification.rb +102 -0
  418. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +95 -0
  419. data/lib/pubid/iso/identifiers.rb +33 -0
  420. data/lib/pubid/iso/parser.rb +512 -0
  421. data/lib/pubid/iso/rendering_style.rb +120 -0
  422. data/lib/pubid/iso/scheme.rb +193 -0
  423. data/lib/pubid/iso/single_identifier.rb +64 -0
  424. data/lib/pubid/iso/supplement_identifier.rb +27 -0
  425. data/lib/pubid/iso/urn_generator.rb +426 -0
  426. data/lib/pubid/iso/urn_parser.rb +437 -0
  427. data/lib/pubid/iso/utilities.rb +86 -0
  428. data/lib/pubid/iso.rb +50 -0
  429. data/lib/pubid/itu/builder.rb +171 -0
  430. data/lib/pubid/itu/components/code.rb +39 -0
  431. data/lib/pubid/itu/components/sector.rb +35 -0
  432. data/lib/pubid/itu/components/series.rb +29 -0
  433. data/lib/pubid/itu/i18n.rb +9 -0
  434. data/lib/pubid/itu/i18n.yaml +30 -0
  435. data/lib/pubid/itu/identifier.rb +118 -0
  436. data/lib/pubid/itu/identifiers/amendment.rb +43 -0
  437. data/lib/pubid/itu/identifiers/annex.rb +74 -0
  438. data/lib/pubid/itu/identifiers/base.rb +154 -0
  439. data/lib/pubid/itu/identifiers/combined_identifier.rb +47 -0
  440. data/lib/pubid/itu/identifiers/corrigendum.rb +44 -0
  441. data/lib/pubid/itu/identifiers/recommendation.rb +16 -0
  442. data/lib/pubid/itu/identifiers/special_publication.rb +31 -0
  443. data/lib/pubid/itu/identifiers/supplement.rb +46 -0
  444. data/lib/pubid/itu/identifiers.rb +16 -0
  445. data/lib/pubid/itu/model.rb +111 -0
  446. data/lib/pubid/itu/parser.rb +225 -0
  447. data/lib/pubid/itu/scheme.rb +174 -0
  448. data/lib/pubid/itu/urn_generator.rb +105 -0
  449. data/lib/pubid/itu.rb +22 -0
  450. data/lib/pubid/jcgm/builder.rb +88 -0
  451. data/lib/pubid/jcgm/components/publisher.rb +20 -0
  452. data/lib/pubid/jcgm/components.rb +9 -0
  453. data/lib/pubid/jcgm/identifier.rb +54 -0
  454. data/lib/pubid/jcgm/identifiers/amendment.rb +35 -0
  455. data/lib/pubid/jcgm/identifiers/guide.rb +21 -0
  456. data/lib/pubid/jcgm/identifiers/gum_guide.rb +51 -0
  457. data/lib/pubid/jcgm/identifiers.rb +11 -0
  458. data/lib/pubid/jcgm/parser.rb +84 -0
  459. data/lib/pubid/jcgm/scheme.rb +60 -0
  460. data/lib/pubid/jcgm/single_identifier.rb +48 -0
  461. data/lib/pubid/jcgm/supplement_identifier.rb +16 -0
  462. data/lib/pubid/jcgm/urn_generator.rb +110 -0
  463. data/lib/pubid/jcgm.rb +31 -0
  464. data/lib/pubid/jis/builder.rb +124 -0
  465. data/lib/pubid/jis/components/code.rb +59 -0
  466. data/lib/pubid/jis/components.rb +9 -0
  467. data/lib/pubid/jis/identifier.rb +61 -0
  468. data/lib/pubid/jis/identifiers/amendment.rb +16 -0
  469. data/lib/pubid/jis/identifiers/base.rb +72 -0
  470. data/lib/pubid/jis/identifiers/explanation.rb +22 -0
  471. data/lib/pubid/jis/identifiers/japanese_industrial_standard.rb +16 -0
  472. data/lib/pubid/jis/identifiers/standard.rb +27 -0
  473. data/lib/pubid/jis/identifiers/technical_report.rb +31 -0
  474. data/lib/pubid/jis/identifiers/technical_specification.rb +31 -0
  475. data/lib/pubid/jis/identifiers.rb +17 -0
  476. data/lib/pubid/jis/parser.rb +109 -0
  477. data/lib/pubid/jis/scheme.rb +49 -0
  478. data/lib/pubid/jis/single_identifier.rb +37 -0
  479. data/lib/pubid/jis/supplement_identifier.rb +47 -0
  480. data/lib/pubid/jis/urn_generator.rb +25 -0
  481. data/lib/pubid/jis.rb +23 -0
  482. data/lib/pubid/lutaml/no_store_registration.rb +30 -0
  483. data/lib/pubid/nist/builder.rb +2269 -0
  484. data/lib/pubid/nist/components/code.rb +38 -0
  485. data/lib/pubid/nist/components/edition.rb +134 -0
  486. data/lib/pubid/nist/components/issue_number.rb +28 -0
  487. data/lib/pubid/nist/components/part.rb +77 -0
  488. data/lib/pubid/nist/components/publisher.rb +24 -0
  489. data/lib/pubid/nist/components/stage.rb +53 -0
  490. data/lib/pubid/nist/components/supplement.rb +188 -0
  491. data/lib/pubid/nist/components/translation.rb +42 -0
  492. data/lib/pubid/nist/components/update.rb +103 -0
  493. data/lib/pubid/nist/components/version.rb +35 -0
  494. data/lib/pubid/nist/components/volume.rb +32 -0
  495. data/lib/pubid/nist/components.rb +19 -0
  496. data/lib/pubid/nist/configuration.rb +77 -0
  497. data/lib/pubid/nist/identifier.rb +62 -0
  498. data/lib/pubid/nist/identifiers/base.rb +578 -0
  499. data/lib/pubid/nist/identifiers/circular.rb +68 -0
  500. data/lib/pubid/nist/identifiers/circular_supplement.rb +50 -0
  501. data/lib/pubid/nist/identifiers/commercial_standard.rb +41 -0
  502. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +56 -0
  503. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +56 -0
  504. data/lib/pubid/nist/identifiers/crpl_report.rb +132 -0
  505. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +104 -0
  506. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +35 -0
  507. data/lib/pubid/nist/identifiers/handbook.rb +50 -0
  508. data/lib/pubid/nist/identifiers/internal_report.rb +56 -0
  509. data/lib/pubid/nist/identifiers/letter_circular.rb +45 -0
  510. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +65 -0
  511. data/lib/pubid/nist/identifiers/monograph.rb +69 -0
  512. data/lib/pubid/nist/identifiers/ncstar.rb +41 -0
  513. data/lib/pubid/nist/identifiers/nsrds.rb +41 -0
  514. data/lib/pubid/nist/identifiers/owmwp.rb +35 -0
  515. data/lib/pubid/nist/identifiers/report.rb +67 -0
  516. data/lib/pubid/nist/identifiers/special_publication.rb +36 -0
  517. data/lib/pubid/nist/identifiers/technical_note.rb +90 -0
  518. data/lib/pubid/nist/identifiers.rb +33 -0
  519. data/lib/pubid/nist/parser.rb +1117 -0
  520. data/lib/pubid/nist/scheme.rb +199 -0
  521. data/lib/pubid/nist/supplement_identifier.rb +67 -0
  522. data/lib/pubid/nist/urn_generator.rb +133 -0
  523. data/lib/pubid/nist.rb +37 -0
  524. data/lib/pubid/oiml/builder.rb +189 -0
  525. data/lib/pubid/oiml/components/code.rb +20 -0
  526. data/lib/pubid/oiml/components.rb +9 -0
  527. data/lib/pubid/oiml/identifier.rb +61 -0
  528. data/lib/pubid/oiml/identifiers/amendment.rb +13 -0
  529. data/lib/pubid/oiml/identifiers/annex.rb +62 -0
  530. data/lib/pubid/oiml/identifiers/base.rb +36 -0
  531. data/lib/pubid/oiml/identifiers/basic_publication.rb +13 -0
  532. data/lib/pubid/oiml/identifiers/document.rb +13 -0
  533. data/lib/pubid/oiml/identifiers/expert_report.rb +13 -0
  534. data/lib/pubid/oiml/identifiers/guide.rb +13 -0
  535. data/lib/pubid/oiml/identifiers/recommendation.rb +13 -0
  536. data/lib/pubid/oiml/identifiers/seminar_report.rb +13 -0
  537. data/lib/pubid/oiml/identifiers/vocabulary.rb +13 -0
  538. data/lib/pubid/oiml/identifiers.rb +18 -0
  539. data/lib/pubid/oiml/parser.rb +173 -0
  540. data/lib/pubid/oiml/scheme.rb +46 -0
  541. data/lib/pubid/oiml/single_identifier.rb +90 -0
  542. data/lib/pubid/oiml/supplement_identifier.rb +43 -0
  543. data/lib/pubid/oiml/urn_generator.rb +64 -0
  544. data/lib/pubid/oiml.rb +26 -0
  545. data/lib/pubid/parser/common_parse_methods.rb +13 -0
  546. data/lib/pubid/parser/common_parse_rules.rb +56 -0
  547. data/lib/pubid/parser.rb +8 -0
  548. data/lib/pubid/parsers/base.rb +11 -0
  549. data/lib/pubid/parsers/mr_string.rb +93 -0
  550. data/lib/pubid/plateau/builder.rb +50 -0
  551. data/lib/pubid/plateau/identifier.rb +57 -0
  552. data/lib/pubid/plateau/identifiers/annex.rb +16 -0
  553. data/lib/pubid/plateau/identifiers/base.rb +51 -0
  554. data/lib/pubid/plateau/identifiers/handbook.rb +34 -0
  555. data/lib/pubid/plateau/identifiers/technical_report.rb +20 -0
  556. data/lib/pubid/plateau/identifiers.rb +12 -0
  557. data/lib/pubid/plateau/parser.rb +63 -0
  558. data/lib/pubid/plateau/scheme.rb +45 -0
  559. data/lib/pubid/plateau/supplement_identifier.rb +72 -0
  560. data/lib/pubid/plateau/urn_generator.rb +29 -0
  561. data/lib/pubid/plateau.rb +26 -0
  562. data/lib/pubid/renderers/base.rb +53 -0
  563. data/lib/pubid/renderers/directives_renderer.rb +61 -0
  564. data/lib/pubid/renderers/guide_renderer.rb +24 -0
  565. data/lib/pubid/renderers/human_readable.rb +70 -0
  566. data/lib/pubid/renderers/iwa_renderer.rb +20 -0
  567. data/lib/pubid/renderers/mr_string.rb +16 -0
  568. data/lib/pubid/renderers/supplement_renderer.rb +36 -0
  569. data/lib/pubid/renderers/urn.rb +11 -0
  570. data/lib/pubid/renderers.rb +14 -0
  571. data/lib/pubid/rendering/base.rb +73 -0
  572. data/lib/pubid/rendering/common.rb +211 -0
  573. data/lib/pubid/rendering/context.rb +159 -0
  574. data/lib/pubid/rendering/date.rb +27 -0
  575. data/lib/pubid/rendering/format.rb +25 -0
  576. data/lib/pubid/rendering/language.rb +21 -0
  577. data/lib/pubid/rendering/numbering.rb +24 -0
  578. data/lib/pubid/rendering/publisher.rb +25 -0
  579. data/lib/pubid/rendering/stage.rb +38 -0
  580. data/lib/pubid/rendering/supplement.rb +46 -0
  581. data/lib/pubid/rendering.rb +16 -0
  582. data/lib/pubid/sae/builder.rb +32 -0
  583. data/lib/pubid/sae/components/code.rb +9 -0
  584. data/lib/pubid/sae/components/date.rb +19 -0
  585. data/lib/pubid/sae/components/type.rb +19 -0
  586. data/lib/pubid/sae/components.rb +11 -0
  587. data/lib/pubid/sae/identifier.rb +37 -0
  588. data/lib/pubid/sae/identifiers/base.rb +42 -0
  589. data/lib/pubid/sae/identifiers.rb +9 -0
  590. data/lib/pubid/sae/parser.rb +55 -0
  591. data/lib/pubid/sae/scheme.rb +47 -0
  592. data/lib/pubid/sae/urn_generator.rb +38 -0
  593. data/lib/pubid/sae.rb +19 -0
  594. data/lib/pubid/scheme.rb +219 -0
  595. data/lib/pubid/urn_generator/base.rb +110 -0
  596. data/lib/pubid/utils/string_normalizer.rb +196 -0
  597. data/lib/pubid/utils.rb +7 -0
  598. data/lib/pubid/version.rb +3 -1
  599. data/lib/pubid.rb +137 -13
  600. data/lib/tasks/docs.rake +37 -0
  601. data/lib/tasks/export.rake +38 -0
  602. data/lib/tasks/website-data.json +7488 -0
  603. metadata +616 -171
  604. data/lib/pubid/registry.rb +0 -30
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ # Scheme class for NIST identifier registry
6
+ # Single Responsibility: Identifier class registry and series-to-class mapping
7
+ class Scheme < Pubid::Scheme
8
+ class << self
9
+ # Aggregate TYPED_STAGES from all identifier classes
10
+ # @return [Array<Components::TypedStage>] all typed stages
11
+ def typed_stages
12
+ @typed_stages ||= identifiers
13
+ .reject { |klass| klass == Identifiers::Base } # Skip Base fallback class
14
+ .flat_map(&:typed_stages)
15
+ .freeze
16
+ end
17
+
18
+ # Locate TypedStage by abbreviation
19
+ # @param abbr [String, Symbol] the type abbreviation
20
+ # @return [Components::TypedStage] the matching typed stage
21
+ # @raise [ArgumentError] if abbreviation not found
22
+ def locate_typed_stage_by_abbr(abbr)
23
+ abbr_str = abbr.to_s.upcase
24
+ typed_stages.find do |ts|
25
+ ts.abbr.any? { |a| a.to_s.upcase == abbr_str }
26
+ end || raise(ArgumentError, "Unknown type abbreviation: #{abbr}")
27
+ end
28
+
29
+ # Locate identifier class by type code
30
+ # @param type_code [String, Symbol] the type code
31
+ # @return [Class] the identifier class
32
+ # @raise [ArgumentError] if type code not found
33
+ def locate_identifier_klass_by_type_code(type_code)
34
+ type_str = type_code.to_s
35
+ identifiers
36
+ .reject { |klass| klass == Identifiers::Base } # Skip Base fallback class
37
+ .find do |klass|
38
+ klass.typed_stages.any? { |ts| ts.type_code.to_s == type_str }
39
+ end || raise(ArgumentError, "Unknown type code: #{type_code}")
40
+ end
41
+
42
+ # Locate identifier class by series and pattern
43
+ # @param parsed_hash [Hash] the parsed identifier data
44
+ # @return [Class] the identifier class
45
+ def locate_identifier_klass(parsed_hash)
46
+ series = parsed_hash[:series]&.to_s
47
+
48
+ # Handle compound series that include publisher (both space and dot separated)
49
+ if series&.start_with?("NBS ")
50
+ simple_series = series.sub("NBS ", "")
51
+
52
+ # Check for CIRC supplement
53
+ if simple_series == "CIRC"
54
+ if has_supplement?(parsed_hash)
55
+ return Identifiers::CircularSupplement
56
+ else
57
+ return Identifiers::Circular
58
+ end
59
+ end
60
+
61
+ # Use simple series for lookup (TYPED_STAGES abbr handles compound forms)
62
+ series = simple_series
63
+ elsif series&.start_with?("NBS.")
64
+ # Handle dot-separated patterns (e.g., "NBS.LCIRC" after preprocessing)
65
+ simple_series = series.sub("NBS.", "")
66
+
67
+ # Check for LCIRC supplement (dot-separated variant)
68
+ if simple_series == "LCIRC"
69
+ if has_supplement?(parsed_hash)
70
+ return Identifiers::CircularSupplement
71
+ else
72
+ return Identifiers::LetterCircular
73
+ end
74
+ end
75
+
76
+ # Check for CIRC supplement (dot-separated variant)
77
+ if simple_series == "CIRC"
78
+ if has_supplement?(parsed_hash)
79
+ return Identifiers::CircularSupplement
80
+ else
81
+ return Identifiers::Circular
82
+ end
83
+ end
84
+
85
+ # Use simple series for lookup
86
+ series = simple_series
87
+ elsif series&.start_with?("NIST.")
88
+ # Handle dot-separated NIST patterns
89
+ simple_series = series.sub("NIST.", "")
90
+
91
+ # Check for LCIRC supplement (dot-separated variant)
92
+ if simple_series == "LCIRC"
93
+ if has_supplement?(parsed_hash)
94
+ return Identifiers::CircularSupplement
95
+ else
96
+ return Identifiers::LetterCircular
97
+ end
98
+ end
99
+
100
+ # Use simple series for lookup
101
+ series = simple_series
102
+ end
103
+
104
+ # Check for CS variants (works for both compound "NBS CS" and simple "CS")
105
+ if series == "CS"
106
+ first_num = parsed_hash[:first_number]
107
+
108
+ # Check for CSM (monthly) - v#n# pattern inside first_number hash
109
+ if first_num.is_a?(Hash) && first_num[:volume_number] && first_num[:issue_number]
110
+ return Identifiers::CommercialStandardsMonthly
111
+ end
112
+
113
+ # Check for CS-E (emergency) - e-prefix with 3+ digits
114
+ # Handle Parslet::Slice by converting to string
115
+ first_num_str = first_num.is_a?(String) ? first_num.to_str : first_num.to_s
116
+
117
+ # Match e104 or e104 (when "e104-43" is split into first+second)
118
+ if /^e\d{3,}/.match?(first_num_str)
119
+ return Identifiers::CommercialStandardEmergency
120
+ end
121
+ end
122
+
123
+ # Look up using TYPED_STAGES registry (replaces series_to_class_map)
124
+ # This handles simple series, compound series (via abbr array), and all variants
125
+ begin
126
+ typed_stage = locate_typed_stage_by_abbr(series)
127
+ type_code = typed_stage.type_code
128
+ locate_identifier_klass_by_type_code(type_code)
129
+ rescue ArgumentError
130
+ # Fallback to Base for unmapped series (e.g., "AMS", "VTS")
131
+ Identifiers::Base
132
+ end
133
+ end
134
+
135
+ # Check if parsed hash has supplement indicators
136
+ def has_supplement?(parsed_hash)
137
+ parsed_hash[:supplement] ||
138
+ parsed_hash[:supplement_date_range] ||
139
+ parsed_hash[:supplement_date] ||
140
+ parsed_hash[:supplement_slash_year] ||
141
+ parsed_hash[:supplement_with_rev]
142
+ end
143
+
144
+ # All identifier classes
145
+ # @return [Array<Class>] list of all identifier classes
146
+ def identifiers
147
+ @identifiers ||= [
148
+ Identifiers::SpecialPublication,
149
+ Identifiers::FederalInformationProcessingStandards,
150
+ Identifiers::InteragencyReport,
151
+ Identifiers::Handbook,
152
+ Identifiers::TechnicalNote,
153
+ Identifiers::Circular,
154
+ Identifiers::CircularSupplement,
155
+ Identifiers::CrplReport,
156
+ Identifiers::Report,
157
+ Identifiers::Monograph,
158
+ Identifiers::MiscellaneousPublication,
159
+ Identifiers::GrantContractorReport,
160
+ Identifiers::Ncstar,
161
+ Identifiers::Owmwp,
162
+ Identifiers::Nsrds,
163
+ Identifiers::LetterCircular,
164
+ Identifiers::CommercialStandard,
165
+ Identifiers::CommercialStandardEmergency,
166
+ Identifiers::CommercialStandardsMonthly,
167
+ Identifiers::Base, # Fallback for unmapped series
168
+ ].freeze
169
+ end
170
+
171
+ # Check if series is valid
172
+ # @param series_code [String] the series code
173
+ # @return [Boolean] true if series is valid
174
+ def valid_series?(series_code)
175
+ VALID_SERIES.include?(series_code)
176
+ end
177
+
178
+ # All valid series codes (comprehensive list)
179
+ VALID_SERIES = [
180
+ # Major series with dedicated classes
181
+ "SP", "FIPS", "IR", "HB", "TN",
182
+ # Specialized series with dedicated classes
183
+ "CIRC", "CRPL", "CS", "CSM",
184
+ # Other series (use Base class)
185
+ "GCR", "AMS", "BSS", "BMS", "BH", "MONO", "MP",
186
+ "NCSTAR", "NSRDS", "CSWP", "VTS", "AI", "OWMWP",
187
+ "PC", "RPT", "SIBS", "TIBM", "TTB", "EAB",
188
+ "JPCRD", "JRES", "CIS", "HR", "IRPL", "IP",
189
+ "LC", "PS", "LCIRC",
190
+ # Compound series
191
+ "BRPD-CRPL-D", "CRPL-F-A", "CRPL-F-B", "CS-E",
192
+ "CSRC Building Block", "CSRC Use Case", "CSRC Book",
193
+ "ITL Bulletin", "NIST LC", "NIST PS", "NIST DCI",
194
+ "NIST Other", "NSRDS-NBS"
195
+ ].freeze
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ # Base class for NIST supplement identifiers
6
+ # Supplements wrap a base identifier with additional edition information
7
+ #
8
+ # Architecture follows ISO pattern:
9
+ # - base_identifier: The base document being supplemented
10
+ # - edition: Edition information for the supplement
11
+ #
12
+ # Examples:
13
+ # - "NBS CIRC 101e2supp" → CircularSupplement(base: "NBS CIRC 101", edition: e2)
14
+ # - "NBS CIRC 25supp-1924" → CircularSupplement(base: "NBS CIRC 25", edition: 1924)
15
+ class SupplementIdentifier < Identifiers::Base
16
+ attribute :base_identifier, Identifiers::Base, polymorphic: true
17
+
18
+ # Delegate publisher to base_identifier
19
+ def publisher
20
+ base_identifier&.publisher
21
+ end
22
+
23
+ # Delegate series to base_identifier
24
+ def series
25
+ base_identifier&.series
26
+ end
27
+
28
+ def to_s(format = :short)
29
+ # Handle date range supplements (no base identifier)
30
+ if supplement_date_range_start && supplement_date_range_end
31
+ return "NBS CIRC sup#{supplement_date_range_start}-#{supplement_date_range_end}"
32
+ end
33
+
34
+ return super unless base_identifier
35
+
36
+ result = base_identifier.to_s(format)
37
+
38
+ # NEW: Handle update attribute (e.g., "Upd12-1926" for supplement patterns)
39
+ if update
40
+ # Implicit supplements (e.g. "145r11/1925") have no explicit marker;
41
+ # everything else uses the canonical single-p "sup" marker
42
+ # (relaton-data-nist uses "sup" across all series).
43
+ is_implicit = self.class.attributes.key?(:implicit_supplement) && implicit_supplement == true
44
+ result += "sup" unless is_implicit
45
+ result += "/#{update}"
46
+ return result
47
+ end
48
+
49
+ # Canonical supplement marker is single-p "sup" across all NIST/NBS
50
+ # series (relaton-data-nist: SP/CIRC/HB/RPT/LC/IR/MONO/BMS all use "sup").
51
+ result += "sup"
52
+
53
+ # Add edition information if present (just ID, not type prefix)
54
+ if edition&.id
55
+ # Smart dash logic: month=no dash, year=dash
56
+ result += if edition.id.match?(/^[A-Z]/)
57
+ edition.id
58
+ else
59
+ "-#{edition.id}"
60
+ end
61
+ end
62
+
63
+ result
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ class UrnGenerator < Pubid::UrnGenerator::Base
6
+ def generate
7
+ parts = ["urn", "nist"]
8
+
9
+ if identifier.series
10
+ series = identifier.series.to_s
11
+ parts << series.downcase
12
+ elsif (sc = maybe(:series_code))
13
+ parts << sc.downcase
14
+ else
15
+ parts << "sp"
16
+ end
17
+
18
+ identifier_parts = []
19
+
20
+ if identifier.number
21
+ number = identifier.number.to_s
22
+ identifier_parts << number
23
+ end
24
+
25
+ if identifier.parts&.any?
26
+ identifier_parts += identifier.parts.map { |p| "-#{p}" }
27
+ end
28
+
29
+ if identifier.edition
30
+ identifier_parts << identifier.edition.to_s
31
+ end
32
+
33
+ if identifier.volume
34
+ vol = identifier.volume.to_s
35
+ identifier_parts << vol
36
+ end
37
+
38
+ if identifier.part && identifier.part
39
+ identifier_parts << identifier.part.to_s
40
+ end
41
+
42
+ if identifier.volume && identifier.issue_number
43
+ vol_str = identifier.volume.to_s
44
+ issue_str = identifier.issue_number.to_s
45
+ identifier_parts << "#{vol_str}n#{issue_str}"
46
+ end
47
+
48
+ if identifier.version_component
49
+ identifier_parts << identifier.version_component.to_s
50
+ elsif identifier.version
51
+ identifier_parts << "ver.#{identifier.version}"
52
+ end
53
+
54
+ if identifier.update_component
55
+ identifier_parts << identifier.update_component.to_s
56
+ elsif identifier.update
57
+ identifier_parts << "-upd#{identifier.update}"
58
+ end
59
+
60
+ if identifier.stage
61
+ identifier_parts << identifier.stage.to_s
62
+ end
63
+
64
+ # Supplement is now a structured component. Preserve the existing URN
65
+ # branching exactly: range → "supp{start}-{end}", revision → "supprev",
66
+ # a valued supplement → "suppX"/"supp-X" (dash unless it starts with an
67
+ # uppercase letter), and — quirk retained — a nil (absent) supplement
68
+ # still emits "supp", while a present-but-empty one emits nothing.
69
+ supp = identifier.supplement
70
+ if supp&.range?
71
+ identifier_parts << "supp#{supp.month}#{supp.year}-#{supp.month_end}#{supp.year_end}"
72
+ elsif supp&.has_revision
73
+ identifier_parts << "supprev"
74
+ elsif supp && !supp.value_string.empty?
75
+ value = supp.value_string
76
+ identifier_parts << if value.match?(/^[A-Z]/)
77
+ "supp#{value}"
78
+ else
79
+ "supp-#{value}"
80
+ end
81
+ elsif supp.nil?
82
+ identifier_parts << "supp"
83
+ end
84
+
85
+ if identifier.errata
86
+ identifier_parts << identifier.errata
87
+ end
88
+
89
+ if identifier.addendum || identifier.addendum_number
90
+ identifier_parts << "add."
91
+ end
92
+
93
+ if identifier.draft_number
94
+ identifier_parts << "#{identifier.draft_number}pd"
95
+ elsif identifier.draft&.to_s&.include?("draft")
96
+ identifier_parts << "-draft"
97
+ end
98
+
99
+ if identifier.index
100
+ identifier_parts << "index"
101
+ end
102
+
103
+ if identifier.insert
104
+ identifier_parts << "insert"
105
+ end
106
+
107
+ if identifier.section
108
+ identifier_parts << "sec#{identifier.section}"
109
+ end
110
+
111
+ if identifier.appendix
112
+ identifier_parts << "app"
113
+ end
114
+
115
+ parts << identifier_parts.join(".") unless identifier_parts.empty?
116
+
117
+ if identifier.translation_component
118
+ trans = identifier.translation_component
119
+ lang = if trans&.language
120
+ trans.language
121
+ elsif trans.is_a?(String)
122
+ trans
123
+ end
124
+ parts << lang.downcase if lang
125
+ elsif identifier.translation
126
+ parts << identifier.translation.downcase
127
+ end
128
+
129
+ parts.join(":")
130
+ end
131
+ end
132
+ end
133
+ end
data/lib/pubid/nist.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ autoload :Builder, "#{__dir__}/nist/builder"
6
+ autoload :Components, "#{__dir__}/nist/components"
7
+ autoload :Configuration, "#{__dir__}/nist/configuration"
8
+ autoload :Identifier, "#{__dir__}/nist/identifier"
9
+ autoload :Identifiers, "#{__dir__}/nist/identifiers"
10
+ autoload :Parser, "#{__dir__}/nist/parser"
11
+ autoload :Scheme, "#{__dir__}/nist/scheme"
12
+ autoload :SupplementIdentifier, "#{__dir__}/nist/supplement_identifier"
13
+ autoload :UrnGenerator, "#{__dir__}/nist/urn_generator"
14
+
15
+ # Parse a NIST identifier string
16
+ # @param identifier [String] the identifier string to parse
17
+ # @return [Identifiers::Base] the parsed identifier
18
+ def self.parse(identifier)
19
+ # Use the Parser class's preprocessing method
20
+ # Note: We call the class method directly to ensure preprocessing is applied
21
+ parsed = Parser.class_parse_with_preprocessing(identifier)
22
+
23
+ # Use Scheme and Builder for clean architecture
24
+ # ONE CLASS PER SERIES TYPE (like ISO)
25
+ builder = Builder.new(Scheme)
26
+ builder.build(parsed)
27
+ end
28
+
29
+ # Get the configuration instance
30
+ # @return [Configuration] the configuration instance
31
+ def self.configuration
32
+ @configuration ||= Configuration.new
33
+ end
34
+ end
35
+ end
36
+
37
+ Pubid::Registry.register(:nist, Pubid::Nist)
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ class Builder
6
+ # Type to identifier class mapping (MECE)
7
+ TYPE_CLASS_MAP = {
8
+ "B" => "BasicPublication",
9
+ "D" => "Document",
10
+ "E" => "ExpertReport",
11
+ "G" => "Guide",
12
+ "R" => "Recommendation",
13
+ "S" => "SeminarReport",
14
+ "V" => "Vocabulary",
15
+ }.freeze
16
+
17
+ def build(parsed_hash)
18
+ # Check for short amendment format (has amd_marker)
19
+ if parsed_hash[:amd_marker]
20
+ return build_short_amendment(parsed_hash)
21
+ end
22
+
23
+ # Check for supplements first (have base_identifier)
24
+ if parsed_hash[:base_identifier]
25
+ return build_supplement(parsed_hash)
26
+ end
27
+
28
+ # Build base document
29
+ build_base_document(parsed_hash)
30
+ end
31
+
32
+ private
33
+
34
+ def build_short_amendment(parsed_hash)
35
+ # Build base identifier from the code and type
36
+ base_hash = {
37
+ publisher: parsed_hash[:publisher],
38
+ type: parsed_hash[:type],
39
+ }
40
+
41
+ # Copy number/part/subpart from base_code
42
+ if parsed_hash[:base_code]
43
+ base_hash[:number] = parsed_hash[:base_code][:number]
44
+ if parsed_hash[:base_code][:part]
45
+ base_hash[:part] =
46
+ parsed_hash[:base_code][:part]
47
+ end
48
+ if parsed_hash[:base_code][:subpart]
49
+ base_hash[:subpart] =
50
+ parsed_hash[:base_code][:subpart]
51
+ end
52
+ end
53
+
54
+ # Build the base document
55
+ base_identifier = build_base_document(base_hash)
56
+
57
+ # Create amendment
58
+ amendment = Identifiers::Amendment.new
59
+ amendment.base_identifier = base_identifier
60
+
61
+ # Extract year from edition_format if present, otherwise from year directly
62
+ year_value = if parsed_hash[:edition_format].is_a?(Hash)
63
+ parsed_hash[:edition_format][:year]
64
+ else
65
+ parsed_hash[:year]
66
+ end
67
+
68
+ amendment.year = year_value.to_s if year_value
69
+ amendment.language = extract_language(parsed_hash[:language]) if parsed_hash[:language]
70
+
71
+ # Track if amendment itself was parsed with Edition format
72
+ if parsed_hash[:edition_format]
73
+ amendment.parsed_format = "long"
74
+ end
75
+
76
+ amendment
77
+ end
78
+
79
+ def build_supplement(parsed_hash)
80
+ # Determine supplement type
81
+ supplement_class = if parsed_hash[:annex_letter] || parsed_hash[:annex_marker]
82
+ Identifiers::Annex
83
+ else
84
+ Identifiers::Amendment
85
+ end
86
+
87
+ supplement = supplement_class.new
88
+
89
+ # Recursively parse base identifier
90
+ if parsed_hash[:base_identifier]
91
+ supplement.base_identifier = build(parsed_hash[:base_identifier])
92
+ end
93
+
94
+ # Extract year from edition_format if present, otherwise from year directly
95
+ year_value = if parsed_hash[:edition_format].is_a?(Hash)
96
+ parsed_hash[:edition_format][:year]
97
+ else
98
+ parsed_hash[:year]
99
+ end
100
+
101
+ # Set supplement-specific attributes
102
+ supplement.year = year_value.to_s if year_value
103
+ supplement.language = extract_language(parsed_hash[:language]) if parsed_hash[:language]
104
+ supplement.letter = parsed_hash[:annex_letter].to_s if parsed_hash[:annex_letter]
105
+
106
+ # Track if supplement itself was parsed with Edition format
107
+ if parsed_hash[:edition_format]
108
+ supplement.parsed_format = "long"
109
+ end
110
+
111
+ supplement
112
+ end
113
+
114
+ def build_base_document(parsed_hash)
115
+ # Determine identifier class from type
116
+ type = parsed_hash[:type].to_s
117
+ class_name = TYPE_CLASS_MAP[type] || "Recommendation" # Default to R
118
+ identifier_class = Identifiers.const_get(class_name)
119
+
120
+ identifier = identifier_class.new
121
+
122
+ # Handle code (number-part-subpart) specially
123
+ if parsed_hash[:number] || parsed_hash[:part] || parsed_hash[:subpart]
124
+ code_attrs = {}
125
+ if parsed_hash[:number]
126
+ code_attrs[:number] =
127
+ parsed_hash[:number].to_s
128
+ end
129
+ code_attrs[:part] = parsed_hash[:part].to_s if parsed_hash[:part]
130
+ if parsed_hash[:subpart]
131
+ code_attrs[:subpart] =
132
+ parsed_hash[:subpart].to_s
133
+ end
134
+ identifier.code = Components::Code.new(**code_attrs)
135
+ end
136
+
137
+ # Handle other attributes
138
+ identifier.publisher = parsed_hash[:publisher].to_s if parsed_hash[:publisher]
139
+
140
+ # Handle edition attribute
141
+ identifier.edition = parsed_hash[:edition].to_s if parsed_hash[:edition]
142
+
143
+ # Handle year -> date conversion
144
+ # Year could be in edition_format hash or directly
145
+ year_value = nil
146
+ if parsed_hash[:edition_format].is_a?(Hash)
147
+ year_value = parsed_hash[:edition_format][:year]
148
+ # Also extract edition if present
149
+ identifier.edition = parsed_hash[:edition_format][:edition].to_s if parsed_hash[:edition_format][:edition]
150
+ elsif parsed_hash[:year]
151
+ year_value = parsed_hash[:year]
152
+ end
153
+
154
+ if year_value
155
+ identifier.date = Pubid::Components::Date.new(year: year_value.to_s)
156
+ end
157
+
158
+ # Determine parsed format for round-trip fidelity
159
+ # If edition_format was captured, it means "Edition" text was present
160
+ identifier.parsed_format = if parsed_hash[:edition_format]
161
+ "long"
162
+ elsif parsed_hash[:space_before_lang]
163
+ "short_with_space"
164
+ else
165
+ "short"
166
+ end
167
+
168
+ # Handle stage attributes
169
+ identifier.stage = parsed_hash[:stage].to_s if parsed_hash[:stage]
170
+ identifier.iteration = parsed_hash[:iteration].to_s if parsed_hash[:iteration]
171
+
172
+ # Handle language
173
+ identifier.language = extract_language(parsed_hash[:language]) if parsed_hash[:language]
174
+
175
+ identifier
176
+ end
177
+
178
+ def extract_language(lang_data)
179
+ # Handle both direct string and nested hash from parser
180
+ case lang_data
181
+ when Hash
182
+ lang_data[:language].to_s
183
+ else
184
+ lang_data.to_s
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ module Components
6
+ class Code < Lutaml::Model::Serializable
7
+ attribute :number, :string
8
+ attribute :part, :string
9
+ attribute :subpart, :string
10
+
11
+ def to_s
12
+ result = number.to_s
13
+ result += "-#{part}" if part
14
+ result += "-#{subpart}" if subpart
15
+ result
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ module Components
6
+ autoload :Code, "#{__dir__}/components/code"
7
+ end
8
+ end
9
+ end