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,126 @@
1
+ require_relative "identifier"
2
+ # frozen_string_literal: true
3
+
4
+ module Pubid
5
+ # Identifier that represents a combined bundle of documents using the + operator.
6
+ # Examples:
7
+ # EN 10077-1:2006+AC:2009+AC2:2009
8
+ # ISO/IEC DIR 1 + IEC SUP:2016-05
9
+ # ISO 8601:2019+Amd 1:2024+Cor 1:2025
10
+ #
11
+ # Semantic: Base document combined with amendments/corrigenda that are applied together
12
+ # This is different from:
13
+ # / operator (SupplementIdentifier) - supplement of a document
14
+ # | operator (CombinedIdentifier) - dual-published by multiple organizations
15
+ class BundledIdentifier < Identifier
16
+ attribute :base_document, Identifier, polymorphic: true
17
+ attribute :supplements, Identifier, polymorphic: true, collection: true
18
+ attribute :type, :string, default: -> { "bundled_identifier" }
19
+
20
+ # Delegate common attributes to base_document for easier access
21
+ def publisher
22
+ base_document&.publisher
23
+ end
24
+
25
+ def copublishers
26
+ base_document&.copublishers
27
+ end
28
+
29
+ def number
30
+ base_document&.number
31
+ end
32
+
33
+ def date
34
+ base_document&.date
35
+ end
36
+
37
+ def type
38
+ base_document&.type
39
+ end
40
+
41
+ def stage
42
+ base_document&.stage
43
+ end
44
+
45
+ def typed_stage
46
+ base_document&.typed_stage
47
+ end
48
+
49
+ def to_s(lang: :en, lang_single: false, with_edition: false, format: nil,
50
+ stage_format_long: nil, with_date: nil)
51
+ result = base_document.to_s(lang: lang, lang_single: lang_single,
52
+ with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date)
53
+
54
+ supplements.each do |supplement|
55
+ # ISO DirectivesSupplement always uses " + " (space before)
56
+ # CEN-style supplements (AC, A) without base_identifier use "+" (no space before)
57
+ # Other ISO supplements with base_identifier use " + " (space before)
58
+ if supplement.class.name&.include?("DirectivesSupplement") ||
59
+ (supplement.class.attributes.key?(:base_identifier) && !supplement.base_identifier.nil?)
60
+ result += " + #{supplement.to_s(lang: lang, lang_single: lang_single,
61
+ with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date)}"
62
+ else
63
+ result += "+#{supplement.to_s(lang: lang, lang_single: lang_single,
64
+ with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date)}"
65
+ end
66
+ end
67
+
68
+ result
69
+ end
70
+
71
+ # Generate URN for bundled identifier
72
+ # Flattens all components into a single URN
73
+ #
74
+ # Example: "ISO/IEC DIR 1:2022 + IEC SUP:2022"
75
+ # → "urn:iso:doc:iso-iec:dir:1:2022:iec:sup:2022"
76
+ def to_urn
77
+ # Start with base document URN components
78
+ parts = base_document.to_urn.split(":")
79
+
80
+ # Add each supplement's components
81
+ supplements.each do |supplement|
82
+ # For DirectivesSupplement: add organization and "sup" (not "dir-sup")
83
+ if supplement.class.name&.include?("DirectivesSupplement")
84
+ # Add organization (e.g., "IEC")
85
+ if supplement.class.attributes.key?(:supplement_publisher) && supplement.supplement_publisher
86
+ parts << supplement.supplement_publisher.body.downcase
87
+ end
88
+
89
+ # Always add "sup" for DirectivesSupplement (not "dir-sup")
90
+ parts << "sup"
91
+
92
+ # Add year
93
+ parts << supplement.date.year.to_s if supplement.date
94
+ else
95
+ # For other supplements: use typed_stage type_code
96
+ if supplement.typed_stage
97
+ type_code = supplement.typed_stage.type_code
98
+ parts << type_code.to_s unless type_code == :is
99
+ end
100
+
101
+ # Add supplement date
102
+ if supplement.date
103
+ parts << supplement.date.year.to_s
104
+ end
105
+
106
+ # Add supplement number if present
107
+ if supplement.number
108
+ parts << "v#{supplement.number.value}"
109
+ end
110
+ end
111
+ end
112
+
113
+ parts.join(":")
114
+ end
115
+
116
+ # Support comparison for sorting
117
+ def <=>(other)
118
+ return nil unless other.is_a?(BundledIdentifier)
119
+
120
+ base_comparison = base_document.to_s <=> other.base_document.to_s
121
+ return base_comparison unless base_comparison.zero?
122
+
123
+ supplements.map(&:to_s).sort <=> other.supplements.map(&:to_s).sort
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ class Builder
6
+ def self.build(parsed_data)
7
+ new.build(parsed_data)
8
+ end
9
+
10
+ def build(data)
11
+ # Check if corrigenda are present - if so, build Corrigendum objects
12
+ if data[:corrigenda] && !data[:corrigenda].empty?
13
+ return build_corrigendum(data)
14
+ end
15
+
16
+ # Build base identifier
17
+ build_base(data)
18
+ end
19
+
20
+ private
21
+
22
+ def build_base(data)
23
+ Identifiers::Base.new(
24
+ number: data[:number].to_s,
25
+ part: data[:part]&.to_s,
26
+ type: data[:type]&.to_s,
27
+ edition: data[:edition]&.to_s,
28
+ suffix: data[:suffix]&.to_s,
29
+ language: data[:language]&.to_s,
30
+ )
31
+ end
32
+
33
+ def build_corrigendum(data)
34
+ # Extract corrigenda numbers
35
+ corr_array = data[:corrigenda]
36
+ corr_array = [corr_array] unless corr_array.is_a?(Array)
37
+ corr_numbers = corr_array.map { |c| c[:cor_number].to_i }
38
+
39
+ # Build base identifier (without corrigenda)
40
+ base_data = data.dup
41
+ base_data.delete(:corrigenda)
42
+ base = build_base(base_data)
43
+
44
+ # Build Corrigendum object for each corrigendum number
45
+ # Note: CCSDS uses "Cor. 1" format (single corrigendum per identifier)
46
+ # If multiple corrigenda exist, we build the last one wrapping the base
47
+ corr_numbers.reduce(base) do |current_base, cor_num|
48
+ Identifiers::Corrigendum.new(
49
+ base_identifier: current_base,
50
+ cor_number: cor_num,
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ module Identifier
6
+ def self.parse(identifier)
7
+ # Apply legacy update_codes normalization first
8
+ normalized = Core::UpdateCodes.apply(identifier, :ccsds)
9
+ parsed = Pubid::Ccsds::Parser.parse(normalized)
10
+ Pubid::Ccsds::Builder.build(parsed)
11
+ rescue Parslet::ParseFailed => e
12
+ raise "Failed to parse CCSDS identifier '#{identifier}': #{e.message}"
13
+ end
14
+
15
+ # Factory that builds a CCSDS identifier from a hash of primitives.
16
+ #
17
+ # Accepts the field shape used by relaton-data-ccsds index entries:
18
+ # `:publisher`, `:number`, `:series`, `:part`, `:book_color`,
19
+ # `:retired`, `:edition`, plus the parsed-shape fields `:type`,
20
+ # `:suffix`, `:language`. CCSDS 2.x maps these as:
21
+ #
22
+ # * `:series` + `:number` → combined number ("A" + "20" → "A20")
23
+ # * `:book_color` → `:type` (B/G/M/R/Y/O)
24
+ # * `:publisher` → ignored (hardcoded "CCSDS")
25
+ # * `:retired` → ignored (no 2.x field)
26
+ #
27
+ # Supplement subclasses (currently just Corrigendum, via `type: :cor`)
28
+ # raise ArgumentError until `base:` kwarg is wired through.
29
+ def self.create(type: nil, **opts)
30
+ if type
31
+ type_sym = type.to_sym
32
+ base_type_key = Identifiers::Base.type[:key].to_sym
33
+
34
+ if type_sym != base_type_key
35
+ supplement = supplement_klass_for(type_sym)
36
+ if supplement
37
+ # TODO(create-shim): supplement subclasses (Corrigendum)
38
+ # require a base_identifier. Wire `base:` kwarg through once
39
+ # a caller needs it.
40
+ raise ArgumentError, "#{supplement} requires a " \
41
+ "base_identifier; Identifier.create " \
42
+ "cannot build supplements yet"
43
+ end
44
+
45
+ # Not a class-dispatch key — treat as book_color data
46
+ # (e.g. `type: "G"` for Green Book) and merge back into opts.
47
+ opts = opts.merge(type: type)
48
+ end
49
+ end
50
+
51
+ Identifiers::Base.new(**coerce_create_attrs(opts))
52
+ end
53
+
54
+ def self.supplement_klass_for(type_sym)
55
+ Scheme.supplement_identifiers.find do |k|
56
+ k.type[:key].to_sym == type_sym
57
+ end
58
+ end
59
+
60
+ def self.coerce_create_attrs(opts)
61
+ attrs = {}
62
+
63
+ if opts[:number]
64
+ num = opts[:number].to_s
65
+ attrs[:number] =
66
+ opts[:series] ? "#{opts[:series]}#{num}" : num
67
+ end
68
+
69
+ attrs[:type] = opts[:book_color].to_s if opts[:book_color]
70
+ # Allow caller to pass :type as data when no :book_color given
71
+ # (parsed identifiers expose it via Base#type attribute).
72
+ attrs[:type] = opts[:type].to_s if opts[:type] && !attrs[:type]
73
+
74
+ %i[part edition suffix language].each do |k|
75
+ v = opts[k]
76
+ attrs[k] = v.to_s unless v.nil?
77
+ end
78
+
79
+ attrs
80
+ end
81
+ private_class_method :supplement_klass_for, :coerce_create_attrs
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ module Identifiers
6
+ # CCSDS identifier
7
+ # Format: CCSDS NUMBER.PART-TYPE-EDITION[-SUFFIX]
8
+ # Example: CCSDS 120.0-G-4, CCSDS 100.0-G-1-S
9
+ class Base < Lutaml::Model::Serializable
10
+ # CCSDS uses a simple architecture without typed stages
11
+ # TYPED_STAGES includes default stage for base identifiers
12
+ TYPED_STAGES = [
13
+ Pubid::Components::TypedStage.new(
14
+ abbr: [""],
15
+ stage_code: "published",
16
+ type_code: "base",
17
+ ),
18
+ ].freeze
19
+
20
+ # Type information for this identifier class
21
+ #
22
+ # @return [Hash] Type information with key, title, and short form
23
+ def self.type
24
+ { key: :base, title: "Base Standard", short: nil }
25
+ end
26
+
27
+ # Return a copy of this identifier with the named attributes
28
+ # nil'd. Mirrors the {Pubid::Identifier#exclude} convenience.
29
+ # CCSDS Base extends Lutaml::Model::Serializable directly (not
30
+ # Pubid::Identifier), so the method is defined here too.
31
+ def exclude(*args)
32
+ attrs = self.class.attributes.each_with_object({}) do |(name, _), h|
33
+ h[name] = args.include?(name) ? nil : send(name)
34
+ end
35
+ self.class.new(attrs)
36
+ end
37
+
38
+ # Generate URN for this identifier
39
+ #
40
+ # @return [String] URN representation
41
+
42
+ # Include CCSDS-specific attributes in serialization
43
+ def base_hash
44
+ hash = super
45
+ # CCSDS uses plain strings for type, edition, suffix
46
+ hash[:type] = type if type
47
+ hash[:suffix] = suffix if suffix
48
+ hash[:language] = language if language
49
+ hash
50
+ end
51
+
52
+ attribute :number, :string
53
+ attribute :part, :string
54
+ attribute :type, :string # B, G, M, R, Y, O, etc.
55
+ attribute :edition, :string
56
+ attribute :suffix, :string # Optional suffix like -S
57
+ attribute :language, :string # Language metadata (e.g., "French", "Russian")
58
+
59
+ def publisher
60
+ "CCSDS"
61
+ end
62
+
63
+ def to_s
64
+ result = "#{publisher} #{number}"
65
+ result += ".#{part}" if part
66
+ result += "-#{type}" if type
67
+ result += "-#{edition}" if edition
68
+ result += "-#{suffix}" if suffix
69
+
70
+ # Add language metadata
71
+ result += " - #{language} Translated" if language
72
+
73
+ result
74
+ end
75
+
76
+ def ==(other)
77
+ return false unless other.is_a?(Base)
78
+
79
+ number == other.number &&
80
+ part == other.part &&
81
+ type == other.type &&
82
+ edition == other.edition &&
83
+ suffix == other.suffix &&
84
+ language == other.language
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require_relative "../../serializable"
5
+ require_relative "../urn_generator"
6
+
7
+ module Pubid
8
+ module Ccsds
9
+ module Identifiers
10
+ # CCSDS identifier
11
+ # Format: CCSDS NUMBER.PART-TYPE-EDITION[-SUFFIX]
12
+ # Example: CCSDS 120.0-G-4, CCSDS 100.0-G-1-S
13
+ class Base < Lutaml::Model::Serializable
14
+ include Pubid::Serializable
15
+
16
+ # Generate URN for this identifier
17
+ #
18
+ # @return [String] URN representation
19
+ def to_urn
20
+ UrnGenerator.new(self).generate
21
+ end
22
+
23
+ # Include CCSDS-specific attributes in serialization
24
+ def base_hash
25
+ hash = super
26
+ # CCSDS uses plain strings for type, edition, suffix
27
+ hash[:type] = type if type
28
+ hash[:suffix] = suffix if suffix
29
+ hash[:language] = language if language
30
+ hash
31
+ end
32
+
33
+ attribute :number, :string
34
+ attribute :part, :string
35
+ attribute :type, :string # B, G, M, R, Y, O, etc.
36
+ attribute :edition, :string
37
+ attribute :suffix, :string # Optional suffix like -S
38
+ attribute :language, :string # Language metadata (e.g., "French", "Russian")
39
+
40
+ def publisher
41
+ "CCSDS"
42
+ end
43
+
44
+ def to_s
45
+ result = "#{publisher} #{number}"
46
+ result += ".#{part}" if part
47
+ result += "-#{type}" if type
48
+ result += "-#{edition}" if edition
49
+ result += "-#{suffix}" if suffix
50
+
51
+ # Add language metadata
52
+ result += " - #{language} Translated" if language
53
+
54
+ result
55
+ end
56
+
57
+ def ==(other)
58
+ return false unless other.is_a?(Base)
59
+
60
+ number == other.number &&
61
+ part == other.part &&
62
+ type == other.type &&
63
+ edition == other.edition &&
64
+ suffix == other.suffix &&
65
+ language == other.language
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ module Identifiers
6
+ class Corrigendum < SupplementIdentifier
7
+ # CCSDS Corrigendum typed stage
8
+ TYPED_STAGES = [
9
+ Pubid::Components::TypedStage.new(
10
+ abbr: ["Cor", "Corr"],
11
+ stage_code: "published",
12
+ type_code: "cor",
13
+ ),
14
+ ].freeze
15
+
16
+ # Type information for this identifier class
17
+ #
18
+ # @return [Hash] Type information with key, title, and short form
19
+ def self.type
20
+ { key: :cor, title: "Corrigendum", short: "Cor" }
21
+ end
22
+
23
+ attribute :cor_number, :integer
24
+
25
+ def to_s
26
+ base_str = base_identifier.to_s
27
+ "#{base_str} Cor. #{cor_number}"
28
+ end
29
+
30
+ def ==(other)
31
+ return false unless other.is_a?(Corrigendum)
32
+
33
+ base_identifier == other.base_identifier &&
34
+ cor_number == other.cor_number
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ module Identifiers
6
+ autoload :Base, "#{__dir__}/identifiers/base"
7
+ autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Ccsds
7
+ class Parser < Parslet::Parser
8
+ rule(:digit) { match["0-9"] }
9
+ rule(:digits) { digit.repeat(1) }
10
+ rule(:alnum) { match["A-Za-z0-9"] }
11
+ rule(:alnums) { alnum.repeat(1) }
12
+ rule(:space) { str(" ") }
13
+ rule(:dash) { str("-") }
14
+ rule(:dot) { str(".") }
15
+
16
+ # CCSDS prefix
17
+ rule(:ccsds_prefix) { str("CCSDS") >> space }
18
+
19
+ # Number (can be alphanumeric like A02)
20
+ rule(:number) { alnums.as(:number) }
21
+
22
+ # Part (can be multi-digit like .21 or alphanumeric like .1)
23
+ rule(:part) { dot >> alnums.as(:part) }
24
+
25
+ # Type (all possible type letters)
26
+ rule(:type) { dash >> match["A-Z"].as(:type) }
27
+
28
+ # Edition (can have dots like 4.1)
29
+ rule(:edition) { dash >> match["0-9."].repeat(1).as(:edition) }
30
+
31
+ # Suffix (like -S)
32
+ rule(:suffix) { dash >> match["A-Z"].as(:suffix) }
33
+
34
+ # Corrigendum
35
+ rule(:corrigendum) do
36
+ space >> str("Cor.") >> space >> digits.as(:cor_number)
37
+ end
38
+
39
+ rule(:corrigenda) { corrigendum.repeat(0).as(:corrigenda) }
40
+
41
+ # Language metadata (e.g., " - French Translated", " - Russian Translated")
42
+ rule(:language_metadata) do
43
+ space >> dash >> space >>
44
+ (
45
+ (str("French") | str("Russian") | str("English") |
46
+ str("German") | str("Spanish") | str("Italian") |
47
+ str("Portuguese") | str("Chinese") | str("Japanese")).as(:language) >>
48
+ (space >> str("Translated")).maybe
49
+ )
50
+ end
51
+
52
+ # Main identifier
53
+ rule(:identifier) do
54
+ ccsds_prefix >>
55
+ number >>
56
+ part.maybe >>
57
+ type.maybe >>
58
+ edition.maybe >>
59
+ suffix.maybe >>
60
+ corrigenda >>
61
+ language_metadata.maybe
62
+ end
63
+
64
+ rule(:root) { identifier }
65
+
66
+ def self.parse(input)
67
+ new.parse(input)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ class Scheme < Pubid::Scheme
6
+ class << self
7
+ def identifiers
8
+ [
9
+ Identifiers::Base,
10
+ ]
11
+ end
12
+
13
+ def supplement_identifiers
14
+ [
15
+ Identifiers::Corrigendum,
16
+ ]
17
+ end
18
+
19
+ def typed_stages
20
+ identifiers.flat_map { |klass| klass::TYPED_STAGES }
21
+ end
22
+
23
+ def supplement_typed_stages
24
+ supplement_identifiers.flat_map { |klass| klass::TYPED_STAGES }
25
+ end
26
+
27
+ def locate_typed_stage_by_abbr(abbr)
28
+ abbr = "" if abbr.nil?
29
+
30
+ typed_stage = (typed_stages + supplement_typed_stages).detect do |ts|
31
+ ts.abbr.include?(abbr)
32
+ end
33
+
34
+ unless typed_stage
35
+ raise ArgumentError,
36
+ "Unknown type abbreviation: '#{abbr}'"
37
+ end
38
+
39
+ typed_stage
40
+ end
41
+
42
+ def locate_identifier_klass_by_type_code(type_code)
43
+ identifier_klass = (identifiers + supplement_identifiers).detect do |klass|
44
+ klass.type[:key].to_s == type_code.to_s
45
+ end
46
+
47
+ unless identifier_klass
48
+ raise ArgumentError,
49
+ "Unknown type code: #{type_code}"
50
+ end
51
+
52
+ identifier_klass
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ccsds
5
+ # Qualified as ::Pubid::Identifier to avoid resolving to the local
6
+ # Pubid::Ccsds::Identifier module, which is a parser entry point
7
+ # (`self.parse`) — not the base class.
8
+ class SingleIdentifier < ::Pubid::Identifier
9
+ attribute :publisher, Components::Publisher, default: -> {
10
+ Components::Publisher.new(body: "CCSDS")
11
+ }
12
+ attribute :series, Components::Code
13
+ attribute :number, Components::Code
14
+ attribute :part, Components::Code
15
+ attribute :book_color, Components::Code
16
+ attribute :edition, Components::Edition
17
+ attribute :retired, :boolean, default: -> { false }
18
+ attribute :language, Components::Language
19
+ attribute :type, Components::Type
20
+ attribute :typed_stage, Components::TypedStage
21
+
22
+ def to_s(lang: :en, lang_single: false)
23
+ result = ""
24
+
25
+ # Publisher
26
+ result += publisher.body if publisher
27
+
28
+ # Space after publisher
29
+ result += " "
30
+
31
+ # Series (optional single letter before number)
32
+ result += series.value if series
33
+
34
+ # Number with part (using dot notation)
35
+ result += number.value
36
+ result += ".#{part.value}" if part
37
+
38
+ # Book color (required) - no space before dash
39
+ result += "-#{book_color.value}" if book_color
40
+
41
+ # Edition (optional)
42
+ result += "-#{edition.number}" if edition
43
+
44
+ # Retired marker (optional)
45
+ result += "-S" if retired
46
+
47
+ # Language (optional)
48
+ result += " - #{language.code} Translated" if language
49
+
50
+ result
51
+ end
52
+
53
+ def <=>(other)
54
+ return nil unless other.is_a?(SingleIdentifier)
55
+
56
+ # Compare by number first
57
+ num_cmp = number.value.to_i <=> other.number.value.to_i
58
+ return num_cmp unless num_cmp.zero?
59
+
60
+ # Then by part
61
+ part_cmp = (part ? part.value.to_i : 0) <=> (other.part ? other.part.value.to_i : 0)
62
+ return part_cmp unless part_cmp.zero?
63
+
64
+ # Then by edition
65
+ if edition && other.edition
66
+ edition.number.to_s <=> other.edition.number.to_s
67
+ elsif edition
68
+ 1
69
+ elsif other.edition
70
+ -1
71
+ else
72
+ 0
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end