pubid 2.0.0.pre.alpha.1 → 2.0.0.pre.alpha.3

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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +5 -1
  3. data/data/nist/update_codes.yaml +27 -0
  4. data/lib/pubid/amca/builder.rb +2 -2
  5. data/lib/pubid/amca/identifier.rb +7 -0
  6. data/lib/pubid/amca/identifiers/base.rb +0 -26
  7. data/lib/pubid/amca/identifiers/interpretation.rb +0 -17
  8. data/lib/pubid/amca/identifiers/publication.rb +0 -13
  9. data/lib/pubid/amca/renderer.rb +82 -0
  10. data/lib/pubid/amca/single_identifier.rb +0 -23
  11. data/lib/pubid/amca/urn_parser.rb +28 -0
  12. data/lib/pubid/amca.rb +42 -1
  13. data/lib/pubid/ansi/builder.rb +5 -3
  14. data/lib/pubid/ansi/identifier.rb +1 -1
  15. data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
  16. data/lib/pubid/ansi/identifiers/standard.rb +2 -3
  17. data/lib/pubid/ansi/renderer.rb +53 -0
  18. data/lib/pubid/ansi/single_identifier.rb +2 -31
  19. data/lib/pubid/ansi/urn_generator.rb +3 -38
  20. data/lib/pubid/ansi/urn_parser.rb +23 -0
  21. data/lib/pubid/ansi.rb +38 -3
  22. data/lib/pubid/api/builder.rb +29 -74
  23. data/lib/pubid/api/identifier.rb +0 -4
  24. data/lib/pubid/api/identifiers/base.rb +0 -2
  25. data/lib/pubid/api/identifiers/bulletin.rb +0 -2
  26. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
  27. data/lib/pubid/api/identifiers/mpms.rb +1 -17
  28. data/lib/pubid/api/identifiers/publication.rb +0 -2
  29. data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
  30. data/lib/pubid/api/identifiers/specification.rb +0 -2
  31. data/lib/pubid/api/identifiers/standard.rb +0 -2
  32. data/lib/pubid/api/identifiers/technical_report.rb +0 -2
  33. data/lib/pubid/api/identifiers/typeless_standard.rb +1 -14
  34. data/lib/pubid/api/identifiers.rb +18 -0
  35. data/lib/pubid/api/renderer.rb +89 -0
  36. data/lib/pubid/api/single_identifier.rb +1 -13
  37. data/lib/pubid/api/urn_generator.rb +0 -18
  38. data/lib/pubid/api/urn_parser.rb +35 -0
  39. data/lib/pubid/api.rb +51 -5
  40. data/lib/pubid/ashrae/builder.rb +3 -3
  41. data/lib/pubid/ashrae/identifier.rb +6 -0
  42. data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
  43. data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
  44. data/lib/pubid/ashrae/identifiers/base.rb +3 -0
  45. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
  46. data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
  47. data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
  48. data/lib/pubid/ashrae/renderer.rb +117 -0
  49. data/lib/pubid/ashrae/single_identifier.rb +0 -13
  50. data/lib/pubid/ashrae/urn_generator.rb +0 -8
  51. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  52. data/lib/pubid/ashrae.rb +42 -1
  53. data/lib/pubid/asme/components/code.rb +10 -2
  54. data/lib/pubid/asme/identifiers/base.rb +0 -60
  55. data/lib/pubid/asme/renderer.rb +66 -0
  56. data/lib/pubid/asme/urn_parser.rb +31 -0
  57. data/lib/pubid/asme.rb +42 -1
  58. data/lib/pubid/astm/components/code.rb +9 -0
  59. data/lib/pubid/{jis → astm}/components.rb +1 -1
  60. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  61. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  62. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  63. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  64. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  65. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  66. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  67. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  68. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  69. data/lib/pubid/astm/identifiers.rb +18 -0
  70. data/lib/pubid/astm/renderer.rb +172 -0
  71. data/lib/pubid/astm/single_identifier.rb +0 -10
  72. data/lib/pubid/astm/urn_parser.rb +30 -0
  73. data/lib/pubid/astm.rb +39 -27
  74. data/lib/pubid/bsi/builder.rb +21 -12
  75. data/lib/pubid/bsi/identifier.rb +8 -2
  76. data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
  77. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
  78. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
  79. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
  80. data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
  81. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
  82. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  83. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
  84. data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
  85. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
  86. data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
  87. data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
  88. data/lib/pubid/bsi/identifiers/disc.rb +1 -27
  89. data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
  90. data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
  91. data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
  92. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
  93. data/lib/pubid/bsi/identifiers/flex.rb +1 -33
  94. data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
  95. data/lib/pubid/bsi/identifiers/index.rb +1 -30
  96. data/lib/pubid/bsi/identifiers/method.rb +1 -39
  97. data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
  98. data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
  99. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
  100. data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
  101. data/lib/pubid/bsi/identifiers/section.rb +1 -28
  102. data/lib/pubid/bsi/identifiers/set.rb +3 -17
  103. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
  104. data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
  105. data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
  106. data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
  107. data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
  108. data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
  109. data/lib/pubid/bsi/identifiers.rb +0 -1
  110. data/lib/pubid/bsi/renderer.rb +1050 -0
  111. data/lib/pubid/bsi/single_identifier.rb +6 -70
  112. data/lib/pubid/bsi/urn_generator.rb +2 -3
  113. data/lib/pubid/bsi/urn_parser.rb +52 -0
  114. data/lib/pubid/bsi.rb +224 -1
  115. data/lib/pubid/builder/base.rb +57 -10
  116. data/lib/pubid/bundled_identifier.rb +0 -1
  117. data/lib/pubid/ccsds/builder.rb +4 -3
  118. data/lib/pubid/ccsds/identifier.rb +66 -1
  119. data/lib/pubid/ccsds/identifiers/base.rb +11 -50
  120. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  121. data/lib/pubid/ccsds/parser.rb +4 -2
  122. data/lib/pubid/ccsds/single_identifier.rb +4 -1
  123. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  124. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  125. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  126. data/lib/pubid/ccsds.rb +39 -1
  127. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  128. data/lib/pubid/cen_cenelec/identifier.rb +8 -2
  129. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
  130. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
  131. data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
  132. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  133. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  134. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
  135. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
  136. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  137. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
  138. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  139. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  140. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  141. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  143. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  144. data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
  145. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  146. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  147. data/lib/pubid/cen_cenelec.rb +168 -1
  148. data/lib/pubid/cie/components/code.rb +8 -0
  149. data/lib/pubid/cie/identifier.rb +6 -4
  150. data/lib/pubid/cie/urn_parser.rb +28 -0
  151. data/lib/pubid/cie.rb +43 -1
  152. data/lib/pubid/components/adoption.rb +104 -0
  153. data/lib/pubid/components/code.rb +22 -8
  154. data/lib/pubid/components/date.rb +23 -16
  155. data/lib/pubid/components/edition.rb +9 -6
  156. data/lib/pubid/components/iteration.rb +32 -0
  157. data/lib/pubid/components/language.rb +6 -4
  158. data/lib/pubid/components/locality.rb +10 -1
  159. data/lib/pubid/components/publisher.rb +9 -6
  160. data/lib/pubid/components/relationship.rb +151 -0
  161. data/lib/pubid/components/stage.rb +5 -14
  162. data/lib/pubid/components/supplement.rb +184 -0
  163. data/lib/pubid/components/type.rb +5 -15
  164. data/lib/pubid/components/typed_stage.rb +11 -8
  165. data/lib/pubid/components.rb +4 -0
  166. data/lib/pubid/core/update_codes.rb +28 -7
  167. data/lib/pubid/csa/identifier.rb +0 -3
  168. data/lib/pubid/csa/identifiers/base.rb +2 -122
  169. data/lib/pubid/csa/identifiers/cec.rb +2 -101
  170. data/lib/pubid/csa/identifiers/series.rb +2 -102
  171. data/lib/pubid/csa/renderer.rb +292 -0
  172. data/lib/pubid/csa/urn_generator.rb +1 -1
  173. data/lib/pubid/csa/urn_parser.rb +33 -0
  174. data/lib/pubid/csa.rb +42 -1
  175. data/lib/pubid/etsi/components/code.rb +9 -2
  176. data/lib/pubid/etsi/identifiers/base.rb +1 -4
  177. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
  178. data/lib/pubid/etsi/renderer.rb +42 -0
  179. data/lib/pubid/etsi/urn_parser.rb +34 -0
  180. data/lib/pubid/etsi.rb +42 -1
  181. data/lib/pubid/export/exporter.rb +4 -46
  182. data/lib/pubid/export/flavor_exporter.rb +111 -278
  183. data/lib/pubid/export.rb +0 -6
  184. data/lib/pubid/identifier.rb +10 -18
  185. data/lib/pubid/identifier_facade.rb +114 -0
  186. data/lib/pubid/identifier_metadata.rb +1 -1
  187. data/lib/pubid/idf/builder.rb +3 -3
  188. data/lib/pubid/idf/identifier.rb +3 -6
  189. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  190. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  191. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  192. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  193. data/lib/pubid/idf/parser.rb +3 -2
  194. data/lib/pubid/idf/renderer.rb +84 -0
  195. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  196. data/lib/pubid/idf/urn_generator.rb +4 -39
  197. data/lib/pubid/idf/urn_parser.rb +25 -0
  198. data/lib/pubid/idf.rb +51 -1
  199. data/lib/pubid/iec/builder.rb +48 -65
  200. data/lib/pubid/iec/components/code.rb +9 -32
  201. data/lib/pubid/iec/components/publisher.rb +1 -1
  202. data/lib/pubid/iec/components.rb +14 -0
  203. data/lib/pubid/iec/identifier.rb +276 -3
  204. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  205. data/lib/pubid/iec/identifiers/base.rb +8 -28
  206. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  207. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  208. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -30
  209. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  210. data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -26
  211. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  212. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  213. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  214. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  215. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  216. data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -15
  217. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  218. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  219. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  220. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  221. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  222. data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
  223. data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -23
  224. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  225. data/lib/pubid/iec/identifiers/working_document.rb +4 -48
  226. data/lib/pubid/iec/identifiers.rb +30 -0
  227. data/lib/pubid/iec/parser.rb +20 -14
  228. data/lib/pubid/iec/renderer.rb +254 -0
  229. data/lib/pubid/iec/single_identifier.rb +6 -12
  230. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  231. data/lib/pubid/iec/urn_generator.rb +57 -171
  232. data/lib/pubid/iec/urn_parser.rb +53 -252
  233. data/lib/pubid/iec.rb +40 -68
  234. data/lib/pubid/ieee/builder.rb +12 -12
  235. data/lib/pubid/ieee/components/code.rb +8 -0
  236. data/lib/pubid/ieee/components/draft.rb +14 -0
  237. data/lib/pubid/ieee/components/relationship.rb +5 -149
  238. data/lib/pubid/ieee/identifier.rb +6 -0
  239. data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
  240. data/lib/pubid/ieee/identifiers/base.rb +101 -458
  241. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
  242. data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
  243. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
  244. data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
  245. data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
  246. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
  247. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
  248. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  249. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
  250. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
  251. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  252. data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
  253. data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
  254. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  255. data/lib/pubid/ieee/pre_parser.rb +301 -0
  256. data/lib/pubid/ieee/renderer.rb +307 -0
  257. data/lib/pubid/ieee/urn_parser.rb +34 -0
  258. data/lib/pubid/ieee.rb +62 -1
  259. data/lib/pubid/ieee_debug.rb +0 -1
  260. data/lib/pubid/iho/builder.rb +2 -2
  261. data/lib/pubid/iho/identifier.rb +8 -0
  262. data/lib/pubid/iho/identifiers/base.rb +49 -10
  263. data/lib/pubid/iho/identifiers/bibliographic.rb +0 -4
  264. data/lib/pubid/iho/identifiers/circular_letter.rb +0 -4
  265. data/lib/pubid/iho/identifiers/miscellaneous.rb +0 -4
  266. data/lib/pubid/iho/identifiers/publication.rb +0 -4
  267. data/lib/pubid/iho/identifiers/standard.rb +0 -4
  268. data/lib/pubid/iho/parser.rb +3 -3
  269. data/lib/pubid/iho/renderer.rb +30 -0
  270. data/lib/pubid/iho/urn_generator.rb +3 -3
  271. data/lib/pubid/iho/urn_parser.rb +58 -0
  272. data/lib/pubid/iho.rb +50 -1
  273. data/lib/pubid/iso/builder.rb +59 -53
  274. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  275. data/lib/pubid/iso/components/code.rb +7 -19
  276. data/lib/pubid/iso/components/publisher.rb +10 -8
  277. data/lib/pubid/iso/components.rb +2 -4
  278. data/lib/pubid/iso/identifier.rb +233 -6
  279. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  280. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  281. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  282. data/lib/pubid/iso/identifiers/data.rb +0 -1
  283. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  284. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  285. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  286. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  287. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  288. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  289. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  290. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  291. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  292. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  293. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  294. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  295. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  296. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  297. data/lib/pubid/iso/identifiers.rb +0 -1
  298. data/lib/pubid/iso/normalizer.rb +89 -0
  299. data/lib/pubid/iso/parser.rb +26 -6
  300. data/lib/pubid/iso/single_identifier.rb +6 -3
  301. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  302. data/lib/pubid/iso/urn_generator.rb +74 -176
  303. data/lib/pubid/iso/urn_parser.rb +28 -9
  304. data/lib/pubid/iso.rb +173 -2
  305. data/lib/pubid/itu/builder.rb +0 -12
  306. data/lib/pubid/itu/components/code.rb +8 -0
  307. data/lib/pubid/itu/components.rb +11 -0
  308. data/lib/pubid/itu/identifier.rb +6 -39
  309. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  310. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  311. data/lib/pubid/itu/identifiers/base.rb +0 -6
  312. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  313. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  314. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  315. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  316. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  317. data/lib/pubid/itu/urn_parser.rb +23 -0
  318. data/lib/pubid/itu.rb +42 -1
  319. data/lib/pubid/jcgm/builder.rb +16 -8
  320. data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
  321. data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
  322. data/lib/pubid/jcgm/renderer.rb +68 -0
  323. data/lib/pubid/jcgm/single_identifier.rb +1 -5
  324. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  325. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  326. data/lib/pubid/jcgm.rb +43 -2
  327. data/lib/pubid/jis/builder.rb +44 -52
  328. data/lib/pubid/jis/identifier.rb +132 -3
  329. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  330. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  331. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  332. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  333. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  334. data/lib/pubid/jis/identifiers.rb +1 -1
  335. data/lib/pubid/jis/parser.rb +31 -5
  336. data/lib/pubid/jis/renderer.rb +69 -0
  337. data/lib/pubid/jis/single_identifier.rb +6 -12
  338. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  339. data/lib/pubid/jis/urn_parser.rb +23 -0
  340. data/lib/pubid/jis.rb +42 -2
  341. data/lib/pubid/nist/builder.rb +122 -1761
  342. data/lib/pubid/nist/caster.rb +1272 -0
  343. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  344. data/lib/pubid/nist/components/code.rb +9 -20
  345. data/lib/pubid/nist/components/edition.rb +16 -0
  346. data/lib/pubid/nist/components/supplement.rb +88 -21
  347. data/lib/pubid/nist/components.rb +0 -1
  348. data/lib/pubid/nist/identifier.rb +25 -0
  349. data/lib/pubid/nist/identifiers/base.rb +206 -64
  350. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  351. data/lib/pubid/nist/identifiers/circular_supplement.rb +3 -2
  352. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  353. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  354. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  355. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -11
  356. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  357. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +17 -16
  358. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  359. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  360. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  361. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  362. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  363. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  364. data/lib/pubid/nist/identifiers/report.rb +4 -3
  365. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  366. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  367. data/lib/pubid/nist/identifiers.rb +1 -0
  368. data/lib/pubid/nist/parser.rb +67 -424
  369. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  370. data/lib/pubid/nist/preprocessor.rb +416 -0
  371. data/lib/pubid/nist/renderer.rb +43 -0
  372. data/lib/pubid/nist/router.rb +148 -0
  373. data/lib/pubid/nist/series/base.rb +58 -0
  374. data/lib/pubid/nist/series/crpl.rb +13 -0
  375. data/lib/pubid/nist/series/fips.rb +14 -0
  376. data/lib/pubid/nist/series/ir.rb +60 -0
  377. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  378. data/lib/pubid/nist/series/mono.rb +19 -0
  379. data/lib/pubid/nist/series/ncstar.rb +20 -0
  380. data/lib/pubid/nist/series.rb +49 -0
  381. data/lib/pubid/nist/supplement_identifier.rb +11 -25
  382. data/lib/pubid/nist/urn_generator.rb +14 -8
  383. data/lib/pubid/nist/urn_parser.rb +67 -0
  384. data/lib/pubid/nist.rb +83 -4
  385. data/lib/pubid/oiml/components/code.rb +10 -0
  386. data/lib/pubid/oiml/identifiers/annex.rb +3 -45
  387. data/lib/pubid/oiml/identifiers/base.rb +2 -17
  388. data/lib/pubid/oiml/renderer.rb +161 -0
  389. data/lib/pubid/oiml/single_identifier.rb +6 -45
  390. data/lib/pubid/oiml/supplement_identifier.rb +4 -19
  391. data/lib/pubid/oiml/urn_generator.rb +0 -8
  392. data/lib/pubid/oiml/urn_parser.rb +22 -0
  393. data/lib/pubid/oiml.rb +42 -1
  394. data/lib/pubid/plateau/identifier.rb +23 -0
  395. data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
  396. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  397. data/lib/pubid/plateau/renderer.rb +51 -0
  398. data/lib/pubid/plateau/supplement_identifier.rb +1 -1
  399. data/lib/pubid/plateau/urn_parser.rb +43 -0
  400. data/lib/pubid/plateau.rb +44 -1
  401. data/lib/pubid/renderers/base.rb +34 -0
  402. data/lib/pubid/renderers/directives_renderer.rb +27 -14
  403. data/lib/pubid/renderers/guide_renderer.rb +7 -1
  404. data/lib/pubid/renderers/human_readable.rb +31 -8
  405. data/lib/pubid/renderers/iwa_renderer.rb +5 -1
  406. data/lib/pubid/renderers/supplement_renderer.rb +4 -1
  407. data/lib/pubid/rendering/context.rb +33 -21
  408. data/lib/pubid/rendering.rb +0 -3
  409. data/lib/pubid/sae/components/date.rb +8 -0
  410. data/lib/pubid/sae/components/type.rb +5 -1
  411. data/lib/pubid/sae/identifiers/base.rb +2 -16
  412. data/lib/pubid/sae/renderer.rb +36 -0
  413. data/lib/pubid/sae/urn_generator.rb +2 -10
  414. data/lib/pubid/sae/urn_parser.rb +36 -0
  415. data/lib/pubid/sae.rb +42 -1
  416. data/lib/pubid/urn_generator/base.rb +12 -12
  417. data/lib/pubid/urn_parser/base.rb +81 -0
  418. data/lib/pubid/urn_parser/errors.rb +9 -0
  419. data/lib/pubid/urn_parser.rb +14 -0
  420. data/lib/pubid/version.rb +1 -1
  421. data/lib/pubid.rb +29 -7
  422. data/lib/tasks/website-data.json +1940 -1882
  423. metadata +77 -43
  424. data/lib/pubid/amca/scheme.rb +0 -16
  425. data/lib/pubid/ansi/scheme.rb +0 -15
  426. data/lib/pubid/api/scheme.rb +0 -66
  427. data/lib/pubid/ashrae/scheme.rb +0 -53
  428. data/lib/pubid/asme/scheme.rb +0 -37
  429. data/lib/pubid/astm/scheme.rb +0 -55
  430. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  431. data/lib/pubid/bsi/scheme.rb +0 -243
  432. data/lib/pubid/ccsds/scheme.rb +0 -57
  433. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  434. data/lib/pubid/cie/scheme.rb +0 -64
  435. data/lib/pubid/csa/scheme.rb +0 -44
  436. data/lib/pubid/etsi/scheme.rb +0 -42
  437. data/lib/pubid/export/data_class_exporter.rb +0 -59
  438. data/lib/pubid/export/ieee_exporter.rb +0 -78
  439. data/lib/pubid/export/itu_exporter.rb +0 -66
  440. data/lib/pubid/export/nist_exporter.rb +0 -64
  441. data/lib/pubid/export/registry_exporter.rb +0 -90
  442. data/lib/pubid/export/scheme_exporter.rb +0 -70
  443. data/lib/pubid/identifier_registry.rb +0 -198
  444. data/lib/pubid/idf/scheme.rb +0 -61
  445. data/lib/pubid/iec/scheme.rb +0 -71
  446. data/lib/pubid/ieee/scheme.rb +0 -90
  447. data/lib/pubid/iho/scheme.rb +0 -29
  448. data/lib/pubid/iso/identifiers/base.rb +0 -115
  449. data/lib/pubid/iso/scheme.rb +0 -187
  450. data/lib/pubid/itu/scheme.rb +0 -174
  451. data/lib/pubid/jcgm/scheme.rb +0 -60
  452. data/lib/pubid/jis/components/code.rb +0 -59
  453. data/lib/pubid/jis/identifiers/base.rb +0 -72
  454. data/lib/pubid/jis/scheme.rb +0 -49
  455. data/lib/pubid/nist/components/publisher.rb +0 -24
  456. data/lib/pubid/nist/scheme.rb +0 -199
  457. data/lib/pubid/oiml/scheme.rb +0 -46
  458. data/lib/pubid/plateau/scheme.rb +0 -45
  459. data/lib/pubid/rendering/base.rb +0 -73
  460. data/lib/pubid/rendering/common.rb +0 -211
  461. data/lib/pubid/rendering/format.rb +0 -25
  462. data/lib/pubid/sae/scheme.rb +0 -47
  463. data/lib/pubid/scheme.rb +0 -207
@@ -3,17 +3,66 @@
3
3
  module Pubid
4
4
  module Iso
5
5
  class Identifier < ::Pubid::Identifier
6
- # Override base types with ISO-specific ones
7
- attribute :publisher, ::Pubid::Iso::Components::Publisher
6
+ # Override base types with ISO-specific ones.
7
+ # Defaults to the type's implied publisher (ISO for most; IWA has none),
8
+ # so an omitted publisher key reconstructs correctly on from_hash.
9
+ attribute :publisher, ::Pubid::Iso::Components::Publisher,
10
+ default: -> { self.class.default_publisher }
8
11
  attribute :copublishers, ::Pubid::Iso::Components::Publisher,
9
12
  collection: true
13
+
14
+ # The publisher implied when none is serialized. ISO for most types;
15
+ # publisher-less types (IWA) override this to nil.
16
+ def self.default_publisher
17
+ ::Pubid::Iso::Components::Publisher.new
18
+ end
19
+
20
+ # typed_stage is the single source of truth for stage (and, with the class,
21
+ # the doctype). Default to the class's published typed_stage, so an omitted
22
+ # "stage" key reconstructs the published state on from_hash.
23
+ attribute :typed_stage, ::Pubid::Components::TypedStage,
24
+ default: -> { self.class.published_typed_stage }
25
+
26
+ # The class's published typed_stage (canonical surface form), or nil for
27
+ # types with no stages (e.g. TC documents).
28
+ def self.published_typed_stage
29
+ return nil unless const_defined?(:TYPED_STAGES)
30
+
31
+ ts = self::TYPED_STAGES.find { |t| t.stage_code.to_s == "published" }
32
+ return nil unless ts
33
+
34
+ ts = ts.dup
35
+ ts.original_abbr = ts.canonical_abbreviation
36
+ ts
37
+ end
38
+
39
+ # type and stage are derived from typed_stage, never stored — so the
40
+ # doctype (fixed by the class / _type) can't be lost when "stage" is
41
+ # omitted for the published default.
42
+ def type
43
+ typed_stage&.to_type
44
+ end
45
+
46
+ def stage
47
+ typed_stage&.to_stage
48
+ end
49
+
50
+ # Return a copy with the lifecycle stage set from an ISO harmonized stage
51
+ # code (e.g. "90.92"). typed_stage is the single source of truth, so this
52
+ # is all that is needed to surface the stage in #to_s and #to_urn. Returns
53
+ # an unchanged copy if the code is not recognised.
54
+ def with_harmonized_stage(harmonized_code)
55
+ ts = Pubid::Iso.locate_stage_by_harmonized_code(harmonized_code)
56
+ ts ? dup.tap { |id| id.typed_stage = ts } : dup
57
+ end
58
+
10
59
  attribute :number, ::Pubid::Iso::Components::Code
11
60
  attribute :part, ::Pubid::Iso::Components::Code
12
61
  attribute :subpart, ::Pubid::Iso::Components::Code
13
62
 
14
63
  # Polymorphic type map for lutaml::Model key_value serialization
15
64
  # Maps polymorphic_name → class name for deserialization
16
- # Validated by spec to stay in sync with Scheme.identifiers
65
+ # Validated by spec to stay in sync with identifier_types
17
66
  ISO_TYPE_MAP = {
18
67
  "pubid:iso:international-standard" => "Pubid::Iso::Identifiers::InternationalStandard",
19
68
  "pubid:iso:international-standardized-profile" => "Pubid::Iso::Identifiers::InternationalStandardizedProfile",
@@ -33,17 +82,180 @@ module Pubid
33
82
  "pubid:iso:data" => "Pubid::Iso::Identifiers::Data",
34
83
  "pubid:iso:tc-document" => "Pubid::Iso::Identifiers::TcDocument",
35
84
  "pubid:iso:technology-trends-assessments" => "Pubid::Iso::Identifiers::TechnologyTrendsAssessments",
85
+ "pubid:iso:bundled-identifier" => "Pubid::Iso::BundledIdentifier",
36
86
  }.freeze
37
87
 
38
- # Build type map from Scheme.identifiers for validation
88
+ # Build type map from Pubid::Iso.identifier_types for validation
39
89
  def self.build_type_map
40
- Scheme.identifiers.to_h do |klass|
90
+ Pubid::Iso.identifier_types.to_h do |klass|
41
91
  [klass.polymorphic_name, klass.name]
42
92
  end
43
93
  end
44
94
 
95
+ # The base Pubid::Identifier no longer auto-maps attributes, so each
96
+ # flavor's top class must declare its own key_value mapping. Subclasses
97
+ # merge their own blocks on top of this one (e.g. SupplementIdentifier
98
+ # adds base_identifier; Directives adds subgroup), so list every base
99
+ # attribute ISO serializes here once.
45
100
  key_value do
46
101
  map "_type", to: :_type, polymorphic_map: ISO_TYPE_MAP
102
+ # Code components serialize as their plain string value, not {value,number}.
103
+ map "number", with: { to: :number_to_kv, from: :number_from_kv }
104
+ map "part", with: { to: :part_to_kv, from: :part_from_kv }
105
+ map "subpart", with: { to: :subpart_to_kv, from: :subpart_from_kv }
106
+ map "stage_iteration",
107
+ with: { to: :stage_iteration_to_kv, from: :stage_iteration_from_kv }
108
+ # date serialized flat as year/month/day, nils omitted.
109
+ map "year", with: { to: :year_to_kv, from: :year_from_kv }
110
+ map "month", with: { to: :month_to_kv, from: :month_from_kv }
111
+ map "day", with: { to: :day_to_kv, from: :day_from_kv }
112
+ map "edition", to: :edition
113
+ map "languages", to: :languages
114
+ # publisher emitted only when the primary isn't the type default;
115
+ # copublishers (the other bodies) as an array, omitted when empty.
116
+ map "publisher", with: { to: :publisher_to_kv, from: :publisher_from_kv }
117
+ map "copublishers", with: { to: :copublishers_to_kv, from: :copublishers_from_kv }
118
+ map "locality", to: :locality
119
+ # `type` and generic `stage` are fully derived from `typed_stage`
120
+ # (builder sets them via to_type/to_stage), so we serialize only the
121
+ # unique typed-stage `code` under "stage" and recompute the rest on
122
+ # load. _type already pins the document type.
123
+ map "stage", with: { to: :stage_to_kv, from: :stage_from_kv }
124
+ # Omit the `false` default; only the meaningful `true` is serialized.
125
+ map "all_parts", with: { to: :all_parts_to_kv, from: :all_parts_from_kv }
126
+ end
127
+
128
+ def all_parts_to_kv(model, doc)
129
+ return unless model.all_parts
130
+
131
+ doc.add_child(
132
+ Lutaml::KeyValue::DataModel::Element.new("all_parts", true),
133
+ )
134
+ end
135
+
136
+ def all_parts_from_kv(model, value)
137
+ model.all_parts = value
138
+ end
139
+
140
+ # Serialize typed_stage as just its unique code (e.g. "is", "dis",
141
+ # "committee_draft_amd"). type/stage are recomputed from it on load.
142
+ def stage_to_kv(model, doc)
143
+ ts = model.typed_stage
144
+ return unless ts&.code
145
+ # Omit the published default (recomputed from the class on load).
146
+ return if ts.stage_code.to_s == "published"
147
+
148
+ doc.add_child(
149
+ Lutaml::KeyValue::DataModel::Element.new("stage", ts.code.to_s),
150
+ )
151
+ end
152
+
153
+ # Resolve the typed-stage code back to the full TypedStage within this
154
+ # identifier's class, then derive type/stage from it.
155
+ def stage_from_kv(model, value)
156
+ return if value.nil? || value.to_s.empty?
157
+
158
+ ts = (model.class.const_defined?(:TYPED_STAGES) &&
159
+ model.class::TYPED_STAGES.find { |t| t.code.to_s == value.to_s }) ||
160
+ Pubid::Iso::Scheme.locate_typed_stage_by_code(value)
161
+ return unless ts
162
+
163
+ # The renderer prefers `original_abbr` (the parsed surface form); without
164
+ # it the supplement renderer falls back to `short_abbr` (e.g. "AMD").
165
+ # Resolving from a code has no surface form, so render the canonical
166
+ # abbreviation (`abbr.first`, e.g. "Amd").
167
+ ts = ts.dup
168
+ ts.original_abbr = ts.canonical_abbreviation
169
+ model.typed_stage = ts
170
+ end
171
+
172
+ # --- Code components <-> plain string ---
173
+ def number_to_kv(model, doc) = emit_code(doc, "number", model.number)
174
+ def number_from_kv(model, value) = model.number = build_code(value)
175
+ def part_to_kv(model, doc) = emit_code(doc, "part", model.part)
176
+ def part_from_kv(model, value) = model.part = build_code(value)
177
+ def subpart_to_kv(model, doc) = emit_code(doc, "subpart", model.subpart)
178
+ def subpart_from_kv(model, value) = model.subpart = build_code(value)
179
+
180
+ def stage_iteration_to_kv(model, doc)
181
+ iter = model.stage_iteration
182
+ v = iter.is_a?(::Pubid::Components::Iteration) ? iter.number : iter
183
+ return if v.nil? || v.to_s.empty?
184
+
185
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("stage_iteration",
186
+ v.to_s))
187
+ end
188
+
189
+ def stage_iteration_from_kv(model, value)
190
+ model.stage_iteration = ::Pubid::Components::Iteration.new(number: value.to_s)
191
+ end
192
+
193
+ def emit_code(doc, key, code)
194
+ v = code.is_a?(::Pubid::Components::Code) ? code.value : code
195
+ return if v.nil? || v.to_s.empty?
196
+
197
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, v.to_s))
198
+ end
199
+
200
+ def build_code(value)
201
+ ::Pubid::Iso::Components::Code.new(value: value.to_s)
202
+ end
203
+
204
+ # --- date serialized flat as year/month/day ---
205
+ def year_to_kv(model, doc) = emit_date_part(doc, "year", model.date&.year)
206
+ def year_from_kv(model, value) = date_for(model).year = value.to_s
207
+ def month_to_kv(model, doc) = emit_date_part(doc, "month", model.date&.month)
208
+ def month_from_kv(model, value) = date_for(model).month = value.to_s
209
+ def day_to_kv(model, doc) = emit_date_part(doc, "day", model.date&.day)
210
+ def day_from_kv(model, value) = date_for(model).day = value.to_s
211
+
212
+ def emit_date_part(doc, key, val)
213
+ return if val.nil? || val.to_s.empty?
214
+
215
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, val.to_s))
216
+ end
217
+
218
+ def date_for(model)
219
+ model.date ||= ::Pubid::Components::Date.new
220
+ end
221
+
222
+ # --- publisher: primary only when non-default; copublishers as a list ---
223
+ def publisher_to_kv(model, doc)
224
+ pub = model.publisher&.publisher
225
+ return if pub.nil? || pub == model.class.default_publisher&.publisher
226
+
227
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("publisher", pub))
228
+ end
229
+
230
+ def publisher_from_kv(model, value)
231
+ publisher_for(model).publisher = value.to_s
232
+ end
233
+
234
+ def copublishers_to_kv(model, doc)
235
+ cp = model.publisher&.copublisher
236
+ return unless cp&.any?
237
+
238
+ doc.add_child(
239
+ Lutaml::KeyValue::DataModel::Element.new("copublishers", cp.map(&:to_s)),
240
+ )
241
+ end
242
+
243
+ def copublishers_from_kv(model, value)
244
+ list = Array(value).map(&:to_s)
245
+ return unless list.any?
246
+
247
+ # Mirror Builder#parse: copublishers live both on the primary
248
+ # publisher (as strings) and as the top-level `copublishers`
249
+ # collection of Publisher objects. `==` compares the latter, so
250
+ # populate both or a deserialized id never equals a parsed one.
251
+ publisher_for(model).copublisher = list
252
+ model.copublishers = list.map do |cp|
253
+ ::Pubid::Iso::Components::Publisher.new(publisher: cp)
254
+ end
255
+ end
256
+
257
+ def publisher_for(model)
258
+ model.publisher ||= ::Pubid::Iso::Components::Publisher.new
47
259
  end
48
260
 
49
261
  def self.parse(string, format: :auto)
@@ -61,8 +273,23 @@ module Pubid
61
273
  "Invalid identifier format"
62
274
  end
63
275
 
64
- Pubid::Iso::Builder.new(Pubid::Iso::Scheme).build(parsed)
276
+ Pubid::Iso::Builder.new.build(parsed)
277
+ end
278
+ end
279
+
280
+ # lutaml's polymorphic key_value mapping reads `_type` only to validate;
281
+ # it does not re-instantiate the concrete subclass on deserialization. So
282
+ # `Identifier.from_hash(corrigendum_hash)` would return a bare Identifier
283
+ # and drop `base_identifier`. Route by `_type` to the right subclass and
284
+ # let its (inherited) from_hash do the real work, mirroring JIS.
285
+ def self.from_hash(data, options = {})
286
+ type = data["_type"] || data[:_type]
287
+ klass_name = ISO_TYPE_MAP[type]
288
+ if klass_name
289
+ klass = Object.const_get(klass_name)
290
+ return klass.from_hash(data, options) unless klass == self
65
291
  end
292
+ super
66
293
  end
67
294
  end
68
295
  end
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Addendum < SupplementIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
 
9
8
  # Override URN supplement type to use generic "sup" instead of "add"
10
9
  # This matches the ISO URN specification where addendums use "sup"
@@ -65,9 +64,11 @@ module Pubid
65
64
  ),
66
65
  ::Pubid::Components::TypedStage.new(
67
66
  code: :dad,
68
- abbr: ["DAD", "DAdd", "D ADD", "Dad"],
67
+ abbr: ["DAD", "DAdd", "D ADD", "Dad", "DIS Add"],
69
68
  short_abbr: "DAD",
70
- long_abbr: "DAdd",
69
+ # "DAdd" stays in `abbr` so it still parses, but render the canonical
70
+ # "DAD" (pubid v1 legacy_abbr parity). No long_abbr → no long render.
71
+ long_abbr: nil,
71
72
  type_code: :add,
72
73
  stage_code: :dad,
73
74
  name: "Draft Addendum",
@@ -75,9 +76,10 @@ module Pubid
75
76
  ),
76
77
  ::Pubid::Components::TypedStage.new(
77
78
  code: :fdad,
78
- abbr: ["FDAD", "FDAdd", "FD ADD", "FDad"],
79
+ abbr: ["FDAD", "FDAdd", "FD ADD", "FDad", "FDIS Add"],
79
80
  short_abbr: "FDAD",
80
- long_abbr: "FDAdd",
81
+ # See :dad — parse "FDAdd", render canonical "FDAD" (v1 parity).
82
+ long_abbr: nil,
81
83
  type_code: :add,
82
84
  stage_code: :fdad,
83
85
  name: "Final Draft Addendum",
@@ -96,7 +98,8 @@ module Pubid
96
98
  ].freeze
97
99
 
98
100
  def self.type
99
- { key: :add, title: "Addendum", short: "ADD" }
101
+ { key: :add,
102
+ web: :addendum, title: "Addendum", short: "ADD" }
100
103
  end
101
104
  end
102
105
  end
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Amendment < SupplementIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
 
9
8
  TYPED_STAGES = [
10
9
  ::Pubid::Components::TypedStage.new(
@@ -71,7 +70,10 @@ module Pubid
71
70
  code: :damd,
72
71
  abbr: ["DAM", "DAmd"],
73
72
  short_abbr: "DAM",
74
- long_abbr: "DAmd",
73
+ # "DAmd" stays in `abbr` so it still parses, but render the canonical
74
+ # "DAM" (matches pubid v1's legacy_abbr semantics: parse the long
75
+ # spelling, emit the short one). No long_abbr → no long rendering.
76
+ long_abbr: nil,
75
77
  type_code: :amd,
76
78
  stage_code: :damd,
77
79
  name: "Draft Amendment",
@@ -81,7 +83,8 @@ module Pubid
81
83
  code: :fdamd,
82
84
  abbr: ["FDAM", "FDAmd"],
83
85
  short_abbr: "FDAM",
84
- long_abbr: "FDAmd",
86
+ # See :damd — parse "FDAmd", render canonical "FDAM" (v1 parity).
87
+ long_abbr: nil,
85
88
  type_code: :amd,
86
89
  stage_code: :fdamd,
87
90
  name: "Final Draft Amendment",
@@ -120,7 +123,8 @@ module Pubid
120
123
  ].freeze
121
124
 
122
125
  def self.type
123
- { key: :amd, title: "Amendment", short: "AMD" }
126
+ { key: :amd,
127
+ web: :amendment, title: "Amendment", short: "AMD" }
124
128
  end
125
129
  end
126
130
  end
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Corrigendum < SupplementIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
 
9
8
  TYPED_STAGES = [
10
9
  ::Pubid::Components::TypedStage.new(
@@ -59,7 +58,7 @@ module Pubid
59
58
  ),
60
59
  ::Pubid::Components::TypedStage.new(
61
60
  code: :dcor,
62
- abbr: ["DCor", "DCOR"],
61
+ abbr: ["DCor", "DCOR", "DIS Cor"],
63
62
  short_abbr: "DCOR",
64
63
  long_abbr: "DCor",
65
64
  type_code: :cor,
@@ -69,7 +68,7 @@ module Pubid
69
68
  ),
70
69
  ::Pubid::Components::TypedStage.new(
71
70
  code: :fdcor,
72
- abbr: ["FDCor", "FDCOR", "FCOR"],
71
+ abbr: ["FDCor", "FDCOR", "FCOR", "FDIS Cor"],
73
72
  short_abbr: "FDCOR",
74
73
  long_abbr: "FDCor",
75
74
  type_code: :cor,
@@ -100,7 +99,8 @@ module Pubid
100
99
  ].freeze
101
100
 
102
101
  def self.type
103
- { key: :cor, title: "Corrigendum", short: "COR" }
102
+ { key: :cor,
103
+ web: :corrigendum, title: "Corrigendum", short: "COR" }
104
104
  end
105
105
  end
106
106
  end
@@ -5,7 +5,6 @@ module Pubid
5
5
  module Identifiers
6
6
  # Data Identifier
7
7
  class Data < SingleIdentifier
8
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
9
8
 
10
9
  TYPED_STAGES = [
11
10
  ::Pubid::Components::TypedStage.new(
@@ -4,9 +4,14 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Directives < SingleIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
  attribute :subgroup, ::Pubid::Components::Code
9
8
 
9
+ # Merges with Identifier's block (base attributes); only adds the
10
+ # Directives-specific subgroup so it survives to_hash/from_hash.
11
+ key_value do
12
+ map "subgroup", to: :subgroup
13
+ end
14
+
10
15
  TYPED_STAGES = [
11
16
  ::Pubid::Components::TypedStage.new(
12
17
  code: :pubguide,
@@ -22,7 +27,8 @@ module Pubid
22
27
  ].freeze
23
28
 
24
29
  def self.type
25
- { key: :dir, title: "Directives", short: "DIR" }
30
+ { key: :dir,
31
+ web: :directives, title: "Directives", short: "DIR" }
26
32
  end
27
33
 
28
34
  def to_s(**opts)
@@ -4,9 +4,35 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class DirectivesSupplement < SupplementIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
  attribute :supplement_publisher, ::Pubid::Components::Publisher
9
8
 
9
+ # supplement_publisher (e.g. "IEC" in "ISO/IEC DIR 1 IEC SUP") is needed
10
+ # by to_s/to_urn; serialize its body under "publisher" (the supplement's
11
+ # own publisher; the base's publisher lives in the nested base). This
12
+ # overrides the inherited publisher map, whose delegated value is nil or
13
+ # the omitted ISO default here.
14
+ key_value do
15
+ map "publisher",
16
+ with: { to: :supplement_publisher_to_kv, from: :supplement_publisher_from_kv }
17
+ end
18
+
19
+ def supplement_publisher_to_kv(model, doc)
20
+ body = model.supplement_publisher&.body
21
+ return if body.nil? || body.to_s.empty?
22
+
23
+ doc.add_child(
24
+ Lutaml::KeyValue::DataModel::Element.new("publisher", body.to_s),
25
+ )
26
+ end
27
+
28
+ def supplement_publisher_from_kv(model, value)
29
+ model.supplement_publisher = ::Pubid::Components::Publisher.new(body: value.to_s)
30
+ end
31
+
32
+ # copublishers here is the base's (delegated), redundant with the nested
33
+ # base; don't duplicate it at the supplement level.
34
+ def copublishers_to_kv(_model, _doc); end
35
+
10
36
  # Delegate base identifier attributes for easier access
11
37
  def copublishers
12
38
  base_identifier&.copublishers
@@ -28,7 +54,8 @@ module Pubid
28
54
  ].freeze
29
55
 
30
56
  def self.type
31
- { key: :"dir-sup", title: "Directives Supplement", short: "SUP" }
57
+ { key: :"dir-sup",
58
+ web: :directives_supplement, title: "Directives Supplement", short: "SUP" }
32
59
  end
33
60
 
34
61
  # def render_directives_supplement_identifier(identifier)
@@ -47,10 +74,10 @@ format: nil, stage_format_long: nil, with_date: nil)
47
74
  [
48
75
  base_identifier.to_s(lang: lang, lang_single: lang_single,
49
76
  with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date),
50
- " #{supplement_publisher.body}",
77
+ " #{supplement_publisher.render}",
51
78
  " SUP", # Always render as "SUP" even though typed_stage.abbreviation is "DIR SUP"
52
- (date ? ":#{date.year}" : ""),
53
- (edition ? " Edition #{edition.number.value}" : ""),
79
+ (date ? ":#{date.render}" : ""),
80
+ (edition ? " Edition #{edition.value}" : ""),
54
81
  ].join
55
82
  else
56
83
  # Simplified rendering for bundled identifiers (just the supplement part)
@@ -63,13 +90,13 @@ format: nil, stage_format_long: nil, with_date: nil)
63
90
  format: nil, stage_format_long: nil, with_date: nil)
64
91
  date_str = if date
65
92
  month_part = date.month ? "-#{date.month}" : ""
66
- ":#{date.year}#{month_part}"
93
+ ":#{date.render}#{month_part}"
67
94
  else
68
95
  ""
69
96
  end
70
97
 
71
98
  [
72
- supplement_publisher.body,
99
+ supplement_publisher.render,
73
100
  " SUP",
74
101
  date_str,
75
102
  ].join
@@ -78,13 +105,15 @@ format: nil, stage_format_long: nil, with_date: nil)
78
105
  # DirectivesSupplement use urn:iso:doc scheme (not urn:iso:std)
79
106
  # Format: urn:iso:doc:{base_urn_parts}:jtc:X:sup[:{year}][:{edition}]
80
107
  def to_urn
108
+ urn_ctx = Rendering::RenderingContext.urn
109
+
81
110
  # If this is a standalone supplement (no base_identifier), build URN directly
82
111
  unless base_identifier
83
112
  parts = ["urn", "iso", "doc"]
84
- parts << supplement_publisher.body.downcase if supplement_publisher
113
+ parts << supplement_publisher.render(context: urn_ctx) if supplement_publisher
85
114
  parts << "sup"
86
- parts << date.year.to_s if date
87
- parts << "ed-#{edition.number}" if edition&.number
115
+ parts << date.render(context: urn_ctx) if date
116
+ parts << edition.render(context: urn_ctx) if edition&.number
88
117
  return parts.join(":")
89
118
  end
90
119
 
@@ -94,7 +123,7 @@ format: nil, stage_format_long: nil, with_date: nil)
94
123
  # Handle JTC pattern specially
95
124
  if supplement_publisher&.body&.match?(/^JTC\s+(\d+)$/i)
96
125
  # Extract JTC number: "JTC 1" -> ["jtc", "1"]
97
- jtc_parts = supplement_publisher.body.downcase.split
126
+ jtc_parts = supplement_publisher.render(context: urn_ctx).split
98
127
  # Insert JTC parts before "sup"
99
128
  parts = base_urn.split(":")
100
129
  parts.concat(jtc_parts) # Add "jtc" and "1"
@@ -102,14 +131,14 @@ format: nil, stage_format_long: nil, with_date: nil)
102
131
  else
103
132
  # Normal supplement
104
133
  parts = [base_urn, "sup"]
105
- parts << supplement_publisher.body.downcase if supplement_publisher
134
+ parts << supplement_publisher.render(context: urn_ctx) if supplement_publisher
106
135
  end
107
136
 
108
137
  # Year (if present)
109
- parts << date.year.to_s if date
138
+ parts << date.render(context: urn_ctx) if date
110
139
 
111
140
  # Edition (if present)
112
- parts << "ed-#{edition.number}" if edition&.number
141
+ parts << edition.render(context: urn_ctx) if edition&.number
113
142
 
114
143
  parts.join(":")
115
144
  end
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Extract < SupplementIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
 
9
8
  TYPED_STAGES = [
10
9
  ::Pubid::Components::TypedStage.new(
@@ -18,7 +17,8 @@ module Pubid
18
17
  ].freeze
19
18
 
20
19
  def self.type
21
- { key: :ext, title: "Extract", short: "Ext" }
20
+ { key: :ext,
21
+ web: :extract, title: "Extract", short: "Ext" }
22
22
  end
23
23
 
24
24
  # def self.get_renderer_class
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class Guide < SingleIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
8
7
 
9
8
  TYPED_STAGES = [
10
9
  ::Pubid::Components::TypedStage.new(
@@ -8,7 +8,6 @@ module Pubid
8
8
  include IdentifierMetadata
9
9
 
10
10
  # Note: type attribute uses shared Components::Type from Pubid namespace
11
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
12
11
 
13
12
  TYPED_STAGES = [
14
13
  ::Pubid::Components::TypedStage.new(
@@ -142,7 +141,8 @@ module Pubid
142
141
  ].freeze
143
142
 
144
143
  def self.type
145
- { key: :is, title: "International Standard", short: nil }
144
+ { key: :is,
145
+ web: :international_standard, title: "International Standard", short: nil }
146
146
  end
147
147
 
148
148
  # Define machine-readable metadata
@@ -164,5 +164,5 @@ module Pubid
164
164
  end
165
165
  end
166
166
 
167
- # NOTE: Identifiers are now registered in the ISO Scheme class
168
- # The global registry has been removed in favor of per-flavor Schemes
167
+ # NOTE: Identifiers are now registered in the ISO flavor module
168
+ # The global registry has been removed in favor of self-describing types
@@ -5,7 +5,6 @@ module Pubid
5
5
  module Identifiers
6
6
  # International Standardized Profile Identifier
7
7
  class InternationalStandardizedProfile < SingleIdentifier
8
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
9
8
 
10
9
  TYPED_STAGES = [
11
10
  ::Pubid::Components::TypedStage.new(
@@ -52,7 +51,7 @@ module Pubid
52
51
  code: :disp,
53
52
  stage_code: :disp,
54
53
  type_code: :isp,
55
- abbr: ["DISP"],
54
+ abbr: ["DISP", "DIS ISP"],
56
55
  name: "Draft International Standardized Profile",
57
56
  harmonized_stages: %w[40.00 40.20 40.60 40.92 40.93 40.98 40.99],
58
57
  ),
@@ -61,7 +60,7 @@ module Pubid
61
60
  code: :fdisp,
62
61
  stage_code: :fdis,
63
62
  type_code: :isp,
64
- abbr: ["FDISP"],
63
+ abbr: ["FDISP", "FDIS ISP"],
65
64
  name: "Final Draft International Standardized Profile",
66
65
  harmonized_stages: %w[50.00 50.20 50.60 50.92],
67
66
  ),
@@ -85,7 +84,8 @@ module Pubid
85
84
  ].freeze
86
85
 
87
86
  def self.type
88
- { key: :isp, title: "International Standardized Profile",
87
+ { key: :isp,
88
+ web: :international_standardized_profile, title: "International Standardized Profile",
89
89
  short: "ISP" }
90
90
  end
91
91
  end
@@ -4,12 +4,17 @@ module Pubid
4
4
  module Iso
5
5
  module Identifiers
6
6
  class InternationalWorkshopAgreement < SingleIdentifier
7
- attribute :type, ::Pubid::Components::Type, default: -> { self.class.type[:key] }
7
+
8
+ # IWA identifiers have no publisher prefix (rendered "IWA 1", not
9
+ # "ISO IWA 1"), so there is no implied publisher to default on load.
10
+ def self.default_publisher
11
+ nil
12
+ end
8
13
 
9
14
  TYPED_STAGES = [
10
15
  ::Pubid::Components::TypedStage.new(
11
- code: :npiwa,
12
- stage_code: :np,
16
+ code: :pwiiwa,
17
+ stage_code: :pwi,
13
18
  type_code: :iwa,
14
19
  abbr: ["PWI IWA"],
15
20
  name: "Proposed Work Item for International Workshop Agreement",
@@ -75,7 +80,8 @@ module Pubid
75
80
  ].freeze
76
81
 
77
82
  def self.type
78
- { key: :iwa, title: "International Workshop Agreement", short: "IWA" }
83
+ { key: :iwa,
84
+ web: :international_workshop_agreement, title: "International Workshop Agreement", short: "IWA" }
79
85
  end
80
86
 
81
87
  def to_s(**opts)