pubid 1.15.17 → 2.0.0.pre.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.adoc +2041 -53
  4. data/archived-gems/pubid-ccsds/update_codes.yaml +1 -0
  5. data/archived-gems/pubid-iec/stages.yaml +129 -0
  6. data/archived-gems/pubid-iec/update_codes.yaml +67 -0
  7. data/archived-gems/pubid-ieee/update_codes.yaml +104 -0
  8. data/archived-gems/pubid-iso/stages.yaml +106 -0
  9. data/archived-gems/pubid-iso/update_codes.yaml +4 -0
  10. data/archived-gems/pubid-itu/i18n.yaml +13 -0
  11. data/archived-gems/pubid-itu/series.yaml +42 -0
  12. data/archived-gems/pubid-nist/publishers.yaml +6 -0
  13. data/archived-gems/pubid-nist/series.yaml +121 -0
  14. data/archived-gems/pubid-nist/stages.yaml +16 -0
  15. data/archived-gems/pubid-nist/update_codes.yaml +93 -0
  16. data/archived-gems/pubid-plateau/update_codes.yaml +6 -0
  17. data/data/ccsds/update_codes.yaml +1 -0
  18. data/data/iec/update_codes.yaml +67 -0
  19. data/data/ieee/update_codes.yaml +104 -0
  20. data/data/iso/update_codes.yaml +21 -0
  21. data/data/nist/update_codes.yaml +87 -0
  22. data/data/plateau/update_codes.yaml +6 -0
  23. data/lib/pubid/amca/builder.rb +176 -0
  24. data/lib/pubid/amca/identifier.rb +18 -0
  25. data/lib/pubid/amca/identifiers/base.rb +64 -0
  26. data/lib/pubid/amca/identifiers/interpretation.rb +51 -0
  27. data/lib/pubid/amca/identifiers/publication.rb +47 -0
  28. data/lib/pubid/amca/identifiers/standard.rb +22 -0
  29. data/lib/pubid/amca/identifiers.rb +12 -0
  30. data/lib/pubid/amca/parser.rb +153 -0
  31. data/lib/pubid/amca/scheme.rb +16 -0
  32. data/lib/pubid/amca/single_identifier.rb +33 -0
  33. data/lib/pubid/amca/urn_generator.rb +50 -0
  34. data/lib/pubid/amca.rb +26 -0
  35. data/lib/pubid/ansi/builder.rb +52 -0
  36. data/lib/pubid/ansi/identifier.rb +13 -0
  37. data/lib/pubid/ansi/identifiers/american_national_standard.rb +12 -0
  38. data/lib/pubid/ansi/identifiers/standard.rb +16 -0
  39. data/lib/pubid/ansi/identifiers.rb +11 -0
  40. data/lib/pubid/ansi/parser.rb +91 -0
  41. data/lib/pubid/ansi/scheme.rb +15 -0
  42. data/lib/pubid/ansi/single_identifier.rb +45 -0
  43. data/lib/pubid/ansi/urn_generator.rb +76 -0
  44. data/lib/pubid/ansi.rb +27 -0
  45. data/lib/pubid/api/builder.rb +85 -0
  46. data/lib/pubid/api/components/code.rb +9 -0
  47. data/lib/pubid/api/identifier.rb +21 -0
  48. data/lib/pubid/api/identifiers/base.rb +24 -0
  49. data/lib/pubid/api/identifiers/bulletin.rb +15 -0
  50. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +15 -0
  51. data/lib/pubid/api/identifiers/mpms.rb +44 -0
  52. data/lib/pubid/api/identifiers/publication.rb +15 -0
  53. data/lib/pubid/api/identifiers/recommended_practice.rb +15 -0
  54. data/lib/pubid/api/identifiers/specification.rb +15 -0
  55. data/lib/pubid/api/identifiers/standard.rb +15 -0
  56. data/lib/pubid/api/identifiers/technical_report.rb +15 -0
  57. data/lib/pubid/api/identifiers/typeless_standard.rb +27 -0
  58. data/lib/pubid/api/parser.rb +140 -0
  59. data/lib/pubid/api/scheme.rb +66 -0
  60. data/lib/pubid/api/single_identifier.rb +46 -0
  61. data/lib/pubid/api/urn_generator.rb +41 -0
  62. data/lib/pubid/api.rb +17 -0
  63. data/lib/pubid/ashrae/builder.rb +498 -0
  64. data/lib/pubid/ashrae/identifier.rb +18 -0
  65. data/lib/pubid/ashrae/identifiers/addenda_package.rb +46 -0
  66. data/lib/pubid/ashrae/identifiers/addendum.rb +55 -0
  67. data/lib/pubid/ashrae/identifiers/base.rb +23 -0
  68. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +51 -0
  69. data/lib/pubid/ashrae/identifiers/errata.rb +40 -0
  70. data/lib/pubid/ashrae/identifiers/guideline.rb +38 -0
  71. data/lib/pubid/ashrae/identifiers/interpretation.rb +39 -0
  72. data/lib/pubid/ashrae/identifiers/standard.rb +38 -0
  73. data/lib/pubid/ashrae/identifiers.rb +16 -0
  74. data/lib/pubid/ashrae/parser.rb +724 -0
  75. data/lib/pubid/ashrae/scheme.rb +53 -0
  76. data/lib/pubid/ashrae/single_identifier.rb +23 -0
  77. data/lib/pubid/ashrae/supplement_identifier.rb +23 -0
  78. data/lib/pubid/ashrae/urn_generator.rb +59 -0
  79. data/lib/pubid/ashrae.rb +21 -0
  80. data/lib/pubid/asme/builder.rb +153 -0
  81. data/lib/pubid/asme/components/code.rb +18 -0
  82. data/lib/pubid/asme/identifier.rb +15 -0
  83. data/lib/pubid/asme/identifiers/base.rb +70 -0
  84. data/lib/pubid/asme/identifiers/standard.rb +12 -0
  85. data/lib/pubid/asme/identifiers.rb +10 -0
  86. data/lib/pubid/asme/parser.rb +308 -0
  87. data/lib/pubid/asme/scheme.rb +37 -0
  88. data/lib/pubid/asme/single_identifier.rb +29 -0
  89. data/lib/pubid/asme/urn_generator.rb +133 -0
  90. data/lib/pubid/asme.rb +21 -0
  91. data/lib/pubid/astm/builder.rb +159 -0
  92. data/lib/pubid/astm/components/code.rb +33 -0
  93. data/lib/pubid/astm/identifier.rb +15 -0
  94. data/lib/pubid/astm/identifiers/adjunct.rb +21 -0
  95. data/lib/pubid/astm/identifiers/base.rb +13 -0
  96. data/lib/pubid/astm/identifiers/data_series.rb +25 -0
  97. data/lib/pubid/astm/identifiers/iso_dual_published.rb +74 -0
  98. data/lib/pubid/astm/identifiers/manual.rb +40 -0
  99. data/lib/pubid/astm/identifiers/monograph.rb +25 -0
  100. data/lib/pubid/astm/identifiers/research_report.rb +18 -0
  101. data/lib/pubid/astm/identifiers/standard.rb +52 -0
  102. data/lib/pubid/astm/identifiers/technical_report.rb +23 -0
  103. data/lib/pubid/astm/identifiers/work_in_progress.rb +21 -0
  104. data/lib/pubid/astm/parser.rb +244 -0
  105. data/lib/pubid/astm/scheme.rb +55 -0
  106. data/lib/pubid/astm/single_identifier.rb +25 -0
  107. data/lib/pubid/astm/urn_generator.rb +99 -0
  108. data/lib/pubid/astm.rb +38 -0
  109. data/lib/pubid/bsi/builder.rb +1483 -0
  110. data/lib/pubid/bsi/components/code.rb +11 -0
  111. data/lib/pubid/bsi/components/date.rb +11 -0
  112. data/lib/pubid/bsi/components/publisher.rb +11 -0
  113. data/lib/pubid/bsi/components/type.rb +11 -0
  114. data/lib/pubid/bsi/identifier.rb +27 -0
  115. data/lib/pubid/bsi/identifiers/addendum_document.rb +64 -0
  116. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +95 -0
  117. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +82 -0
  118. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +118 -0
  119. data/lib/pubid/bsi/identifiers/amendment.rb +40 -0
  120. data/lib/pubid/bsi/identifiers/base.rb +11 -0
  121. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +27 -0
  122. data/lib/pubid/bsi/identifiers/british_standard.rb +33 -0
  123. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +114 -0
  124. data/lib/pubid/bsi/identifiers/committee_document.rb +51 -0
  125. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +152 -0
  126. data/lib/pubid/bsi/identifiers/corrigendum.rb +28 -0
  127. data/lib/pubid/bsi/identifiers/detailed_specification.rb +69 -0
  128. data/lib/pubid/bsi/identifiers/disc.rb +56 -0
  129. data/lib/pubid/bsi/identifiers/draft_document.rb +71 -0
  130. data/lib/pubid/bsi/identifiers/electronic_book.rb +52 -0
  131. data/lib/pubid/bsi/identifiers/expert_commentary.rb +47 -0
  132. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +82 -0
  133. data/lib/pubid/bsi/identifiers/flex.rb +61 -0
  134. data/lib/pubid/bsi/identifiers/handbook.rb +39 -0
  135. data/lib/pubid/bsi/identifiers/index.rb +62 -0
  136. data/lib/pubid/bsi/identifiers/method.rb +76 -0
  137. data/lib/pubid/bsi/identifiers/national_annex.rb +73 -0
  138. data/lib/pubid/bsi/identifiers/practice_guide.rb +27 -0
  139. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +79 -0
  140. data/lib/pubid/bsi/identifiers/published_document.rb +79 -0
  141. data/lib/pubid/bsi/identifiers/section.rb +62 -0
  142. data/lib/pubid/bsi/identifiers/set.rb +46 -0
  143. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +40 -0
  144. data/lib/pubid/bsi/identifiers/supplement_document.rb +51 -0
  145. data/lib/pubid/bsi/identifiers/supplementary_index.rb +81 -0
  146. data/lib/pubid/bsi/identifiers/technical_specification.rb +79 -0
  147. data/lib/pubid/bsi/identifiers/test_method.rb +67 -0
  148. data/lib/pubid/bsi/identifiers/value_added_publication.rb +52 -0
  149. data/lib/pubid/bsi/identifiers.rb +52 -0
  150. data/lib/pubid/bsi/model.rb +196 -0
  151. data/lib/pubid/bsi/parser.rb +659 -0
  152. data/lib/pubid/bsi/scheme.rb +243 -0
  153. data/lib/pubid/bsi/single_identifier.rb +129 -0
  154. data/lib/pubid/bsi/urn_generator.rb +84 -0
  155. data/lib/pubid/bsi.rb +32 -0
  156. data/lib/pubid/builder/base.rb +138 -0
  157. data/lib/pubid/bundled_identifier.rb +126 -0
  158. data/lib/pubid/ccsds/builder.rb +56 -0
  159. data/lib/pubid/ccsds/identifier.rb +16 -0
  160. data/lib/pubid/ccsds/identifiers/base.rb +78 -0
  161. data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +70 -0
  162. data/lib/pubid/ccsds/identifiers/corrigendum.rb +39 -0
  163. data/lib/pubid/ccsds/identifiers.rb +10 -0
  164. data/lib/pubid/ccsds/parser.rb +71 -0
  165. data/lib/pubid/ccsds/scheme.rb +57 -0
  166. data/lib/pubid/ccsds/single_identifier.rb +74 -0
  167. data/lib/pubid/ccsds/supplement_identifier.rb +33 -0
  168. data/lib/pubid/ccsds/urn_generator.rb +115 -0
  169. data/lib/pubid/ccsds.rb +21 -0
  170. data/lib/pubid/cen_cenelec/builder.rb +330 -0
  171. data/lib/pubid/cen_cenelec/identifier.rb +15 -0
  172. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +40 -0
  173. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +29 -0
  174. data/lib/pubid/cen_cenelec/identifiers/base.rb +75 -0
  175. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +28 -0
  176. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +27 -0
  177. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +28 -0
  178. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +61 -0
  179. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +35 -0
  180. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +41 -0
  181. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +37 -0
  182. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +28 -0
  183. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +22 -0
  184. data/lib/pubid/cen_cenelec/identifiers/guide.rb +27 -0
  185. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +27 -0
  186. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +27 -0
  187. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +35 -0
  188. data/lib/pubid/cen_cenelec/identifiers.rb +32 -0
  189. data/lib/pubid/cen_cenelec/parser.rb +144 -0
  190. data/lib/pubid/cen_cenelec/scheme.rb +164 -0
  191. data/lib/pubid/cen_cenelec/single_identifier.rb +130 -0
  192. data/lib/pubid/cen_cenelec/supplement_identifier.rb +48 -0
  193. data/lib/pubid/cen_cenelec/urn_generator.rb +129 -0
  194. data/lib/pubid/cen_cenelec.rb +21 -0
  195. data/lib/pubid/cie/builder.rb +399 -0
  196. data/lib/pubid/cie/components/code.rb +72 -0
  197. data/lib/pubid/cie/components/language.rb +58 -0
  198. data/lib/pubid/cie/identifier.rb +18 -0
  199. data/lib/pubid/cie/identifiers/bundle.rb +20 -0
  200. data/lib/pubid/cie/identifiers/conference.rb +32 -0
  201. data/lib/pubid/cie/identifiers/corrigendum.rb +40 -0
  202. data/lib/pubid/cie/identifiers/dual_published.rb +41 -0
  203. data/lib/pubid/cie/identifiers/identical.rb +64 -0
  204. data/lib/pubid/cie/identifiers/joint_published.rb +52 -0
  205. data/lib/pubid/cie/identifiers/standard.rb +58 -0
  206. data/lib/pubid/cie/identifiers/supplement.rb +45 -0
  207. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +20 -0
  208. data/lib/pubid/cie/identifiers.rb +17 -0
  209. data/lib/pubid/cie/parser.rb +347 -0
  210. data/lib/pubid/cie/scheme.rb +64 -0
  211. data/lib/pubid/cie/single_identifier.rb +30 -0
  212. data/lib/pubid/cie/supplement_identifier.rb +26 -0
  213. data/lib/pubid/cie/urn_generator.rb +123 -0
  214. data/lib/pubid/cie.rb +28 -0
  215. data/lib/pubid/components/code.rb +33 -0
  216. data/lib/pubid/components/date.rb +49 -0
  217. data/lib/pubid/components/edition.rb +32 -0
  218. data/lib/pubid/components/language.rb +37 -0
  219. data/lib/pubid/components/locality.rb +10 -0
  220. data/lib/pubid/components/publisher.rb +36 -0
  221. data/lib/pubid/components/stage.rb +54 -0
  222. data/lib/pubid/components/type.rb +58 -0
  223. data/lib/pubid/components/typed_stage.rb +55 -0
  224. data/lib/pubid/components.rb +15 -0
  225. data/lib/pubid/core/pattern_doc_generator.rb +272 -0
  226. data/lib/pubid/core/update_codes.rb +77 -0
  227. data/lib/pubid/core.rb +8 -0
  228. data/lib/pubid/csa/builder.rb +671 -0
  229. data/lib/pubid/csa/components/code.rb +9 -0
  230. data/lib/pubid/csa/components.rb +9 -0
  231. data/lib/pubid/csa/composite_identifier.rb +27 -0
  232. data/lib/pubid/csa/identifier.rb +457 -0
  233. data/lib/pubid/csa/identifiers/base.rb +133 -0
  234. data/lib/pubid/csa/identifiers/bundled.rb +125 -0
  235. data/lib/pubid/csa/identifiers/canadian_adopted.rb +82 -0
  236. data/lib/pubid/csa/identifiers/cec.rb +129 -0
  237. data/lib/pubid/csa/identifiers/combined.rb +130 -0
  238. data/lib/pubid/csa/identifiers/csa_adopted.rb +78 -0
  239. data/lib/pubid/csa/identifiers/package.rb +65 -0
  240. data/lib/pubid/csa/identifiers/series.rb +127 -0
  241. data/lib/pubid/csa/identifiers/standard.rb +10 -0
  242. data/lib/pubid/csa/identifiers.rb +17 -0
  243. data/lib/pubid/csa/parser.rb +445 -0
  244. data/lib/pubid/csa/scheme.rb +44 -0
  245. data/lib/pubid/csa/single_identifier.rb +30 -0
  246. data/lib/pubid/csa/urn_generator.rb +80 -0
  247. data/lib/pubid/csa/wrapper_identifier.rb +31 -0
  248. data/lib/pubid/csa.rb +25 -0
  249. data/lib/pubid/etsi/builder.rb +133 -0
  250. data/lib/pubid/etsi/components/code.rb +42 -0
  251. data/lib/pubid/etsi/components/version.rb +37 -0
  252. data/lib/pubid/etsi/components.rb +10 -0
  253. data/lib/pubid/etsi/identifier.rb +14 -0
  254. data/lib/pubid/etsi/identifiers/amendment.rb +15 -0
  255. data/lib/pubid/etsi/identifiers/base.rb +38 -0
  256. data/lib/pubid/etsi/identifiers/corrigendum.rb +15 -0
  257. data/lib/pubid/etsi/identifiers/etsi_standard.rb +19 -0
  258. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +91 -0
  259. data/lib/pubid/etsi/identifiers.rb +14 -0
  260. data/lib/pubid/etsi/parser.rb +133 -0
  261. data/lib/pubid/etsi/scheme.rb +42 -0
  262. data/lib/pubid/etsi/urn_generator.rb +76 -0
  263. data/lib/pubid/etsi.rb +21 -0
  264. data/lib/pubid/export/auditor.rb +89 -0
  265. data/lib/pubid/export/data_class_exporter.rb +59 -0
  266. data/lib/pubid/export/exporter.rb +74 -0
  267. data/lib/pubid/export/flavor_exporter.rb +402 -0
  268. data/lib/pubid/export/ieee_exporter.rb +78 -0
  269. data/lib/pubid/export/itu_exporter.rb +66 -0
  270. data/lib/pubid/export/nist_exporter.rb +64 -0
  271. data/lib/pubid/export/registry_exporter.rb +90 -0
  272. data/lib/pubid/export/result.rb +97 -0
  273. data/lib/pubid/export/scheme_exporter.rb +70 -0
  274. data/lib/pubid/export.rb +18 -0
  275. data/lib/pubid/format_detector.rb +16 -0
  276. data/lib/pubid/format_registry.rb +42 -0
  277. data/lib/pubid/identifier.rb +235 -0
  278. data/lib/pubid/identifier_metadata.rb +148 -0
  279. data/lib/pubid/identifier_registry.rb +198 -0
  280. data/lib/pubid/idf/builder.rb +82 -0
  281. data/lib/pubid/idf/identifier.rb +69 -0
  282. data/lib/pubid/idf/identifiers/amendment.rb +27 -0
  283. data/lib/pubid/idf/identifiers/corrigendum.rb +27 -0
  284. data/lib/pubid/idf/identifiers/international_standard.rb +123 -0
  285. data/lib/pubid/idf/identifiers/reviewed_method.rb +100 -0
  286. data/lib/pubid/idf/identifiers.rb +13 -0
  287. data/lib/pubid/idf/parser.rb +143 -0
  288. data/lib/pubid/idf/scheme.rb +61 -0
  289. data/lib/pubid/idf/single_identifier.rb +19 -0
  290. data/lib/pubid/idf/supplement_identifier.rb +43 -0
  291. data/lib/pubid/idf/urn_generator.rb +84 -0
  292. data/lib/pubid/idf.rb +25 -0
  293. data/lib/pubid/iec/builder.rb +457 -0
  294. data/lib/pubid/iec/components/code.rb +59 -0
  295. data/lib/pubid/iec/components/consolidated_amendment.rb +59 -0
  296. data/lib/pubid/iec/components/publisher.rb +35 -0
  297. data/lib/pubid/iec/components/sheet.rb +32 -0
  298. data/lib/pubid/iec/components/trf_info.rb +38 -0
  299. data/lib/pubid/iec/components/vap_suffix.rb +41 -0
  300. data/lib/pubid/iec/identifier.rb +21 -0
  301. data/lib/pubid/iec/identifiers/amendment.rb +94 -0
  302. data/lib/pubid/iec/identifiers/base.rb +78 -0
  303. data/lib/pubid/iec/identifiers/component_specification.rb +39 -0
  304. data/lib/pubid/iec/identifiers/conformity_assessment.rb +39 -0
  305. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +86 -0
  306. data/lib/pubid/iec/identifiers/corrigendum.rb +94 -0
  307. data/lib/pubid/iec/identifiers/fragment_identifier.rb +141 -0
  308. data/lib/pubid/iec/identifiers/guide.rb +104 -0
  309. data/lib/pubid/iec/identifiers/international_standard.rb +147 -0
  310. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +104 -0
  311. data/lib/pubid/iec/identifiers/operational_document.rb +39 -0
  312. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +101 -0
  313. data/lib/pubid/iec/identifiers/sheet_identifier.rb +66 -0
  314. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +40 -0
  315. data/lib/pubid/iec/identifiers/systems_reference_document.rb +40 -0
  316. data/lib/pubid/iec/identifiers/technical_report.rb +132 -0
  317. data/lib/pubid/iec/identifiers/technical_specification.rb +132 -0
  318. data/lib/pubid/iec/identifiers/technology_report.rb +39 -0
  319. data/lib/pubid/iec/identifiers/test_report_form.rb +78 -0
  320. data/lib/pubid/iec/identifiers/vap_identifier.rb +77 -0
  321. data/lib/pubid/iec/identifiers/white_paper.rb +39 -0
  322. data/lib/pubid/iec/identifiers/working_document.rb +96 -0
  323. data/lib/pubid/iec/parser.rb +412 -0
  324. data/lib/pubid/iec/rendering_style.rb +113 -0
  325. data/lib/pubid/iec/scheme.rb +71 -0
  326. data/lib/pubid/iec/single_identifier.rb +80 -0
  327. data/lib/pubid/iec/supplement_identifier.rb +161 -0
  328. data/lib/pubid/iec/urn_generator.rb +193 -0
  329. data/lib/pubid/iec/urn_parser.rb +289 -0
  330. data/lib/pubid/iec.rb +85 -0
  331. data/lib/pubid/ieee/aiee/builder.rb +71 -0
  332. data/lib/pubid/ieee/aiee/identifier.rb +105 -0
  333. data/lib/pubid/ieee/aiee/parser.rb +130 -0
  334. data/lib/pubid/ieee/aiee.rb +11 -0
  335. data/lib/pubid/ieee/builder.rb +1237 -0
  336. data/lib/pubid/ieee/components/code.rb +102 -0
  337. data/lib/pubid/ieee/components/draft.rb +93 -0
  338. data/lib/pubid/ieee/components/relationship.rb +157 -0
  339. data/lib/pubid/ieee/components/typed_stage.rb +100 -0
  340. data/lib/pubid/ieee/identifier.rb +13 -0
  341. data/lib/pubid/ieee/identifiers/adopted_standard.rb +33 -0
  342. data/lib/pubid/ieee/identifiers/base.rb +591 -0
  343. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +35 -0
  344. data/lib/pubid/ieee/identifiers/corrigendum.rb +37 -0
  345. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +51 -0
  346. data/lib/pubid/ieee/identifiers/dual_identifier.rb +18 -0
  347. data/lib/pubid/ieee/identifiers/dual_published.rb +28 -0
  348. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +27 -0
  349. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +34 -0
  350. data/lib/pubid/ieee/identifiers/joint_development.rb +172 -0
  351. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +51 -0
  352. data/lib/pubid/ieee/identifiers/nesc/base.rb +56 -0
  353. data/lib/pubid/ieee/identifiers/nesc/draft.rb +28 -0
  354. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +32 -0
  355. data/lib/pubid/ieee/identifiers/nesc/redline.rb +26 -0
  356. data/lib/pubid/ieee/identifiers/nesc/standard.rb +26 -0
  357. data/lib/pubid/ieee/identifiers/nesc.rb +15 -0
  358. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +20 -0
  359. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +26 -0
  360. data/lib/pubid/ieee/identifiers/redlined_standard.rb +33 -0
  361. data/lib/pubid/ieee/identifiers/si_standard.rb +73 -0
  362. data/lib/pubid/ieee/identifiers/standard.rb +41 -0
  363. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +23 -0
  364. data/lib/pubid/ieee/identifiers.rb +33 -0
  365. data/lib/pubid/ieee/ire/builder.rb +61 -0
  366. data/lib/pubid/ieee/ire/identifier.rb +58 -0
  367. data/lib/pubid/ieee/ire/parser.rb +91 -0
  368. data/lib/pubid/ieee/ire.rb +11 -0
  369. data/lib/pubid/ieee/nesc/builder.rb +101 -0
  370. data/lib/pubid/ieee/nesc/parser.rb +154 -0
  371. data/lib/pubid/ieee/nesc.rb +10 -0
  372. data/lib/pubid/ieee/parser.rb +1226 -0
  373. data/lib/pubid/ieee/scheme.rb +90 -0
  374. data/lib/pubid/ieee/typed_stages.rb +172 -0
  375. data/lib/pubid/ieee/urn_generator.rb +188 -0
  376. data/lib/pubid/ieee.rb +32 -0
  377. data/lib/pubid/ieee_debug.rb +31 -0
  378. data/lib/pubid/iho/builder.rb +37 -0
  379. data/lib/pubid/iho/identifier.rb +19 -0
  380. data/lib/pubid/iho/identifiers/base.rb +41 -0
  381. data/lib/pubid/iho/identifiers/bibliographic.rb +20 -0
  382. data/lib/pubid/iho/identifiers/circular_letter.rb +19 -0
  383. data/lib/pubid/iho/identifiers/miscellaneous.rb +20 -0
  384. data/lib/pubid/iho/identifiers/publication.rb +19 -0
  385. data/lib/pubid/iho/identifiers/standard.rb +19 -0
  386. data/lib/pubid/iho/identifiers.rb +14 -0
  387. data/lib/pubid/iho/parser.rb +68 -0
  388. data/lib/pubid/iho/scheme.rb +29 -0
  389. data/lib/pubid/iho/urn_generator.rb +29 -0
  390. data/lib/pubid/iho.rb +21 -0
  391. data/lib/pubid/iso/builder.rb +305 -0
  392. data/lib/pubid/iso/bundled_identifier.rb +85 -0
  393. data/lib/pubid/iso/combined_identifier.rb +22 -0
  394. data/lib/pubid/iso/components/code.rb +36 -0
  395. data/lib/pubid/iso/components/publisher.rb +60 -0
  396. data/lib/pubid/iso/components.rb +12 -0
  397. data/lib/pubid/iso/format_resolver.rb +45 -0
  398. data/lib/pubid/iso/identifier.rb +69 -0
  399. data/lib/pubid/iso/identifiers/addendum.rb +104 -0
  400. data/lib/pubid/iso/identifiers/amendment.rb +128 -0
  401. data/lib/pubid/iso/identifiers/base.rb +115 -0
  402. data/lib/pubid/iso/identifiers/corrigendum.rb +108 -0
  403. data/lib/pubid/iso/identifiers/data.rb +76 -0
  404. data/lib/pubid/iso/identifiers/directives.rb +59 -0
  405. data/lib/pubid/iso/identifiers/directives_supplement.rb +119 -0
  406. data/lib/pubid/iso/identifiers/extract.rb +30 -0
  407. data/lib/pubid/iso/identifiers/guide.rb +100 -0
  408. data/lib/pubid/iso/identifiers/international_standard.rb +168 -0
  409. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +94 -0
  410. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +89 -0
  411. data/lib/pubid/iso/identifiers/pas.rb +93 -0
  412. data/lib/pubid/iso/identifiers/recommendation.rb +45 -0
  413. data/lib/pubid/iso/identifiers/supplement.rb +87 -0
  414. data/lib/pubid/iso/identifiers/tc_document.rb +108 -0
  415. data/lib/pubid/iso/identifiers/technical_report.rb +103 -0
  416. data/lib/pubid/iso/identifiers/technical_specification.rb +102 -0
  417. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +95 -0
  418. data/lib/pubid/iso/identifiers.rb +33 -0
  419. data/lib/pubid/iso/parser.rb +510 -0
  420. data/lib/pubid/iso/rendering_style.rb +120 -0
  421. data/lib/pubid/iso/scheme.rb +187 -0
  422. data/lib/pubid/iso/single_identifier.rb +61 -0
  423. data/lib/pubid/iso/supplement_identifier.rb +27 -0
  424. data/lib/pubid/iso/urn_generator.rb +412 -0
  425. data/lib/pubid/iso/urn_parser.rb +423 -0
  426. data/lib/pubid/iso/utilities.rb +86 -0
  427. data/lib/pubid/iso.rb +50 -0
  428. data/lib/pubid/itu/builder.rb +171 -0
  429. data/lib/pubid/itu/components/code.rb +39 -0
  430. data/lib/pubid/itu/components/sector.rb +35 -0
  431. data/lib/pubid/itu/components/series.rb +29 -0
  432. data/lib/pubid/itu/i18n.rb +9 -0
  433. data/lib/pubid/itu/i18n.yaml +30 -0
  434. data/lib/pubid/itu/identifier.rb +53 -0
  435. data/lib/pubid/itu/identifiers/amendment.rb +43 -0
  436. data/lib/pubid/itu/identifiers/annex.rb +74 -0
  437. data/lib/pubid/itu/identifiers/base.rb +154 -0
  438. data/lib/pubid/itu/identifiers/combined_identifier.rb +47 -0
  439. data/lib/pubid/itu/identifiers/corrigendum.rb +44 -0
  440. data/lib/pubid/itu/identifiers/recommendation.rb +16 -0
  441. data/lib/pubid/itu/identifiers/special_publication.rb +31 -0
  442. data/lib/pubid/itu/identifiers/supplement.rb +46 -0
  443. data/lib/pubid/itu/identifiers.rb +16 -0
  444. data/lib/pubid/itu/model.rb +111 -0
  445. data/lib/pubid/itu/parser.rb +225 -0
  446. data/lib/pubid/itu/scheme.rb +174 -0
  447. data/lib/pubid/itu/urn_generator.rb +105 -0
  448. data/lib/pubid/itu.rb +22 -0
  449. data/lib/pubid/jcgm/builder.rb +88 -0
  450. data/lib/pubid/jcgm/components/publisher.rb +20 -0
  451. data/lib/pubid/jcgm/components.rb +9 -0
  452. data/lib/pubid/jcgm/identifier.rb +11 -0
  453. data/lib/pubid/jcgm/identifiers/amendment.rb +35 -0
  454. data/lib/pubid/jcgm/identifiers/guide.rb +21 -0
  455. data/lib/pubid/jcgm/identifiers/gum_guide.rb +51 -0
  456. data/lib/pubid/jcgm/identifiers.rb +11 -0
  457. data/lib/pubid/jcgm/parser.rb +84 -0
  458. data/lib/pubid/jcgm/scheme.rb +60 -0
  459. data/lib/pubid/jcgm/single_identifier.rb +48 -0
  460. data/lib/pubid/jcgm/supplement_identifier.rb +16 -0
  461. data/lib/pubid/jcgm/urn_generator.rb +110 -0
  462. data/lib/pubid/jcgm.rb +31 -0
  463. data/lib/pubid/jis/builder.rb +124 -0
  464. data/lib/pubid/jis/components/code.rb +59 -0
  465. data/lib/pubid/jis/components.rb +9 -0
  466. data/lib/pubid/jis/identifier.rb +18 -0
  467. data/lib/pubid/jis/identifiers/amendment.rb +16 -0
  468. data/lib/pubid/jis/identifiers/base.rb +72 -0
  469. data/lib/pubid/jis/identifiers/explanation.rb +22 -0
  470. data/lib/pubid/jis/identifiers/japanese_industrial_standard.rb +16 -0
  471. data/lib/pubid/jis/identifiers/standard.rb +27 -0
  472. data/lib/pubid/jis/identifiers/technical_report.rb +31 -0
  473. data/lib/pubid/jis/identifiers/technical_specification.rb +31 -0
  474. data/lib/pubid/jis/identifiers.rb +17 -0
  475. data/lib/pubid/jis/parser.rb +109 -0
  476. data/lib/pubid/jis/scheme.rb +49 -0
  477. data/lib/pubid/jis/single_identifier.rb +37 -0
  478. data/lib/pubid/jis/supplement_identifier.rb +47 -0
  479. data/lib/pubid/jis/urn_generator.rb +25 -0
  480. data/lib/pubid/jis.rb +23 -0
  481. data/lib/pubid/lutaml/no_store_registration.rb +30 -0
  482. data/lib/pubid/nist/builder.rb +2100 -0
  483. data/lib/pubid/nist/components/code.rb +38 -0
  484. data/lib/pubid/nist/components/edition.rb +118 -0
  485. data/lib/pubid/nist/components/issue_number.rb +28 -0
  486. data/lib/pubid/nist/components/part.rb +77 -0
  487. data/lib/pubid/nist/components/publisher.rb +24 -0
  488. data/lib/pubid/nist/components/stage.rb +53 -0
  489. data/lib/pubid/nist/components/supplement.rb +121 -0
  490. data/lib/pubid/nist/components/translation.rb +42 -0
  491. data/lib/pubid/nist/components/update.rb +103 -0
  492. data/lib/pubid/nist/components/version.rb +35 -0
  493. data/lib/pubid/nist/components/volume.rb +32 -0
  494. data/lib/pubid/nist/components.rb +19 -0
  495. data/lib/pubid/nist/configuration.rb +77 -0
  496. data/lib/pubid/nist/identifiers/base.rb +499 -0
  497. data/lib/pubid/nist/identifiers/circular.rb +68 -0
  498. data/lib/pubid/nist/identifiers/circular_supplement.rb +50 -0
  499. data/lib/pubid/nist/identifiers/commercial_standard.rb +41 -0
  500. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +56 -0
  501. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +56 -0
  502. data/lib/pubid/nist/identifiers/crpl_report.rb +135 -0
  503. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +94 -0
  504. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +35 -0
  505. data/lib/pubid/nist/identifiers/handbook.rb +50 -0
  506. data/lib/pubid/nist/identifiers/internal_report.rb +56 -0
  507. data/lib/pubid/nist/identifiers/letter_circular.rb +45 -0
  508. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +65 -0
  509. data/lib/pubid/nist/identifiers/monograph.rb +69 -0
  510. data/lib/pubid/nist/identifiers/ncstar.rb +41 -0
  511. data/lib/pubid/nist/identifiers/nsrds.rb +41 -0
  512. data/lib/pubid/nist/identifiers/owmwp.rb +35 -0
  513. data/lib/pubid/nist/identifiers/report.rb +68 -0
  514. data/lib/pubid/nist/identifiers/special_publication.rb +36 -0
  515. data/lib/pubid/nist/identifiers/technical_note.rb +90 -0
  516. data/lib/pubid/nist/identifiers.rb +33 -0
  517. data/lib/pubid/nist/parser.rb +1084 -0
  518. data/lib/pubid/nist/scheme.rb +199 -0
  519. data/lib/pubid/nist/supplement_identifier.rb +83 -0
  520. data/lib/pubid/nist/urn_generator.rb +127 -0
  521. data/lib/pubid/nist.rb +36 -0
  522. data/lib/pubid/oiml/builder.rb +189 -0
  523. data/lib/pubid/oiml/components/code.rb +20 -0
  524. data/lib/pubid/oiml/components.rb +9 -0
  525. data/lib/pubid/oiml/identifier.rb +11 -0
  526. data/lib/pubid/oiml/identifiers/amendment.rb +13 -0
  527. data/lib/pubid/oiml/identifiers/annex.rb +62 -0
  528. data/lib/pubid/oiml/identifiers/base.rb +36 -0
  529. data/lib/pubid/oiml/identifiers/basic_publication.rb +13 -0
  530. data/lib/pubid/oiml/identifiers/document.rb +13 -0
  531. data/lib/pubid/oiml/identifiers/expert_report.rb +13 -0
  532. data/lib/pubid/oiml/identifiers/guide.rb +13 -0
  533. data/lib/pubid/oiml/identifiers/recommendation.rb +13 -0
  534. data/lib/pubid/oiml/identifiers/seminar_report.rb +13 -0
  535. data/lib/pubid/oiml/identifiers/vocabulary.rb +13 -0
  536. data/lib/pubid/oiml/identifiers.rb +18 -0
  537. data/lib/pubid/oiml/parser.rb +173 -0
  538. data/lib/pubid/oiml/scheme.rb +46 -0
  539. data/lib/pubid/oiml/single_identifier.rb +90 -0
  540. data/lib/pubid/oiml/supplement_identifier.rb +43 -0
  541. data/lib/pubid/oiml/urn_generator.rb +64 -0
  542. data/lib/pubid/oiml.rb +26 -0
  543. data/lib/pubid/parser/common_parse_methods.rb +13 -0
  544. data/lib/pubid/parser/common_parse_rules.rb +56 -0
  545. data/lib/pubid/parser.rb +8 -0
  546. data/lib/pubid/parsers/base.rb +11 -0
  547. data/lib/pubid/parsers/mr_string.rb +93 -0
  548. data/lib/pubid/plateau/builder.rb +50 -0
  549. data/lib/pubid/plateau/identifiers/annex.rb +16 -0
  550. data/lib/pubid/plateau/identifiers/base.rb +51 -0
  551. data/lib/pubid/plateau/identifiers/handbook.rb +34 -0
  552. data/lib/pubid/plateau/identifiers/technical_report.rb +20 -0
  553. data/lib/pubid/plateau/identifiers.rb +12 -0
  554. data/lib/pubid/plateau/parser.rb +63 -0
  555. data/lib/pubid/plateau/scheme.rb +45 -0
  556. data/lib/pubid/plateau/supplement_identifier.rb +72 -0
  557. data/lib/pubid/plateau/urn_generator.rb +29 -0
  558. data/lib/pubid/plateau.rb +25 -0
  559. data/lib/pubid/renderers/base.rb +19 -0
  560. data/lib/pubid/renderers/directives_renderer.rb +62 -0
  561. data/lib/pubid/renderers/guide_renderer.rb +20 -0
  562. data/lib/pubid/renderers/human_readable.rb +58 -0
  563. data/lib/pubid/renderers/iwa_renderer.rb +16 -0
  564. data/lib/pubid/renderers/mr_string.rb +16 -0
  565. data/lib/pubid/renderers/supplement_renderer.rb +33 -0
  566. data/lib/pubid/renderers/urn.rb +11 -0
  567. data/lib/pubid/renderers.rb +14 -0
  568. data/lib/pubid/rendering/base.rb +73 -0
  569. data/lib/pubid/rendering/common.rb +211 -0
  570. data/lib/pubid/rendering/context.rb +156 -0
  571. data/lib/pubid/rendering/date.rb +27 -0
  572. data/lib/pubid/rendering/format.rb +25 -0
  573. data/lib/pubid/rendering/language.rb +21 -0
  574. data/lib/pubid/rendering/numbering.rb +24 -0
  575. data/lib/pubid/rendering/publisher.rb +25 -0
  576. data/lib/pubid/rendering/stage.rb +38 -0
  577. data/lib/pubid/rendering/supplement.rb +46 -0
  578. data/lib/pubid/rendering.rb +16 -0
  579. data/lib/pubid/sae/builder.rb +32 -0
  580. data/lib/pubid/sae/components/code.rb +9 -0
  581. data/lib/pubid/sae/components/date.rb +19 -0
  582. data/lib/pubid/sae/components/type.rb +19 -0
  583. data/lib/pubid/sae/components.rb +11 -0
  584. data/lib/pubid/sae/identifier.rb +14 -0
  585. data/lib/pubid/sae/identifiers/base.rb +42 -0
  586. data/lib/pubid/sae/identifiers.rb +9 -0
  587. data/lib/pubid/sae/parser.rb +55 -0
  588. data/lib/pubid/sae/scheme.rb +47 -0
  589. data/lib/pubid/sae/urn_generator.rb +38 -0
  590. data/lib/pubid/sae.rb +19 -0
  591. data/lib/pubid/scheme.rb +207 -0
  592. data/lib/pubid/urn_generator/base.rb +110 -0
  593. data/lib/pubid/utils/string_normalizer.rb +196 -0
  594. data/lib/pubid/utils.rb +7 -0
  595. data/lib/pubid/version.rb +3 -1
  596. data/lib/pubid.rb +137 -13
  597. data/lib/tasks/docs.rake +37 -0
  598. data/lib/tasks/export.rake +38 -0
  599. data/lib/tasks/website-data.json +7488 -0
  600. metadata +613 -171
  601. data/lib/pubid/registry.rb +0 -30
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iso
5
+ # ISO Scheme with memoized parser/builder and hash-based indexing
6
+ class Scheme < Pubid::Scheme
7
+ class << self
8
+ # Singleton instance for memoization
9
+ # @return [Pubid::Iso::Scheme] the singleton scheme instance
10
+ def instance
11
+ @instance ||= new
12
+ end
13
+
14
+ # Delegate class methods to singleton instance for backward compatibility
15
+ # @param identifier [String] the identifier string to parse
16
+ # @return [Identifier] the parsed identifier
17
+ def parse(identifier)
18
+ instance.parse(identifier)
19
+ end
20
+
21
+ # @param abbr [String, Symbol] the abbreviation to find
22
+ # @return [TypedStage] the matching typed stage
23
+ def locate_typed_stage_by_abbr(abbr)
24
+ instance.locate_typed_stage_by_abbr(abbr)
25
+ end
26
+
27
+ # @param type_code [String, Symbol] the type code to find
28
+ # @return [Class] the matching identifier class
29
+ def locate_identifier_klass_by_type_code(type_code)
30
+ instance.locate_identifier_klass_by_type_code(type_code)
31
+ end
32
+
33
+ # @param stage_code [String, Symbol] the stage code to find
34
+ # @return [TypedStage] the matching typed stage
35
+ def locate_typed_stage_by_stage_code(stage_code)
36
+ instance.locate_typed_stage_by_stage_code(stage_code)
37
+ end
38
+
39
+ # @param harmonized_code [String] the harmonized stage code to find
40
+ # @return [TypedStage, nil] the matching typed stage
41
+ def locate_typed_stage_by_harmonized_code(harmonized_code)
42
+ instance.locate_typed_stage_by_harmonized_code(harmonized_code)
43
+ end
44
+
45
+ # Keep existing class methods for backward compatibility
46
+ # @return [Array<Class>] all base identifier classes
47
+ def identifiers
48
+ [
49
+ Identifiers::InternationalStandard,
50
+ Identifiers::TechnicalReport,
51
+ Identifiers::TechnicalSpecification,
52
+ Identifiers::Guide,
53
+ Identifiers::Pas,
54
+ Identifiers::Data,
55
+ Identifiers::TechnologyTrendsAssessments,
56
+ Identifiers::InternationalWorkshopAgreement,
57
+ Identifiers::InternationalStandardizedProfile,
58
+ Identifiers::Recommendation,
59
+ Identifiers::Directives,
60
+ Identifiers::Amendment,
61
+ Identifiers::Corrigendum,
62
+ Identifiers::Supplement,
63
+ Identifiers::Extract,
64
+ Identifiers::DirectivesSupplement,
65
+ Identifiers::Addendum,
66
+ Identifiers::TcDocument,
67
+ ]
68
+ end
69
+
70
+ def typed_stages
71
+ identifiers.flat_map { |klass| klass::TYPED_STAGES }.compact
72
+ end
73
+
74
+ def supplement_typed_stages
75
+ supplement_identifiers = [
76
+ Identifiers::Amendment,
77
+ Identifiers::Corrigendum,
78
+ Identifiers::Supplement,
79
+ Identifiers::Extract,
80
+ Identifiers::Addendum,
81
+ ]
82
+ supplement_identifiers.flat_map { |klass| klass::TYPED_STAGES }
83
+ end
84
+ end
85
+
86
+ # Initialize the scheme with identifiers
87
+ def initialize
88
+ super(
89
+ identifiers: self.class.identifiers,
90
+ supplement_identifiers: [
91
+ Identifiers::Amendment,
92
+ Identifiers::Corrigendum,
93
+ Identifiers::Supplement,
94
+ Identifiers::Extract,
95
+ Identifiers::Addendum,
96
+ ],
97
+ )
98
+ end
99
+
100
+ # Parse an ISO identifier string using memoized parser/builder
101
+ # @param identifier [String] the identifier string to parse
102
+ # @return [Identifier] the parsed identifier
103
+ def parse(identifier)
104
+ # Handle DAD/FDAD patterns that parser can't recognize
105
+ if match = identifier.match(/^(.+?)\/(F?DAD)\s+(\d+)(?::(\d{4}))?$/)
106
+ parse_dad_pattern(match)
107
+ else
108
+ # Apply legacy update_codes normalization first, before any other preprocessing
109
+ normalized = Core::UpdateCodes.apply(identifier, :iso)
110
+ # Normalize Cyrillic (Russian) identifiers to Latin equivalents
111
+ normalized = normalize_cyrillic(normalized)
112
+ parsed = parser.parse(normalized)
113
+ builder.build(parsed)
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ # Memoized parser instance
120
+ # @return [Pubid::Iso::Parser] parser instance
121
+ def parser
122
+ @parser ||= ::Pubid::Iso::Parser.new
123
+ end
124
+
125
+ # Memoized builder instance
126
+ # @return [Pubid::Iso::Builder] builder instance
127
+ def builder
128
+ @builder ||= ::Pubid::Iso::Builder.new(self)
129
+ end
130
+
131
+ # Normalize Cyrillic (Russian) ISO identifiers to Latin equivalents
132
+ # ИСО = ISO, МЭК = IEC, Руководство/Руководства = Guide,
133
+ # ОПМС = FDIS, ПМС = DIS, ТО = TR, ТС = TS
134
+ def normalize_cyrillic(identifier)
135
+ return identifier unless identifier.match?(/[а-яА-Я]/)
136
+
137
+ normalized = identifier.dup
138
+ # Remove inline comments (Russian style comments with #)
139
+ normalized = normalized.gsub(/\s*#\s*.*$/, "")
140
+ # Translate Russian abbreviations (order matters: longer first)
141
+ normalized = normalized.gsub("Руководства", "GUIDE")
142
+ normalized = normalized.gsub("Руководство", "GUIDE")
143
+ normalized = normalized.gsub("ИСО/МЭК", "ISO/IEC")
144
+ normalized = normalized.gsub("ИСО/ОПМС", "ISO/FDIS")
145
+ normalized = normalized.gsub("ИСО/ПМС", "ISO/DIS")
146
+ normalized = normalized.gsub("ИСО/ТО", "ISO/TR")
147
+ normalized = normalized.gsub("ИСО/ТС", "ISO/TS")
148
+ normalized = normalized.gsub("ИСО", "ISO")
149
+ normalized = normalized.gsub("МЭК", "IEC")
150
+ # Standalone Cyrillic stage abbreviations (after publisher replacements)
151
+ normalized = normalized.gsub("ТО", "TR")
152
+ normalized = normalized.gsub("ТС", "TS")
153
+ normalized = normalized.gsub("ОПМС", "FDIS")
154
+ normalized = normalized.gsub("ПМС", "DIS")
155
+ normalized.strip
156
+ end
157
+
158
+ # Parse DAD/FDAM pattern manually
159
+ # Pattern: "ISO 2631/DAD 1" or "ISO 2553/DAD 1:1987"
160
+ # The parser fails because it treats "/" as copublisher separator
161
+ def parse_dad_pattern(match)
162
+ base_str = match[1] # "ISO 2631" or "ISO 2553"
163
+ stage_abbr = match[2] # "DAD" or "FDAD"
164
+ supplement_number = match[3] # "1"
165
+ supplement_year = match[4] # "1987" or nil
166
+
167
+ # Parse the base identifier normally (without supplement)
168
+ base_parsed = parser.parse(base_str)
169
+ base_identifier = builder.build(base_parsed)
170
+
171
+ # Construct the Addendum supplement manually
172
+ addendum = Identifiers::Addendum.new
173
+ addendum.base_identifier = base_identifier
174
+ addendum.number = Iso::Components::Code.new(number: supplement_number)
175
+ addendum.date = Pubid::Components::Date.new(year: supplement_year) if supplement_year
176
+
177
+ # Set typed_stage from register (uses TYPED_STAGES in Addendum class)
178
+ typed_stage = locate_typed_stage_by_abbr(stage_abbr)
179
+ addendum.typed_stage = typed_stage
180
+ addendum.stage = typed_stage.to_stage
181
+ addendum.type = typed_stage.to_type
182
+
183
+ addendum
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iso
5
+ class SingleIdentifier < Identifier
6
+ def to_s(**opts)
7
+ render(format: :human, **opts)
8
+ end
9
+
10
+ private
11
+
12
+ def build_rendering_context(_renderer, format:, with_edition: false,
13
+ lang: :en, lang_single: false,
14
+ stage_format_long: nil, with_date: nil)
15
+ if format == :mr_string
16
+ nil
17
+ elsif lang_single || stage_format_long || !with_date.nil?
18
+ Rendering::RenderingContext.new(
19
+ with_language_code: lang_single ? :single : :none,
20
+ stage_format_long: stage_format_long || false,
21
+ with_date: with_date.nil? || with_date,
22
+ )
23
+ else
24
+ detect_rendering_context
25
+ end
26
+ end
27
+
28
+ def detect_rendering_context
29
+ Rendering::RenderingContext.new(
30
+ with_language_code: detect_language_code_format,
31
+ stage_format_long: detect_stage_format_long,
32
+ with_date: true,
33
+ )
34
+ end
35
+
36
+ def detect_stage_format_long
37
+ return false unless typed_stage
38
+
39
+ ts = typed_stage
40
+ if ts.long_abbr && ts.original_abbr&.start_with?(ts.long_abbr)
41
+ true
42
+ elsif ts.long_abbr && ts.original_abbr&.include?("Directives")
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ def detect_language_code_format
50
+ return :none unless languages&.any?
51
+
52
+ first_lang = languages.first
53
+ if first_lang.original_code && first_lang.original_code.length == 1
54
+ :single
55
+ else
56
+ :iso
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iso
5
+ class SupplementIdentifier < SingleIdentifier
6
+ attribute :base_identifier, Identifier,
7
+ polymorphic: true
8
+
9
+ key_value do
10
+ map "base_identifier", to: :base_identifier, polymorphic: {
11
+ attribute: "_type",
12
+ class_map: Identifier::ISO_TYPE_MAP,
13
+ }
14
+ end
15
+
16
+ def publisher
17
+ base_identifier&.publisher
18
+ end
19
+
20
+ def to_s(**opts)
21
+ context = build_rendering_context(nil, format: :human, **opts)
22
+ Pubid::Renderers::SupplementRenderer.new(self).render(context:,
23
+ **opts.slice(:with_edition))
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,412 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iso
5
+ # Generates RFC 5141-bis compliant URNs from ISO identifiers
6
+ #
7
+ # RFC 5141-bis extensions implemented:
8
+ # - Explicit language specification (explicit > implicit)
9
+ # - Extended copublisher syntax (dynamic combinations)
10
+ # - Extended document types (DIR, DIR-SUP, IWA-SUP)
11
+ # - Typed stage codes (WD, CD, DIS, FDIS, PDAM, etc.)
12
+ # - Supplement chain ordering semantics
13
+ # - Bundled identifier syntax
14
+ class UrnGenerator
15
+ # Stage code mapping for RFC 5141-bis typed stages
16
+ # Maps TypedStage stage_code to URN stage abbreviation
17
+ TYPED_STAGE_MAP = {
18
+ wd: "WD", # Working Draft
19
+ wds: "WDS", # Working Draft Study
20
+ cd: "CD", # Committee Draft
21
+ cdv: "CDV", # Committee Draft for Vote
22
+ dis: "DIS", # Draft International Standard
23
+ fdis: "FDIS", # Final Draft International Standard
24
+ pdam: "PDAM", # Proposed Draft Amendment
25
+ dam: "DAM", # Draft Amendment
26
+ fdamd: "FDAM", # Final Draft Amendment (note: stage_code is fdamd)
27
+ dcor: "DCOR", # Draft Corrigendum
28
+ fdcor: "FDCOR", # Final Draft Corrigendum
29
+ cdts: "CDTS", # Committee Draft Technical Specification
30
+ dts: "DTS", # Draft Technical Specification
31
+ fdts: "FDTS", # Final Draft Technical Specification
32
+ }.freeze
33
+
34
+ # Document type mapping for RFC 5141-bis extended types
35
+ TYPE_CODE_MAP = {
36
+ dir: "dir", # Directive
37
+ dir_sup: "dir-sup", # Directive Supplement
38
+ iwa_sup: "iwa-sup", # IWA Supplement
39
+ }.freeze
40
+
41
+ attr_reader :identifier
42
+
43
+ # Initialize URN generator
44
+ #
45
+ # @param identifier [Identifier] The ISO identifier to generate URN for
46
+ def initialize(identifier)
47
+ @identifier = identifier
48
+ end
49
+
50
+ # Generate complete URN string
51
+ #
52
+ # @return [String] The URN in format urn:iso:std:...
53
+ def generate
54
+ if identifier.is_a?(SupplementIdentifier)
55
+ generate_supplement_urn
56
+ else
57
+ generate_base_urn
58
+ end
59
+ end
60
+
61
+ protected
62
+
63
+ # Generate URN for base identifier (SingleIdentifier)
64
+ def generate_base_urn
65
+ parts = ["urn", "iso", "std"]
66
+
67
+ # Publisher (lowercase, hyphen-separated)
68
+ parts << originator_component
69
+
70
+ # Type (for non-IS types like TR, TS, Guide)
71
+ type_comp = type_component
72
+ parts << type_comp if type_comp
73
+
74
+ # Number
75
+ parts << identifier.number.value if identifier.number
76
+
77
+ # Part (with colon-dash prefix)
78
+ part_comp = part_component
79
+ parts << part_comp if part_comp
80
+
81
+ # Stage (only for non-published documents)
82
+ stage_comp = stage_component
83
+ parts << stage_comp if stage_comp
84
+
85
+ # Year (for published documents and when edition is present)
86
+ year_comp = year_component
87
+ parts << year_comp if year_comp
88
+
89
+ # Edition
90
+ edition_comp = edition_component
91
+ parts << edition_comp if edition_comp
92
+
93
+ # Language (RFC 5141-bis: explicit specification)
94
+ lang_comp = language_component
95
+ parts << lang_comp if lang_comp
96
+
97
+ parts.join(":")
98
+ end
99
+
100
+ # Generate URN for supplement identifier
101
+ # Handles multi-level supplements by walking up the chain
102
+ def generate_supplement_urn
103
+ # Walk up supplement chain to collect all supplements
104
+ current = identifier
105
+ supplement_chain = []
106
+
107
+ while current.is_a?(SupplementIdentifier)
108
+ supplement_chain.unshift(current) # Add to front (reverse order)
109
+ current = current.base_identifier
110
+ end
111
+
112
+ # Now 'current' is the base document (not a supplement)
113
+ base_id = current
114
+
115
+ # Build URN from base identifier
116
+ parts = ["urn", "iso", "std"]
117
+
118
+ if base_id
119
+ base_gen = self.class.new(base_id)
120
+
121
+ # Publisher
122
+ parts << base_gen.originator_component
123
+
124
+ # Type (for non-IS types like TR, TS, Guide)
125
+ type_comp = base_gen.type_component
126
+ parts << type_comp if type_comp
127
+
128
+ # Number
129
+ parts << base_id.number.value if base_id.number
130
+
131
+ # Part
132
+ part_comp = base_gen.part_component
133
+ parts << part_comp if part_comp
134
+
135
+ # Collect ALL editions (base + supplements) and add them here
136
+ # This ensures editions come before all supplement chains
137
+ all_editions = []
138
+
139
+ # Base edition first
140
+ edition_comp = base_gen.edition_component
141
+ all_editions << edition_comp if edition_comp
142
+
143
+ # Then supplement editions
144
+ supplement_chain.each do |supp|
145
+ if supp.edition&.number
146
+ all_editions << "ed-#{supp.edition.number}"
147
+ end
148
+ end
149
+
150
+ # Add all editions to parts
151
+ parts.concat(all_editions)
152
+
153
+ # Base stage logic:
154
+ # - Include if base is proposal stage (10.xx) and supplement has different stage
155
+ # - Don't include if base is approval/publication stage (50.xx, 60.xx)
156
+ # - Don't include if supplement has same stage as base
157
+ base_stage_comp = base_gen.stage_component
158
+ if base_stage_comp
159
+ # Check if any supplement has a stage
160
+ supplement_stages = supplement_chain.filter_map do |supp|
161
+ supp_gen = self.class.new(supp)
162
+ supp_gen.stage_component
163
+ end
164
+
165
+ # Only include base stage if:
166
+ # 1. No supplements have a stage, OR
167
+ # 2. Base is proposal stage (starts with "stage-10.") AND supplements don't duplicate it
168
+ if supplement_stages.empty?
169
+ parts << base_stage_comp
170
+ elsif base_stage_comp.start_with?("stage-10.") && !supplement_stages.include?(base_stage_comp)
171
+ parts << base_stage_comp
172
+ end
173
+ end
174
+
175
+ # Base language (if present)
176
+ if base_id.languages&.any?
177
+ lang_comp = base_id.languages.map(&:code).join(",")
178
+ parts << lang_comp
179
+ end
180
+ end
181
+
182
+ # Now flatten all supplements in order
183
+ supplement_chain.each do |supp|
184
+ supp_gen = self.class.new(supp)
185
+
186
+ # Supplement stage (for draft supplements)
187
+ # Note: editions are added at base level, not here
188
+ stage_comp = supp_gen.stage_component
189
+ parts << stage_comp if stage_comp
190
+
191
+ # Supplement type code (amd, cor, sup)
192
+ suppl_type = supp_gen.supplement_type_component
193
+ parts << suppl_type if suppl_type
194
+
195
+ # Year and version (following RFC 5141-bis supplement semantics)
196
+ if supp.date
197
+ # With date: year:vN
198
+ parts << supp.date.year.to_s
199
+
200
+ # Version with "v" prefix
201
+ # Amendments/Corrigenda keep iteration, generic Supplements don't
202
+ if supp.number
203
+ if supp.stage_iteration && !supp.is_a?(Pubid::Iso::Identifiers::Supplement)
204
+ parts << "v#{supp.number.value}.#{supp.stage_iteration.value}"
205
+ else
206
+ parts << "v#{supp.number.value}"
207
+ end
208
+ end
209
+ else
210
+ # Without date: N:v1 (number directly, then "v1")
211
+ if supp.number
212
+ parts << supp.number.value
213
+ end
214
+
215
+ # Always add "v1" when no date
216
+ # Amendments/Corrigenda keep iteration, generic Supplements don't
217
+ if supp.stage_iteration && !supp.is_a?(Pubid::Iso::Identifiers::Supplement)
218
+ parts << "v1.#{supp.stage_iteration.value}"
219
+ else
220
+ parts << "v1"
221
+ end
222
+ end
223
+
224
+ # Supplement language (RFC 5141-bis: explicit specification)
225
+ if supp.languages&.any?
226
+ lang_comp = supp.languages.map(&:code).join(",")
227
+ parts << lang_comp
228
+ end
229
+ end
230
+
231
+ parts.join(":")
232
+ end
233
+
234
+ # Generate originator component (publisher with copublishers)
235
+ # RFC 5141-bis: supports dynamic copublisher combinations
236
+ def originator_component
237
+ # For identifiers like IWA that don't render publisher, default to "iso"
238
+ return "iso" unless identifier.publisher
239
+
240
+ copubs = identifier.copublishers || []
241
+
242
+ # Collect all publishers in order
243
+ publishers = [identifier.publisher] + copubs
244
+
245
+ # Convert to lowercase and join with hyphen
246
+ # Keep original order (not alphabetical) for backward compatibility
247
+ publishers.map(&:body).map(&:downcase).join("-")
248
+ end
249
+
250
+ # Generate type component
251
+ # RFC 5141-bis: supports extended document types (dir, dir-sup, iwa-sup)
252
+ def type_component
253
+ return nil unless identifier.typed_stage
254
+
255
+ type_code = identifier.typed_stage.type_code
256
+ # International Standard is default (skip it)
257
+ return nil if !type_code || type_code.to_s == "is"
258
+
259
+ # Check for extended type codes first (RFC 5141-bis)
260
+ type_code_sym = type_code.to_sym
261
+ extended_type = TYPE_CODE_MAP[type_code_sym]
262
+ return extended_type if extended_type
263
+
264
+ # Use urn_type_code override if available (e.g., Recommendation uses 'r')
265
+ urn_override = identifier.urn_type_code
266
+ return urn_override if urn_override
267
+
268
+ # Default: use type_code as-is (already a string)
269
+ type_code.to_s
270
+ end
271
+
272
+ # Generate part component
273
+ def part_component
274
+ return nil unless identifier.part
275
+
276
+ result = "-#{identifier.part.value}"
277
+ result += "-#{identifier.subpart.value}" if identifier.subpart
278
+ result
279
+ end
280
+
281
+ # Generate stage component
282
+ # RFC 5141-bis: supports typed stage codes (WD, CD, DIS, FDIS, etc.)
283
+ def stage_component
284
+ return nil unless identifier.typed_stage
285
+
286
+ stage_code = identifier.typed_stage.stage_code
287
+ return nil if !stage_code || stage_code == :published
288
+
289
+ # Try combined stage+type code first (e.g., "cdts" for CD+TS)
290
+ # This handles typed stages where stage_code differs from the full typed stage code
291
+ combined_key = nil
292
+ if identifier.typed_stage.type_code &&
293
+ identifier.typed_stage.type_code != "is" &&
294
+ identifier.typed_stage.type_code.to_s != ""
295
+ combined_key = :"#{stage_code}#{identifier.typed_stage.type_code}"
296
+ end
297
+
298
+ stage_abbr = if combined_key && TYPED_STAGE_MAP.key?(combined_key)
299
+ TYPED_STAGE_MAP[combined_key]
300
+ elsif TYPED_STAGE_MAP.key?(stage_code.to_sym)
301
+ TYPED_STAGE_MAP[stage_code.to_sym]
302
+ end
303
+
304
+ if stage_abbr
305
+
306
+ # Add iteration if present (no 'v' prefix for iterations)
307
+ if identifier.stage_iteration
308
+ return "#{stage_abbr}.#{identifier.stage_iteration.value}"
309
+ end
310
+
311
+ return stage_abbr
312
+ end
313
+
314
+ # Fallback: use harmonized stage codes for unmapped stages
315
+ # This handles stages like PWI, NP, AWI, PRF that don't have typed abbreviations
316
+ harmonized_codes = identifier.typed_stage.harmonized_stages
317
+ return nil unless harmonized_codes&.any?
318
+
319
+ # Use first harmonized code from the array
320
+ harmonized_code = harmonized_codes.first
321
+
322
+ # Skip published documents (60.00, 60.60) EXCEPT for PRF (Proof) stage
323
+ # PRF is at 60.00 but should still be included in URNs
324
+ if harmonized_code.start_with?("60.") && stage_code.to_s != "prf"
325
+ return nil
326
+ end
327
+
328
+ # Format as stage-XX.XX
329
+ stage_part = "stage-#{harmonized_code}"
330
+
331
+ # For base identifiers (not supplements), include iteration in stage code
332
+ # For supplements, iteration goes in the version part (v1.2)
333
+ if identifier.stage_iteration && !identifier.is_a?(SupplementIdentifier)
334
+ stage_part += ".v#{identifier.stage_iteration.value}"
335
+ end
336
+
337
+ stage_part
338
+ end
339
+
340
+ # Generate edition component
341
+ def edition_component
342
+ return nil unless identifier.edition&.number
343
+
344
+ "ed-#{identifier.edition.number}"
345
+ end
346
+
347
+ # Generate year component
348
+ def year_component
349
+ return nil unless identifier.date&.year
350
+
351
+ # ISO base identifiers (SingleIdentifier) use undated URN format (no year)
352
+ # Supplements include their own year in the supplement section
353
+ return nil if identifier.is_a?(Pubid::Iso::SingleIdentifier)
354
+
355
+ identifier.date.year.to_s
356
+ end
357
+
358
+ # Generate language component
359
+ # RFC 5141-bis: explicit specification guidance (explicit > implicit)
360
+ # URN spec: all values in lowercase
361
+ def language_component
362
+ return nil unless identifier.languages&.any?
363
+
364
+ identifier.languages.map(&:code).map(&:downcase).join(",")
365
+ end
366
+
367
+ # Generate supplement type component
368
+ def supplement_type_component
369
+ return nil unless identifier.typed_stage
370
+
371
+ urn_override = identifier.urn_supplement_type
372
+ return urn_override if urn_override
373
+
374
+ identifier.typed_stage.type_code.to_s
375
+ end
376
+
377
+ # Generate supplement year/version components
378
+ # Returns array of parts to be joined with ":"
379
+ def supplement_year_version_components
380
+ parts = []
381
+
382
+ if identifier.date
383
+ # With year: year:version
384
+ parts << identifier.date.year.to_s
385
+
386
+ # Version number with "v" prefix
387
+ if identifier.number
388
+ parts << if identifier.stage_iteration
389
+ "v#{identifier.number.value}.#{identifier.stage_iteration.value}"
390
+ else
391
+ "v#{identifier.number.value}"
392
+ end
393
+ end
394
+ else
395
+ # Without year: number directly or "v1"
396
+ if identifier.number
397
+ parts << identifier.number.value
398
+ end
399
+
400
+ # Version with iteration if present
401
+ parts << if identifier.stage_iteration
402
+ "v1.#{identifier.stage_iteration.value}"
403
+ else
404
+ "v1"
405
+ end
406
+ end
407
+
408
+ parts
409
+ end
410
+ end
411
+ end
412
+ end