pubid 1.15.18 → 2.0.0.pre.alpha.1

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 (601) 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 +87 -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 +18 -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 +13 -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 +21 -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 +18 -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 +15 -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 +15 -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 +27 -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 +16 -0
  160. data/lib/pubid/ccsds/identifiers/base.rb +78 -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 +74 -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 +15 -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 +18 -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/language.rb +37 -0
  219. data/lib/pubid/components/locality.rb +10 -0
  220. data/lib/pubid/components/publisher.rb +36 -0
  221. data/lib/pubid/components/stage.rb +54 -0
  222. data/lib/pubid/components/type.rb +58 -0
  223. data/lib/pubid/components/typed_stage.rb +55 -0
  224. data/lib/pubid/components.rb +15 -0
  225. data/lib/pubid/core/pattern_doc_generator.rb +272 -0
  226. data/lib/pubid/core/update_codes.rb +77 -0
  227. data/lib/pubid/core.rb +8 -0
  228. data/lib/pubid/csa/builder.rb +671 -0
  229. data/lib/pubid/csa/components/code.rb +9 -0
  230. data/lib/pubid/csa/components.rb +9 -0
  231. data/lib/pubid/csa/composite_identifier.rb +27 -0
  232. data/lib/pubid/csa/identifier.rb +457 -0
  233. data/lib/pubid/csa/identifiers/base.rb +133 -0
  234. data/lib/pubid/csa/identifiers/bundled.rb +125 -0
  235. data/lib/pubid/csa/identifiers/canadian_adopted.rb +82 -0
  236. data/lib/pubid/csa/identifiers/cec.rb +129 -0
  237. data/lib/pubid/csa/identifiers/combined.rb +130 -0
  238. data/lib/pubid/csa/identifiers/csa_adopted.rb +78 -0
  239. data/lib/pubid/csa/identifiers/package.rb +65 -0
  240. data/lib/pubid/csa/identifiers/series.rb +127 -0
  241. data/lib/pubid/csa/identifiers/standard.rb +10 -0
  242. data/lib/pubid/csa/identifiers.rb +17 -0
  243. data/lib/pubid/csa/parser.rb +445 -0
  244. data/lib/pubid/csa/scheme.rb +44 -0
  245. data/lib/pubid/csa/single_identifier.rb +30 -0
  246. data/lib/pubid/csa/urn_generator.rb +80 -0
  247. data/lib/pubid/csa/wrapper_identifier.rb +31 -0
  248. data/lib/pubid/csa.rb +25 -0
  249. data/lib/pubid/etsi/builder.rb +133 -0
  250. data/lib/pubid/etsi/components/code.rb +42 -0
  251. data/lib/pubid/etsi/components/version.rb +37 -0
  252. data/lib/pubid/etsi/components.rb +10 -0
  253. data/lib/pubid/etsi/identifier.rb +14 -0
  254. data/lib/pubid/etsi/identifiers/amendment.rb +15 -0
  255. data/lib/pubid/etsi/identifiers/base.rb +38 -0
  256. data/lib/pubid/etsi/identifiers/corrigendum.rb +15 -0
  257. data/lib/pubid/etsi/identifiers/etsi_standard.rb +19 -0
  258. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +91 -0
  259. data/lib/pubid/etsi/identifiers.rb +14 -0
  260. data/lib/pubid/etsi/parser.rb +133 -0
  261. data/lib/pubid/etsi/scheme.rb +42 -0
  262. data/lib/pubid/etsi/urn_generator.rb +76 -0
  263. data/lib/pubid/etsi.rb +21 -0
  264. data/lib/pubid/export/auditor.rb +89 -0
  265. data/lib/pubid/export/data_class_exporter.rb +59 -0
  266. data/lib/pubid/export/exporter.rb +74 -0
  267. data/lib/pubid/export/flavor_exporter.rb +402 -0
  268. data/lib/pubid/export/ieee_exporter.rb +78 -0
  269. data/lib/pubid/export/itu_exporter.rb +66 -0
  270. data/lib/pubid/export/nist_exporter.rb +64 -0
  271. data/lib/pubid/export/registry_exporter.rb +90 -0
  272. data/lib/pubid/export/result.rb +97 -0
  273. data/lib/pubid/export/scheme_exporter.rb +70 -0
  274. data/lib/pubid/export.rb +18 -0
  275. data/lib/pubid/format_detector.rb +16 -0
  276. data/lib/pubid/format_registry.rb +42 -0
  277. data/lib/pubid/identifier.rb +235 -0
  278. data/lib/pubid/identifier_metadata.rb +148 -0
  279. data/lib/pubid/identifier_registry.rb +198 -0
  280. data/lib/pubid/idf/builder.rb +82 -0
  281. data/lib/pubid/idf/identifier.rb +69 -0
  282. data/lib/pubid/idf/identifiers/amendment.rb +27 -0
  283. data/lib/pubid/idf/identifiers/corrigendum.rb +27 -0
  284. data/lib/pubid/idf/identifiers/international_standard.rb +123 -0
  285. data/lib/pubid/idf/identifiers/reviewed_method.rb +100 -0
  286. data/lib/pubid/idf/identifiers.rb +13 -0
  287. data/lib/pubid/idf/parser.rb +143 -0
  288. data/lib/pubid/idf/scheme.rb +61 -0
  289. data/lib/pubid/idf/single_identifier.rb +19 -0
  290. data/lib/pubid/idf/supplement_identifier.rb +43 -0
  291. data/lib/pubid/idf/urn_generator.rb +84 -0
  292. data/lib/pubid/idf.rb +25 -0
  293. data/lib/pubid/iec/builder.rb +457 -0
  294. data/lib/pubid/iec/components/code.rb +59 -0
  295. data/lib/pubid/iec/components/consolidated_amendment.rb +59 -0
  296. data/lib/pubid/iec/components/publisher.rb +35 -0
  297. data/lib/pubid/iec/components/sheet.rb +32 -0
  298. data/lib/pubid/iec/components/trf_info.rb +38 -0
  299. data/lib/pubid/iec/components/vap_suffix.rb +41 -0
  300. data/lib/pubid/iec/identifier.rb +21 -0
  301. data/lib/pubid/iec/identifiers/amendment.rb +94 -0
  302. data/lib/pubid/iec/identifiers/base.rb +78 -0
  303. data/lib/pubid/iec/identifiers/component_specification.rb +39 -0
  304. data/lib/pubid/iec/identifiers/conformity_assessment.rb +39 -0
  305. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +86 -0
  306. data/lib/pubid/iec/identifiers/corrigendum.rb +94 -0
  307. data/lib/pubid/iec/identifiers/fragment_identifier.rb +141 -0
  308. data/lib/pubid/iec/identifiers/guide.rb +104 -0
  309. data/lib/pubid/iec/identifiers/international_standard.rb +147 -0
  310. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +104 -0
  311. data/lib/pubid/iec/identifiers/operational_document.rb +39 -0
  312. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +101 -0
  313. data/lib/pubid/iec/identifiers/sheet_identifier.rb +66 -0
  314. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +40 -0
  315. data/lib/pubid/iec/identifiers/systems_reference_document.rb +40 -0
  316. data/lib/pubid/iec/identifiers/technical_report.rb +132 -0
  317. data/lib/pubid/iec/identifiers/technical_specification.rb +132 -0
  318. data/lib/pubid/iec/identifiers/technology_report.rb +39 -0
  319. data/lib/pubid/iec/identifiers/test_report_form.rb +78 -0
  320. data/lib/pubid/iec/identifiers/vap_identifier.rb +77 -0
  321. data/lib/pubid/iec/identifiers/white_paper.rb +39 -0
  322. data/lib/pubid/iec/identifiers/working_document.rb +96 -0
  323. data/lib/pubid/iec/parser.rb +412 -0
  324. data/lib/pubid/iec/rendering_style.rb +113 -0
  325. data/lib/pubid/iec/scheme.rb +71 -0
  326. data/lib/pubid/iec/single_identifier.rb +80 -0
  327. data/lib/pubid/iec/supplement_identifier.rb +161 -0
  328. data/lib/pubid/iec/urn_generator.rb +193 -0
  329. data/lib/pubid/iec/urn_parser.rb +289 -0
  330. data/lib/pubid/iec.rb +85 -0
  331. data/lib/pubid/ieee/aiee/builder.rb +71 -0
  332. data/lib/pubid/ieee/aiee/identifier.rb +105 -0
  333. data/lib/pubid/ieee/aiee/parser.rb +130 -0
  334. data/lib/pubid/ieee/aiee.rb +11 -0
  335. data/lib/pubid/ieee/builder.rb +1237 -0
  336. data/lib/pubid/ieee/components/code.rb +102 -0
  337. data/lib/pubid/ieee/components/draft.rb +93 -0
  338. data/lib/pubid/ieee/components/relationship.rb +157 -0
  339. data/lib/pubid/ieee/components/typed_stage.rb +100 -0
  340. data/lib/pubid/ieee/identifier.rb +13 -0
  341. data/lib/pubid/ieee/identifiers/adopted_standard.rb +33 -0
  342. data/lib/pubid/ieee/identifiers/base.rb +591 -0
  343. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +35 -0
  344. data/lib/pubid/ieee/identifiers/corrigendum.rb +37 -0
  345. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +51 -0
  346. data/lib/pubid/ieee/identifiers/dual_identifier.rb +18 -0
  347. data/lib/pubid/ieee/identifiers/dual_published.rb +28 -0
  348. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +27 -0
  349. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +34 -0
  350. data/lib/pubid/ieee/identifiers/joint_development.rb +172 -0
  351. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +51 -0
  352. data/lib/pubid/ieee/identifiers/nesc/base.rb +56 -0
  353. data/lib/pubid/ieee/identifiers/nesc/draft.rb +28 -0
  354. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +32 -0
  355. data/lib/pubid/ieee/identifiers/nesc/redline.rb +26 -0
  356. data/lib/pubid/ieee/identifiers/nesc/standard.rb +26 -0
  357. data/lib/pubid/ieee/identifiers/nesc.rb +15 -0
  358. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +20 -0
  359. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +26 -0
  360. data/lib/pubid/ieee/identifiers/redlined_standard.rb +33 -0
  361. data/lib/pubid/ieee/identifiers/si_standard.rb +73 -0
  362. data/lib/pubid/ieee/identifiers/standard.rb +41 -0
  363. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +23 -0
  364. data/lib/pubid/ieee/identifiers.rb +33 -0
  365. data/lib/pubid/ieee/ire/builder.rb +61 -0
  366. data/lib/pubid/ieee/ire/identifier.rb +58 -0
  367. data/lib/pubid/ieee/ire/parser.rb +91 -0
  368. data/lib/pubid/ieee/ire.rb +11 -0
  369. data/lib/pubid/ieee/nesc/builder.rb +101 -0
  370. data/lib/pubid/ieee/nesc/parser.rb +154 -0
  371. data/lib/pubid/ieee/nesc.rb +10 -0
  372. data/lib/pubid/ieee/parser.rb +1226 -0
  373. data/lib/pubid/ieee/scheme.rb +90 -0
  374. data/lib/pubid/ieee/typed_stages.rb +172 -0
  375. data/lib/pubid/ieee/urn_generator.rb +188 -0
  376. data/lib/pubid/ieee.rb +32 -0
  377. data/lib/pubid/ieee_debug.rb +31 -0
  378. data/lib/pubid/iho/builder.rb +37 -0
  379. data/lib/pubid/iho/identifier.rb +19 -0
  380. data/lib/pubid/iho/identifiers/base.rb +41 -0
  381. data/lib/pubid/iho/identifiers/bibliographic.rb +20 -0
  382. data/lib/pubid/iho/identifiers/circular_letter.rb +19 -0
  383. data/lib/pubid/iho/identifiers/miscellaneous.rb +20 -0
  384. data/lib/pubid/iho/identifiers/publication.rb +19 -0
  385. data/lib/pubid/iho/identifiers/standard.rb +19 -0
  386. data/lib/pubid/iho/identifiers.rb +14 -0
  387. data/lib/pubid/iho/parser.rb +68 -0
  388. data/lib/pubid/iho/scheme.rb +29 -0
  389. data/lib/pubid/iho/urn_generator.rb +29 -0
  390. data/lib/pubid/iho.rb +21 -0
  391. data/lib/pubid/iso/builder.rb +305 -0
  392. data/lib/pubid/iso/bundled_identifier.rb +85 -0
  393. data/lib/pubid/iso/combined_identifier.rb +22 -0
  394. data/lib/pubid/iso/components/code.rb +36 -0
  395. data/lib/pubid/iso/components/publisher.rb +60 -0
  396. data/lib/pubid/iso/components.rb +12 -0
  397. data/lib/pubid/iso/format_resolver.rb +45 -0
  398. data/lib/pubid/iso/identifier.rb +69 -0
  399. data/lib/pubid/iso/identifiers/addendum.rb +104 -0
  400. data/lib/pubid/iso/identifiers/amendment.rb +128 -0
  401. data/lib/pubid/iso/identifiers/base.rb +115 -0
  402. data/lib/pubid/iso/identifiers/corrigendum.rb +108 -0
  403. data/lib/pubid/iso/identifiers/data.rb +76 -0
  404. data/lib/pubid/iso/identifiers/directives.rb +59 -0
  405. data/lib/pubid/iso/identifiers/directives_supplement.rb +119 -0
  406. data/lib/pubid/iso/identifiers/extract.rb +30 -0
  407. data/lib/pubid/iso/identifiers/guide.rb +100 -0
  408. data/lib/pubid/iso/identifiers/international_standard.rb +168 -0
  409. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +94 -0
  410. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +89 -0
  411. data/lib/pubid/iso/identifiers/pas.rb +93 -0
  412. data/lib/pubid/iso/identifiers/recommendation.rb +45 -0
  413. data/lib/pubid/iso/identifiers/supplement.rb +87 -0
  414. data/lib/pubid/iso/identifiers/tc_document.rb +108 -0
  415. data/lib/pubid/iso/identifiers/technical_report.rb +103 -0
  416. data/lib/pubid/iso/identifiers/technical_specification.rb +102 -0
  417. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +95 -0
  418. data/lib/pubid/iso/identifiers.rb +33 -0
  419. data/lib/pubid/iso/parser.rb +510 -0
  420. data/lib/pubid/iso/rendering_style.rb +120 -0
  421. data/lib/pubid/iso/scheme.rb +187 -0
  422. data/lib/pubid/iso/single_identifier.rb +61 -0
  423. data/lib/pubid/iso/supplement_identifier.rb +27 -0
  424. data/lib/pubid/iso/urn_generator.rb +412 -0
  425. data/lib/pubid/iso/urn_parser.rb +423 -0
  426. data/lib/pubid/iso/utilities.rb +86 -0
  427. data/lib/pubid/iso.rb +50 -0
  428. data/lib/pubid/itu/builder.rb +171 -0
  429. data/lib/pubid/itu/components/code.rb +39 -0
  430. data/lib/pubid/itu/components/sector.rb +35 -0
  431. data/lib/pubid/itu/components/series.rb +29 -0
  432. data/lib/pubid/itu/i18n.rb +9 -0
  433. data/lib/pubid/itu/i18n.yaml +30 -0
  434. data/lib/pubid/itu/identifier.rb +53 -0
  435. data/lib/pubid/itu/identifiers/amendment.rb +43 -0
  436. data/lib/pubid/itu/identifiers/annex.rb +74 -0
  437. data/lib/pubid/itu/identifiers/base.rb +154 -0
  438. data/lib/pubid/itu/identifiers/combined_identifier.rb +47 -0
  439. data/lib/pubid/itu/identifiers/corrigendum.rb +44 -0
  440. data/lib/pubid/itu/identifiers/recommendation.rb +16 -0
  441. data/lib/pubid/itu/identifiers/special_publication.rb +31 -0
  442. data/lib/pubid/itu/identifiers/supplement.rb +46 -0
  443. data/lib/pubid/itu/identifiers.rb +16 -0
  444. data/lib/pubid/itu/model.rb +111 -0
  445. data/lib/pubid/itu/parser.rb +225 -0
  446. data/lib/pubid/itu/scheme.rb +174 -0
  447. data/lib/pubid/itu/urn_generator.rb +105 -0
  448. data/lib/pubid/itu.rb +22 -0
  449. data/lib/pubid/jcgm/builder.rb +88 -0
  450. data/lib/pubid/jcgm/components/publisher.rb +20 -0
  451. data/lib/pubid/jcgm/components.rb +9 -0
  452. data/lib/pubid/jcgm/identifier.rb +11 -0
  453. data/lib/pubid/jcgm/identifiers/amendment.rb +35 -0
  454. data/lib/pubid/jcgm/identifiers/guide.rb +21 -0
  455. data/lib/pubid/jcgm/identifiers/gum_guide.rb +51 -0
  456. data/lib/pubid/jcgm/identifiers.rb +11 -0
  457. data/lib/pubid/jcgm/parser.rb +84 -0
  458. data/lib/pubid/jcgm/scheme.rb +60 -0
  459. data/lib/pubid/jcgm/single_identifier.rb +48 -0
  460. data/lib/pubid/jcgm/supplement_identifier.rb +16 -0
  461. data/lib/pubid/jcgm/urn_generator.rb +110 -0
  462. data/lib/pubid/jcgm.rb +31 -0
  463. data/lib/pubid/jis/builder.rb +124 -0
  464. data/lib/pubid/jis/components/code.rb +59 -0
  465. data/lib/pubid/jis/components.rb +9 -0
  466. data/lib/pubid/jis/identifier.rb +18 -0
  467. data/lib/pubid/jis/identifiers/amendment.rb +16 -0
  468. data/lib/pubid/jis/identifiers/base.rb +72 -0
  469. data/lib/pubid/jis/identifiers/explanation.rb +22 -0
  470. data/lib/pubid/jis/identifiers/japanese_industrial_standard.rb +16 -0
  471. data/lib/pubid/jis/identifiers/standard.rb +27 -0
  472. data/lib/pubid/jis/identifiers/technical_report.rb +31 -0
  473. data/lib/pubid/jis/identifiers/technical_specification.rb +31 -0
  474. data/lib/pubid/jis/identifiers.rb +17 -0
  475. data/lib/pubid/jis/parser.rb +109 -0
  476. data/lib/pubid/jis/scheme.rb +49 -0
  477. data/lib/pubid/jis/single_identifier.rb +37 -0
  478. data/lib/pubid/jis/supplement_identifier.rb +47 -0
  479. data/lib/pubid/jis/urn_generator.rb +25 -0
  480. data/lib/pubid/jis.rb +23 -0
  481. data/lib/pubid/lutaml/no_store_registration.rb +30 -0
  482. data/lib/pubid/nist/builder.rb +2100 -0
  483. data/lib/pubid/nist/components/code.rb +38 -0
  484. data/lib/pubid/nist/components/edition.rb +118 -0
  485. data/lib/pubid/nist/components/issue_number.rb +28 -0
  486. data/lib/pubid/nist/components/part.rb +77 -0
  487. data/lib/pubid/nist/components/publisher.rb +24 -0
  488. data/lib/pubid/nist/components/stage.rb +53 -0
  489. data/lib/pubid/nist/components/supplement.rb +121 -0
  490. data/lib/pubid/nist/components/translation.rb +42 -0
  491. data/lib/pubid/nist/components/update.rb +103 -0
  492. data/lib/pubid/nist/components/version.rb +35 -0
  493. data/lib/pubid/nist/components/volume.rb +32 -0
  494. data/lib/pubid/nist/components.rb +19 -0
  495. data/lib/pubid/nist/configuration.rb +77 -0
  496. data/lib/pubid/nist/identifiers/base.rb +499 -0
  497. data/lib/pubid/nist/identifiers/circular.rb +68 -0
  498. data/lib/pubid/nist/identifiers/circular_supplement.rb +50 -0
  499. data/lib/pubid/nist/identifiers/commercial_standard.rb +41 -0
  500. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +56 -0
  501. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +56 -0
  502. data/lib/pubid/nist/identifiers/crpl_report.rb +135 -0
  503. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +94 -0
  504. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +35 -0
  505. data/lib/pubid/nist/identifiers/handbook.rb +50 -0
  506. data/lib/pubid/nist/identifiers/internal_report.rb +56 -0
  507. data/lib/pubid/nist/identifiers/letter_circular.rb +45 -0
  508. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +65 -0
  509. data/lib/pubid/nist/identifiers/monograph.rb +69 -0
  510. data/lib/pubid/nist/identifiers/ncstar.rb +41 -0
  511. data/lib/pubid/nist/identifiers/nsrds.rb +41 -0
  512. data/lib/pubid/nist/identifiers/owmwp.rb +35 -0
  513. data/lib/pubid/nist/identifiers/report.rb +68 -0
  514. data/lib/pubid/nist/identifiers/special_publication.rb +36 -0
  515. data/lib/pubid/nist/identifiers/technical_note.rb +90 -0
  516. data/lib/pubid/nist/identifiers.rb +33 -0
  517. data/lib/pubid/nist/parser.rb +1084 -0
  518. data/lib/pubid/nist/scheme.rb +199 -0
  519. data/lib/pubid/nist/supplement_identifier.rb +83 -0
  520. data/lib/pubid/nist/urn_generator.rb +127 -0
  521. data/lib/pubid/nist.rb +36 -0
  522. data/lib/pubid/oiml/builder.rb +189 -0
  523. data/lib/pubid/oiml/components/code.rb +20 -0
  524. data/lib/pubid/oiml/components.rb +9 -0
  525. data/lib/pubid/oiml/identifier.rb +11 -0
  526. data/lib/pubid/oiml/identifiers/amendment.rb +13 -0
  527. data/lib/pubid/oiml/identifiers/annex.rb +62 -0
  528. data/lib/pubid/oiml/identifiers/base.rb +36 -0
  529. data/lib/pubid/oiml/identifiers/basic_publication.rb +13 -0
  530. data/lib/pubid/oiml/identifiers/document.rb +13 -0
  531. data/lib/pubid/oiml/identifiers/expert_report.rb +13 -0
  532. data/lib/pubid/oiml/identifiers/guide.rb +13 -0
  533. data/lib/pubid/oiml/identifiers/recommendation.rb +13 -0
  534. data/lib/pubid/oiml/identifiers/seminar_report.rb +13 -0
  535. data/lib/pubid/oiml/identifiers/vocabulary.rb +13 -0
  536. data/lib/pubid/oiml/identifiers.rb +18 -0
  537. data/lib/pubid/oiml/parser.rb +173 -0
  538. data/lib/pubid/oiml/scheme.rb +46 -0
  539. data/lib/pubid/oiml/single_identifier.rb +90 -0
  540. data/lib/pubid/oiml/supplement_identifier.rb +43 -0
  541. data/lib/pubid/oiml/urn_generator.rb +64 -0
  542. data/lib/pubid/oiml.rb +26 -0
  543. data/lib/pubid/parser/common_parse_methods.rb +13 -0
  544. data/lib/pubid/parser/common_parse_rules.rb +56 -0
  545. data/lib/pubid/parser.rb +8 -0
  546. data/lib/pubid/parsers/base.rb +11 -0
  547. data/lib/pubid/parsers/mr_string.rb +93 -0
  548. data/lib/pubid/plateau/builder.rb +50 -0
  549. data/lib/pubid/plateau/identifiers/annex.rb +16 -0
  550. data/lib/pubid/plateau/identifiers/base.rb +51 -0
  551. data/lib/pubid/plateau/identifiers/handbook.rb +34 -0
  552. data/lib/pubid/plateau/identifiers/technical_report.rb +20 -0
  553. data/lib/pubid/plateau/identifiers.rb +12 -0
  554. data/lib/pubid/plateau/parser.rb +63 -0
  555. data/lib/pubid/plateau/scheme.rb +45 -0
  556. data/lib/pubid/plateau/supplement_identifier.rb +72 -0
  557. data/lib/pubid/plateau/urn_generator.rb +29 -0
  558. data/lib/pubid/plateau.rb +25 -0
  559. data/lib/pubid/renderers/base.rb +19 -0
  560. data/lib/pubid/renderers/directives_renderer.rb +62 -0
  561. data/lib/pubid/renderers/guide_renderer.rb +20 -0
  562. data/lib/pubid/renderers/human_readable.rb +58 -0
  563. data/lib/pubid/renderers/iwa_renderer.rb +16 -0
  564. data/lib/pubid/renderers/mr_string.rb +16 -0
  565. data/lib/pubid/renderers/supplement_renderer.rb +33 -0
  566. data/lib/pubid/renderers/urn.rb +11 -0
  567. data/lib/pubid/renderers.rb +14 -0
  568. data/lib/pubid/rendering/base.rb +73 -0
  569. data/lib/pubid/rendering/common.rb +211 -0
  570. data/lib/pubid/rendering/context.rb +156 -0
  571. data/lib/pubid/rendering/date.rb +27 -0
  572. data/lib/pubid/rendering/format.rb +25 -0
  573. data/lib/pubid/rendering/language.rb +21 -0
  574. data/lib/pubid/rendering/numbering.rb +24 -0
  575. data/lib/pubid/rendering/publisher.rb +25 -0
  576. data/lib/pubid/rendering/stage.rb +38 -0
  577. data/lib/pubid/rendering/supplement.rb +46 -0
  578. data/lib/pubid/rendering.rb +16 -0
  579. data/lib/pubid/sae/builder.rb +32 -0
  580. data/lib/pubid/sae/components/code.rb +9 -0
  581. data/lib/pubid/sae/components/date.rb +19 -0
  582. data/lib/pubid/sae/components/type.rb +19 -0
  583. data/lib/pubid/sae/components.rb +11 -0
  584. data/lib/pubid/sae/identifier.rb +14 -0
  585. data/lib/pubid/sae/identifiers/base.rb +42 -0
  586. data/lib/pubid/sae/identifiers.rb +9 -0
  587. data/lib/pubid/sae/parser.rb +55 -0
  588. data/lib/pubid/sae/scheme.rb +47 -0
  589. data/lib/pubid/sae/urn_generator.rb +38 -0
  590. data/lib/pubid/sae.rb +19 -0
  591. data/lib/pubid/scheme.rb +207 -0
  592. data/lib/pubid/urn_generator/base.rb +110 -0
  593. data/lib/pubid/utils/string_normalizer.rb +196 -0
  594. data/lib/pubid/utils.rb +7 -0
  595. data/lib/pubid/version.rb +3 -1
  596. data/lib/pubid.rb +137 -13
  597. data/lib/tasks/docs.rake +37 -0
  598. data/lib/tasks/export.rake +38 -0
  599. data/lib/tasks/website-data.json +7488 -0
  600. metadata +613 -171
  601. data/lib/pubid/registry.rb +0 -30
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ module Identifiers
6
+ # SeriesIdentifier represents CSA identifiers where SERIES
7
+ # is the primary document type, not just a keyword modifier
8
+ #
9
+ # Examples:
10
+ # CSA MH SERIES 3.14:20
11
+ # CSA RV SERIES 1:19
12
+ # CSA SERIES Z1000:22
13
+ #
14
+ # Difference from Standard with series_keyword:
15
+ # - Series: SERIES is the document type (primary)
16
+ # - Standard: SERIES is a modifier keyword (secondary)
17
+ class Series < Base
18
+ # Series prefix (MH, RV, etc.) - optional
19
+ attribute :series_prefix, :string
20
+
21
+ def to_s
22
+ result = publisher_prefix_portion
23
+
24
+ # Add code FIRST (before SERIES keyword)
25
+ result += code.to_s
26
+
27
+ # Add space before series prefix/SERIES keyword
28
+ result += " "
29
+
30
+ # Add series prefix if present
31
+ result += "#{series_prefix} " if series_prefix && !series_prefix.empty?
32
+
33
+ # Add SERIES keyword
34
+ result += "SERIES"
35
+
36
+ # Add year
37
+ result += year_portion
38
+
39
+ # Add language
40
+ result += language_portion
41
+
42
+ # Add reaffirmation
43
+ result += reaffirmation_portion
44
+
45
+ result
46
+ end
47
+
48
+ private
49
+
50
+ def publisher_prefix_portion
51
+ prefix = publisher_prefix || "CSA"
52
+
53
+ # Handle code_only identifiers (empty string means no prefix)
54
+ return "" if prefix == ""
55
+
56
+ # Determine if we need space after prefix
57
+ # CAN/CSA- and CAN3- end with dash, so no space needed
58
+ needs_space = !prefix.end_with?("-")
59
+
60
+ needs_space ? "#{prefix} " : prefix
61
+ end
62
+
63
+ def year_portion
64
+ return "" unless year
65
+
66
+ # Use dash if year_format is dash, otherwise colon
67
+ separator = year_format == "dash" ? "-" : ":"
68
+ year_part = separator
69
+ year_part += year_prefix if year_prefix # Add M or F prefix
70
+ year_part += "F" if french && year_format != "dash" && !year_prefix # Only add F if no prefix
71
+
72
+ # Convert 4-digit year back to 2-digit
73
+ year_str = year.to_s
74
+ year_part += if year_str.length == 4 && year_str.start_with?("20")
75
+ year_str[2..3]
76
+ else
77
+ year_str
78
+ end
79
+
80
+ year_part
81
+ end
82
+
83
+ def language_portion
84
+ "" # CSA doesn't use language codes in rendering
85
+ end
86
+
87
+ def reaffirmation_portion
88
+ return "" unless reaffirmation
89
+
90
+ # Check if year was originally 2-digit (original_year_4digit flag)
91
+ year_was_2digit = !original_year_4digit
92
+
93
+ # Check if reaffirmation was originally 4-digit (original_reaffirmation_4digit flag)
94
+ reaffirmation_was_4digit = original_reaffirmation_4digit
95
+
96
+ # Preserve original reaffirmation format
97
+ # If original was 4-digit, keep as 4-digit
98
+ # If original was 2-digit, convert from 4-digit storage back to 2-digit
99
+ reaffirmation_str = if reaffirmation_was_4digit
100
+ # Original was 4-digit, keep as-is
101
+ reaffirmation.to_s
102
+ elsif reaffirmation.to_s.length == 4 && reaffirmation.to_s.start_with?(
103
+ "19", "20"
104
+ )
105
+ # Original was 2-digit, convert 4-digit storage back to 2-digit
106
+ # (R2004) → (R04), (R1994) → (R94)
107
+ reaffirmation.to_s[2..3]
108
+ else
109
+ # Already 2-digit or other format
110
+ reaffirmation.to_s
111
+ end
112
+
113
+ # Determine spacing based on original formats
114
+ # Space needed if year is 2-digit and reaffirmation is 4-digit (original format)
115
+ # No space if both year and reaffirmation are 2-digit, or both are 4-digit
116
+ if year_was_2digit && reaffirmation_was_4digit
117
+ # Year was 2-digit, reaffirmation was 4-digit → add space
118
+ " (R#{reaffirmation_str})"
119
+ else
120
+ # Both 2-digit, both 4-digit, or other cases → no space
121
+ "(R#{reaffirmation_str})"
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ module Identifiers
6
+ class Standard < Base
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ module Identifiers
6
+ autoload :Base, "#{__dir__}/identifiers/base"
7
+ autoload :Bundled, "#{__dir__}/identifiers/bundled"
8
+ autoload :CanadianAdopted, "#{__dir__}/identifiers/canadian_adopted"
9
+ autoload :Cec, "#{__dir__}/identifiers/cec"
10
+ autoload :Combined, "#{__dir__}/identifiers/combined"
11
+ autoload :CsaAdopted, "#{__dir__}/identifiers/csa_adopted"
12
+ autoload :Package, "#{__dir__}/identifiers/package"
13
+ autoload :Series, "#{__dir__}/identifiers/series"
14
+ autoload :Standard, "#{__dir__}/identifiers/standard"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,445 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Csa
7
+ class Parser < Parslet::Parser
8
+ # Basic building blocks
9
+ rule(:space) { str(" ") }
10
+ rule(:dash) { str("-") }
11
+ rule(:slash) { str("/") }
12
+ rule(:colon) { str(":") }
13
+ rule(:comma) { str(",") }
14
+ rule(:dot) { str(".") }
15
+ rule(:ampersand) { str("&") }
16
+ rule(:plus) { str(" + ") }
17
+ rule(:digit) { match("[0-9]") }
18
+ rule(:digits) { digit.repeat(1) }
19
+ rule(:letter) { match("[A-Z]") }
20
+ rule(:letters) { letter.repeat(1) }
21
+
22
+ # Publisher
23
+ rule(:publisher) do
24
+ str("CSA") >> space >> (str("").as(:has_publisher) | str("0").as(:has_publisher))
25
+ end
26
+
27
+ # Code pattern: letter + dotted numbers (e.g., B149.1, C22.2, A123.17)
28
+ # Can also have dash-number-letter suffix (e.g., for NO. numbers like 60950-1A)
29
+ # Can have letter suffixes like HB, CIICHB, SP at the end
30
+ # Can have multiple dash-number sequences (e.g., C13256-1-01)
31
+ # NEW: Also support pure numbers with HB suffix (e.g., 15189HB)
32
+ # NEW: Simple letter+number codes (e.g., Z240, A220) for Series identifiers
33
+ rule(:code_pattern) do
34
+ # Pattern 1: Pure dotted numbers - e.g., 12.4, 2.15, 3.11
35
+ (match("[0-9]").repeat(1) >> dot >> match("[0-9]").repeat(1) >>
36
+ # Allow single-dash suffix for part numbers (e.g., "12.4-1")
37
+ # But NOT 2-digit years which are handled separately
38
+ (dash >> match("[0-9]").repeat(1)).repeat(0, 1) >>
39
+ letter.repeat(2, 6).maybe).as(:code) |
40
+ # Pattern 2: Pure numbers with HB suffix - e.g., 15189HB (NEW)
41
+ (match("[0-9]").repeat(1) >> letter.repeat(2, 6)).as(:code) |
42
+ # Pattern 3: Letter + numbers with dots then dashes - e.g., C22.2-144, B149.1
43
+ (letter >> match("[0-9]").repeat(1) >>
44
+ (dot >> match("[0-9]").repeat(1)).repeat >> # Dot sections first
45
+ # Dash sections after - allow part numbers but not 2-digit years
46
+ # Single digit dash = part number (e.g., "-1", "-2")
47
+ # 3+ digits or letter suffix = part number (e.g., "-144", "-1A")
48
+ # But DON'T consume 2-digit years which are matched separately
49
+ (dash >> (
50
+ (match("[0-9]") >> match("[0-9]").absent?) | # exactly 1 digit (no digit follows)
51
+ match("[0-9]").repeat(3) | # 3+ digits = part number (e.g., "-144")
52
+ (match("[0-9]").repeat(1) >> letter.repeat(1)) # digit + letter = part number (e.g., "-1A")
53
+ )).repeat >>
54
+ letter.repeat(2, 6).maybe).as(:code) | # Allow HB, CIICHB, SP, etc.
55
+ # Pattern 4: Simple letter + number codes - e.g., Z240, A220, B140 (for Series)
56
+ (letter >> match("[0-9]").repeat(1) >> dot >> match("[0-9]").repeat(1).maybe).as(:code) |
57
+ # Pattern 5: Letter + multi-digit number without dots/dashes - e.g., Z240, A220
58
+ (letter >> match("[0-9]").repeat(2)).as(:code)
59
+ end
60
+
61
+ # NO. notation - "Number" designation within a series (e.g., C22.2 NO. 1)
62
+ rule(:no_notation) do
63
+ space >> (str("NO.") | str("No.")).as(:no_notation) >> space
64
+ end
65
+
66
+ # Number after NO. - can be complex (e.g., 60601-1-9, 144.1, 1010.2.031, 1, 60601-1)
67
+ # Note: Single-dash patterns allowed only when first part has 3+ digits
68
+ # to avoid consuming year patterns like "1-04" where "-04" is the year
69
+ rule(:no_number) do
70
+ (
71
+ # Multi-part with dashes (e.g., 60601-1-9, 1-9-2)
72
+ # Requires at least 2 dashes (3+ numeric parts) to distinguish from year patterns
73
+ (match("[0-9]").repeat(1) >>
74
+ (dash >> match("[0-9]").repeat(1)).repeat(2, 10)) |
75
+ # Single-dash pattern (e.g., 60601-1, 60079-11) - allowed if first part has 3+ digits
76
+ # This prevents consuming year patterns like "1-04"
77
+ # CRITICAL: 2-digit suffix allowed only when first part has 5+ digits
78
+ # (IEC-style numbers like 60601, 60079). 3-4 digit first parts with 2-digit
79
+ # suffixes are year patterns (e.g., "109-17" = number 109, year 2017).
80
+ (match("[0-9]").repeat(5) >> dash >> match("[0-9]").repeat(1)) | # 5+ digits: any suffix
81
+ (match("[0-9]").repeat(3, 4) >> dash >> (
82
+ (match("[0-9]") >> match("[0-9]").absent?) | # exactly 1 digit (e.g., -1)
83
+ match("[0-9]").repeat(3) # 3+ digits (e.g., -144)
84
+ )) |
85
+ # Multi-part dotted number (e.g., 144.1, 1010.2.031, 1010.2.031.5)
86
+ # Can have 1-3 dots (2-4 numeric parts)
87
+ (match("[0-9]").repeat(1) >>
88
+ (dot >> match("[0-9]").repeat(1)).repeat(1, 3)) |
89
+ # Simple number (e.g., 1, 286)
90
+ match("[0-9]").repeat(1)
91
+ ).as(:no_number)
92
+ end
93
+
94
+ # Year format with optional F or M prefix
95
+ rule(:year_prefix) { (str("F") | str("M")).as(:year_prefix).maybe }
96
+ rule(:year_2digit) { digit.repeat(2, 2) }
97
+ rule(:year_4digit) { digit.repeat(4, 4) }
98
+
99
+ # Year with colon (modern format) - mark as colon_year
100
+ # Support both with prefix (:M04) and without prefix (:04)
101
+ rule(:colon_year) do
102
+ str("").as(:colon_format) >> # Mark that colon format was used
103
+ colon >> (
104
+ # With M/F prefix (e.g., :M04, :F04)
105
+ (year_prefix >> (year_4digit | year_2digit).as(:year)) |
106
+ # Without prefix (e.g., :04)
107
+ (year_4digit | year_2digit).as(:year)
108
+ )
109
+ end
110
+
111
+ # Year with dash (older format) - mark as dash_year
112
+ # Support both with prefix (-M04) and without prefix (-04)
113
+ rule(:dash_year) do
114
+ str("").as(:dash_format) >> # Mark that dash format was used
115
+ dash >> (
116
+ # With M/F prefix (e.g., -M04, -F04)
117
+ (year_prefix >> (year_4digit | year_2digit).as(:year)) |
118
+ # Without prefix (e.g., -04)
119
+ (year_4digit | year_2digit).as(:year)
120
+ )
121
+ end
122
+
123
+ # Reaffirmation notation - supports both 2-digit and 4-digit years
124
+ # Tracks original format via :reaffirmation_4digit flag
125
+ rule(:reaffirmation) do
126
+ space >> str("(R") >>
127
+ (year_4digit.as(:reaffirmation_4digit) | year_2digit.as(:reaffirmation_2digit)) >>
128
+ str(")")
129
+ end
130
+
131
+ # Amendment notation (e.g., /A1:15, /A2:22, /Amd 1)
132
+ rule(:amendment_slash) do
133
+ slash >>
134
+ (str("Amd") >> space).maybe >>
135
+ str("A").maybe >>
136
+ digits.as(:amendment_number) >>
137
+ (colon >> year_2digit.as(:amendment_year)).maybe
138
+ end
139
+
140
+ # Package keywords
141
+ rule(:package_keyword) do
142
+ str("Code") | str("Handbook") | str("Training Package") | str("Package")
143
+ end
144
+
145
+ # Package portion: "Code, Handbook & Training Package"
146
+ rule(:package_portion) do
147
+ space >>
148
+ package_keyword >>
149
+ (
150
+ (comma >> space >> package_keyword) |
151
+ (space >> ampersand >> space >> package_keyword)
152
+ ).repeat
153
+ end
154
+
155
+ # Series prefix: 2-3 letters before SERIES keyword (e.g., MH, RV)
156
+ rule(:series_prefix) do
157
+ letter.repeat(2, 3).as(:series_prefix)
158
+ end
159
+
160
+ # SERIES keyword - just the word, don't consume the delimiter
161
+ rule(:series_keyword) do
162
+ str("SERIES")
163
+ end
164
+
165
+ # Series identifier - SERIES as PRIMARY type (not modifier)
166
+ # Pattern: CSA code [PREFIX] SERIES:year
167
+ # Examples: CSA Z240 MH SERIES:16, CSA Z240 RV SERIES:23, CSA Z245.20 SERIES:22
168
+ rule(:series_identifier) do
169
+ publisher >>
170
+ # Code comes first (can be letter+number or dotted numbers)
171
+ (
172
+ code_pattern |
173
+ # Letter + multi-digit number for Series (e.g., Z240, A220, B139)
174
+ (letter >> match("[0-9]").repeat(2)).as(:code) |
175
+ # Dotted numeric code (e.g., 245.20)
176
+ (match("[0-9]").repeat(1) >> dot >> match("[0-9]").repeat(1)).as(:code)
177
+ ) >>
178
+ space >>
179
+ # Optional series prefix (MH, RV, etc.) before SERIES keyword
180
+ (series_prefix >> space).maybe >>
181
+ series_keyword.as(:series_type) >>
182
+ (colon_year | dash_year) >>
183
+ reaffirmation.maybe
184
+ end
185
+
186
+ # CEC (Canadian Electrical Code) identifier
187
+ # Pattern: CSA C22.{2,3,4,6} NO. {number}:{year}
188
+ # Examples: CSA C22.2 NO. 286:23, CSA C22.3 NO. 7:20
189
+ # The "NO." notation is a semantic component and must be preserved
190
+ rule(:cec_identifier) do
191
+ publisher >>
192
+ (
193
+ str("C22.2") | str("C22.3") | str("C22.4") | str("C22.6")
194
+ ).as(:cec_part) >>
195
+ no_notation >>
196
+ no_number >>
197
+ (colon_year | dash_year) >>
198
+ reaffirmation.maybe
199
+ end
200
+
201
+ # ISO/IEC/CISPR/CEI adopted standards pattern
202
+ # Examples:
203
+ # CSA ISO/IEC 9594-2:21
204
+ # CSA ISO/IEC TR 12785-3:15
205
+ # CSA CISPR 16-1-1:18
206
+ # CAN/CSA-ISO 10819:16
207
+ # CAN/CSA-IEC 62443-2-4:17
208
+ # CAN/CSA-CEI/IEC 61000-4-28-01
209
+ rule(:adoption_identifier) do
210
+ publisher.as(:adoption_pub) >>
211
+ (
212
+ # Option 1: ISO/IEC with TR/TS
213
+ (str("ISO/IEC").as(:adoption_org) >> space >>
214
+ (str("TR") | str("TS")).as(:iso_type) >> space >>
215
+ match("[0-9-]").repeat(1).as(:adoption_number)) |
216
+ # Option 1a: ISO/IEC without TR/TS (must come after TR/TS option in priority)
217
+ (str("ISO/IEC").as(:adoption_org_with_type) >> space >>
218
+ match("[0-9-]").repeat(1).as(:adoption_number)) |
219
+ # Option 2: ISO alone
220
+ (str("ISO").as(:adoption_org) >> space >>
221
+ match("[0-9-]").repeat(1).as(:adoption_number)) |
222
+ # Option 3: IEC alone
223
+ (str("IEC").as(:adoption_org) >> space >>
224
+ match("[0-9-]").repeat(1).as(:adoption_number)) |
225
+ # Option 4: CEI/IEC (French name for IEC)
226
+ (str("CEI/IEC").as(:adoption_org) >> space >>
227
+ match("[0-9-]").repeat(1).as(:adoption_number)) |
228
+ # Option 5: CISPR
229
+ (str("CISPR").as(:adoption_org) >> space >>
230
+ match("[0-9-]").repeat(1).as(:adoption_number))
231
+ ) >>
232
+ (colon | dash).as(:adoption_year_sep) >>
233
+ (year_4digit | year_2digit).as(:adoption_year) >>
234
+ (
235
+ # Amendment with year: /A1:22 or /A1-22
236
+ slash >> str("A") >> digit.as(:adoption_amendment) >>
237
+ (colon | dash) >> (year_4digit | year_2digit).as(:adoption_amendment_year)
238
+ ).maybe >>
239
+ reaffirmation.maybe
240
+ end
241
+
242
+ # Legacy: ISO/IEC TR/TS only pattern (for backward compatibility)
243
+ rule(:iso_iec_adoption) do
244
+ adoption_identifier
245
+ end
246
+
247
+ # Basic CSA identifier
248
+ rule(:csa_code) do
249
+ publisher >>
250
+ code_pattern >>
251
+ (
252
+ # Option 1: NO. notation (e.g., C22.2 NO. 1:20)
253
+ (no_notation >> no_number >> (colon_year | dash_year)) |
254
+ # Option 2: series with prefix (space + prefix + space + keyword + year)
255
+ (space >> series_prefix >> space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
256
+ # Option 3: series without prefix (space + keyword + year)
257
+ (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
258
+ # Option 4: just year (no series, no NO.)
259
+ (colon_year | dash_year)
260
+ ) >>
261
+ amendment_slash.maybe # Add amendment support here
262
+ end
263
+
264
+ # Base CSA code without amendment (for combined identifiers)
265
+ rule(:base_csa_code) do
266
+ publisher >>
267
+ code_pattern >>
268
+ (
269
+ # Option 1: NO. notation
270
+ (no_notation >> no_number >> (colon_year | dash_year)) |
271
+ # Option 2: series with prefix
272
+ (space >> series_prefix >> space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
273
+ # Option 3: series without prefix
274
+ (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
275
+ # Option 4: just year
276
+ (colon_year | dash_year)
277
+ )
278
+ end
279
+
280
+ # Continuation code (optional CSA publisher prefix, for combined identifiers)
281
+ rule(:continuation_code) do
282
+ publisher.as(:has_publisher).maybe >>
283
+ code_pattern >>
284
+ (
285
+ # Option 1: NO. notation
286
+ (no_notation >> no_number >> (colon_year | dash_year)) |
287
+ # Option 2: series with prefix
288
+ (space >> series_prefix >> space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
289
+ # Option 3: series without prefix
290
+ (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
291
+ # Option 4: just year
292
+ (colon_year | dash_year)
293
+ ) >>
294
+ amendment_slash.maybe
295
+ end
296
+
297
+ # Bundled portion - code that follows + (base is implied, no CSA prefix)
298
+ # Example: "A2:22" in "CSA C22.2 NO. 60601-1:14 + A2:22"
299
+ rule(:bundled_portion) do
300
+ code_pattern >>
301
+ (
302
+ # Option 1: NO. notation
303
+ (no_notation >> no_number >> (colon_year | dash_year).maybe) |
304
+ # Option 2: just year or no year
305
+ (colon_year | dash_year).maybe
306
+ )
307
+ end
308
+
309
+ # Bundled identifier with + notation (consolidated documents)
310
+ rule(:bundled_identifier) do
311
+ csa_code.as(:base) >>
312
+ plus >>
313
+ bundled_portion.as(:bundled_first) >>
314
+ (plus >> bundled_portion).repeat.as(:bundled_rest) >>
315
+ reaffirmation.maybe
316
+ end
317
+
318
+ # Combined CSA standards with slash
319
+ rule(:combined_slash) do
320
+ base_csa_code.as(:first) >>
321
+ slash >>
322
+ continuation_code.as(:second) >>
323
+ (slash >> continuation_code.as(:third)).maybe >>
324
+ reaffirmation.maybe >>
325
+ package_portion.maybe
326
+ end
327
+
328
+ # Combined with comma (CSA B149.1:25, CSA B149.2:25)
329
+ rule(:combined_comma) do
330
+ csa_code.as(:first) >>
331
+ comma >> space >>
332
+ csa_code.as(:second) >>
333
+ reaffirmation.maybe >>
334
+ (
335
+ (space >> ampersand >> package_portion) |
336
+ package_portion
337
+ ).as(:package_portion).maybe >>
338
+ str("").as(:comma_separator) # Mark as comma-based
339
+ end
340
+
341
+ # Single identifier with optional package
342
+ rule(:single_identifier) do
343
+ csa_code >> reaffirmation.maybe >> package_portion.as(:package_portion).maybe
344
+ end
345
+
346
+ # Code-only identifier (no CSA prefix) - try this last
347
+ rule(:code_only_identifier) do
348
+ code_pattern >>
349
+ (
350
+ # Option 1: series with prefix
351
+ (space >> series_prefix >> space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
352
+ # Option 2: series without prefix
353
+ (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
354
+ # Option 3: just year
355
+ (colon_year | dash_year)
356
+ ) >>
357
+ (space >> str("PACKAGE")).as(:package_portion).maybe
358
+ end
359
+
360
+ # Main identifier
361
+ rule(:identifier) do
362
+ iso_iec_adoption | series_identifier | cec_identifier | bundled_identifier | combined_slash | combined_comma | single_identifier | code_only_identifier
363
+ end
364
+
365
+ root(:identifier)
366
+
367
+ # Preprocessing to normalize input
368
+ def parse(input)
369
+ # Skip comment lines
370
+ raise Parslet::ParseFailed.new("Comment line") if input.strip.start_with?("#")
371
+
372
+ # Remove CONSOLIDATED notation FIRST (before other processing)
373
+ normalized = input.gsub(/\s*\(\s*CONSOLIDATED\s*\)\s*/, " ")
374
+ normalized = normalized.gsub(/\s*\bCONSOLIDATED\b\s*/, " ")
375
+
376
+ # Fix missing space before reaffirmation
377
+ # Matches: XX(RYYYY), XXX(RYY), or any non-space chars before (R
378
+ # Examples: 04(R2009) -> 04 (R2009), 16(R24) -> 16 (R24)
379
+ normalized = normalized.gsub(/(\S)\(R(\d{2,4})\)/, '\1 (R\2)')
380
+
381
+ # DO NOT normalize NO., let it be parsed as a separate identifier component
382
+
383
+ # Normalize CEI/IEC to IEC (CEI is French name for IEC)
384
+ normalized = normalized.gsub("CEI/IEC", "IEC")
385
+ normalized = normalized.gsub(/\bCEI\b/, "IEC")
386
+
387
+ # Track original publisher prefix
388
+ publisher_prefix = if normalized.start_with?("CAN/CSA-")
389
+ "CAN/CSA-"
390
+ elsif normalized.start_with?("CAN3-")
391
+ "CAN3-"
392
+ elsif normalized.start_with?("CSA ")
393
+ "CSA"
394
+ end
395
+
396
+ # Normalize CAN/CSA- and CAN3- to CSA (preserving space before code)
397
+ normalized = normalized.gsub("CAN/CSA-", "CSA ")
398
+ normalized = normalized.gsub("CAN3-", "CSA ")
399
+
400
+ # Clean up extra spaces
401
+ normalized = normalized.gsub(/\s+/, " ").strip
402
+
403
+ # Parse and inject publisher_prefix into result
404
+ result = super(normalized)
405
+
406
+ # Inject publisher_prefix if we have one
407
+ if publisher_prefix && result.is_a?(Hash)
408
+ inject_publisher_prefix(result, publisher_prefix)
409
+ end
410
+
411
+ result
412
+ end
413
+
414
+ private
415
+
416
+ def inject_publisher_prefix(hash, prefix)
417
+ # For combined identifiers
418
+ if hash[:first]
419
+ hash[:first][:publisher_prefix] = prefix
420
+ end
421
+ # For combined_comma (has comma_separator), both first and second are full csa_code
422
+ # For combined_slash (no comma_separator), second is continuation that may have has_publisher
423
+ if hash[:second] && (hash[:comma_separator] || hash[:second][:has_publisher])
424
+ hash[:second][:publisher_prefix] = prefix
425
+ end
426
+ if hash[:third] && hash[:third][:has_publisher]
427
+ hash[:third][:publisher_prefix] =
428
+ prefix
429
+ end
430
+
431
+ # For bundled identifiers
432
+ if hash[:base]
433
+ inject_publisher_prefix(hash[:base], prefix)
434
+ end
435
+
436
+ # For single identifiers (no :first, no :base, just raw attributes)
437
+ if !hash[:first] && !hash[:base] && !hash[:bundled_first]
438
+ hash[:publisher_prefix] = prefix
439
+ end
440
+
441
+ hash
442
+ end
443
+ end
444
+ end
445
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ class Scheme < Pubid::Scheme
6
+ class << self
7
+ def identifiers
8
+ @identifiers ||= [
9
+ Identifiers::Standard,
10
+ Identifiers::Bundled,
11
+ Identifiers::CanadianAdopted,
12
+ Identifiers::CsaAdopted,
13
+ Identifiers::Package,
14
+ Identifiers::Series,
15
+ Identifiers::Cec,
16
+ Identifiers::Combined,
17
+ ].freeze
18
+ end
19
+
20
+ def supplement_identifiers
21
+ @supplement_identifiers ||= [].freeze
22
+ end
23
+
24
+ def typed_stages
25
+ @typed_stages ||= [].freeze
26
+ end
27
+
28
+ def supplement_typed_stages
29
+ @supplement_typed_stages ||= [].freeze
30
+ end
31
+
32
+ def locate_typed_stage_by_abbr(_abbr)
33
+ raise ArgumentError,
34
+ "CSA identifiers do not use typed stages"
35
+ end
36
+
37
+ def locate_identifier_klass_by_type_code(_type_code)
38
+ raise ArgumentError,
39
+ "CSA identifiers do not use type codes"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Csa
5
+ class SingleIdentifier < Pubid::Identifier
6
+ # Generate URN for this identifier
7
+ #
8
+ # @return [String] URN representation
9
+
10
+ attribute :code, Components::Code
11
+ attribute :no_number, :string
12
+ attribute :year, :string
13
+ attribute :year_format, :string # "colon" or "dash"
14
+ attribute :year_prefix, :string # "F" or "M"
15
+ attribute :original_year_4digit, :boolean, default: -> {
16
+ false
17
+ } # Track if original input was 4-digit (e.g., "M1981" vs "M83")
18
+ attribute :french, :boolean
19
+ attribute :reaffirmation, :string
20
+ attribute :original_reaffirmation_4digit, :boolean, default: -> {
21
+ false
22
+ } # Track if original reaffirmation was 4-digit (e.g., "R2004" vs "R04")
23
+ attribute :has_publisher, :boolean # Track if CSA prefix present
24
+ attribute :series_prefix, :string # MH, RV, etc.
25
+ attribute :series, :boolean # Track if SERIES keyword present
26
+ attribute :package, :string # Package portion (Code, Handbook, etc.)
27
+ attribute :publisher_prefix, :string # Original prefix: "CAN/CSA-", "CSA", "CAN3-"
28
+ end
29
+ end
30
+ end