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,41 @@
1
+ require "lutaml/model"
2
+ # frozen_string_literal: true
3
+
4
+ module Pubid
5
+ module Iec
6
+ module Components
7
+ # VAP (Validation Assessment Programme) suffix codes
8
+ # Single Responsibility: Represents VAP validation status suffixes
9
+ class VapSuffix < Lutaml::Model::Serializable
10
+ # VAP suffix codes as defined by IEC
11
+ CODES = {
12
+ "CMV" => "Common Modifications and Variations",
13
+ "RLV" => "Relevant",
14
+ "SER" => "Serial",
15
+ }.freeze
16
+
17
+ attribute :code, :string
18
+
19
+ def validate!
20
+ unless CODES.key?(code)
21
+ raise ArgumentError,
22
+ "Unknown VAP suffix code: #{code}. Valid codes: #{CODES.keys.join(', ')}"
23
+ end
24
+ end
25
+
26
+ def to_s
27
+ code
28
+ end
29
+
30
+ def full_name
31
+ CODES[code]
32
+ end
33
+
34
+ # VAP suffix appears after the main identifier with a space
35
+ def render_with_space
36
+ " #{code}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,256 @@
1
+ require_relative "../identifier"
2
+ # frozen_string_literal: true
3
+ require_relative "../components/typed_stage"
4
+ require_relative "../components/factory"
5
+
6
+ module Pubid
7
+ module Iec
8
+ class Identifier < ::Pubid::Identifier
9
+ # Long-tail document types that `create` may build but which are not in
10
+ # Scheme.identifiers (the parse/build candidate set). Loaded lazily (not
11
+ # at require time) to avoid a circular load with identifiers/base.rb.
12
+ EXTRA_CREATE_KLASS_FILES = %w[
13
+ conformity_assessment technology_report white_paper
14
+ societal_technology_trend_report systems_reference_document
15
+ interpretation_sheet
16
+ ].freeze
17
+ def self.parse(string)
18
+ # Route URN strings to the URN parser (mirrors Iso::Identifier.parse)
19
+ if Pubid::FormatDetector.detect(string) == :urn
20
+ return Pubid::Iec::UrnParser.parse(string)
21
+ end
22
+
23
+ # Apply legacy update_codes normalization first, before any other preprocessing
24
+ normalized = Core::UpdateCodes.apply(string, :iec)
25
+ parsed = Pubid::Iec::Parser.new.parse(normalized)
26
+ if parsed.nil? || parsed.empty?
27
+ raise Pubid::Iec::Parser::ParseError,
28
+ "Invalid identifier format"
29
+ end
30
+
31
+ Pubid::Iec::Builder.new(Pubid::Iec::Scheme).build(parsed)
32
+ end
33
+
34
+ # Factory mirroring pubid 1.x's `Pubid::Iec::Identifier.create` API.
35
+ # See {Pubid::Iso::Identifier.create} for the shared design. Builds the
36
+ # IEC `Components::*` subclasses (not the base ones) and populates
37
+ # type/stage from the resolved TypedStage, so that a created identifier
38
+ # round-trips `==` against the same identifier produced by `parse`.
39
+ def self.create(type: nil, stage: nil, **opts)
40
+ # A VAP suffix (CSV/RLV/…) is the outermost wrapper around the base
41
+ # document (which may itself be amended); rebuild it first.
42
+ if (vap = opts.delete(:vap))
43
+ base = create(type: type, stage: stage, **opts)
44
+ return Identifiers::VapIdentifier.new(
45
+ base_identifier: base,
46
+ vap_suffix: Components::VapSuffix.new(code: Array(vap).first.to_s),
47
+ )
48
+ end
49
+
50
+ # Structured index rows carry amendments/corrigendums as a flat list
51
+ # alongside the base document's keys; rebuild the supplement wrapping
52
+ # the recursively-created base, mirroring what parse produces.
53
+ if (supp = extract_supplement(opts))
54
+ return build_supplement(supp, type: type, stage: stage, opts: opts)
55
+ end
56
+
57
+ # A nested base: holds the base document of a supplement whose own
58
+ # number/year sit at the top level (e.g. an Interpretation Sheet).
59
+ if (base_hash = opts.delete(:base))
60
+ return build_based_supplement(type: type, base_hash: base_hash,
61
+ opts: opts)
62
+ end
63
+
64
+ klass = resolve_create_class(type: type, stage: stage)
65
+ attrs = coerce_create_attrs(opts)
66
+ ts = resolve_create_typed_stage(klass, stage)
67
+ if ts
68
+ attrs[:typed_stage] = ts
69
+ # Parse derives `type` and `stage` from the TypedStage (see
70
+ # Builder#cast for :type_with_stage); mirror that here.
71
+ attrs[:type] ||= ts.to_type
72
+ attrs[:stage] ||= ts.to_stage
73
+ end
74
+ klass.new(**attrs)
75
+ end
76
+
77
+ # Pop a supplement spec off the flat opts hash, if present. Returns
78
+ # { klass:, entry: } or nil. Amendments take precedence over
79
+ # corrigendums for the (rare) consolidated rows that carry both.
80
+ def self.extract_supplement(opts)
81
+ if (amds = opts.delete(:amendments))
82
+ { klass: Identifiers::Amendment, entry: Array(amds).first }
83
+ elsif (cors = opts.delete(:corrigendums))
84
+ { klass: Identifiers::Corrigendum, entry: Array(cors).first }
85
+ end
86
+ end
87
+
88
+ # Build an Amendment/Corrigendum from { number:, year: } wrapping a base
89
+ # identifier created from the remaining opts (which may themselves carry
90
+ # a type, e.g. an amendment to a TR).
91
+ def self.build_supplement(supp, type:, stage:, opts:)
92
+ base = create(type: type, stage: stage, **opts)
93
+ klass = supp[:klass]
94
+ entry = supp[:entry] || {}
95
+ ts = klass::TYPED_STAGES.find { |t| t.stage_code.to_sym == :published }
96
+ attrs = { base_identifier: base, typed_stage: ts,
97
+ type: ts.to_type, stage: ts.to_stage }
98
+ if (n = entry[:number])
99
+ attrs[:number] = Components::Code.new(number: n.to_s)
100
+ end
101
+ if (y = entry[:year])
102
+ attrs[:date] = ::Pubid::Components::Date.new(year: y.to_s)
103
+ end
104
+ klass.new(**attrs)
105
+ end
106
+
107
+ # Build a supplement whose base document is carried in a nested base:
108
+ # hash (e.g. type: "ISH"); the supplement's own number/year are the
109
+ # remaining top-level keys.
110
+ def self.build_based_supplement(type:, base_hash:, opts:)
111
+ klass = (type && locate_klass_by_type_or_short(type)) ||
112
+ Identifiers::InternationalStandard
113
+ base = create(**base_hash.transform_keys(&:to_sym))
114
+ attrs = coerce_create_attrs(opts)
115
+ .slice(:number, :part, :subpart, :date, :publisher, :copublishers)
116
+ attrs[:base_identifier] = base
117
+ if klass.const_defined?(:TYPED_STAGES) &&
118
+ (ts = klass::TYPED_STAGES.find { |t| t.stage_code.to_sym == :published })
119
+ attrs[:typed_stage] = ts
120
+ attrs[:type] ||= ts.to_type
121
+ attrs[:stage] ||= ts.to_stage
122
+ end
123
+ klass.new(**attrs)
124
+ end
125
+
126
+ # Coerce a 1.x-style attribute hash into IEC Component instances,
127
+ # matching what the parser/builder produces. Unknown keys are dropped.
128
+ def self.coerce_create_attrs(opts)
129
+ out = {}
130
+ if (v = opts[:publisher])
131
+ out[:publisher] = Components::Publisher.new(body: v.to_s)
132
+ end
133
+ if (copubs = opts[:copublishers] || opts[:copublisher])
134
+ out[:copublishers] =
135
+ Array(copubs).map { |c| Components::Publisher.new(body: c.to_s) }
136
+ end
137
+ if (v = opts[:number])
138
+ out[:number] = Components::Code.new(number: v.to_s)
139
+ end
140
+ # Indexes fold the subpart into a single "2-4" part string; parse
141
+ # keeps part and subpart separate, so split to match.
142
+ part, subpart = split_part(opts[:part], opts[:subpart])
143
+ out[:part] = Components::Code.new(number: part.to_s) unless part.nil?
144
+ out[:subpart] = Components::Code.new(number: subpart.to_s) unless subpart.nil?
145
+ if (v = opts[:year])
146
+ out[:date] = ::Pubid::Components::Date.new(year: v.to_s)
147
+ end
148
+ if (v = opts[:edition])
149
+ out[:edition] = ::Pubid::Components::Edition.new(number: v)
150
+ end
151
+ if (v = opts[:language])
152
+ out[:languages] = [::Pubid::Components::Language.new(code: v.to_s)]
153
+ end
154
+ out[:database] = true if opts[:database]
155
+ out
156
+ end
157
+
158
+ # Split a folded "2-4" part into [part, subpart], matching parse. A part
159
+ # without a dash (or an explicit subpart already supplied) is untouched.
160
+ def self.split_part(part, subpart)
161
+ return [nil, subpart] if part.nil?
162
+ if subpart.nil? && part.to_s.include?("-")
163
+ part.to_s.split("-", 2)
164
+ else
165
+ [part, subpart]
166
+ end
167
+ end
168
+
169
+ def self.resolve_create_class(type:, stage:)
170
+ if type && supplement_type?(type)
171
+ # Supplements are built from amendments:/corrigendums: data (which
172
+ # carry the supplement number/year); an explicit supplement `type:`
173
+ # alone has no base to wrap.
174
+ raise ArgumentError,
175
+ "#{type} requires a base_identifier; pass amendments:/" \
176
+ "corrigendums: instead of type:"
177
+ end
178
+
179
+ klass =
180
+ if type
181
+ locate_klass_by_type_or_short(type)
182
+ elsif stage
183
+ ts = safe_locate_typed_stage(stage)
184
+ ts && locate_klass_by_type_or_short(ts.type_code)
185
+ end
186
+ klass || Identifiers::InternationalStandard
187
+ end
188
+
189
+ # True when `type` names a supplement identifier (Amendment/Corrigendum/
190
+ # Fragment) by key, downcased key, or short abbreviation.
191
+ def self.supplement_type?(type)
192
+ t = type.to_s
193
+ Scheme.supplement_identifiers.any? do |k|
194
+ k.type[:key].to_s == t || k.type[:key].to_s == t.downcase ||
195
+ Array(k.type[:short]).map(&:to_s).include?(t)
196
+ end
197
+ end
198
+
199
+ # Structured indexes store `type:` as the registry key (:tr), an
200
+ # upper-cased abbreviation ("TR"), or a title ("Technology Report").
201
+ # Try each spelling, across every IEC identifier class (the create
202
+ # candidate set is wider than Scheme.identifiers).
203
+ def self.locate_klass_by_type_or_short(type)
204
+ t = type.to_s
205
+ all_create_klasses.detect { |k| k.type[:key].to_s == t } ||
206
+ all_create_klasses.detect { |k| k.type[:key].to_s == t.downcase } ||
207
+ all_create_klasses.detect { |k| Array(k.type[:short]).map(&:to_s).include?(t) } ||
208
+ all_create_klasses.detect { |k| k.type[:title].to_s == t }
209
+ end
210
+
211
+ # All IEC identifier classes that `create` may build, including the
212
+ # long-tail document types absent from Scheme.identifiers. Memoized;
213
+ # the extra classes are required here (not at load time) to dodge the
214
+ # circular require with identifiers/base.rb.
215
+ def self.all_create_klasses
216
+ @all_create_klasses ||= begin
217
+ extra = EXTRA_CREATE_KLASS_FILES.map do |f|
218
+ require_relative "identifiers/#{f}"
219
+ Identifiers.const_get(camelize_klass_file(f))
220
+ end
221
+ Scheme.identifiers + extra
222
+ end
223
+ end
224
+
225
+ def self.camelize_klass_file(file)
226
+ file.split("_").map(&:capitalize).join
227
+ end
228
+
229
+ # IEC Scheme raises ArgumentError on miss instead of returning nil;
230
+ # wrap so the same control flow works as in the ISO factory.
231
+ def self.safe_locate_typed_stage(abbr)
232
+ Scheme.locate_typed_stage_by_abbr(abbr.to_s)
233
+ rescue ArgumentError
234
+ nil
235
+ end
236
+
237
+ def self.resolve_create_typed_stage(klass, stage)
238
+ if stage
239
+ safe_locate_typed_stage(stage)
240
+ elsif klass.const_defined?(:TYPED_STAGES)
241
+ klass.const_get(:TYPED_STAGES).find do |ts|
242
+ ts.stage_code.to_sym == :published
243
+ end
244
+ end
245
+ end
246
+ private_class_method :resolve_create_class,
247
+ :safe_locate_typed_stage,
248
+ :resolve_create_typed_stage, :coerce_create_attrs,
249
+ :extract_supplement, :build_supplement,
250
+ :build_based_supplement,
251
+ :locate_klass_by_type_or_short, :all_create_klasses,
252
+ :camelize_klass_file, :supplement_type?,
253
+ :split_part
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,94 @@
1
+ require_relative "../supplement_identifier"
2
+ # frozen_string_literal: true
3
+ require_relative "../../components/typed_stage"
4
+
5
+ module Pubid
6
+ module Iec
7
+ module Identifiers
8
+ # Amendment Identifier
9
+ class Amendment < SupplementIdentifier
10
+ attribute :type, Pubid::Components::Type, default: -> { self.class.type[:key] }
11
+
12
+ TYPED_STAGES = [
13
+ Pubid::Components::TypedStage.new(
14
+ code: :pwi_amd,
15
+ stage_code: :pwi,
16
+ type_code: :amd,
17
+ abbr: ["PWI Amd"],
18
+ name: "Preliminary Work Item Amendment",
19
+ harmonized_stages: %w[00.00 00.20 00.60 00.98 00.99],
20
+ ),
21
+ Pubid::Components::TypedStage.new(
22
+ code: :np_amd,
23
+ stage_code: :np,
24
+ type_code: :amd,
25
+ abbr: ["NP Amd"],
26
+ name: "New Proposal Amendment",
27
+ harmonized_stages: %w[10.00 10.20 10.60 10.92 10.98],
28
+ ),
29
+ Pubid::Components::TypedStage.new(
30
+ code: :anw_amd,
31
+ stage_code: :anw,
32
+ type_code: :amd,
33
+ abbr: ["ANW Amd"],
34
+ name: "Approved New Work Item Amendment",
35
+ harmonized_stages: %w[10.99 20.00],
36
+ ),
37
+ Pubid::Components::TypedStage.new(
38
+ code: :wd_amd,
39
+ stage_code: :wd,
40
+ type_code: :amd,
41
+ abbr: ["WD Amd"],
42
+ name: "Working Draft Amendment",
43
+ harmonized_stages: %w[20.20 20.60 20.98 20.99],
44
+ ),
45
+ Pubid::Components::TypedStage.new(
46
+ code: :cdamd,
47
+ stage_code: :cd,
48
+ type_code: :amd,
49
+ abbr: ["CDAM"],
50
+ short_abbr: "CDV",
51
+ long_abbr: "CD",
52
+ name: "Committee Draft Amendment",
53
+ harmonized_stages: %w[30.00 30.20 30.60 30.92 30.98 30.99],
54
+ ),
55
+ Pubid::Components::TypedStage.new(
56
+ code: :damd,
57
+ stage_code: :damd,
58
+ type_code: :amd,
59
+ abbr: ["DAM"],
60
+ short_abbr: "DAM",
61
+ long_abbr: "DAm",
62
+ name: "Draft Amendment",
63
+ harmonized_stages: %w[40.00 40.20 40.60 40.92 40.98 40.99],
64
+ ),
65
+ Pubid::Components::TypedStage.new(
66
+ code: :fdamd,
67
+ stage_code: :fdamd,
68
+ type_code: :amd,
69
+ abbr: ["FDAM", "PRF Amd"],
70
+ short_abbr: "FDIS",
71
+ long_abbr: "FDIS",
72
+ name: "Final Draft Amendment",
73
+ harmonized_stages: %w[50.00 50.20 50.60 50.92 50.98 50.99],
74
+ ),
75
+ Pubid::Components::TypedStage.new(
76
+ code: :pubamd,
77
+ stage_code: :published,
78
+ type_code: :amd,
79
+ abbr: ["Amd", "AMD"],
80
+ short_abbr: "AMD",
81
+ long_abbr: "Amd",
82
+ name: "Amendment",
83
+ harmonized_stages: %w[60.00 60.60 90.20 90.60 90.92 90.93 90.99
84
+ 95.20 95.60 95.92 95.99],
85
+ ),
86
+ ].freeze
87
+
88
+ def self.type
89
+ { key: :amd, title: "Amendment", short: "AMD" }
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,82 @@
1
+ require_relative "../single_identifier"
2
+ # frozen_string_literal: true
3
+ require_relative "../components/publisher"
4
+ require_relative "../components/code"
5
+ require_relative "../components/vap_suffix"
6
+ require_relative "../components/trf_info"
7
+
8
+ module Pubid
9
+ module Iec
10
+ module Identifiers
11
+ # Base class for all IEC identifiers
12
+ # Inherits from SingleIdentifier to get common functionality
13
+ # Single Responsibility: Common IEC identifier attributes and behavior
14
+ class Base < SingleIdentifier
15
+ # IEC-specific attributes
16
+ attribute :vap_suffix, Components::VapSuffix, default: -> {}
17
+ attribute :trf_info, Components::TrfInfo, default: -> {}
18
+ attribute :database, :boolean, default: -> { false }
19
+ attribute :fragment, :string, default: -> {}
20
+ attribute :version, :string, default: -> {}
21
+ attribute :decision_sheet, :string, default: -> {}
22
+
23
+ def to_s(_format = :short)
24
+ parts = []
25
+
26
+ # Publisher and type portion (from typed_stage) - uses inherited method
27
+ parts << publisher_portion
28
+
29
+ # Number portion (number with part/subpart)
30
+ parts << number_portion
31
+
32
+ # Edition if present - add space before edition
33
+ parts << " #{edition}" if edition&.number
34
+
35
+ # VAP suffix
36
+ parts << vap_suffix.render_with_space if vap_suffix
37
+
38
+ # Database flag
39
+ parts << " DB" if database
40
+
41
+ # All-parts marker — rendered the same as the generic
42
+ # HumanReadable renderer for parity (see Pubid::Renderers::HumanReadable#render).
43
+ parts << " (all parts)" if all_parts
44
+
45
+ parts.compact.join
46
+ end
47
+
48
+ def number_portion
49
+ return "" unless number
50
+
51
+ result = " #{number}"
52
+
53
+ # Add part if present
54
+ result += "-#{part}" if part && part.to_s != ""
55
+
56
+ # Add subpart if present
57
+ result += "-#{subpart}" if subpart && subpart.to_s != ""
58
+
59
+ # Add date if present
60
+ result += ":#{date.year}" if date
61
+
62
+ result
63
+ end
64
+
65
+ def self.type
66
+ raise NotImplementedError, "Subclass must implement self.type method"
67
+ end
68
+
69
+ # Validate IEC-specific constraints
70
+ def validate!
71
+ super if defined?(super)
72
+
73
+ # Validate VAP suffix if present
74
+ vap_suffix&.validate!
75
+
76
+ # Validate TRF info if present
77
+ trf_info&.validate! if trf_info && !trf_info.empty?
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "base"
2
+ require_relative "../../components/typed_stage"
3
+
4
+ module Pubid
5
+ module Iec
6
+ module Identifiers
7
+ # Component Specification identifier class
8
+ # Single Responsibility: Represents IEC CS documents
9
+ class ComponentSpecification < Base
10
+ # Component Specifications have CS as type abbreviation
11
+ TYPED_STAGES = [
12
+ Pubid::Components::TypedStage.new(
13
+ code: :cs,
14
+ stage_code: :published,
15
+ type_code: :cs,
16
+ abbr: ["CS"],
17
+ name: "Component Specification",
18
+ harmonized_stages: %w[60.00 60.60],
19
+ ),
20
+ ].freeze
21
+
22
+ def self.type
23
+ { key: :cs, title: "Component Specification", short: "CS" }
24
+ end
25
+
26
+ # Override publisher_portion to add CS
27
+ def publisher_portion
28
+ result = publisher.to_s
29
+
30
+ if typed_stage && typed_stage.abbreviation == "CS"
31
+ result += " CS"
32
+ end
33
+
34
+ result
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "base"
2
+ require_relative "../../components/typed_stage"
3
+
4
+ module Pubid
5
+ module Iec
6
+ module Identifiers
7
+ # Conformity Assessment identifier class
8
+ # Single Responsibility: Represents IEC CA documents
9
+ class ConformityAssessment < Base
10
+ # Conformity Assessment has CA as type abbreviation
11
+ TYPED_STAGES = [
12
+ Pubid::Components::TypedStage.new(
13
+ code: :ca,
14
+ stage_code: :published,
15
+ type_code: :ca,
16
+ abbr: ["CA"],
17
+ name: "Conformity Assessment",
18
+ harmonized_stages: %w[60.00 60.60],
19
+ ),
20
+ ].freeze
21
+
22
+ def self.type
23
+ { key: :ca, title: "Conformity Assessment", short: "CA" }
24
+ end
25
+
26
+ # Override publisher_portion to add /CA
27
+ def publisher_portion
28
+ result = publisher.to_s
29
+
30
+ if typed_stage && typed_stage.abbreviation == "CA"
31
+ result += " CA"
32
+ end
33
+
34
+ result
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,82 @@
1
+ require_relative "../identifier"
2
+ # frozen_string_literal: true
3
+
4
+ module Pubid
5
+ module Iec
6
+ module Identifiers
7
+ # Consolidated Identifier
8
+ # Single Responsibility: Represents a consolidated publication containing multiple documents
9
+ # Example: "IEC 60529:1989+AMD1:1999" contains [IS, AMD] as separate identifier objects
10
+ # This is MODEL-DRIVEN: stores the actual identifiers, not just renders with +
11
+ class ConsolidatedIdentifier < Identifier
12
+ attribute :identifiers, Identifier, polymorphic: true, collection: true
13
+
14
+ def to_s(lang: :en, lang_single: false, with_edition: false)
15
+ identifiers.map.with_index do |id, idx|
16
+ if idx.zero?
17
+ # First identifier renders normally
18
+ id.to_s(lang: lang, lang_single: lang_single,
19
+ with_edition: with_edition)
20
+ elsif id.is_a?(Amendment)
21
+ # Subsequent identifiers render with + prefix
22
+ # For amendments, just show +AMDn:year part (or +AMDn if no date)
23
+ if id.date&.year && !id.date.year.empty?
24
+ "+AMD#{id.number}:#{id.date.year}"
25
+ else
26
+ "+AMD#{id.number}"
27
+ end
28
+ elsif id.is_a?(Corrigendum)
29
+ if id.date&.year && !id.date.year.empty?
30
+ "+COR#{id.number}:#{id.date.year}"
31
+ else
32
+ "+COR#{id.number}"
33
+ end
34
+ else
35
+ "+#{id.to_s(lang: lang, lang_single: lang_single,
36
+ with_edition: with_edition)}"
37
+ end
38
+ end.join
39
+ end
40
+
41
+ # Delegate common attributes to first identifier (base document)
42
+ def publisher
43
+ identifiers&.first&.publisher
44
+ end
45
+
46
+ def copublishers
47
+ identifiers&.first&.copublishers
48
+ end
49
+
50
+ def code
51
+ identifiers&.first&.code
52
+ end
53
+
54
+ def number
55
+ identifiers&.first&.number
56
+ end
57
+
58
+ def date
59
+ identifiers&.first&.date
60
+ end
61
+
62
+ def stage
63
+ identifiers&.first&.stage
64
+ end
65
+
66
+ def typed_stage
67
+ identifiers&.first&.typed_stage
68
+ end
69
+
70
+ # Get the base document (first identifier)
71
+ def base_document
72
+ identifiers&.first
73
+ end
74
+
75
+ # Get all supplements (identifiers after first)
76
+ def supplements
77
+ identifiers&.drop(1) || []
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end