pubid 2.0.0.alpha.10 → 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 (811) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +51 -54
  3. data/data/iec/update_codes.yaml +0 -3
  4. data/data/ieee/update_codes.yaml +1 -107
  5. data/data/nist/update_codes.yaml +0 -35
  6. data/lib/pubid/amca/builder.rb +6 -6
  7. data/lib/pubid/amca/identifier.rb +16 -2
  8. data/lib/pubid/amca/identifiers/base.rb +46 -74
  9. data/lib/pubid/amca/identifiers/interpretation.rb +30 -17
  10. data/lib/pubid/amca/identifiers/publication.rb +27 -14
  11. data/lib/pubid/amca/identifiers/standard.rb +5 -3
  12. data/lib/pubid/amca/identifiers.rb +1 -0
  13. data/lib/pubid/amca/parser.rb +1 -1
  14. data/lib/pubid/amca/scheme.rb +16 -0
  15. data/lib/pubid/amca/single_identifier.rb +24 -1
  16. data/lib/pubid/amca/urn_generator.rb +3 -4
  17. data/lib/pubid/amca.rb +3 -50
  18. data/lib/pubid/ansi/builder.rb +5 -7
  19. data/lib/pubid/ansi/identifier.rb +1 -19
  20. data/lib/pubid/ansi/identifiers/american_national_standard.rb +1 -2
  21. data/lib/pubid/ansi/identifiers/standard.rb +3 -2
  22. data/lib/pubid/ansi/parser.rb +1 -1
  23. data/lib/pubid/ansi/scheme.rb +15 -0
  24. data/lib/pubid/ansi/single_identifier.rb +31 -2
  25. data/lib/pubid/ansi/urn_generator.rb +38 -3
  26. data/lib/pubid/ansi.rb +6 -47
  27. data/lib/pubid/api/builder.rb +72 -45
  28. data/lib/pubid/api/identifier.rb +9 -30
  29. data/lib/pubid/api/identifiers/base.rb +14 -2
  30. data/lib/pubid/api/identifiers/bulletin.rb +2 -0
  31. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +2 -0
  32. data/lib/pubid/api/identifiers/mpms.rb +28 -10
  33. data/lib/pubid/api/identifiers/publication.rb +2 -0
  34. data/lib/pubid/api/identifiers/recommended_practice.rb +2 -0
  35. data/lib/pubid/api/identifiers/specification.rb +2 -0
  36. data/lib/pubid/api/identifiers/standard.rb +2 -0
  37. data/lib/pubid/api/identifiers/technical_report.rb +2 -0
  38. data/lib/pubid/api/identifiers/typeless_standard.rb +16 -0
  39. data/lib/pubid/api/parser.rb +1 -1
  40. data/lib/pubid/api/scheme.rb +66 -0
  41. data/lib/pubid/api/single_identifier.rb +32 -10
  42. data/lib/pubid/api/urn_generator.rb +18 -0
  43. data/lib/pubid/api.rb +5 -56
  44. data/lib/pubid/ashrae/builder.rb +35 -56
  45. data/lib/pubid/ashrae/identifier.rb +16 -6
  46. data/lib/pubid/ashrae/identifiers/addenda_package.rb +11 -7
  47. data/lib/pubid/ashrae/identifiers/addendum.rb +20 -9
  48. data/lib/pubid/ashrae/identifiers/base.rb +15 -111
  49. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +16 -8
  50. data/lib/pubid/ashrae/identifiers/errata.rb +10 -9
  51. data/lib/pubid/ashrae/identifiers/guideline.rb +0 -3
  52. data/lib/pubid/ashrae/identifiers/interpretation.rb +10 -16
  53. data/lib/pubid/ashrae/identifiers/standard.rb +0 -3
  54. data/lib/pubid/ashrae/identifiers.rb +1 -0
  55. data/lib/pubid/ashrae/parser.rb +16 -40
  56. data/lib/pubid/ashrae/scheme.rb +53 -0
  57. data/lib/pubid/ashrae/single_identifier.rb +14 -1
  58. data/lib/pubid/ashrae/supplement_identifier.rb +6 -21
  59. data/lib/pubid/ashrae/urn_generator.rb +10 -8
  60. data/lib/pubid/ashrae.rb +2 -58
  61. data/lib/pubid/asme/builder.rb +2 -11
  62. data/lib/pubid/asme/components/code.rb +2 -10
  63. data/lib/pubid/asme/identifier.rb +0 -9
  64. data/lib/pubid/asme/identifiers/base.rb +60 -0
  65. data/lib/pubid/asme/identifiers/standard.rb +2 -86
  66. data/lib/pubid/asme/parser.rb +1 -1
  67. data/lib/pubid/asme/scheme.rb +37 -0
  68. data/lib/pubid/asme/single_identifier.rb +2 -11
  69. data/lib/pubid/asme/urn_generator.rb +2 -2
  70. data/lib/pubid/asme.rb +1 -47
  71. data/lib/pubid/astm/builder.rb +3 -10
  72. data/lib/pubid/astm/components/code.rb +0 -9
  73. data/lib/pubid/astm/identifier.rb +0 -9
  74. data/lib/pubid/astm/identifiers/adjunct.rb +9 -16
  75. data/lib/pubid/astm/identifiers/data_series.rb +14 -2
  76. data/lib/pubid/astm/identifiers/iso_dual_published.rb +34 -25
  77. data/lib/pubid/astm/identifiers/manual.rb +25 -8
  78. data/lib/pubid/astm/identifiers/monograph.rb +14 -2
  79. data/lib/pubid/astm/identifiers/research_report.rb +5 -8
  80. data/lib/pubid/astm/identifiers/standard.rb +37 -8
  81. data/lib/pubid/astm/identifiers/technical_report.rb +13 -2
  82. data/lib/pubid/astm/identifiers/work_in_progress.rb +10 -1
  83. data/lib/pubid/astm/parser.rb +1 -1
  84. data/lib/pubid/astm/scheme.rb +55 -0
  85. data/lib/pubid/astm/single_identifier.rb +10 -32
  86. data/lib/pubid/astm/urn_generator.rb +5 -7
  87. data/lib/pubid/astm.rb +27 -44
  88. data/lib/pubid/bsi/builder.rb +107 -119
  89. data/lib/pubid/bsi/identifier.rb +25 -4
  90. data/lib/pubid/bsi/identifiers/addendum_document.rb +37 -3
  91. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +47 -19
  92. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +39 -8
  93. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +55 -2
  94. data/lib/pubid/bsi/identifiers/amendment.rb +22 -30
  95. data/lib/pubid/bsi/identifiers/base.rb +11 -0
  96. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +7 -1
  97. data/lib/pubid/bsi/identifiers/british_standard.rb +1 -2
  98. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +87 -13
  99. data/lib/pubid/bsi/identifiers/committee_document.rb +17 -10
  100. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +87 -19
  101. data/lib/pubid/bsi/identifiers/corrigendum.rb +10 -26
  102. data/lib/pubid/bsi/identifiers/detailed_specification.rb +36 -0
  103. data/lib/pubid/bsi/identifiers/disc.rb +29 -0
  104. data/lib/pubid/bsi/identifiers/draft_document.rb +46 -2
  105. data/lib/pubid/bsi/identifiers/electronic_book.rb +38 -2
  106. data/lib/pubid/bsi/identifiers/expert_commentary.rb +21 -10
  107. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +47 -0
  108. data/lib/pubid/bsi/identifiers/flex.rb +34 -3
  109. data/lib/pubid/bsi/identifiers/handbook.rb +17 -1
  110. data/lib/pubid/bsi/identifiers/index.rb +32 -0
  111. data/lib/pubid/bsi/identifiers/method.rb +41 -0
  112. data/lib/pubid/bsi/identifiers/national_annex.rb +29 -4
  113. data/lib/pubid/bsi/identifiers/practice_guide.rb +7 -1
  114. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +54 -2
  115. data/lib/pubid/bsi/identifiers/published_document.rb +54 -2
  116. data/lib/pubid/bsi/identifiers/section.rb +30 -0
  117. data/lib/pubid/bsi/identifiers/set.rb +20 -14
  118. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -10
  119. data/lib/pubid/bsi/identifiers/supplement_document.rb +25 -3
  120. data/lib/pubid/bsi/identifiers/supplementary_index.rb +46 -0
  121. data/lib/pubid/bsi/identifiers/technical_specification.rb +47 -2
  122. data/lib/pubid/bsi/identifiers/test_method.rb +32 -0
  123. data/lib/pubid/bsi/identifiers/value_added_publication.rb +22 -7
  124. data/lib/pubid/bsi/identifiers.rb +1 -0
  125. data/lib/pubid/bsi/parser.rb +6 -20
  126. data/lib/pubid/bsi/scheme.rb +243 -0
  127. data/lib/pubid/bsi/single_identifier.rb +82 -94
  128. data/lib/pubid/bsi/urn_generator.rb +5 -13
  129. data/lib/pubid/bsi.rb +2 -252
  130. data/lib/pubid/builder/base.rb +13 -62
  131. data/lib/pubid/bundled_identifier.rb +10 -18
  132. data/lib/pubid/ccsds/builder.rb +4 -5
  133. data/lib/pubid/ccsds/identifier.rb +3 -63
  134. data/lib/pubid/ccsds/identifiers/base.rb +51 -14
  135. data/lib/pubid/ccsds/identifiers/corrigendum.rb +8 -9
  136. data/lib/pubid/ccsds/parser.rb +3 -5
  137. data/lib/pubid/ccsds/scheme.rb +57 -0
  138. data/lib/pubid/ccsds/single_identifier.rb +3 -6
  139. data/lib/pubid/ccsds/supplement_identifier.rb +13 -17
  140. data/lib/pubid/ccsds/urn_generator.rb +6 -6
  141. data/lib/pubid/ccsds.rb +1 -44
  142. data/lib/pubid/cen_cenelec/builder.rb +29 -61
  143. data/lib/pubid/cen_cenelec/identifier.rb +5 -28
  144. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +4 -9
  145. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +12 -2
  146. data/lib/pubid/cen_cenelec/identifiers/base.rb +46 -5
  147. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -2
  148. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -2
  149. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +27 -6
  150. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +17 -2
  151. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +4 -62
  152. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +7 -20
  153. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -2
  154. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +6 -2
  155. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -2
  156. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -2
  157. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -2
  158. data/lib/pubid/cen_cenelec/parser.rb +1 -1
  159. data/lib/pubid/cen_cenelec/scheme.rb +164 -0
  160. data/lib/pubid/cen_cenelec/single_identifier.rb +91 -10
  161. data/lib/pubid/cen_cenelec/supplement_identifier.rb +7 -6
  162. data/lib/pubid/cen_cenelec/urn_generator.rb +7 -7
  163. data/lib/pubid/cen_cenelec.rb +1 -188
  164. data/lib/pubid/cie/builder.rb +24 -149
  165. data/lib/pubid/cie/components/code.rb +72 -0
  166. data/lib/pubid/cie/identifier.rb +5 -20
  167. data/lib/pubid/cie/identifiers/bundle.rb +5 -35
  168. data/lib/pubid/cie/identifiers/conference.rb +6 -11
  169. data/lib/pubid/cie/identifiers/corrigendum.rb +23 -17
  170. data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
  171. data/lib/pubid/cie/identifiers/identical.rb +9 -9
  172. data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
  173. data/lib/pubid/cie/identifiers/standard.rb +8 -43
  174. data/lib/pubid/cie/identifiers/supplement.rb +25 -27
  175. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +3 -7
  176. data/lib/pubid/cie/identifiers.rb +0 -2
  177. data/lib/pubid/cie/parser.rb +6 -55
  178. data/lib/pubid/cie/scheme.rb +64 -0
  179. data/lib/pubid/cie/single_identifier.rb +5 -44
  180. data/lib/pubid/cie/supplement_identifier.rb +16 -29
  181. data/lib/pubid/cie/urn_generator.rb +8 -11
  182. data/lib/pubid/cie.rb +2 -57
  183. data/lib/pubid/components/code.rb +8 -22
  184. data/lib/pubid/components/date.rb +18 -41
  185. data/lib/pubid/components/edition.rb +6 -9
  186. data/lib/pubid/components/language.rb +4 -6
  187. data/lib/pubid/components/locality.rb +1 -10
  188. data/lib/pubid/components/publisher.rb +6 -9
  189. data/lib/pubid/components/stage.rb +14 -5
  190. data/lib/pubid/components/type.rb +15 -5
  191. data/lib/pubid/components/typed_stage.rb +8 -11
  192. data/lib/pubid/components.rb +0 -4
  193. data/lib/pubid/core/update_codes.rb +7 -28
  194. data/lib/pubid/csa/builder.rb +48 -48
  195. data/lib/pubid/csa/composite_identifier.rb +7 -18
  196. data/lib/pubid/csa/identifier.rb +78 -191
  197. data/lib/pubid/csa/identifiers/base.rb +123 -0
  198. data/lib/pubid/csa/identifiers/bundled.rb +9 -25
  199. data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
  200. data/lib/pubid/csa/identifiers/cec.rb +103 -40
  201. data/lib/pubid/csa/identifiers/combined.rb +69 -97
  202. data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
  203. data/lib/pubid/csa/identifiers/package.rb +4 -4
  204. data/lib/pubid/csa/identifiers/series.rb +104 -0
  205. data/lib/pubid/csa/parser.rb +8 -12
  206. data/lib/pubid/csa/scheme.rb +44 -0
  207. data/lib/pubid/csa/single_identifier.rb +5 -94
  208. data/lib/pubid/csa/urn_generator.rb +2 -9
  209. data/lib/pubid/csa/wrapper_identifier.rb +10 -43
  210. data/lib/pubid/csa.rb +1 -56
  211. data/lib/pubid/etsi/builder.rb +4 -13
  212. data/lib/pubid/etsi/components/code.rb +9 -10
  213. data/lib/pubid/etsi/components/version.rb +5 -0
  214. data/lib/pubid/etsi/identifier.rb +12 -2
  215. data/lib/pubid/etsi/identifiers/base.rb +24 -60
  216. data/lib/pubid/etsi/identifiers/etsi_standard.rb +4 -207
  217. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +14 -46
  218. data/lib/pubid/etsi/identifiers.rb +1 -0
  219. data/lib/pubid/etsi/parser.rb +3 -9
  220. data/lib/pubid/etsi/scheme.rb +42 -0
  221. data/lib/pubid/etsi.rb +2 -52
  222. data/lib/pubid/export/data_class_exporter.rb +59 -0
  223. data/lib/pubid/export/exporter.rb +47 -6
  224. data/lib/pubid/export/flavor_exporter.rb +276 -124
  225. data/lib/pubid/export/ieee_exporter.rb +78 -0
  226. data/lib/pubid/export/itu_exporter.rb +66 -0
  227. data/lib/pubid/export/nist_exporter.rb +64 -0
  228. data/lib/pubid/export/registry_exporter.rb +90 -0
  229. data/lib/pubid/export/scheme_exporter.rb +70 -0
  230. data/lib/pubid/export.rb +6 -0
  231. data/lib/pubid/identifier.rb +37 -920
  232. data/lib/pubid/identifier_metadata.rb +1 -1
  233. data/lib/pubid/identifier_registry.rb +198 -0
  234. data/lib/pubid/idf/builder.rb +7 -7
  235. data/lib/pubid/idf/identifier.rb +13 -23
  236. data/lib/pubid/idf/identifiers/amendment.rb +1 -2
  237. data/lib/pubid/idf/identifiers/corrigendum.rb +1 -2
  238. data/lib/pubid/idf/identifiers/international_standard.rb +1 -2
  239. data/lib/pubid/idf/identifiers/reviewed_method.rb +1 -2
  240. data/lib/pubid/idf/parser.rb +5 -6
  241. data/lib/pubid/idf/scheme.rb +61 -0
  242. data/lib/pubid/idf/supplement_identifier.rb +13 -5
  243. data/lib/pubid/idf/urn_generator.rb +39 -4
  244. data/lib/pubid/idf.rb +1 -65
  245. data/lib/pubid/iec/builder.rb +91 -92
  246. data/lib/pubid/iec/components/code.rb +32 -9
  247. data/lib/pubid/iec/components/publisher.rb +1 -1
  248. data/lib/pubid/iec/identifier.rb +8 -328
  249. data/lib/pubid/iec/identifiers/amendment.rb +5 -8
  250. data/lib/pubid/iec/identifiers/base.rb +31 -7
  251. data/lib/pubid/iec/identifiers/component_specification.rb +13 -3
  252. data/lib/pubid/iec/identifiers/conformity_assessment.rb +12 -1
  253. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +30 -29
  254. data/lib/pubid/iec/identifiers/corrigendum.rb +5 -4
  255. data/lib/pubid/iec/identifiers/fragment_identifier.rb +36 -43
  256. data/lib/pubid/iec/identifiers/guide.rb +18 -0
  257. data/lib/pubid/iec/identifiers/international_standard.rb +9 -24
  258. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +3 -2
  259. data/lib/pubid/iec/identifiers/operational_document.rb +13 -3
  260. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +15 -2
  261. data/lib/pubid/iec/identifiers/sheet_identifier.rb +24 -26
  262. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +13 -3
  263. data/lib/pubid/iec/identifiers/systems_reference_document.rb +13 -2
  264. data/lib/pubid/iec/identifiers/technical_report.rb +21 -3
  265. data/lib/pubid/iec/identifiers/technical_specification.rb +21 -3
  266. data/lib/pubid/iec/identifiers/technology_report.rb +12 -1
  267. data/lib/pubid/iec/identifiers/test_report_form.rb +46 -3
  268. data/lib/pubid/iec/identifiers/vap_identifier.rb +34 -33
  269. data/lib/pubid/iec/identifiers/white_paper.rb +13 -3
  270. data/lib/pubid/iec/identifiers/working_document.rb +60 -26
  271. data/lib/pubid/iec/parser.rb +42 -73
  272. data/lib/pubid/iec/scheme.rb +71 -0
  273. data/lib/pubid/iec/single_identifier.rb +23 -15
  274. data/lib/pubid/iec/supplement_identifier.rb +67 -84
  275. data/lib/pubid/iec/urn_generator.rb +143 -195
  276. data/lib/pubid/iec/urn_parser.rb +246 -85
  277. data/lib/pubid/iec.rb +66 -45
  278. data/lib/pubid/ieee/aiee/builder.rb +3 -17
  279. data/lib/pubid/ieee/aiee/identifier.rb +62 -46
  280. data/lib/pubid/ieee/aiee/parser.rb +1 -1
  281. data/lib/pubid/ieee/builder.rb +81 -398
  282. data/lib/pubid/ieee/components/code.rb +0 -8
  283. data/lib/pubid/ieee/components/draft.rb +0 -54
  284. data/lib/pubid/ieee/components/relationship.rb +149 -5
  285. data/lib/pubid/ieee/identifier.rb +11 -3
  286. data/lib/pubid/ieee/identifiers/adopted_standard.rb +14 -62
  287. data/lib/pubid/ieee/identifiers/base.rb +547 -340
  288. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +12 -6
  289. data/lib/pubid/ieee/identifiers/corrigendum.rb +12 -15
  290. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +13 -24
  291. data/lib/pubid/ieee/identifiers/dual_identifier.rb +7 -3
  292. data/lib/pubid/ieee/identifiers/dual_published.rb +7 -58
  293. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +11 -99
  294. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +11 -25
  295. data/lib/pubid/ieee/identifiers/joint_development.rb +15 -66
  296. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +24 -58
  297. data/lib/pubid/ieee/identifiers/nesc/base.rb +19 -90
  298. data/lib/pubid/ieee/identifiers/nesc/draft.rb +5 -20
  299. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +5 -16
  300. data/lib/pubid/ieee/identifiers/nesc/redline.rb +2 -11
  301. data/lib/pubid/ieee/identifiers/nesc/standard.rb +3 -18
  302. data/lib/pubid/ieee/identifiers/nesc.rb +0 -1
  303. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +9 -3
  304. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +6 -29
  305. data/lib/pubid/ieee/identifiers/redlined_standard.rb +11 -4
  306. data/lib/pubid/ieee/identifiers/si_standard.rb +39 -4
  307. data/lib/pubid/ieee/identifiers/standard.rb +2 -5
  308. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +7 -26
  309. data/lib/pubid/ieee/identifiers.rb +1 -2
  310. data/lib/pubid/ieee/ire/builder.rb +6 -7
  311. data/lib/pubid/ieee/ire/identifier.rb +33 -48
  312. data/lib/pubid/ieee/ire/parser.rb +1 -1
  313. data/lib/pubid/ieee/nesc/builder.rb +20 -33
  314. data/lib/pubid/ieee/nesc/parser.rb +15 -16
  315. data/lib/pubid/ieee/parser.rb +44 -462
  316. data/lib/pubid/ieee/scheme.rb +90 -0
  317. data/lib/pubid/ieee/typed_stages.rb +1 -12
  318. data/lib/pubid/ieee/urn_generator.rb +8 -35
  319. data/lib/pubid/ieee.rb +2 -133
  320. data/lib/pubid/ieee_debug.rb +1 -0
  321. data/lib/pubid/iho/builder.rb +2 -2
  322. data/lib/pubid/iho/identifier.rb +17 -5
  323. data/lib/pubid/iho/identifiers/base.rb +30 -64
  324. data/lib/pubid/iho/identifiers/bibliographic.rb +5 -1
  325. data/lib/pubid/iho/identifiers/circular_letter.rb +5 -1
  326. data/lib/pubid/iho/identifiers/miscellaneous.rb +5 -1
  327. data/lib/pubid/iho/identifiers/publication.rb +5 -1
  328. data/lib/pubid/iho/identifiers/standard.rb +5 -1
  329. data/lib/pubid/iho/identifiers.rb +1 -0
  330. data/lib/pubid/iho/parser.rb +4 -4
  331. data/lib/pubid/iho/scheme.rb +29 -0
  332. data/lib/pubid/iho/urn_generator.rb +3 -3
  333. data/lib/pubid/iho.rb +3 -59
  334. data/lib/pubid/iso/builder.rb +57 -68
  335. data/lib/pubid/iso/bundled_identifier.rb +3 -56
  336. data/lib/pubid/iso/combined_identifier.rb +4 -6
  337. data/lib/pubid/iso/components/code.rb +19 -7
  338. data/lib/pubid/iso/components/publisher.rb +8 -10
  339. data/lib/pubid/iso/components.rb +4 -2
  340. data/lib/pubid/iso/identifier.rb +11 -260
  341. data/lib/pubid/iso/identifiers/addendum.rb +6 -9
  342. data/lib/pubid/iso/identifiers/amendment.rb +4 -8
  343. data/lib/pubid/iso/identifiers/base.rb +115 -0
  344. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  345. data/lib/pubid/iso/identifiers/data.rb +1 -0
  346. data/lib/pubid/iso/identifiers/directives.rb +2 -8
  347. data/lib/pubid/iso/identifiers/directives_supplement.rb +26 -55
  348. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  349. data/lib/pubid/iso/identifiers/guide.rb +1 -0
  350. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  351. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  352. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +4 -10
  353. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  354. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  355. data/lib/pubid/iso/identifiers/supplement.rb +3 -11
  356. data/lib/pubid/iso/identifiers/tc_document.rb +15 -44
  357. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  358. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  359. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  360. data/lib/pubid/iso/identifiers.rb +1 -0
  361. data/lib/pubid/iso/parser.rb +19 -43
  362. data/lib/pubid/iso/scheme.rb +187 -0
  363. data/lib/pubid/iso/single_identifier.rb +7 -6
  364. data/lib/pubid/iso/supplement_identifier.rb +3 -29
  365. data/lib/pubid/iso/urn_generator.rb +177 -78
  366. data/lib/pubid/iso/urn_parser.rb +10 -29
  367. data/lib/pubid/iso.rb +2 -188
  368. data/lib/pubid/itu/builder.rb +41 -230
  369. data/lib/pubid/itu/components/code.rb +12 -57
  370. data/lib/pubid/itu/components/sector.rb +4 -15
  371. data/lib/pubid/itu/components/series.rb +4 -0
  372. data/lib/pubid/itu/identifier.rb +51 -2
  373. data/lib/pubid/itu/identifiers/amendment.rb +31 -7
  374. data/lib/pubid/itu/identifiers/annex.rb +4 -13
  375. data/lib/pubid/itu/identifiers/base.rb +128 -456
  376. data/lib/pubid/itu/identifiers/combined_identifier.rb +25 -99
  377. data/lib/pubid/itu/identifiers/corrigendum.rb +25 -16
  378. data/lib/pubid/itu/identifiers/recommendation.rb +4 -3
  379. data/lib/pubid/itu/identifiers/special_publication.rb +3 -3
  380. data/lib/pubid/itu/identifiers/supplement.rb +16 -119
  381. data/lib/pubid/itu/identifiers.rb +1 -10
  382. data/lib/pubid/itu/model.rb +1 -1
  383. data/lib/pubid/itu/parser.rb +27 -481
  384. data/lib/pubid/itu/scheme.rb +174 -0
  385. data/lib/pubid/itu/urn_generator.rb +6 -36
  386. data/lib/pubid/itu.rb +2 -58
  387. data/lib/pubid/jcgm/builder.rb +19 -37
  388. data/lib/pubid/jcgm/identifier.rb +0 -10
  389. data/lib/pubid/jcgm/identifiers/amendment.rb +11 -0
  390. data/lib/pubid/jcgm/identifiers/gum_guide.rb +15 -3
  391. data/lib/pubid/jcgm/identifiers.rb +0 -2
  392. data/lib/pubid/jcgm/parser.rb +7 -74
  393. data/lib/pubid/jcgm/scheme.rb +60 -0
  394. data/lib/pubid/jcgm/single_identifier.rb +14 -84
  395. data/lib/pubid/jcgm/supplement_identifier.rb +4 -39
  396. data/lib/pubid/jcgm/urn_generator.rb +19 -25
  397. data/lib/pubid/jcgm.rb +2 -57
  398. data/lib/pubid/jis/builder.rb +52 -44
  399. data/lib/pubid/jis/components/code.rb +59 -0
  400. data/lib/pubid/{astm → jis}/components.rb +1 -1
  401. data/lib/pubid/jis/identifier.rb +5 -181
  402. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  403. data/lib/pubid/jis/identifiers/base.rb +72 -0
  404. data/lib/pubid/jis/identifiers/standard.rb +1 -2
  405. data/lib/pubid/jis/identifiers/technical_report.rb +1 -2
  406. data/lib/pubid/jis/identifiers/technical_specification.rb +1 -2
  407. data/lib/pubid/jis/identifiers.rb +1 -1
  408. data/lib/pubid/jis/parser.rb +6 -32
  409. data/lib/pubid/jis/scheme.rb +49 -0
  410. data/lib/pubid/jis/single_identifier.rb +12 -6
  411. data/lib/pubid/jis/supplement_identifier.rb +14 -17
  412. data/lib/pubid/jis.rb +2 -48
  413. data/lib/pubid/nist/builder.rb +1765 -146
  414. data/lib/pubid/nist/components/code.rb +20 -9
  415. data/lib/pubid/nist/components/edition.rb +0 -16
  416. data/lib/pubid/nist/components/publisher.rb +24 -0
  417. data/lib/pubid/nist/components/supplement.rb +21 -91
  418. data/lib/pubid/nist/components.rb +1 -0
  419. data/lib/pubid/nist/configuration.rb +2 -12
  420. data/lib/pubid/nist/identifiers/base.rb +417 -662
  421. data/lib/pubid/nist/identifiers/circular.rb +5 -17
  422. data/lib/pubid/nist/identifiers/circular_supplement.rb +6 -16
  423. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -3
  424. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +5 -7
  425. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +5 -18
  426. data/lib/pubid/nist/identifiers/crpl_report.rb +13 -16
  427. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +17 -18
  428. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -3
  429. data/lib/pubid/nist/identifiers/handbook.rb +4 -12
  430. data/lib/pubid/nist/identifiers/internal_report.rb +7 -15
  431. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -3
  432. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +11 -20
  433. data/lib/pubid/nist/identifiers/monograph.rb +11 -22
  434. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  435. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  436. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  437. data/lib/pubid/nist/identifiers/report.rb +10 -19
  438. data/lib/pubid/nist/identifiers/special_publication.rb +2 -12
  439. data/lib/pubid/nist/identifiers/technical_note.rb +3 -4
  440. data/lib/pubid/nist/identifiers.rb +1 -1
  441. data/lib/pubid/nist/parser.rb +429 -97
  442. data/lib/pubid/nist/scheme.rb +199 -0
  443. data/lib/pubid/nist/supplement_identifier.rb +34 -35
  444. data/lib/pubid/nist/urn_generator.rb +8 -14
  445. data/lib/pubid/nist.rb +5 -107
  446. data/lib/pubid/oiml/builder.rb +10 -91
  447. data/lib/pubid/oiml/components/code.rb +0 -17
  448. data/lib/pubid/oiml/identifier.rb +0 -53
  449. data/lib/pubid/oiml/identifiers/annex.rb +46 -13
  450. data/lib/pubid/oiml/identifiers/base.rb +36 -0
  451. data/lib/pubid/oiml/identifiers/basic_publication.rb +0 -2
  452. data/lib/pubid/oiml/identifiers/document.rb +0 -2
  453. data/lib/pubid/oiml/identifiers/expert_report.rb +0 -2
  454. data/lib/pubid/oiml/identifiers/guide.rb +0 -2
  455. data/lib/pubid/oiml/identifiers/recommendation.rb +0 -2
  456. data/lib/pubid/oiml/identifiers/seminar_report.rb +0 -2
  457. data/lib/pubid/oiml/identifiers/vocabulary.rb +0 -2
  458. data/lib/pubid/oiml/identifiers.rb +1 -3
  459. data/lib/pubid/oiml/parser.rb +17 -118
  460. data/lib/pubid/oiml/scheme.rb +46 -0
  461. data/lib/pubid/oiml/single_identifier.rb +43 -66
  462. data/lib/pubid/oiml/supplement_identifier.rb +17 -62
  463. data/lib/pubid/oiml/urn_generator.rb +8 -22
  464. data/lib/pubid/oiml.rb +1 -56
  465. data/lib/pubid/parser.rb +0 -1
  466. data/lib/pubid/parsers/mr_string.rb +7 -120
  467. data/lib/pubid/plateau/builder.rb +4 -8
  468. data/lib/pubid/plateau/identifiers/base.rb +36 -40
  469. data/lib/pubid/plateau/identifiers/handbook.rb +7 -1
  470. data/lib/pubid/plateau/identifiers/technical_report.rb +5 -1
  471. data/lib/pubid/plateau/identifiers.rb +1 -0
  472. data/lib/pubid/plateau/parser.rb +6 -16
  473. data/lib/pubid/plateau/scheme.rb +45 -0
  474. data/lib/pubid/plateau/supplement_identifier.rb +15 -11
  475. data/lib/pubid/plateau.rb +1 -58
  476. data/lib/pubid/renderers/base.rb +0 -47
  477. data/lib/pubid/renderers/directives_renderer.rb +14 -27
  478. data/lib/pubid/renderers/guide_renderer.rb +1 -7
  479. data/lib/pubid/renderers/human_readable.rb +9 -34
  480. data/lib/pubid/renderers/iwa_renderer.rb +1 -5
  481. data/lib/pubid/renderers/mr_string.rb +6 -54
  482. data/lib/pubid/renderers/supplement_renderer.rb +2 -5
  483. data/lib/pubid/renderers.rb +0 -1
  484. data/lib/pubid/rendering/base.rb +73 -0
  485. data/lib/pubid/rendering/common.rb +211 -0
  486. data/lib/pubid/rendering/context.rb +21 -33
  487. data/lib/pubid/rendering/format.rb +25 -0
  488. data/lib/pubid/rendering/numbering.rb +7 -25
  489. data/lib/pubid/rendering/supplement.rb +4 -4
  490. data/lib/pubid/rendering.rb +3 -0
  491. data/lib/pubid/sae/builder.rb +1 -1
  492. data/lib/pubid/sae/components/date.rb +0 -8
  493. data/lib/pubid/sae/components/type.rb +1 -5
  494. data/lib/pubid/sae/identifier.rb +12 -2
  495. data/lib/pubid/sae/identifiers/base.rb +28 -33
  496. data/lib/pubid/sae/identifiers.rb +1 -0
  497. data/lib/pubid/sae/parser.rb +1 -1
  498. data/lib/pubid/sae/scheme.rb +47 -0
  499. data/lib/pubid/sae/urn_generator.rb +10 -2
  500. data/lib/pubid/sae.rb +2 -49
  501. data/lib/pubid/scheme.rb +207 -0
  502. data/lib/pubid/urn_generator/base.rb +12 -12
  503. data/lib/pubid/version.rb +1 -1
  504. data/lib/pubid.rb +10 -424
  505. data/lib/tasks/export.rake +5 -6
  506. data/lib/tasks/website-data.json +1796 -1854
  507. metadata +45 -307
  508. data/data/bipm/update_codes.yaml +0 -9
  509. data/data/nist/series.yaml +0 -155
  510. data/lib/pubid/adobe/builder.rb +0 -52
  511. data/lib/pubid/adobe/identifier.rb +0 -47
  512. data/lib/pubid/adobe/identifiers/publication.rb +0 -31
  513. data/lib/pubid/adobe/identifiers/tech_note.rb +0 -32
  514. data/lib/pubid/adobe/identifiers.rb +0 -10
  515. data/lib/pubid/adobe/parser.rb +0 -136
  516. data/lib/pubid/adobe/renderer.rb +0 -39
  517. data/lib/pubid/adobe/urn_generator.rb +0 -42
  518. data/lib/pubid/adobe/urn_parser.rb +0 -69
  519. data/lib/pubid/adobe.rb +0 -60
  520. data/lib/pubid/amca/renderer.rb +0 -82
  521. data/lib/pubid/amca/urn_parser.rb +0 -28
  522. data/lib/pubid/ansi/renderer.rb +0 -53
  523. data/lib/pubid/ansi/urn_parser.rb +0 -23
  524. data/lib/pubid/api/identifiers.rb +0 -18
  525. data/lib/pubid/api/renderer.rb +0 -98
  526. data/lib/pubid/api/urn_parser.rb +0 -35
  527. data/lib/pubid/ashrae/renderer.rb +0 -117
  528. data/lib/pubid/ashrae/urn_parser.rb +0 -27
  529. data/lib/pubid/asme/renderer.rb +0 -66
  530. data/lib/pubid/asme/urn_parser.rb +0 -31
  531. data/lib/pubid/astm/identifiers/code_number.rb +0 -81
  532. data/lib/pubid/astm/identifiers.rb +0 -19
  533. data/lib/pubid/astm/renderer.rb +0 -172
  534. data/lib/pubid/astm/urn_parser.rb +0 -30
  535. data/lib/pubid/bipm/builder.rb +0 -163
  536. data/lib/pubid/bipm/identifier.rb +0 -285
  537. data/lib/pubid/bipm/identifiers/committee_document.rb +0 -36
  538. data/lib/pubid/bipm/identifiers/guide.rb +0 -35
  539. data/lib/pubid/bipm/identifiers/meeting.rb +0 -53
  540. data/lib/pubid/bipm/identifiers/mep.rb +0 -33
  541. data/lib/pubid/bipm/identifiers/metrologia_article.rb +0 -48
  542. data/lib/pubid/bipm/identifiers/si_brochure.rb +0 -33
  543. data/lib/pubid/bipm/identifiers.rb +0 -15
  544. data/lib/pubid/bipm/parser.rb +0 -237
  545. data/lib/pubid/bipm/renderer.rb +0 -118
  546. data/lib/pubid/bipm/urn_generator.rb +0 -58
  547. data/lib/pubid/bipm/urn_parser.rb +0 -60
  548. data/lib/pubid/bipm.rb +0 -91
  549. data/lib/pubid/bsi/renderer.rb +0 -1064
  550. data/lib/pubid/bsi/urn_parser.rb +0 -52
  551. data/lib/pubid/calconnect/builder.rb +0 -38
  552. data/lib/pubid/calconnect/identifier.rb +0 -121
  553. data/lib/pubid/calconnect/identifiers/standard.rb +0 -29
  554. data/lib/pubid/calconnect/identifiers.rb +0 -9
  555. data/lib/pubid/calconnect/parser.rb +0 -54
  556. data/lib/pubid/calconnect/renderer.rb +0 -36
  557. data/lib/pubid/calconnect/urn_generator.rb +0 -33
  558. data/lib/pubid/calconnect/urn_parser.rb +0 -34
  559. data/lib/pubid/calconnect.rb +0 -82
  560. data/lib/pubid/ccsds/urn_parser.rb +0 -20
  561. data/lib/pubid/cen_cenelec/renderer.rb +0 -261
  562. data/lib/pubid/cen_cenelec/urn_parser.rb +0 -28
  563. data/lib/pubid/cie/identifiers/code_attributes.rb +0 -52
  564. data/lib/pubid/cie/identifiers/proceedings.rb +0 -41
  565. data/lib/pubid/cie/urn_parser.rb +0 -28
  566. data/lib/pubid/components/adoption.rb +0 -104
  567. data/lib/pubid/components/iteration.rb +0 -32
  568. data/lib/pubid/components/relationship.rb +0 -151
  569. data/lib/pubid/components/supplement.rb +0 -184
  570. data/lib/pubid/csa/renderer.rb +0 -300
  571. data/lib/pubid/csa/urn_parser.rb +0 -33
  572. data/lib/pubid/doi/builder.rb +0 -18
  573. data/lib/pubid/doi/identifier.rb +0 -49
  574. data/lib/pubid/doi/identifiers/resource.rb +0 -30
  575. data/lib/pubid/doi/identifiers.rb +0 -9
  576. data/lib/pubid/doi/parser.rb +0 -52
  577. data/lib/pubid/doi/renderer.rb +0 -13
  578. data/lib/pubid/doi.rb +0 -55
  579. data/lib/pubid/easc/builder.rb +0 -55
  580. data/lib/pubid/easc/identifier.rb +0 -59
  581. data/lib/pubid/easc/identifiers/pmg.rb +0 -20
  582. data/lib/pubid/easc/identifiers/rmg.rb +0 -19
  583. data/lib/pubid/easc/identifiers.rb +0 -10
  584. data/lib/pubid/easc/parser.rb +0 -88
  585. data/lib/pubid/easc/renderer.rb +0 -48
  586. data/lib/pubid/easc/urn_generator.rb +0 -46
  587. data/lib/pubid/easc/urn_parser.rb +0 -57
  588. data/lib/pubid/easc.rb +0 -52
  589. data/lib/pubid/ecma/builder.rb +0 -45
  590. data/lib/pubid/ecma/identifier.rb +0 -147
  591. data/lib/pubid/ecma/identifiers/memento.rb +0 -30
  592. data/lib/pubid/ecma/identifiers/standard.rb +0 -31
  593. data/lib/pubid/ecma/identifiers/technical_report.rb +0 -31
  594. data/lib/pubid/ecma/identifiers.rb +0 -11
  595. data/lib/pubid/ecma/parser.rb +0 -76
  596. data/lib/pubid/ecma/renderer.rb +0 -67
  597. data/lib/pubid/ecma/urn_generator.rb +0 -46
  598. data/lib/pubid/ecma/urn_parser.rb +0 -51
  599. data/lib/pubid/ecma.rb +0 -67
  600. data/lib/pubid/errors.rb +0 -79
  601. data/lib/pubid/etsi/renderer.rb +0 -48
  602. data/lib/pubid/etsi/urn_parser.rb +0 -34
  603. data/lib/pubid/gb/builder.rb +0 -45
  604. data/lib/pubid/gb/identifier.rb +0 -67
  605. data/lib/pubid/gb/identifiers/standard.rb +0 -34
  606. data/lib/pubid/gb/identifiers.rb +0 -9
  607. data/lib/pubid/gb/parser.rb +0 -63
  608. data/lib/pubid/gb/renderer.rb +0 -35
  609. data/lib/pubid/gb.rb +0 -87
  610. data/lib/pubid/gost/builder.rb +0 -148
  611. data/lib/pubid/gost/identifier.rb +0 -47
  612. data/lib/pubid/gost/identifiers/foreign_reference.rb +0 -25
  613. data/lib/pubid/gost/identifiers/harmonized.rb +0 -39
  614. data/lib/pubid/gost/identifiers/identical_adoption.rb +0 -39
  615. data/lib/pubid/gost/identifiers/interstate_standard.rb +0 -20
  616. data/lib/pubid/gost/identifiers/national_standard.rb +0 -19
  617. data/lib/pubid/gost/identifiers.rb +0 -13
  618. data/lib/pubid/gost/parser.rb +0 -105
  619. data/lib/pubid/gost/renderer.rb +0 -48
  620. data/lib/pubid/gost/urn_generator.rb +0 -46
  621. data/lib/pubid/gost/urn_parser.rb +0 -52
  622. data/lib/pubid/gost.rb +0 -49
  623. data/lib/pubid/iala/builder.rb +0 -102
  624. data/lib/pubid/iala/identifier.rb +0 -90
  625. data/lib/pubid/iala/identifiers/advice.rb +0 -15
  626. data/lib/pubid/iala/identifiers/annex.rb +0 -57
  627. data/lib/pubid/iala/identifiers/general_assembly.rb +0 -19
  628. data/lib/pubid/iala/identifiers/guideline.rb +0 -17
  629. data/lib/pubid/iala/identifiers/letter.rb +0 -16
  630. data/lib/pubid/iala/identifiers/manual.rb +0 -18
  631. data/lib/pubid/iala/identifiers/model_course.rb +0 -17
  632. data/lib/pubid/iala/identifiers/recommendation.rb +0 -17
  633. data/lib/pubid/iala/identifiers/report.rb +0 -16
  634. data/lib/pubid/iala/identifiers/resolution.rb +0 -16
  635. data/lib/pubid/iala/identifiers/standard.rb +0 -17
  636. data/lib/pubid/iala/identifiers.rb +0 -19
  637. data/lib/pubid/iala/parser.rb +0 -138
  638. data/lib/pubid/iala/renderer.rb +0 -36
  639. data/lib/pubid/iala/urn_generator.rb +0 -49
  640. data/lib/pubid/iala/urn_parser.rb +0 -67
  641. data/lib/pubid/iala.rb +0 -71
  642. data/lib/pubid/iana/builder.rb +0 -22
  643. data/lib/pubid/iana/identifier.rb +0 -140
  644. data/lib/pubid/iana/identifiers/registry.rb +0 -69
  645. data/lib/pubid/iana/identifiers.rb +0 -9
  646. data/lib/pubid/iana/parser.rb +0 -38
  647. data/lib/pubid/iana/renderer.rb +0 -32
  648. data/lib/pubid/iana/urn_generator.rb +0 -19
  649. data/lib/pubid/iana/urn_parser.rb +0 -24
  650. data/lib/pubid/iana.rb +0 -69
  651. data/lib/pubid/idf/renderer.rb +0 -84
  652. data/lib/pubid/idf/urn_parser.rb +0 -25
  653. data/lib/pubid/iec/components.rb +0 -14
  654. data/lib/pubid/iec/identifiers/technical_group.rb +0 -30
  655. data/lib/pubid/iec/identifiers.rb +0 -31
  656. data/lib/pubid/iec/renderer.rb +0 -267
  657. data/lib/pubid/ieee/compaction.rb +0 -121
  658. data/lib/pubid/ieee/identifiers/amendment.rb +0 -40
  659. data/lib/pubid/ieee/identifiers/code_number.rb +0 -82
  660. data/lib/pubid/ieee/identifiers/nesc/edition.rb +0 -32
  661. data/lib/pubid/ieee/pre_parser.rb +0 -301
  662. data/lib/pubid/ieee/renderer.rb +0 -408
  663. data/lib/pubid/ieee/urn_parser.rb +0 -34
  664. data/lib/pubid/ietf/builder.rb +0 -78
  665. data/lib/pubid/ietf/identifier.rb +0 -5
  666. data/lib/pubid/ietf/identifiers/base.rb +0 -72
  667. data/lib/pubid/ietf/identifiers/bcp.rb +0 -36
  668. data/lib/pubid/ietf/identifiers/fyi.rb +0 -36
  669. data/lib/pubid/ietf/identifiers/internet_draft.rb +0 -45
  670. data/lib/pubid/ietf/identifiers/rfc.rb +0 -27
  671. data/lib/pubid/ietf/identifiers/serialization.rb +0 -51
  672. data/lib/pubid/ietf/identifiers/std.rb +0 -36
  673. data/lib/pubid/ietf/identifiers.rb +0 -14
  674. data/lib/pubid/ietf/parser.rb +0 -61
  675. data/lib/pubid/ietf/renderer.rb +0 -64
  676. data/lib/pubid/ietf/urn_generator.rb +0 -37
  677. data/lib/pubid/ietf/urn_parser.rb +0 -43
  678. data/lib/pubid/ietf.rb +0 -85
  679. data/lib/pubid/iho/renderer.rb +0 -30
  680. data/lib/pubid/iho/urn_parser.rb +0 -58
  681. data/lib/pubid/isbn/builder.rb +0 -44
  682. data/lib/pubid/isbn/check_digit.rb +0 -53
  683. data/lib/pubid/isbn/identifier.rb +0 -81
  684. data/lib/pubid/isbn/identifiers/book.rb +0 -30
  685. data/lib/pubid/isbn/identifiers.rb +0 -9
  686. data/lib/pubid/isbn/parser.rb +0 -45
  687. data/lib/pubid/isbn/renderer.rb +0 -16
  688. data/lib/pubid/isbn.rb +0 -52
  689. data/lib/pubid/iso/normalizer.rb +0 -89
  690. data/lib/pubid/itu/components/designation.rb +0 -35
  691. data/lib/pubid/itu/components.rb +0 -12
  692. data/lib/pubid/itu/identifiers/addendum.rb +0 -15
  693. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +0 -87
  694. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +0 -92
  695. data/lib/pubid/itu/identifiers/errata.rb +0 -15
  696. data/lib/pubid/itu/identifiers/handbook.rb +0 -38
  697. data/lib/pubid/itu/identifiers/question.rb +0 -63
  698. data/lib/pubid/itu/identifiers/report.rb +0 -39
  699. data/lib/pubid/itu/identifiers/standard_serialization.rb +0 -58
  700. data/lib/pubid/itu/urn_parser.rb +0 -31
  701. data/lib/pubid/jcgm/identifiers/corrigendum.rb +0 -34
  702. data/lib/pubid/jcgm/identifiers/meeting.rb +0 -47
  703. data/lib/pubid/jcgm/renderer.rb +0 -89
  704. data/lib/pubid/jcgm/urn_parser.rb +0 -177
  705. data/lib/pubid/jis/identifiers/corrigendum.rb +0 -16
  706. data/lib/pubid/jis/renderer.rb +0 -69
  707. data/lib/pubid/jis/urn_parser.rb +0 -23
  708. data/lib/pubid/nist/caster.rb +0 -1234
  709. data/lib/pubid/nist/circular_supplement_builder.rb +0 -293
  710. data/lib/pubid/nist/identifier.rb +0 -8
  711. data/lib/pubid/nist/identifiers/dated_document.rb +0 -49
  712. data/lib/pubid/nist/parser_output_normalizer.rb +0 -233
  713. data/lib/pubid/nist/preprocessor.rb +0 -443
  714. data/lib/pubid/nist/renderer.rb +0 -43
  715. data/lib/pubid/nist/router.rb +0 -149
  716. data/lib/pubid/nist/series/base.rb +0 -58
  717. data/lib/pubid/nist/series/crpl.rb +0 -13
  718. data/lib/pubid/nist/series/fips.rb +0 -14
  719. data/lib/pubid/nist/series/ir.rb +0 -57
  720. data/lib/pubid/nist/series/letter_preserving.rb +0 -15
  721. data/lib/pubid/nist/series/mono.rb +0 -19
  722. data/lib/pubid/nist/series/ncstar.rb +0 -20
  723. data/lib/pubid/nist/series.rb +0 -49
  724. data/lib/pubid/nist/urn_parser.rb +0 -67
  725. data/lib/pubid/oasis/builder.rb +0 -79
  726. data/lib/pubid/oasis/identifier.rb +0 -160
  727. data/lib/pubid/oasis/identifiers/standard.rb +0 -29
  728. data/lib/pubid/oasis/identifiers.rb +0 -9
  729. data/lib/pubid/oasis/parser.rb +0 -34
  730. data/lib/pubid/oasis/renderer.rb +0 -29
  731. data/lib/pubid/oasis/urn_generator.rb +0 -25
  732. data/lib/pubid/oasis/urn_parser.rb +0 -22
  733. data/lib/pubid/oasis.rb +0 -79
  734. data/lib/pubid/ogc/builder.rb +0 -33
  735. data/lib/pubid/ogc/identifier.rb +0 -81
  736. data/lib/pubid/ogc/identifiers/document.rb +0 -26
  737. data/lib/pubid/ogc/identifiers.rb +0 -10
  738. data/lib/pubid/ogc/parser.rb +0 -40
  739. data/lib/pubid/ogc/renderer.rb +0 -33
  740. data/lib/pubid/ogc/urn_generator.rb +0 -14
  741. data/lib/pubid/ogc/urn_parser.rb +0 -22
  742. data/lib/pubid/ogc.rb +0 -71
  743. data/lib/pubid/oiml/identifiers/bulletin.rb +0 -137
  744. data/lib/pubid/oiml/identifiers/code_number.rb +0 -90
  745. data/lib/pubid/oiml/identifiers/errata.rb +0 -15
  746. data/lib/pubid/oiml/renderer.rb +0 -232
  747. data/lib/pubid/oiml/urn_parser.rb +0 -39
  748. data/lib/pubid/omg/builder.rb +0 -19
  749. data/lib/pubid/omg/identifier.rb +0 -47
  750. data/lib/pubid/omg/identifiers/specification.rb +0 -32
  751. data/lib/pubid/omg/identifiers.rb +0 -9
  752. data/lib/pubid/omg/parser.rb +0 -40
  753. data/lib/pubid/omg/renderer.rb +0 -19
  754. data/lib/pubid/omg.rb +0 -51
  755. data/lib/pubid/parser/grammar.rb +0 -74
  756. data/lib/pubid/plateau/identifier.rb +0 -4
  757. data/lib/pubid/plateau/renderer.rb +0 -51
  758. data/lib/pubid/plateau/urn_parser.rb +0 -43
  759. data/lib/pubid/prefixes_support.rb +0 -51
  760. data/lib/pubid/renderers/annotator.rb +0 -233
  761. data/lib/pubid/sae/renderer.rb +0 -36
  762. data/lib/pubid/sae/urn_parser.rb +0 -36
  763. data/lib/pubid/tgpp/builder.rb +0 -41
  764. data/lib/pubid/tgpp/identifier.rb +0 -107
  765. data/lib/pubid/tgpp/identifiers/technical_report.rb +0 -32
  766. data/lib/pubid/tgpp/identifiers/technical_specification.rb +0 -33
  767. data/lib/pubid/tgpp/identifiers.rb +0 -11
  768. data/lib/pubid/tgpp/parser.rb +0 -78
  769. data/lib/pubid/tgpp/renderer.rb +0 -52
  770. data/lib/pubid/tgpp/urn_generator.rb +0 -39
  771. data/lib/pubid/tgpp/urn_parser.rb +0 -30
  772. data/lib/pubid/tgpp.rb +0 -83
  773. data/lib/pubid/type_resolver.rb +0 -59
  774. data/lib/pubid/un/builder.rb +0 -42
  775. data/lib/pubid/un/identifier.rb +0 -40
  776. data/lib/pubid/un/identifiers/document.rb +0 -24
  777. data/lib/pubid/un/identifiers.rb +0 -9
  778. data/lib/pubid/un/parser.rb +0 -25
  779. data/lib/pubid/un/renderer.rb +0 -11
  780. data/lib/pubid/un.rb +0 -46
  781. data/lib/pubid/urn_parser/base.rb +0 -81
  782. data/lib/pubid/urn_parser/errors.rb +0 -16
  783. data/lib/pubid/urn_parser.rb +0 -14
  784. data/lib/pubid/w3c/builder.rb +0 -55
  785. data/lib/pubid/w3c/identifier.rb +0 -130
  786. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +0 -31
  787. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +0 -31
  788. data/lib/pubid/w3c/identifiers/draft_note.rb +0 -31
  789. data/lib/pubid/w3c/identifiers/note.rb +0 -30
  790. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +0 -31
  791. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +0 -31
  792. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +0 -31
  793. data/lib/pubid/w3c/identifiers/recommendation.rb +0 -31
  794. data/lib/pubid/w3c/identifiers/standard.rb +0 -12
  795. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +0 -31
  796. data/lib/pubid/w3c/identifiers/working_draft.rb +0 -30
  797. data/lib/pubid/w3c/identifiers.rb +0 -25
  798. data/lib/pubid/w3c/parser.rb +0 -43
  799. data/lib/pubid/w3c/renderer.rb +0 -35
  800. data/lib/pubid/w3c/urn_generator.rb +0 -18
  801. data/lib/pubid/w3c/urn_parser.rb +0 -36
  802. data/lib/pubid/w3c.rb +0 -67
  803. data/lib/pubid/xsf/builder.rb +0 -17
  804. data/lib/pubid/xsf/identifier.rb +0 -66
  805. data/lib/pubid/xsf/identifiers/xep.rb +0 -31
  806. data/lib/pubid/xsf/identifiers.rb +0 -9
  807. data/lib/pubid/xsf/parser.rb +0 -25
  808. data/lib/pubid/xsf/renderer.rb +0 -23
  809. data/lib/pubid/xsf/urn_generator.rb +0 -13
  810. data/lib/pubid/xsf/urn_parser.rb +0 -18
  811. data/lib/pubid/xsf.rb +0 -81
@@ -2,743 +2,498 @@
2
2
 
3
3
  module Pubid
4
4
  module Nist
5
- # NIST/NBS flavor base class. Canonical name Pubid::Nist::Identifier; every
6
- # concrete NIST identifier (Identifiers::*) descends from it. Being a real Pubid::Identifier subclass gives
7
- # native `is_a?` identity and the shared polymorphic `from_hash`.
8
- class Identifier < ::Pubid::Identifier
9
- # Delegate to the flavor module so callers can use
10
- # `Pubid::Nist::Identifier.parse` consistently with other flavors.
11
- def self.parse(identifier)
12
- Pubid::Nist.parse(identifier)
13
- end
14
-
15
- # Compact, index-friendly serialization (mirrors the key_value flavors
16
- # ISO/ITU/ETSI, without a 38-field key_value block). Two transforms,
17
- # applied symmetrically by to_hash/from_hash so the round-trip stays
18
- # idempotent:
19
- # - flatten the single-value Code components (series, number) to bare
20
- # scalars — `value` is the only stored field. NIST's
21
- # `Components::Code#part` is a *computed* reader
22
- # (`value.split("-").last`), and prefix/subpart/parts are never
23
- # assigned on series/number, so the scalar `value` is lossless:
24
- # expand recomputes exactly what the object would compute anyway;
25
- # - flatten the plain single-value components (volume) to bare scalars
26
- # too — `Components::Volume` holds only `value`, so it expands to a
27
- # bare { "value" => … } with no part;
28
- # - drop the redundant build artifacts, decomposed pieces of the
29
- # canonical number that identity/rendering never read.
30
- COMPACT_FLAT_CODES = %w[series number subseries].freeze
31
- COMPACT_FLAT_VALUES = %w[volume].freeze
32
- COMPACT_DROP_ATTRS = %w[first_number second_number].freeze
33
-
34
- # Deserialize a (possibly compact) hash: expand the flattened scalars
35
- # back into Code sub-hashes, then let the shared polymorphic from_hash
36
- # do the real work. Nested `base` documents are expanded recursively by
37
- # their own from_hash via apply_mappings, so only this level is touched.
38
- def self.from_hash(data, options = {})
39
- super(expand_compact_hash(data), options)
40
- end
41
-
42
- # Expand a compact hash in place-safe fashion: a scalar series/number
43
- # becomes { "value" => …, "part" => <last-dash segment> }.
44
- def self.expand_compact_hash(data)
45
- return data unless data.is_a?(::Hash)
46
-
47
- out = data.dup
48
- COMPACT_FLAT_CODES.each do |key|
49
- out[key] = expand_code(out[key]) if out[key].is_a?(::String)
50
- end
51
- COMPACT_FLAT_VALUES.each do |key|
52
- out[key] = { "value" => out[key] } if out[key].is_a?(::String)
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
+ []
53
12
  end
54
- out
55
- end
56
13
 
57
- # A flattened Code scalar -> { "value" => …, "part" => <last-dash seg> }.
58
- def self.expand_code(value)
59
- code = { "value" => value }
60
- code["part"] = value.split("-").last if value.include?("-")
61
- code
62
- end
63
-
64
- # Serialize, then apply the compact transforms (recursing into a nested
65
- # `base`, which lutaml serialized via its own transform — bypassing this
66
- # override — so it is not compacted otherwise).
67
- def to_hash(*args)
68
- hash = super
69
- compact_hash!(hash) if hash.is_a?(::Hash)
70
- hash
71
- end
72
-
73
- def compact_hash!(hash)
74
- COMPACT_DROP_ATTRS.each { |key| hash.delete(key) }
75
- (COMPACT_FLAT_CODES + COMPACT_FLAT_VALUES).each do |key|
76
- value = hash[key]
77
- next unless value.is_a?(::Hash) && value.key?("value")
78
-
79
- hash[key] = value["value"]
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
80
69
  end
81
- compact_hash!(hash["base"]) if hash["base"].is_a?(::Hash)
82
- hash
83
- end
84
- private :compact_hash!
85
70
 
86
- # Default: no typed stages. Subclasses override as needed.
87
- def self.typed_stages
88
- []
89
- end
71
+ def initialize(**attributes)
72
+ super()
90
73
 
91
- # Generate URN for this identifier
92
- #
93
- # @return [String] URN representation
94
-
95
- # Plain string ("NIST"/"NBS"), not a Components::Publisher wrapper: the
96
- # value is a single token, so a string serializes flat
97
- # (`publisher: NBS`, not `publisher: {publisher: NBS}`) and accepts the
98
- # raw string the circular/supplement builders pass straight through.
99
- attribute :publisher, :string
100
- attribute :series, Components::Code # Set by Builder from parsed data
101
- # SP subseries (Appendix A.2 of the NIST PubID Syntax): for "NIST SP 800-53"
102
- # the subseries is "800" and the sequence is "53". Populated by the Builder
103
- # when the series is "SP" and the first number matches a known subseries
104
- # code. Informational metadata derived from series+number — ignored in
105
- # equality so a manually-built id (without subseries set) still equals a
106
- # parsed one.
107
- attribute :subseries, Components::Code
108
- attribute :number, Components::Code
109
-
110
- # V2 COMPONENTS (Lutaml::Model objects) - PROPER SEPARATION
111
- # `edition` (Components::Edition: type + id + additional_text) is the
112
- # single source of truth for edition/revision. The former
113
- # `edition_component` (a byte-identical duplicate) and the `revision`
114
- # string (always "#{edition.type}#{edition.id}") were unfinished V1->V2
115
- # migration aliases; both removed. `#revision` survives as a derived
116
- # reader below.
117
- attribute :edition, Components::Edition # Edition (type + id): e2, e2021, r5, -3
118
- attribute :volume, Components::Volume # Volume component (v6)
119
- attribute :part, Components::Part # Part component (n1 or pt1)
120
- attribute :stage, Components::Stage
121
- attribute :version_component, Components::Version
122
- attribute :update_component, Components::Update
123
- attribute :translation_component, Components::Translation
124
- attribute :issue_number, Components::IssueNumber
125
- attribute :parsed_format, :string # :mr, :short, :long, :abbrev
126
- # Whether the publisher prefix (NIST/NBS) should be rendered. Defaults
127
- # to true so the common publisher-bearing id need not serialize the
128
- # flag at all — the Builder only assigns it (false) for prefix-less
129
- # inputs, so `to_hash` carries `publisher_was_parsed: false` only in
130
- # that case and omits it otherwise. (lutaml emits a boolean iff it was
131
- # explicitly assigned; an omitted key loads as this default.)
132
- attribute :publisher_was_parsed, :boolean, default: -> { true }
133
-
134
- # LEGACY attributes (keep for backward compatibility during migration)
135
- attribute :parts, Components::Code, collection: true
136
- attribute :revision_year, :string # Year for revision (e.g., r6/1925, r1963, rJun1992)
137
- attribute :revision_month, :string # Month for revision (e.g., rJun1992)
138
- attribute :edition_year, :string # Legacy edition year for backward compatibility
139
- attribute :version, :string
140
- attribute :update, Components::Update
141
- attribute :year, :integer
142
- attribute :month, :integer
143
-
144
- # Additional attributes for complex patterns
145
- attribute :first_number, Components::Code
146
- attribute :second_number, Components::Code
147
- attribute :update_number, :string
148
- attribute :update_year, :string
149
- attribute :addendum, :string
150
- attribute :addendum_number, :string
151
- # Single source of truth for the supplement: a structured component with
152
- # isolated parts (number / year / month / date-range / revision), so a
153
- # supplement's year is queryable independently of its number. Presence
154
- # (non-nil) means "is a supplement"; an all-empty component is a bare
155
- # "sup" marker. Replaces the former flat :supplement string plus the
156
- # separate date-range/has_revision fields.
157
- attribute :supplement, Components::Supplement
158
- attribute :errata, :string
159
- attribute :index, :string
160
- attribute :insert, :string
161
- attribute :section, :string
162
- attribute :appendix, :string
163
- attribute :translation, :string
164
- attribute :draft, :string
165
- attribute :draft_number, :string # For -draft N → N pd rendering
166
-
167
- # Default series_code — subclasses override to provide a normalized series name.
168
- def series_code
169
- nil
170
- end
171
-
172
- def initialize(**attributes)
173
- # This override calls `super()` with no attributes and assigns through
174
- # setters instead, so it bypasses the base constructor's coercion and
175
- # unknown-key check. Apply them here to keep the cross-flavor contract.
176
- attributes = self.class.normalize_init_attributes(attributes)
177
- super()
74
+ attrs = self.class.attributes
75
+ attributes.each do |key, value|
76
+ next if value.nil?
178
77
 
179
- attrs = self.class.attributes
180
- attributes.each do |key, value|
181
- next if value.nil?
78
+ setter = :"#{key}="
79
+ public_send(setter, value) if attrs.key?(key)
80
+ end
182
81
 
183
- setter = :"#{key}="
184
- public_send(setter, value) if attrs.key?(key)
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
185
85
  end
186
86
 
187
- # NOTE: Compound number building is handled by the Builder class
188
- # Do NOT build compound numbers here - let the builder apply special patterns first
189
- # See lib/pubid/nist/builder.rb lines 368-472 for compound number logic
190
- end
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
191
91
 
192
- # Attributes that are build artifacts or rendering aliases, not part
193
- # of an identifier's logical identity. They diverge between equally-
194
- # valid spellings of the same id (e.g. long "Rev. 1" vs short "r1"):
195
- # - first_number/second_number: decomposed parts of the canonical
196
- # :number, retained from the parse for building
197
- # - parsed_format: records the input format for round-trip rendering
198
- # - subseries: derived from series+number (which SP subseries the
199
- # document belongs to); populated by the Builder for known SP
200
- # subseries codes. Ignored in equality so a manually-built id
201
- # without subseries set still equals a parsed one.
202
- EQUALITY_IGNORED_ATTRS = %i[
203
- first_number second_number parsed_format subseries
204
- ].freeze
205
-
206
- # Logical identity comparison: equal when every attribute except the
207
- # build artifacts/aliases above matches. (Edition#== already ignores
208
- # its rendering-only original_prefix.)
209
- def ==(other)
210
- return false unless other.instance_of?(self.class)
211
-
212
- self.class.attributes.each_key.all? do |name|
213
- EQUALITY_IGNORED_ATTRS.include?(name) || public_send(name) == other.public_send(name)
92
+ # Compute from edition component if available
93
+ if edition&.type && edition.id
94
+ "#{edition.type}#{edition.id}"
95
+ end
214
96
  end
215
- end
216
-
217
- alias eql? ==
218
97
 
219
- def hash
220
- vals = self.class.attributes.each_key.reject do |name|
221
- EQUALITY_IGNORED_ATTRS.include?(name)
222
- end.map { |name| public_send(name) }
223
- [self.class, *vals].hash
224
- end
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
225
103
 
226
- # Wildcard / partial-identifier match. Treats +self+ as a QUERY pattern
227
- # and +candidate+ as a concrete document: every ID part SET on the query
228
- # must equal the candidate's, while parts left unset (nil/empty) are
229
- # wildcards that match any value. So a query carrying no edition and no
230
- # supplement matches that document across ALL editions, years, and
231
- # supplements — the basis for "select docs by ID parts".
232
- #
233
- # Asymmetric (unlike ==): "NBS CIRC 25".matches?("NBS CIRC 25sup1924")
234
- # is true, but not the reverse. The candidate must be the same class or
235
- # a subclass so series-level identity still holds.
236
- def matches?(candidate)
237
- return false unless candidate.is_a?(self.class)
238
-
239
- self.class.attributes.each_key.all? do |name|
240
- next true if EQUALITY_IGNORED_ATTRS.include?(name)
241
-
242
- query_val = public_send(name)
243
- next true if query_val.nil?
244
- next true if query_val.is_a?(String) && query_val.empty?
245
- next true if query_val.is_a?(Array) && query_val.empty?
246
-
247
- query_val == candidate.public_send(name)
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
248
108
  end
249
- end
250
109
 
251
- # NIST inherits Pubid::Identifier#exclude directly: it now rebuilds via
252
- # `self.class.new(**attrs)`, so NIST's keyword-only initialize
253
- # (initialize(**attributes)) works without a local override, and the base
254
- # version additionally carries the nested-identifier recursion this class's
255
- # old copy lacked.
256
-
257
- # Short-form supplement fragment ("sup", "sup1924", "supJan1924",
258
- # "suprev", " supJun1925-Jun1926"), rendered from the structured
259
- # component. A present-but-empty component is the bare "sup" marker; a
260
- # number-less date range gets the leading space the number would have
261
- # supplied. Shared by base and the per-series to_short_style overrides.
262
- def supplement_short
263
- return "" unless supplement
264
-
265
- prefix = supplement.range? && !number ? " " : ""
266
- rendered = supplement.to_s(:short)
267
- prefix + (rendered.empty? ? "sup" : rendered)
268
- end
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
269
134
 
270
- # Derived, read-only revision string ("r5", "e1979", "-3") for backward
271
- # compatibility. `edition` is the single stored representation; this is
272
- # never persisted, compared, or merged — just a convenience view of it.
273
- # @return [String, nil] revision string (e.g., "r5") or nil
274
- def revision
275
- "#{edition.type}#{edition.id}" if edition&.type && edition.id
276
- end
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
277
144
 
278
- # Backward compatibility: translation method returns translation_component
279
- # This allows tests to use parsed.translation.language instead of parsed.translation_component.language
280
- def translation
281
- translation_component
282
- end
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
283
176
 
284
- # Backward compatibility: language method returns translation_component
285
- # This allows tests to use parsed.language instead of parsed.translation_component
286
- def language
287
- translation_component
288
- end
177
+ public_send(:"#{var_name}=", new_val) if should_merge
178
+ end
289
179
 
290
- # Override parent render to pass NIST-specific format option through
291
- # to the renderer. Pubid::Identifier#render only forwards
292
- # :with_edition; NIST needs :nist_format for multi-format support.
293
- def render(format: :human, **opts)
294
- registry = self.class.format_registry
295
- unless registry
296
- raise ArgumentError, "No format registry configured on #{self.class}"
180
+ self
297
181
  end
298
182
 
299
- renderer = registry.renderer_for(format)
300
- unless renderer
301
- raise ArgumentError, "No renderer registered for format: #{format}"
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
302
189
  end
303
190
 
304
- renderer.new(self).render(**opts)
305
- end
306
-
307
- # Generate identifier string in specified format
308
- # @param format [:full, :long, :abbreviated, :short, :mr] output format
309
- def to_s(format = nil)
310
- # Handle both keyword argument (hash) and positional argument (symbol/string)
311
- annotated = format.is_a?(Hash) ? format[:annotated] : nil
312
- format = format[:format] if format.is_a?(Hash)
313
-
314
- # Default to parsed_format if available (preserves input format on round-trip)
315
- # Falls back to :short format for output (normalization)
316
- # Explicit format parameter always overrides parsed_format
317
- rendered = render(format: :human,
318
- nist_format: format || parsed_format&.to_sym || :short)
319
-
320
- # NIST's `to_s` takes a POSITIONAL format and its `render` override
321
- # builds no rendering context, so neither the flag nor the context
322
- # reaches the shared hook. Apply the annotation fallback here.
323
- annotate_plain_render(rendered, annotated: annotated)
324
- end
325
-
326
- # NIST has its own defined MR format (to_mr_style) used by relaton-nist
327
- # and downstream tooling. The generic Renderers::MrString does not know
328
- # about NIST series, revisions, supplements, etc., so delegate to the
329
- # established style for losslessness (issue #142).
330
- def to_mr_string
331
- to_mr_style
332
- end
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
333
200
 
334
- # NIST's MR shape is fixed by the pubid standard and stays uppercase
335
- # (e.g. `NIST.SP.800-53`). The slug, however, must be lowercase to
336
- # match the cross-flavor convention; project the MR through `downcase`.
337
- def to_slug
338
- to_mr_string.downcase
339
- end
201
+ private
340
202
 
341
- # Returns weight based on amount of defined attributes
342
- # Used for ranking identifiers by specificity for conflict resolution
343
- # @return [Integer] weight score (higher = more specific)
344
- def weight
345
- self.class.attributes.keys.inject(0) do |sum, key|
346
- next sum if EQUALITY_IGNORED_ATTRS.include?(key)
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?
347
209
 
348
- val = public_send(key)
349
- val && !val.to_s.empty? ? sum + 1 : sum
350
- end
351
- end
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
352
216
 
353
- # Merge another document into this one
354
- # Used for combining document data, preferring more specific values
355
- # @param document [Base] another NIST document to merge
356
- # @return [Base] self with merged attributes
357
- def merge(document)
358
- return self unless document.is_a?(Pubid::Nist::Identifier)
359
-
360
- attrs = self.class.attributes
361
- attrs.each_key do |var_name|
362
- next if var_name == :rendering_style
363
- next if var_name == :parsed_format
364
-
365
- current_val = public_send(var_name)
366
- new_val = document.public_send(var_name)
367
- next unless new_val
368
-
369
- should_merge = case var_name
370
- when :publisher, :series, :number
371
- true
372
- when :edition
373
- current_val.nil? || edition_greater?(new_val,
374
- current_val)
375
- when :volume, :part, :version
376
- current_val.nil? || (new_val.to_s.length > current_val.to_s.length)
377
- when :supplement, :errata, :index, :insert, :section, :appendix, :translation
378
- true
379
- when :year, :month, :update, :draft
380
- true
381
- else
382
- false
383
- end
384
-
385
- public_send(:"#{var_name}=", new_val) if should_merge
386
- end
217
+ # NEW: Use edition component properly
218
+ result += " #{edition.to_s(:long)}" if edition
387
219
 
388
- self
389
- end
220
+ result += ", Revision #{revision.sub(/^r/, '')}" if revision
390
221
 
391
- # Helper to compare edition values numerically
392
- # @return [Boolean] true if edition1 is greater than edition2
393
- def edition_greater?(edition1, edition2)
394
- num1 = extract_edition_number(edition1)
395
- num2 = extract_edition_number(edition2)
396
- num1 && num2 && num1 > num2
397
- end
222
+ # V2: Use version_component
223
+ result += " #{version_component.to_s(:long)}" if version_component
398
224
 
399
- # Extract numeric value from edition (r3 -> 3, r5 -> 5, e2 -> 2)
400
- # @return [Integer, nil] the edition number or nil if not extractable
401
- def extract_edition_number(edition)
402
- # Handle both String and Edition component
403
- edition_str = edition.to_s
404
- # Match patterns like r3, r5, e2, etc.
405
- match = edition_str.match(/^[er]?(\d+)$/)
406
- match ? match[1].to_i : nil
407
- end
225
+ # V2: Use update_component
226
+ result += " #{update_component.to_s(:long)}" if update_component
408
227
 
409
- public
228
+ # V2: Use stage
229
+ result += " #{stage.to_s(:long)}" if stage
410
230
 
411
- def to_full_style
412
- # "National Institute of Standards and Technology Special Publication 800-27, Revision A"
413
- result = publisher_full_name
414
- result += " #{series_full_name}" if series
415
- result += " #{number.value}" if number
416
- result += parts.map { |p| "-#{p}" }.join if parts&.any?
231
+ # V2: Use translation_component (already includes space)
232
+ result += translation_component.to_s(:long) if translation_component
417
233
 
418
- # Render volume and issue number in long form: "Vol. 6, No. 12"
419
- if volume && issue_number
420
- result += " Vol. #{volume}, #{issue_number.to_s(:long)}"
421
- elsif volume
422
- result += " Vol. #{volume}"
234
+ result
423
235
  end
424
236
 
425
- # NEW: Use edition component properly
426
- result += " #{edition.to_s(:long)}" if edition
427
-
428
- result += ", Revision #{revision.sub(/^r/, '')}" if revision
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?
429
243
 
430
- # V2: Use version_component
431
- result += " #{version_component.to_s(:long)}" if version_component
244
+ # NEW: Use edition component properly
245
+ result += " #{edition.to_s(:abbrev)}" if edition
432
246
 
433
- # V2: Use update_component
434
- result += " #{update_component.to_s(:long)}" if update_component
247
+ result += ", Revision #{revision}" if revision
435
248
 
436
- # V2: Use stage
437
- result += " #{stage.to_s(:long)}" if stage
249
+ # V2: Use version_component
250
+ result += " #{version_component.to_s(:abbrev)}" if version_component
438
251
 
439
- # V2: Use translation_component (already includes space)
440
- result += translation_component.to_s(:long) if translation_component
252
+ # V2: Use update_component
253
+ result += " #{update_component.to_s(:abbrev)}" if update_component
441
254
 
442
- result
443
- end
444
-
445
- def to_abbreviated_style
446
- # "Natl. Inst. Stand. Technol. Spec. Publ. 800-57 Part 1, Revision 4"
447
- result = publisher_abbreviated_name
448
- result += " #{series_abbreviated_name}" if series
449
- result += " #{number}" if number
450
- result += " Part #{parts.first}" if parts&.any?
255
+ # V2: Use stage
256
+ result += " #{stage.to_s(:abbrev)}" if stage
451
257
 
452
- # NEW: Use edition component properly
453
- result += " #{edition.to_s(:abbrev)}" if edition
258
+ # V2: Use translation_component
259
+ result += ", #{translation_component.to_s(:abbrev)}" if translation_component
454
260
 
455
- result += ", Revision #{revision}" if revision
261
+ result
262
+ end
456
263
 
457
- # V2: Use version_component
458
- result += " #{version_component.to_s(:abbrev)}" if version_component
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
459
299
 
460
- # V2: Use update_component
461
- result += " #{update_component.to_s(:abbrev)}" if update_component
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
462
319
 
463
- # V2: Use stage
464
- result += " #{stage.to_s(:abbrev)}" if stage
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
465
335
 
466
- # V2: Use translation_component
467
- result += ", #{translation_component.to_s(:abbrev)}" if translation_component
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
468
342
 
469
- result
470
- end
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
471
360
 
472
- def to_short_style
473
- # "SP 800-187" or "NIST SP 800-187" - handle compound series properly
474
- result = ""
475
-
476
- # Determine effective publisher
477
- # Only show publisher if it was explicitly parsed (either directly or from series prefix)
478
- effective_publisher = if publisher && publisher_was_parsed
479
- # Publisher was in input (either as separate field or extracted from "NBS CS" series)
480
- publisher.to_s
481
- else
482
- # No publisher in input, don't show default
483
- nil
484
- end
485
-
486
- # Determine effective series - PREFER series_code if subclass defines it
487
- # This allows normalization (e.g., LCIRC → LC in LetterCircular)
488
- effective_series = if series_code
489
- series_code
490
- elsif series
491
- series.to_s
492
- end
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
493
367
 
494
- # Special handling for compound series that include publisher prefix
495
- # If series starts with "NBS " (like "NBS CIRC"), use it as-is
496
- if effective_series&.start_with?("NBS ")
497
- result += effective_series
498
- elsif effective_publisher && effective_series
499
- result += "#{effective_publisher} #{effective_series}"
500
- elsif effective_series && publisher_was_parsed
501
- # Only add "NIST" prefix if publisher was explicitly in the input
502
- result += "NIST #{effective_series}"
503
- elsif effective_series
504
- # No publisher in input, just show series without prefix
505
- result += effective_series
506
- end
368
+ # Add addendum - render as " Add." suffix
369
+ if addendum || addendum_number
370
+ result += " Add."
371
+ end
507
372
 
508
- result += " #{number}" if number
509
- result += parts.map { |p| "-#{p}" }.join if parts&.any?
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
510
379
 
511
- # "NIST Research Library (YYYY)" — oddball identifier with no number;
512
- # the year appears in parens rather than as a date component.
513
- result += " (#{year})" if year && !number
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
514
386
 
515
- # Append every optional component the parser may have attached
516
- # (volume, part, edition, version, supplement, update, stage, ...).
517
- # Shared with the lossy subclasses so they cannot silently drop a
518
- # distinguishing component and collide with another document.
519
- result += append_short_components
387
+ # V2: Add stage component (at end, before translation)
388
+ if stage
389
+ result += " #{stage.to_s(:short)}"
390
+ end
520
391
 
521
- result
522
- end
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
523
399
 
524
- # Render the optional component "tail" that follows
525
- # publisher/series/number in short (human) form. Extracted from
526
- # #to_short_style so subclasses that build a series-specific prefix can
527
- # reuse it instead of hand-listing components (and forgetting some).
528
- #
529
- # skip_part: true lets a series that renders its part differently
530
- # (e.g. FIPS uses dash "-1", not "pt1") emit the part itself and skip
531
- # the generic part rendering here, while still getting volume/edition/
532
- # supplement/etc.
533
- def append_short_components(skip_part: false)
534
- result = ""
535
- effective_part = skip_part ? nil : part
536
-
537
- # Volume and Part components (v6n1 notation for CSM, pt1 for SP)
538
- if volume.is_a?(Components::Volume) && effective_part.is_a?(Components::Part)
539
- # CSM series: v#n# notation
540
- result += " #{volume}#{effective_part}"
541
- elsif effective_part.is_a?(Components::Part)
542
- # SP and other series: use Part.type to determine format
543
- result += effective_part.to_s
544
- # Legacy: Render standalone volume (not part of v#n#)
545
- elsif volume && !issue_number && !effective_part
546
- vol_str = volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}"
547
- result += vol_str
548
- elsif volume && issue_number
549
- # Render volume and issue number in short form: "v6n12"
550
- vol_str = volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}"
551
- result += "#{vol_str}n#{issue_number.number}"
400
+ result
552
401
  end
553
402
 
554
- # Use edition component properly (e2, e2021, r5, -3)
555
- # NO space before edition when number present (per NIST spec)
556
- # Only add space for bare edition (no number case) or if original_prefix has specific format
557
- if edition
558
- if edition.original_prefix && !edition.original_prefix.empty?
559
- # original_prefix includes the full prefix (e.g., " Rev. " for verbose format)
560
- result += edition.to_s
561
- elsif number
562
- # Number present, NO space: "800-53r5"
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
563
428
  result += edition.to_s
564
- else
565
- # Bare edition, add space: " r5"
566
- result += " #{edition}"
567
429
  end
568
- end
569
430
 
570
- # Use version_component if available, else use version string.
571
- # Attach directly (no leading space) to match edition rendering
572
- # (e.g. "800-53r5"), so version reads "800-45ver2" not
573
- # "800-45 ver2".
574
- if version_component
575
- result += version_component.to_s(:short)
576
- elsif version
577
- result += "ver#{version}"
578
- end
431
+ # V2: Use version_component
432
+ result += version_component.to_s(:mr) if version_component
579
433
 
580
- # Add supplement. NIST/NBS canonical short form is single-p "sup"
581
- # with the suffix attached directly, no dash (relaton-data-nist
582
- # uses "sup2", "sup1940", "supA"); date-range keeps its inner dash.
583
- # Rendered from the structured component; a present-but-empty
584
- # component is the bare "sup" marker.
585
- result += supplement_short
586
-
587
- # Add other attributes
588
- result += errata.to_s if errata
589
- result += "index" if index
590
- result += "insert" if insert
591
- result += "sec#{section}" if section
592
- result += "app" if appendix
593
-
594
- # Add addendum - render as " Add." suffix
595
- if addendum || addendum_number
596
- result += " Add."
597
- end
434
+ # V2: Use update_component
435
+ result += update_component.to_s(:mr) if update_component
598
436
 
599
- # Use update_component if available, else use update string
600
- if update_component
601
- result += update_component.to_s(:short)
602
- elsif update
603
- result += "-upd#{update}"
604
- end
437
+ # V2: Use stage
438
+ result += ".#{stage.to_s(:mr)}" if stage
605
439
 
606
- # Add draft - render as {N}pd if draft_number present
607
- if draft_number
608
- result += " #{draft_number}pd"
609
- elsif draft&.to_s&.include?("draft") && !draft.to_s.include?("Draft)")
610
- result += "-draft"
611
- end
440
+ # Add addendum - render as ".Add." suffix in MR format
441
+ if addendum || addendum_number
442
+ result += ".Add."
443
+ end
612
444
 
613
- # Add stage component (at end, before translation)
614
- if stage
615
- result += " #{stage.to_s(:short)}"
616
- end
445
+ # V2: Use translation_component
446
+ result += translation_component.to_s(:mr) if translation_component
617
447
 
618
- # Use translation_component if available, else use translation string
619
- # Note: translation_component.to_s already includes the space prefix
620
- if translation_component
621
- result += translation_component.to_s(:short)
622
- elsif translation
623
- result += " #{translation}"
448
+ result
624
449
  end
625
450
 
626
- result
627
- end
628
-
629
- def to_mr_style
630
- # "NIST.SP.800-116r1.ipd" (machine-readable with dots)
631
- result = (publisher || "NIST").to_s
632
-
633
- # Determine effective series - PREFER series_code if subclass defines it
634
- # This allows normalization (e.g., LCIRC → LC in LetterCircular)
635
- effective_series = if series_code
636
- series_code
637
- elsif series
638
- series.to_s
639
- end
640
-
641
- result += ".#{effective_series}" if effective_series
642
- result += ".#{number}" if number
643
- result += parts.map { |p| "-#{p}" }.join if parts&.any?
644
-
645
- result += append_mr_components
646
-
647
- result
648
- end
649
-
650
- # Render the optional component tail for machine-readable (MR) form.
651
- # Mirrors #append_short_components so the MR output is just as lossless;
652
- # subclasses that override #to_mr_style reuse this instead of
653
- # hand-listing components. skip_part: behaves as in the short helper.
654
- def append_mr_components(skip_part: false)
655
- result = ""
656
- effective_part = skip_part ? nil : part
657
-
658
- # Volume / Part components (pt1, v6n1, etc.)
659
- if volume.is_a?(Components::Volume) && effective_part.is_a?(Components::Part)
660
- result += "#{volume}#{effective_part}"
661
- elsif effective_part.is_a?(Components::Part)
662
- result += effective_part.to_s
663
- elsif volume && !issue_number && !effective_part
664
- result += (volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}")
665
- elsif volume && issue_number
666
- vol_str = volume.is_a?(Components::Volume) ? volume.to_s : "v#{volume}"
667
- result += "#{vol_str}n#{issue_number.number}"
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
668
458
  end
669
459
 
670
- # Use edition component - NO space before edition in MR format (per NIST spec)
671
- result += edition.to_s if edition
672
-
673
- # Use version_component
674
- result += version_component.to_s(:mr) if version_component
675
-
676
- # Supplement (e.g. ".9981sup7") - keep distinct documents distinct
677
- result += supplement_short
678
-
679
- # Use update_component
680
- result += update_component.to_s(:mr) if update_component
681
-
682
- # Use stage
683
- result += ".#{stage.to_s(:mr)}" if stage
684
-
685
- # Add addendum - render as ".Add." suffix in MR format
686
- if addendum || addendum_number
687
- result += ".Add."
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)
688
467
  end
689
468
 
690
- # Use translation_component
691
- result += translation_component.to_s(:mr) if translation_component
692
-
693
- result
694
- end
695
-
696
- def series_full_name
697
- {
698
- "SP" => "Special Publication",
699
- "FIPS" => "Federal Information Processing Standards",
700
- "IR" => "Interagency Report",
701
- "TN" => "Technical Note",
702
- }[series] || series
703
- end
704
-
705
- def series_abbreviated_name
706
- {
707
- "SP" => "Spec. Publ.",
708
- "FIPS" => "Fed. Inf. Proc. Stand.",
709
- "IR" => "Interag. Rep.",
710
- "TN" => "Tech. Note",
711
- }[series&.to_s || series_code] || (series&.to_s || series_code)
712
- end
713
-
714
- def publisher_full_name
715
- case publisher.to_s
716
- when "NBS"
717
- "National Bureau of Standards"
718
- when "NIST"
719
- "National Institute of Standards and Technology"
720
- else
721
- publisher.to_s
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
722
478
  end
723
- end
724
479
 
725
- def publisher_abbreviated_name
726
- case publisher.to_s
727
- when "NBS"
728
- "Natl. Bur. Stand."
729
- when "NIST"
730
- "Natl. Inst. Stand. Technol."
731
- else
732
- publisher.to_s
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
733
489
  end
734
- end
735
490
 
736
- # Default publisher for series without explicit publisher
737
- # Subclasses can override
738
- def default_publisher
739
- "NIST"
491
+ # Default publisher for series without explicit publisher
492
+ # Subclasses can override
493
+ def default_publisher
494
+ "NIST"
495
+ end
740
496
  end
741
497
  end
742
-
743
498
  end
744
499
  end