pubid 1.15.19 → 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,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ module Components
6
+ autoload :Code, "#{__dir__}/components/code"
7
+ autoload :Edition, "#{__dir__}/components/edition"
8
+ autoload :IssueNumber, "#{__dir__}/components/issue_number"
9
+ autoload :Part, "#{__dir__}/components/part"
10
+ autoload :Publisher, "#{__dir__}/components/publisher"
11
+ autoload :Stage, "#{__dir__}/components/stage"
12
+ autoload :Supplement, "#{__dir__}/components/supplement"
13
+ autoload :Translation, "#{__dir__}/components/translation"
14
+ autoload :Update, "#{__dir__}/components/update"
15
+ autoload :Version, "#{__dir__}/components/version"
16
+ autoload :Volume, "#{__dir__}/components/volume"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Pubid
6
+ module Nist
7
+ # Configuration class responsible for loading and managing series definitions
8
+ # Single Responsibility: Series configuration management
9
+ class Configuration
10
+ attr_reader :series
11
+
12
+ def initialize(series_file_path = nil)
13
+ @series_file_path = series_file_path || default_series_path
14
+ load_series
15
+ end
16
+
17
+ # Get series long name
18
+ # @param series_code [String] the series code (e.g., "SP", "FIPS")
19
+ # @return [String, nil] the long name or nil if not found
20
+ def series_long_name(series_code)
21
+ @series.dig("long", series_code)
22
+ end
23
+
24
+ # Get series abbreviation
25
+ # @param series_code [String] the series code
26
+ # @return [String, nil] the abbreviation or nil if not found
27
+ def series_abbrev(series_code)
28
+ @series.dig("abbrev", series_code)
29
+ end
30
+
31
+ # Get series MR (machine-readable) format
32
+ # @param series_code [String] the series code
33
+ # @return [String, nil] the MR format or nil if not found
34
+ def series_mr(series_code)
35
+ @series.dig("mr", series_code)
36
+ end
37
+
38
+ # Check if series code is valid
39
+ # @param series_code [String] the series code
40
+ # @return [Boolean] true if series is valid
41
+ def valid_series?(series_code)
42
+ @series["long"].key?(series_code)
43
+ end
44
+
45
+ # Get all series codes
46
+ # @return [Array<String>] all valid series codes
47
+ def all_series_codes
48
+ @series["long"].keys
49
+ end
50
+
51
+ # Get series code from MR format
52
+ # @param mr_format [String] the MR format
53
+ # @return [String, nil] the series code or nil if not found
54
+ def series_from_mr(mr_format)
55
+ @series["mr"].key(mr_format)
56
+ end
57
+
58
+ private
59
+
60
+ def default_series_path
61
+ File.join(__dir__, "../../../gems/pubid-nist/series.yaml")
62
+ end
63
+
64
+ def load_series
65
+ @series = YAML.load_file(@series_file_path)
66
+ rescue Errno::ENOENT
67
+ raise ConfigurationError,
68
+ "Series configuration file not found: #{@series_file_path}"
69
+ rescue Psych::SyntaxError => e
70
+ raise ConfigurationError,
71
+ "Invalid YAML in series configuration: #{e.message}"
72
+ end
73
+ end
74
+
75
+ class ConfigurationError < StandardError; end
76
+ end
77
+ end
@@ -0,0 +1,499 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ module Identifiers
6
+ # Base NIST/NBS identifier class
7
+ # Each series type inherits from this and overrides series_code
8
+ class Base < Pubid::Identifier
9
+ # Default: no typed stages. Subclasses override as needed.
10
+ def self.typed_stages
11
+ []
12
+ end
13
+
14
+ # Generate URN for this identifier
15
+ #
16
+ # @return [String] URN representation
17
+
18
+ attribute :publisher, Components::Publisher
19
+ attribute :series, Components::Code # Set by Builder from parsed data
20
+ attribute :number, Components::Code
21
+
22
+ # V2 COMPONENTS (Lutaml::Model objects) - PROPER SEPARATION
23
+ attribute :edition, Components::Edition # Edition (type + id): e2, e2021, r5, -3
24
+ attribute :edition_component, Components::Edition # V2 edition component (alias)
25
+ attribute :volume, Components::Volume # Volume component (v6)
26
+ attribute :part, Components::Part # Part component (n1 or pt1)
27
+ attribute :stage, Components::Stage
28
+ attribute :version_component, Components::Version
29
+ attribute :update_component, Components::Update
30
+ attribute :translation_component, Components::Translation
31
+ attribute :issue_number, Components::IssueNumber
32
+ attribute :parsed_format, :string # :mr, :short, :long, :abbrev
33
+ attribute :publisher_was_parsed, :boolean, default: -> { false }
34
+
35
+ # LEGACY attributes (keep for backward compatibility during migration)
36
+ attribute :parts, Components::Code, collection: true
37
+ attribute :revision, :string
38
+ attribute :revision_year, :string # Year for revision (e.g., r6/1925, r1963, rJun1992)
39
+ attribute :revision_month, :string # Month for revision (e.g., rJun1992)
40
+ attribute :edition_year, :string # Legacy edition year for backward compatibility
41
+ attribute :version, :string
42
+ attribute :update, Components::Update
43
+ attribute :year, :integer
44
+ attribute :month, :integer
45
+
46
+ # Additional attributes for complex patterns
47
+ attribute :first_number, Components::Code
48
+ attribute :second_number, Components::Code
49
+ attribute :update_number, :string
50
+ attribute :update_year, :string
51
+ attribute :addendum, :string
52
+ attribute :addendum_number, :string
53
+ attribute :supplement, :string
54
+ attribute :supplement_date_range_start, :string # For date ranges like Jan1924-Jan1926
55
+ attribute :supplement_date_range_end, :string
56
+ attribute :supplement_has_revision, :boolean, default: -> { false }
57
+ attribute :errata, :string
58
+ attribute :index, :string
59
+ attribute :insert, :string
60
+ attribute :section, :string
61
+ attribute :appendix, :string
62
+ attribute :translation, :string
63
+ attribute :draft, :string
64
+ attribute :draft_number, :string # For -draft N → N pd rendering
65
+
66
+ # Default series_code — subclasses override to provide a normalized series name.
67
+ def series_code
68
+ nil
69
+ end
70
+
71
+ def initialize(**attributes)
72
+ super()
73
+
74
+ attrs = self.class.attributes
75
+ attributes.each do |key, value|
76
+ next if value.nil?
77
+
78
+ setter = :"#{key}="
79
+ public_send(setter, value) if attrs.key?(key)
80
+ end
81
+
82
+ # NOTE: Compound number building is handled by the Builder class
83
+ # Do NOT build compound numbers here - let the builder apply special patterns first
84
+ # See lib/pubid/nist/builder.rb lines 368-472 for compound number logic
85
+ end
86
+
87
+ # Compute revision from edition component for backward compatibility
88
+ # @return [String, nil] revision string (e.g., "r5") or nil
89
+ def revision
90
+ return @revision if @revision
91
+
92
+ # Compute from edition component if available
93
+ if edition&.type && edition.id
94
+ "#{edition.type}#{edition.id}"
95
+ end
96
+ end
97
+
98
+ # Backward compatibility: translation method returns translation_component
99
+ # This allows tests to use parsed.translation.language instead of parsed.translation_component.language
100
+ def translation
101
+ translation_component
102
+ end
103
+
104
+ # Backward compatibility: language method returns translation_component
105
+ # This allows tests to use parsed.language instead of parsed.translation_component
106
+ def language
107
+ translation_component
108
+ end
109
+
110
+ # Generate identifier string in specified format
111
+ # @param format [:full, :long, :abbreviated, :short, :mr] output format
112
+ def to_s(format = nil)
113
+ # Handle both keyword argument (hash) and positional argument (symbol/string)
114
+ format = format[:format] if format.is_a?(Hash)
115
+
116
+ # Default to parsed_format if available (preserves input format on round-trip)
117
+ # Falls back to :short format for output (normalization)
118
+ # Explicit format parameter always overrides parsed_format
119
+ effective_format = format || parsed_format&.to_sym || :short
120
+ effective_format = effective_format.to_sym if effective_format.is_a?(String)
121
+ case effective_format
122
+ when :full, :long
123
+ to_full_style
124
+ when :abbreviated, :abbrev
125
+ to_abbreviated_style
126
+ when :short
127
+ to_short_style
128
+ when :mr
129
+ to_mr_style
130
+ else
131
+ to_short_style
132
+ end
133
+ end
134
+
135
+ # Returns weight based on amount of defined attributes
136
+ # Used for ranking identifiers by specificity for conflict resolution
137
+ # @return [Integer] weight score (higher = more specific)
138
+ def weight
139
+ self.class.attributes.keys.inject(0) do |sum, key|
140
+ val = public_send(key)
141
+ val && !val.to_s.empty? ? sum + 1 : sum
142
+ end
143
+ end
144
+
145
+ # Merge another document into this one
146
+ # Used for combining document data, preferring more specific values
147
+ # @param document [Base] another NIST document to merge
148
+ # @return [Base] self with merged attributes
149
+ def merge(document)
150
+ return self unless document.is_a?(Base)
151
+
152
+ attrs = self.class.attributes
153
+ attrs.each_key do |var_name|
154
+ next if var_name == :rendering_style
155
+ next if var_name == :parsed_format
156
+
157
+ current_val = public_send(var_name)
158
+ new_val = document.public_send(var_name)
159
+ next unless new_val
160
+
161
+ should_merge = case var_name
162
+ when :publisher, :series, :number
163
+ true
164
+ when :edition
165
+ current_val.nil? || edition_greater?(new_val,
166
+ current_val)
167
+ when :volume, :part, :version, :revision
168
+ current_val.nil? || (new_val.to_s.length > current_val.to_s.length)
169
+ when :supplement, :errata, :index, :insert, :section, :appendix, :translation
170
+ true
171
+ when :year, :month, :update, :draft
172
+ true
173
+ else
174
+ false
175
+ end
176
+
177
+ public_send(:"#{var_name}=", new_val) if should_merge
178
+ end
179
+
180
+ self
181
+ end
182
+
183
+ # Helper to compare edition values numerically
184
+ # @return [Boolean] true if edition1 is greater than edition2
185
+ def edition_greater?(edition1, edition2)
186
+ num1 = extract_edition_number(edition1)
187
+ num2 = extract_edition_number(edition2)
188
+ num1 && num2 && num1 > num2
189
+ end
190
+
191
+ # Extract numeric value from edition (r3 -> 3, r5 -> 5, e2 -> 2)
192
+ # @return [Integer, nil] the edition number or nil if not extractable
193
+ def extract_edition_number(edition)
194
+ # Handle both String and Edition component
195
+ edition_str = edition.to_s
196
+ # Match patterns like r3, r5, e2, etc.
197
+ match = edition_str.match(/^[er]?(\d+)$/)
198
+ match ? match[1].to_i : nil
199
+ end
200
+
201
+ private
202
+
203
+ def to_full_style
204
+ # "National Institute of Standards and Technology Special Publication 800-27, Revision A"
205
+ result = publisher_full_name
206
+ result += " #{series_full_name}" if series
207
+ result += " #{number.value}" if number
208
+ result += parts.map { |p| "-#{p}" }.join if parts&.any?
209
+
210
+ # Render volume and issue number in long form: "Vol. 6, No. 12"
211
+ if volume && issue_number
212
+ result += " Vol. #{volume}, #{issue_number.to_s(:long)}"
213
+ elsif volume
214
+ result += " Vol. #{volume}"
215
+ end
216
+
217
+ # NEW: Use edition component properly
218
+ result += " #{edition.to_s(:long)}" if edition
219
+
220
+ result += ", Revision #{revision.sub(/^r/, '')}" if revision
221
+
222
+ # V2: Use version_component
223
+ result += " #{version_component.to_s(:long)}" if version_component
224
+
225
+ # V2: Use update_component
226
+ result += " #{update_component.to_s(:long)}" if update_component
227
+
228
+ # V2: Use stage
229
+ result += " #{stage.to_s(:long)}" if stage
230
+
231
+ # V2: Use translation_component (already includes space)
232
+ result += translation_component.to_s(:long) if translation_component
233
+
234
+ result
235
+ end
236
+
237
+ def to_abbreviated_style
238
+ # "Natl. Inst. Stand. Technol. Spec. Publ. 800-57 Part 1, Revision 4"
239
+ result = publisher_abbreviated_name
240
+ result += " #{series_abbreviated_name}" if series
241
+ result += " #{number}" if number
242
+ result += " Part #{parts.first}" if parts&.any?
243
+
244
+ # NEW: Use edition component properly
245
+ result += " #{edition.to_s(:abbrev)}" if edition
246
+
247
+ result += ", Revision #{revision}" if revision
248
+
249
+ # V2: Use version_component
250
+ result += " #{version_component.to_s(:abbrev)}" if version_component
251
+
252
+ # V2: Use update_component
253
+ result += " #{update_component.to_s(:abbrev)}" if update_component
254
+
255
+ # V2: Use stage
256
+ result += " #{stage.to_s(:abbrev)}" if stage
257
+
258
+ # V2: Use translation_component
259
+ result += ", #{translation_component.to_s(:abbrev)}" if translation_component
260
+
261
+ result
262
+ end
263
+
264
+ def to_short_style
265
+ # "SP 800-187" or "NIST SP 800-187" - handle compound series properly
266
+ result = ""
267
+
268
+ # Determine effective publisher
269
+ # Only show publisher if it was explicitly parsed (either directly or from series prefix)
270
+ effective_publisher = if publisher && publisher_was_parsed
271
+ # Publisher was in input (either as separate field or extracted from "NBS CS" series)
272
+ publisher.to_s
273
+ else
274
+ # No publisher in input, don't show default
275
+ nil
276
+ end
277
+
278
+ # Determine effective series - PREFER series_code if subclass defines it
279
+ # This allows normalization (e.g., LCIRC → LC in LetterCircular)
280
+ effective_series = if series_code
281
+ series_code
282
+ elsif series
283
+ series.to_s
284
+ end
285
+
286
+ # Special handling for compound series that include publisher prefix
287
+ # If series starts with "NBS " (like "NBS CIRC"), use it as-is
288
+ if effective_series&.start_with?("NBS ")
289
+ result += effective_series
290
+ elsif effective_publisher && effective_series
291
+ result += "#{effective_publisher} #{effective_series}"
292
+ elsif effective_series && publisher_was_parsed
293
+ # Only add "NIST" prefix if publisher was explicitly in the input
294
+ result += "NIST #{effective_series}"
295
+ elsif effective_series
296
+ # No publisher in input, just show series without prefix
297
+ result += effective_series
298
+ end
299
+
300
+ result += " #{number}" if number
301
+ result += parts.map { |p| "-#{p}" }.join if parts&.any?
302
+
303
+ # NEW: Use Volume and Part components (v6n1 notation for CSM, pt1 for SP)
304
+ if volume.is_a?(Components::Volume) && part.is_a?(Components::Part)
305
+ # CSM series: v#n# notation
306
+ result += " #{volume}#{part}"
307
+ elsif part.is_a?(Components::Part)
308
+ # SP and other series: use Part.type to determine format
309
+ result += part.to_s
310
+ # Legacy: Render standalone volume (not part of v#n#)
311
+ elsif volume && !issue_number && !part
312
+ vol_str = volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}"
313
+ result += vol_str
314
+ elsif volume && issue_number
315
+ # Render volume and issue number in short form: "v6n12"
316
+ vol_str = volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}"
317
+ result += "#{vol_str}n#{issue_number.number}"
318
+ end
319
+
320
+ # NEW: Use edition component properly (e2, e2021, r5, -3)
321
+ # NO space before edition when number present (per NIST spec)
322
+ # Only add space for bare edition (no number case) or if original_prefix has specific format
323
+ if edition
324
+ if edition.original_prefix && !edition.original_prefix.empty?
325
+ # original_prefix includes the full prefix (e.g., " Rev. " for verbose format)
326
+ result += edition.to_s
327
+ elsif number
328
+ # Number present, NO space: "800-53r5"
329
+ result += edition.to_s
330
+ else
331
+ # Bare edition, add space: " r5"
332
+ result += " #{edition}"
333
+ end
334
+ end
335
+
336
+ # V2: Use version_component if available, else use version string
337
+ if version_component
338
+ result += " #{version_component.to_s(:short)}"
339
+ elsif version
340
+ result += " Ver. #{version}"
341
+ end
342
+
343
+ # Add supplement with date range support - FIX: proper spacing
344
+ if supplement_date_range_start && supplement_date_range_end
345
+ result += "supp#{supplement_date_range_start}-#{supplement_date_range_end}"
346
+ elsif supplement_has_revision
347
+ result += "supprev"
348
+ elsif supplement && !supplement.empty?
349
+ # Smart dash logic:
350
+ # - If supplement starts with letter (month like "Jan1924"), NO dash
351
+ # - If supplement is digits only (year like "1924"), WITH dash
352
+ result += if supplement.match?(/^[A-Z]/)
353
+ "supp#{supplement}"
354
+ else
355
+ "supp-#{supplement}"
356
+ end
357
+ elsif supplement
358
+ result += "supp"
359
+ end
360
+
361
+ # Add other attributes
362
+ result += errata.to_s if errata
363
+ result += "index" if index
364
+ result += "insert" if insert
365
+ result += "sec#{section}" if section
366
+ result += "app" if appendix
367
+
368
+ # Add addendum - render as " Add." suffix
369
+ if addendum || addendum_number
370
+ result += " Add."
371
+ end
372
+
373
+ # V2: Use update_component if available, else use update string
374
+ if update_component
375
+ result += update_component.to_s(:short)
376
+ elsif update
377
+ result += "-upd#{update}"
378
+ end
379
+
380
+ # Add draft - render as {N}pd if draft_number present
381
+ if draft_number
382
+ result += " #{draft_number}pd"
383
+ elsif draft&.to_s&.include?("draft") && !draft.to_s.include?("Draft)")
384
+ result += "-draft"
385
+ end
386
+
387
+ # V2: Add stage component (at end, before translation)
388
+ if stage
389
+ result += " #{stage.to_s(:short)}"
390
+ end
391
+
392
+ # V2: Use translation_component if available, else use translation string
393
+ # Note: translation_component.to_s already includes the space prefix
394
+ if translation_component
395
+ result += translation_component.to_s(:short)
396
+ elsif translation
397
+ result += " #{translation}"
398
+ end
399
+
400
+ result
401
+ end
402
+
403
+ def to_mr_style
404
+ # "NIST.SP.800-116r1.ipd" (machine-readable with dots)
405
+ result = (publisher || "NIST").to_s
406
+
407
+ # Determine effective series - PREFER series_code if subclass defines it
408
+ # This allows normalization (e.g., LCIRC → LC in LetterCircular)
409
+ effective_series = if series_code
410
+ series_code
411
+ elsif series
412
+ series.to_s
413
+ end
414
+
415
+ result += ".#{effective_series}" if effective_series
416
+ result += ".#{number}" if number
417
+ result += parts.map { |p| "-#{p}" }.join if parts&.any?
418
+
419
+ # Part component (pt1, v6n1, etc.)
420
+ result += part.to_s if part.is_a?(Components::Part)
421
+
422
+ # NEW: Use edition component - NO space before edition in MR format (per NIST spec)
423
+ if edition
424
+ # If edition has original_prefix set (e.g., verbose " Rev. "), use it as-is
425
+ # Otherwise, no space needed in MR format: ".800-53r5"
426
+ if edition.original_prefix && !edition.original_prefix.empty?
427
+ end
428
+ result += edition.to_s
429
+ end
430
+
431
+ # V2: Use version_component
432
+ result += version_component.to_s(:mr) if version_component
433
+
434
+ # V2: Use update_component
435
+ result += update_component.to_s(:mr) if update_component
436
+
437
+ # V2: Use stage
438
+ result += ".#{stage.to_s(:mr)}" if stage
439
+
440
+ # Add addendum - render as ".Add." suffix in MR format
441
+ if addendum || addendum_number
442
+ result += ".Add."
443
+ end
444
+
445
+ # V2: Use translation_component
446
+ result += translation_component.to_s(:mr) if translation_component
447
+
448
+ result
449
+ end
450
+
451
+ def series_full_name
452
+ {
453
+ "SP" => "Special Publication",
454
+ "FIPS" => "Federal Information Processing Standards",
455
+ "IR" => "Interagency Report",
456
+ "TN" => "Technical Note",
457
+ }[series] || series
458
+ end
459
+
460
+ def series_abbreviated_name
461
+ {
462
+ "SP" => "Spec. Publ.",
463
+ "FIPS" => "Fed. Inf. Proc. Stand.",
464
+ "IR" => "Interag. Rep.",
465
+ "TN" => "Tech. Note",
466
+ }[series&.to_s || series_code] || (series&.to_s || series_code)
467
+ end
468
+
469
+ def publisher_full_name
470
+ case publisher.to_s
471
+ when "NBS"
472
+ "National Bureau of Standards"
473
+ when "NIST"
474
+ "National Institute of Standards and Technology"
475
+ else
476
+ publisher.to_s
477
+ end
478
+ end
479
+
480
+ def publisher_abbreviated_name
481
+ case publisher.to_s
482
+ when "NBS"
483
+ "Natl. Bur. Stand."
484
+ when "NIST"
485
+ "Natl. Inst. Stand. Technol."
486
+ else
487
+ publisher.to_s
488
+ end
489
+ end
490
+
491
+ # Default publisher for series without explicit publisher
492
+ # Subclasses can override
493
+ def default_publisher
494
+ "NIST"
495
+ end
496
+ end
497
+ end
498
+ end
499
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Nist
5
+ module Identifiers
6
+ # NBS Circular Identifier
7
+ # Examples:
8
+ # - "NBS CIRC 13e2revJune1908" = Circular 13, edition 2, revised June 1908
9
+ # - "NBS CIRC 13" = Circular 13
10
+ class Circular < Base
11
+ TYPED_STAGES = [
12
+ Pubid::Components::TypedStage.new(
13
+ abbr: ["CIRC", "NBS CIRC"],
14
+ stage_code: "published",
15
+ type_code: "circ",
16
+ ),
17
+ ].freeze
18
+
19
+ class << self
20
+ def typed_stages
21
+ TYPED_STAGES
22
+ end
23
+
24
+ def type
25
+ { key: :circ, title: "NBS Circular", short: "CIRC" }
26
+ end
27
+ end
28
+
29
+ attribute :revised_date, :string # For revJune1908 notation
30
+
31
+ def default_publisher
32
+ "NBS"
33
+ end
34
+
35
+ def series_code
36
+ "CIRC"
37
+ end
38
+
39
+ # Convenience methods for tests that expect string values
40
+ def publisher
41
+ super&.to_s || default_publisher
42
+ end
43
+
44
+ def series
45
+ super&.to_s || series_code
46
+ end
47
+
48
+ # Override to_s for CIRC-specific edition+year rendering
49
+ # CIRC uses dot notation: "NBS CIRC 11e2.1915" instead of "NBS CIRC 11e2-1915"
50
+ def to_s(format = nil)
51
+ result = super
52
+
53
+ # For CIRC edition patterns with additional_text (year), render with dot notation
54
+ # "11e2-1915" format: edition.id="2", additional_text="1915" → render as "11e2.1915"
55
+ if edition && edition.type == "e" && edition.additional_text&.match?(/^\d{4}$/)
56
+ # Replace "11e1915" with "11e2.1915" format
57
+ # Pattern: number + "e" + year (where year was stored in edition.id)
58
+ # Need to reconstruct: number + "e" + edition.id + "." + additional_text
59
+ result = result.gsub(/e(\d{4})$/,
60
+ "e#{edition.id || '?'}.#{edition.additional_text}")
61
+ end
62
+
63
+ result
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end