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,671 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ class Builder
6
+ def build(parsed_hash)
7
+ # Handle Canadian adopted identifiers (CAN/CSA- or CAN3- prefix)
8
+ # Check this BEFORE series_type because CAN/CSA-X SERIES:YY should be
9
+ # CanadianAdopted wrapping a Series, not a plain Series identifier
10
+ if parsed_hash[:publisher_prefix] &&
11
+ ["CAN/CSA-", "CAN3-"].include?(parsed_hash[:publisher_prefix].to_s)
12
+ return build_canadian_adopted(parsed_hash)
13
+ end
14
+
15
+ # Handle adoption identifiers (ISO/IEC/CISPR/CEI adoptions)
16
+ if parsed_hash.key?(:adoption_number)
17
+ return build_adoption(parsed_hash)
18
+ end
19
+
20
+ # Handle series identifiers (SERIES as primary type)
21
+ if parsed_hash.key?(:series_type)
22
+ return build_series(parsed_hash)
23
+ end
24
+
25
+ # Handle CEC identifiers (C22.x NO. patterns)
26
+ if parsed_hash.key?(:cec_part)
27
+ return build_cec(parsed_hash)
28
+ end
29
+
30
+ # Handle package identifiers (with package_portion marker)
31
+ if parsed_hash.key?(:package_portion)
32
+ return build_package(parsed_hash)
33
+ end
34
+
35
+ # Handle bundled identifiers (with + notation)
36
+ if parsed_hash.key?(:bundled_first)
37
+ return build_bundled(parsed_hash)
38
+ end
39
+
40
+ # Handle combined identifiers (with / notation)
41
+ if parsed_hash[:first] && parsed_hash[:second]
42
+ return build_combined(parsed_hash)
43
+ end
44
+
45
+ build_single(parsed_hash)
46
+ end
47
+
48
+ private
49
+
50
+ def build_package(parsed_hash)
51
+ package = Identifiers::Package.new
52
+
53
+ # Build base identifier (without package_portion)
54
+ base_data = parsed_hash.dup
55
+ base_data.delete(:package_portion)
56
+ package.base_identifier = build_single(base_data)
57
+
58
+ # Set package materials
59
+ if parsed_hash[:package_portion]
60
+ package.package_materials = parsed_hash[:package_portion].to_s
61
+ end
62
+
63
+ package
64
+ end
65
+
66
+ def build_adoption(parsed_hash)
67
+ adoption = Identifiers::CsaAdopted.new
68
+
69
+ # Get the organization prefix (ISO/IEC, ISO, IEC, CISPR, CEI/IEC)
70
+ adoption_org = parsed_hash[:adoption_org].to_s
71
+ adoption_number = parsed_hash[:adoption_number].to_s
72
+ adoption_year = parsed_hash[:adoption_year].to_s
73
+
74
+ # Add ISO type (TR/TS) if present
75
+ if parsed_hash[:iso_type]
76
+ adoption_org += " #{parsed_hash[:iso_type]}"
77
+ end
78
+
79
+ # Year separator for wrapped identifier
80
+ year_sep = parsed_hash[:adoption_year_sep] || ":"
81
+
82
+ # Build the wrapped identifier string for the external standard
83
+ # Convert 2-digit year to 4-digit for external parser
84
+ wrapped_year = if adoption_year.length == 2
85
+ "20#{adoption_year}"
86
+ else
87
+ adoption_year
88
+ end
89
+
90
+ # Handle amendment if present
91
+ if parsed_hash[:adoption_amendment]
92
+ # There's an amendment, build Amendment identifier
93
+ # Build base identifier string
94
+ base_str = "#{adoption_org} #{adoption_number}#{year_sep}#{wrapped_year}"
95
+
96
+ # Parse base identifier
97
+ if adoption_org.start_with?("ISO", "CEI")
98
+ Pubid::Iso.parse(base_str)
99
+ elsif adoption_org.start_with?("IEC")
100
+ Pubid::Iec.parse(base_str)
101
+ else
102
+ begin
103
+ Pubid::Iso.parse(base_str)
104
+ rescue Pubid::Errors::ParseError
105
+ Pubid::Iec.parse(base_str)
106
+ end
107
+ end
108
+
109
+ # Build amendment string for external parser
110
+ amendment_year = parsed_hash[:adoption_amendment_year].to_s
111
+ wrapped_amendment_year = if amendment_year.length == 2
112
+ "20#{amendment_year}"
113
+ else
114
+ amendment_year
115
+ end
116
+
117
+ # The external parser uses Amendment class which wraps the base
118
+ # We need to construct the amendment identifier
119
+ # For ISO: "ISO/IEC 9594-2:2021/Amd 1:2022"
120
+ # For IEC: similar format
121
+
122
+ if adoption_org.start_with?("ISO", "CEI")
123
+ # ISO format
124
+ elsif adoption_org.start_with?("IEC")
125
+ # IEC format
126
+ else
127
+ # CISPR or other
128
+ end
129
+ amendment_str = "#{base_str}/Amd #{parsed_hash[:adoption_amendment]}:#{wrapped_amendment_year}"
130
+
131
+ wrapped_identifier = if adoption_org.start_with?("ISO", "CEI")
132
+ Pubid::Iso.parse(amendment_str)
133
+ elsif adoption_org.start_with?("IEC")
134
+ Pubid::Iec.parse(amendment_str)
135
+ else
136
+ begin
137
+ Pubid::Iso.parse(amendment_str)
138
+ rescue Pubid::Errors::ParseError
139
+ Pubid::Iec.parse(amendment_str)
140
+ end
141
+ end
142
+ else
143
+ # No amendment, simple base identifier
144
+ wrapped_id_str = "#{adoption_org} #{adoption_number}#{year_sep}#{wrapped_year}"
145
+
146
+ # CEI/IEC is normalized to IEC for parsing
147
+ if adoption_org == "CEI/IEC"
148
+ wrapped_id_str = wrapped_id_str.sub("CEI/IEC", "IEC")
149
+ end
150
+
151
+ wrapped_identifier = if adoption_org.start_with?("ISO", "CEI")
152
+ Pubid::Iso.parse(wrapped_id_str)
153
+ elsif adoption_org.start_with?("IEC")
154
+ Pubid::Iec.parse(wrapped_id_str)
155
+ else
156
+ begin
157
+ Pubid::Iso.parse(wrapped_id_str)
158
+ rescue Pubid::Errors::ParseError
159
+ Pubid::Iec.parse(wrapped_id_str)
160
+ end
161
+ end
162
+ end
163
+
164
+ adoption.wrapped_identifier = wrapped_identifier
165
+
166
+ # Handle reaffirmation
167
+ if parsed_hash[:reaffirmation]
168
+ reaffirm_data = parsed_hash[:reaffirmation]
169
+ adoption.reaffirmation = if reaffirm_data.is_a?(Hash) && reaffirm_data[:year]
170
+ reaffirm_data[:year].to_s
171
+ else
172
+ reaffirm_data.to_s
173
+ end
174
+ end
175
+
176
+ adoption
177
+ end
178
+
179
+ def build_canadian_adopted(parsed_hash)
180
+ canadian_adopted = Identifiers::CanadianAdopted.new
181
+
182
+ # Store the original publisher_prefix (CAN/CSA- or CAN3-)
183
+ original_prefix = parsed_hash[:publisher_prefix]&.to_s
184
+
185
+ # Build the wrapped identifier based on what the parser matched
186
+ # The parser may have matched series_identifier, cec_identifier, or csa_code
187
+ # We build the appropriate wrapped type based on the presence of specific keys
188
+ wrapped_data = parsed_hash.dup
189
+
190
+ # Remove publisher_prefix from wrapped_data so the wrapped identifier
191
+ # doesn't also include the prefix (we only want it on the CanadianAdopted wrapper)
192
+ # But for Series with CAN/CSA- prefix, the to_s method expects the Series
193
+ # to have publisher_prefix = "CAN/CSA-" to render correctly
194
+ if parsed_hash.key?(:series_type)
195
+ # SERIES matched - build Series identifier with CAN/CSA- prefix
196
+ # The Series.to_s will handle rendering as "CAN/CSA-A220 SERIES-06"
197
+ # (keeping the full prefix instead of "CAN/CSA-A220...")
198
+ wrapped_identifier = build_series(wrapped_data)
199
+ # Set the full publisher_prefix on the wrapped Series for proper rendering
200
+ # The test expects wrapped_identifier.publisher_prefix to be "CAN/CSA-"
201
+ elsif parsed_hash.key?(:cec_part)
202
+ # CEC matched - build Cec identifier
203
+ wrapped_identifier = build_cec(wrapped_data)
204
+ else
205
+ # Standard CSA identifier
206
+ wrapped_identifier = build_single(wrapped_data)
207
+ end
208
+ wrapped_identifier.publisher_prefix = original_prefix if original_prefix && wrapped_identifier.class.attributes.key?(:publisher_prefix)
209
+
210
+ canadian_adopted.wrapped_identifier = wrapped_identifier
211
+
212
+ # Handle reaffirmation - supports both 2-digit and 4-digit years
213
+ # Note: CanadianAdopted (WrapperIdentifier) doesn't track original_reaffirmation_4digit
214
+ # That's only for Series/Cec identifiers
215
+ if parsed_hash[:reaffirmation_4digit]
216
+ # Original was 4-digit (e.g., "R2019")
217
+ canadian_adopted.reaffirmation = parsed_hash[:reaffirmation_4digit].to_s
218
+ elsif parsed_hash[:reaffirmation_2digit]
219
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
220
+ year_2digit = parsed_hash[:reaffirmation_2digit].to_s
221
+ year_int = year_2digit.to_i
222
+ canadian_adopted.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
223
+ elsif parsed_hash[:reaffirmation]
224
+ # Legacy format (Hash or String)
225
+ reaffirm_data = parsed_hash[:reaffirmation]
226
+ canadian_adopted.reaffirmation = if reaffirm_data.is_a?(Hash) && reaffirm_data[:year]
227
+ reaffirm_data[:year].to_s
228
+ else
229
+ reaffirm_data.to_s
230
+ end
231
+ end
232
+
233
+ canadian_adopted
234
+ end
235
+
236
+ def build_series(parsed_hash)
237
+ series = Identifiers::Series.new
238
+
239
+ # Series identifiers always have series = true (this is how they're identified)
240
+ series.series = true
241
+
242
+ # Publisher prefix
243
+ if parsed_hash[:publisher_prefix]
244
+ series.publisher_prefix = parsed_hash[:publisher_prefix].to_s
245
+ end
246
+
247
+ # Series prefix (MH, RV, etc.)
248
+ if parsed_hash[:series_prefix]
249
+ series.series_prefix = parsed_hash[:series_prefix].to_s
250
+ end
251
+
252
+ # Code
253
+ if parsed_hash[:code]
254
+ series.code = Components::Code.new(value: parsed_hash[:code].to_s)
255
+ end
256
+
257
+ # Year format and year
258
+ year_format = if parsed_hash[:dash_format]
259
+ "dash"
260
+ elsif parsed_hash[:colon_format]
261
+ "colon"
262
+ else
263
+ "colon" # default
264
+ end
265
+
266
+ if parsed_hash[:year]
267
+ year_str = parsed_hash[:year].to_s
268
+ if year_str.length == 2
269
+ # Convert 2-digit year to 4-digit
270
+ # Rule: 00-49 → 2000s, 50-99 → 1900s
271
+ # M prefix also means 1900s (metric/old standards)
272
+ year_int = year_str.to_i
273
+ if parsed_hash[:year_prefix] && parsed_hash[:year_prefix].to_s == "M"
274
+ # M prefix always means 1900s
275
+ series.year = "19#{year_str}"
276
+ elsif year_int < 50
277
+ # 00-49 → 2000s
278
+ series.year = "20#{year_str}"
279
+ else
280
+ # 50-99 → 1900s
281
+ series.year = "19#{year_str}"
282
+ end
283
+ else
284
+ # Keep 4-digit years as-is AND mark original format
285
+ series.year = year_str
286
+ series.original_year_4digit = true
287
+ end
288
+ series.year_format = year_format
289
+ end
290
+
291
+ # Year prefix (F or M)
292
+ if parsed_hash[:year_prefix]
293
+ series.year_prefix = parsed_hash[:year_prefix].to_s
294
+ end
295
+
296
+ # Reaffirmation - supports both 2-digit and 4-digit years
297
+ # Tracks original format via original_reaffirmation_4digit flag
298
+ # Check NEW parser keys first (outside of legacy :reaffirmation check)
299
+ if parsed_hash[:reaffirmation_4digit]
300
+ # Original was 4-digit (e.g., "R2019")
301
+ series.reaffirmation = parsed_hash[:reaffirmation_4digit].to_s
302
+ series.original_reaffirmation_4digit = true
303
+ elsif parsed_hash[:reaffirmation_2digit]
304
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
305
+ year_2digit = parsed_hash[:reaffirmation_2digit].to_s
306
+ year_int = year_2digit.to_i
307
+ series.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
308
+ series.original_reaffirmation_4digit = false
309
+ elsif parsed_hash[:reaffirmation]
310
+ # Legacy format (Hash or String)
311
+ reaffirm_data = parsed_hash[:reaffirmation]
312
+ series.reaffirmation = if reaffirm_data.is_a?(Hash) && reaffirm_data[:year]
313
+ reaffirm_data[:year].to_s
314
+ else
315
+ reaffirm_data.to_s
316
+ end
317
+ end
318
+
319
+ series
320
+ end
321
+
322
+ def build_cec(parsed_hash)
323
+ cec = Identifiers::Cec.new
324
+
325
+ # Publisher prefix (if set)
326
+ if parsed_hash[:publisher_prefix]
327
+ cec.publisher_prefix = parsed_hash[:publisher_prefix].to_s
328
+ end
329
+
330
+ # CEC part (C22.2, C22.3, etc.)
331
+ if parsed_hash[:cec_part]
332
+ cec.cec_part = Components::Code.new(value: parsed_hash[:cec_part].to_s)
333
+ end
334
+
335
+ # NO. number
336
+ if parsed_hash[:no_number]
337
+ cec.no_number = Components::Code.new(value: parsed_hash[:no_number].to_s)
338
+ end
339
+
340
+ # Year format and year
341
+ year_format = if parsed_hash[:dash_format]
342
+ "dash"
343
+ elsif parsed_hash[:colon_format]
344
+ "colon"
345
+ else
346
+ "colon" # default
347
+ end
348
+
349
+ if parsed_hash[:year]
350
+ year_str = parsed_hash[:year].to_s
351
+ if year_str.length == 2
352
+ # Convert 2-digit year to 4-digit
353
+ # Rule: 00-49 → 2000s, 50-99 → 1900s
354
+ # M prefix also means 1900s (metric/old standards)
355
+ year_int = year_str.to_i
356
+ cec.year = if parsed_hash[:year_prefix] && parsed_hash[:year_prefix].to_s == "M"
357
+ # M prefix always means 1900s
358
+ "19#{year_str}"
359
+ elsif year_int < 50
360
+ # 00-49 → 2000s
361
+ "20#{year_str}"
362
+ else
363
+ # 50-99 → 1900s
364
+ "19#{year_str}"
365
+ end
366
+ else
367
+ # Keep 4-digit years as-is AND mark original format
368
+ cec.year = year_str
369
+ cec.original_year_4digit = true
370
+ end
371
+ cec.year_format = year_format
372
+ end
373
+
374
+ # Year prefix (F or M)
375
+ if parsed_hash[:year_prefix]
376
+ cec.year_prefix = parsed_hash[:year_prefix].to_s
377
+ # If year prefix is F, set french flag
378
+ if parsed_hash[:year_prefix].to_s == "F"
379
+ cec.french = true
380
+ end
381
+ end
382
+
383
+ # French flag
384
+ if parsed_hash[:french]
385
+ cec.french = true
386
+ end
387
+
388
+ # Reaffirmation - supports both 2-digit and 4-digit years
389
+ # Tracks original format via original_reaffirmation_4digit flag
390
+ # Check NEW parser keys first (outside of legacy :reaffirmation check)
391
+ if parsed_hash[:reaffirmation_4digit]
392
+ # Original was 4-digit (e.g., "R2019")
393
+ cec.reaffirmation = parsed_hash[:reaffirmation_4digit].to_s
394
+ cec.original_reaffirmation_4digit = true
395
+ elsif parsed_hash[:reaffirmation_2digit]
396
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
397
+ year_2digit = parsed_hash[:reaffirmation_2digit].to_s
398
+ year_int = year_2digit.to_i
399
+ cec.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
400
+ cec.original_reaffirmation_4digit = false
401
+ elsif parsed_hash[:reaffirmation]
402
+ # Legacy format (Hash or String)
403
+ reaffirm_data = parsed_hash[:reaffirmation]
404
+ cec.reaffirmation = if reaffirm_data.is_a?(Hash)
405
+ reaffirm_data[:year].to_s
406
+ else
407
+ reaffirm_data.to_s
408
+ end
409
+ end
410
+
411
+ cec
412
+ end
413
+
414
+ def build_bundled(parsed_hash)
415
+ bundled = Identifiers::Bundled.new
416
+
417
+ # Build base identifier
418
+ bundled.base = build_single(parsed_hash[:base])
419
+
420
+ # Build bundled portions (amendments/supplements)
421
+ # Combine bundled_first with bundled_rest array
422
+ bundled_portions = [parsed_hash[:bundled_first]]
423
+ if parsed_hash[:bundled_rest] && !parsed_hash[:bundled_rest].empty?
424
+ bundled_portions += parsed_hash[:bundled_rest]
425
+ end
426
+
427
+ bundled.bundled_with = bundled_portions.map do |portion|
428
+ build_single(portion)
429
+ end
430
+
431
+ # Reaffirmation - supports both 2-digit and 4-digit years
432
+ # Tracks original format via original_reaffirmation_4digit flag
433
+ if parsed_hash[:reaffirmation_4digit]
434
+ # Original was 4-digit (e.g., "R2019")
435
+ bundled.reaffirmation = parsed_hash[:reaffirmation_4digit].to_s
436
+ bundled.original_reaffirmation_4digit = true
437
+ elsif parsed_hash[:reaffirmation_2digit]
438
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
439
+ year_2digit = parsed_hash[:reaffirmation_2digit].to_s
440
+ year_int = year_2digit.to_i
441
+ bundled.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
442
+ bundled.original_reaffirmation_4digit = false
443
+ elsif parsed_hash[:reaffirmation]
444
+ # Legacy format (String)
445
+ bundled.reaffirmation = parsed_hash[:reaffirmation].to_s
446
+ end
447
+
448
+ bundled
449
+ end
450
+
451
+ def build_combined(parsed_hash)
452
+ combined = Identifiers::Combined.new
453
+
454
+ # Build each part
455
+ combined.first = build_single(parsed_hash[:first])
456
+ combined.second = build_single(parsed_hash[:second])
457
+ combined.third = build_single(parsed_hash[:third]) if parsed_hash[:third]
458
+
459
+ # Detect separator from parser marker
460
+ combined.separator = if parsed_hash[:comma_separator]
461
+ # Combined comma: "CSA X, CSA Y"
462
+ ", "
463
+ else
464
+ # Combined slash: "CSA X/Y" (default)
465
+ "/"
466
+ end
467
+
468
+ # Reaffirmation - supports both 2-digit and 4-digit years
469
+ # Tracks original format via original_reaffirmation_4digit flag
470
+ if parsed_hash[:reaffirmation_4digit]
471
+ # Original was 4-digit (e.g., "R2019")
472
+ combined.reaffirmation = parsed_hash[:reaffirmation_4digit].to_s
473
+ combined.original_reaffirmation_4digit = true
474
+ elsif parsed_hash[:reaffirmation_2digit]
475
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
476
+ year_2digit = parsed_hash[:reaffirmation_2digit].to_s
477
+ year_int = year_2digit.to_i
478
+ combined.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
479
+ combined.original_reaffirmation_4digit = false
480
+ elsif parsed_hash[:reaffirmation]
481
+ # Legacy format (String)
482
+ combined.reaffirmation = parsed_hash[:reaffirmation].to_s
483
+ end
484
+
485
+ # Handle package portion if present
486
+ if parsed_hash[:package_portion]
487
+ combined.package = parsed_hash[:package_portion].to_s
488
+ end
489
+
490
+ combined
491
+ end
492
+
493
+ def build_single(data)
494
+ # Select appropriate identifier class based on MECE criteria
495
+ identifier_class = select_identifier_class(data)
496
+ identifier = identifier_class.new
497
+
498
+ # Publisher prefix (CAN/CSA-, CAN3-, or CSA)
499
+ # For code_only identifiers (no prefix in original), set to empty string
500
+ # to prevent default "CSA" from being added in rendering
501
+ if data[:publisher_prefix]
502
+ identifier.publisher_prefix = data[:publisher_prefix].to_s
503
+ elsif data[:code] && !data[:publisher_prefix]
504
+ # Code exists but no publisher_prefix = code_only identifier
505
+ # Use empty string to indicate "no prefix wanted"
506
+ identifier.publisher_prefix = ""
507
+ end
508
+
509
+ # Publisher presence flag
510
+ if data[:has_publisher]
511
+ identifier.has_publisher = true
512
+ end
513
+
514
+ # Code - with dash-year extraction if needed
515
+ # Skip setting code for Cec identifiers (they use cec_part + no_number instead)
516
+ if data[:code] && !identifier.is_a?(Identifiers::Cec)
517
+ code_value = data[:code].to_s
518
+
519
+ # Extract year from code if it ends with -NN (2-digit year) and no separate year parsed
520
+ # Pattern: "C22.1-15" should become code="C22.1", year="2015"
521
+ if !data[:year] && code_value =~ /^(.+)-(\d{2})$/
522
+ # Split code and year
523
+ identifier.code = Components::Code.new(value: $1)
524
+ # Convert 2-digit year to 4-digit
525
+ year_2digit = $2
526
+ identifier.year = "20#{year_2digit}"
527
+ identifier.year_format = "dash"
528
+ else
529
+ identifier.code = Components::Code.new(value: code_value)
530
+ end
531
+ end
532
+
533
+ # Special handling for Cec identifiers: map :code to :cec_part
534
+ if identifier.is_a?(Identifiers::Cec) && data[:code] && !identifier.cec_part
535
+ identifier.cec_part = Components::Code.new(value: data[:code].to_s)
536
+ end
537
+
538
+ # NO. number handling for Cec identifiers
539
+ if identifier.is_a?(Identifiers::Cec) && data[:no_number]
540
+ identifier.no_number = Components::Code.new(value: data[:no_number].to_s)
541
+ end
542
+
543
+ # Series prefix (MH, RV, etc.)
544
+ if data[:series_prefix]
545
+ identifier.series_prefix = data[:series_prefix].to_s
546
+ end
547
+
548
+ # Series keyword flag
549
+ if data[:series]
550
+ identifier.series = true
551
+ end
552
+
553
+ # Determine year format from markers
554
+ year_format = if data[:dash_format]
555
+ "dash"
556
+ elsif data[:colon_format]
557
+ "colon"
558
+ else
559
+ "colon" # default
560
+ end
561
+
562
+ # Year (2-digit needs conversion to 4-digit, 4-digit stays as-is)
563
+ # Only set if not already set by code extraction above
564
+ if data[:year] && !identifier.year
565
+ year_str = data[:year].to_s
566
+ if year_str.length == 2
567
+ # Convert 2-digit year to 4-digit
568
+ # Rule: 00-49 → 2000s, 50-99 → 1900s
569
+ # M prefix also means 1900s (metric/old standards)
570
+ year_int = year_str.to_i
571
+ identifier.year = if data[:year_prefix] && data[:year_prefix].to_s == "M"
572
+ # M prefix always means 1900s
573
+ "19#{year_str}"
574
+ elsif year_int < 50
575
+ # 00-49 → 2000s
576
+ "20#{year_str}"
577
+ else
578
+ # 50-99 → 1900s
579
+ "19#{year_str}"
580
+ end
581
+ else
582
+ # Keep 4-digit years as-is AND mark original format
583
+ identifier.year = year_str
584
+ identifier.original_year_4digit = true
585
+ end
586
+ identifier.year_format = year_format
587
+ end
588
+
589
+ # Year prefix (F or M)
590
+ if data[:year_prefix]
591
+ identifier.year_prefix = data[:year_prefix].to_s
592
+ # If year prefix is F, set french flag
593
+ if data[:year_prefix].to_s == "F"
594
+ identifier.french = true
595
+ end
596
+ end
597
+
598
+ # French edition flag
599
+ if data[:french]
600
+ identifier.french = true
601
+ end
602
+
603
+ # Reaffirmation - supports both 2-digit and 4-digit years
604
+ # Tracks original format via original_reaffirmation_4digit flag
605
+ if data[:reaffirmation_4digit]
606
+ # Original was 4-digit (e.g., "R2019")
607
+ identifier.reaffirmation = data[:reaffirmation_4digit].to_s
608
+ identifier.original_reaffirmation_4digit = true
609
+ elsif data[:reaffirmation_2digit]
610
+ # Original was 2-digit (e.g., "R19"), convert to 4-digit for internal storage
611
+ year_2digit = data[:reaffirmation_2digit].to_s
612
+ year_int = year_2digit.to_i
613
+ identifier.reaffirmation = year_int < 50 ? "20#{year_2digit}" : "19#{year_2digit}"
614
+ identifier.original_reaffirmation_4digit = false
615
+ elsif data[:reaffirmation]
616
+ # Legacy format (Hash or String)
617
+ reaffirm_data = data[:reaffirmation]
618
+ identifier.reaffirmation = if reaffirm_data.is_a?(Hash) && reaffirm_data[:year]
619
+ reaffirm_data[:year].to_s
620
+ else
621
+ reaffirm_data.to_s
622
+ end
623
+ end
624
+
625
+ # Package portion
626
+ if data[:package_portion]
627
+ identifier.package = data[:package_portion].to_s
628
+ end
629
+
630
+ identifier
631
+ end
632
+
633
+ def select_identifier_class(data)
634
+ # Priority order (MECE - mutually exclusive, collectively exhaustive):
635
+ # Wrappers first, then type-based classification
636
+
637
+ # 1. Check for CAN/CSA- or CAN3- prefix → CanadianAdopted (wrapper)
638
+ if data[:publisher_prefix] &&
639
+ ["CAN/CSA-", "CAN3-"].include?(data[:publisher_prefix].to_s)
640
+ return Identifiers::CanadianAdopted
641
+ end
642
+
643
+ # 2. Check for adoption patterns → CsaAdopted (wrapper)
644
+ # Detect adoption_identifier patterns (ISO/IEC/CISPR/CEI adoptions)
645
+ if data[:adoption_number] || data[:iso_type]
646
+ return Identifiers::CsaAdopted
647
+ end
648
+
649
+ # 2.5. Check for NO. notation (cec_identifiers parsed with NO. notation)
650
+ if data[:no_notation] && data[:no_number]
651
+ return Identifiers::Cec
652
+ end
653
+
654
+ # 3. Check for Series type (series_type means SERIES as primary type from series_identifier rule)
655
+ # NOTE: Do NOT check :series flag here - that's a modifier, not a primary type
656
+ if data[:series_type]
657
+ return Identifiers::Series
658
+ end
659
+
660
+ # 3.5. Check for SERIES keyword in combined continuation patterns
661
+ # When SERIES appears in second/third part of combined identifier, it's captured as :series (string)
662
+ if data[:series] && data[:series].to_s == "SERIES"
663
+ return Identifiers::Series
664
+ end
665
+
666
+ # 4. Default: Standard
667
+ Identifiers::Standard
668
+ end
669
+ end
670
+ end
671
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ module Components
6
+ Code = Pubid::Components::Code
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ module Components
6
+ autoload :Code, "#{__dir__}/components/code"
7
+ end
8
+ end
9
+ end