pubid 2.0.0.pre.alpha.2 → 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 (458) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +5 -1
  3. data/data/nist/update_codes.yaml +25 -0
  4. data/lib/pubid/amca/builder.rb +2 -2
  5. data/lib/pubid/amca/identifier.rb +7 -39
  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 -43
  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 -51
  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 -39
  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/identifier.rb +0 -46
  55. data/lib/pubid/asme/identifiers/base.rb +0 -60
  56. data/lib/pubid/asme/renderer.rb +66 -0
  57. data/lib/pubid/asme/urn_parser.rb +31 -0
  58. data/lib/pubid/asme.rb +42 -1
  59. data/lib/pubid/astm/components/code.rb +9 -0
  60. data/lib/pubid/{jis → astm}/components.rb +1 -1
  61. data/lib/pubid/astm/identifier.rb +0 -77
  62. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  63. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  64. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  65. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  66. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  67. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  68. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  69. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  70. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  71. data/lib/pubid/astm/identifiers.rb +18 -0
  72. data/lib/pubid/astm/renderer.rb +172 -0
  73. data/lib/pubid/astm/single_identifier.rb +0 -10
  74. data/lib/pubid/astm/urn_parser.rb +30 -0
  75. data/lib/pubid/astm.rb +39 -27
  76. data/lib/pubid/bsi/builder.rb +21 -12
  77. data/lib/pubid/bsi/identifier.rb +8 -62
  78. data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
  79. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
  80. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
  81. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
  82. data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
  83. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
  84. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  85. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
  86. data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
  87. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
  88. data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
  89. data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
  90. data/lib/pubid/bsi/identifiers/disc.rb +1 -27
  91. data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
  92. data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
  93. data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
  94. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
  95. data/lib/pubid/bsi/identifiers/flex.rb +1 -33
  96. data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
  97. data/lib/pubid/bsi/identifiers/index.rb +1 -30
  98. data/lib/pubid/bsi/identifiers/method.rb +1 -39
  99. data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
  100. data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
  101. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
  102. data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
  103. data/lib/pubid/bsi/identifiers/section.rb +1 -28
  104. data/lib/pubid/bsi/identifiers/set.rb +3 -17
  105. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
  106. data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
  107. data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
  108. data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
  109. data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
  110. data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
  111. data/lib/pubid/bsi/identifiers.rb +0 -1
  112. data/lib/pubid/bsi/renderer.rb +1050 -0
  113. data/lib/pubid/bsi/single_identifier.rb +6 -70
  114. data/lib/pubid/bsi/urn_generator.rb +2 -3
  115. data/lib/pubid/bsi/urn_parser.rb +52 -0
  116. data/lib/pubid/bsi.rb +224 -1
  117. data/lib/pubid/builder/base.rb +57 -10
  118. data/lib/pubid/bundled_identifier.rb +0 -1
  119. data/lib/pubid/ccsds/builder.rb +4 -3
  120. data/lib/pubid/ccsds/identifier.rb +63 -66
  121. data/lib/pubid/ccsds/identifiers/base.rb +11 -61
  122. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  123. data/lib/pubid/ccsds/parser.rb +4 -2
  124. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  125. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  126. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  127. data/lib/pubid/ccsds.rb +39 -1
  128. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  129. data/lib/pubid/cen_cenelec/identifier.rb +7 -38
  130. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
  131. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
  132. data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
  133. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  134. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  135. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
  136. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
  137. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  138. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
  139. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  140. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  141. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  143. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  144. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  145. data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
  146. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  147. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  148. data/lib/pubid/cen_cenelec.rb +168 -1
  149. data/lib/pubid/cie/components/code.rb +8 -0
  150. data/lib/pubid/cie/identifier.rb +6 -57
  151. data/lib/pubid/cie/urn_parser.rb +28 -0
  152. data/lib/pubid/cie.rb +43 -1
  153. data/lib/pubid/components/adoption.rb +104 -0
  154. data/lib/pubid/components/code.rb +22 -8
  155. data/lib/pubid/components/date.rb +23 -16
  156. data/lib/pubid/components/edition.rb +9 -6
  157. data/lib/pubid/components/iteration.rb +32 -0
  158. data/lib/pubid/components/language.rb +6 -4
  159. data/lib/pubid/components/locality.rb +10 -1
  160. data/lib/pubid/components/publisher.rb +9 -6
  161. data/lib/pubid/components/relationship.rb +151 -0
  162. data/lib/pubid/components/stage.rb +5 -14
  163. data/lib/pubid/components/supplement.rb +184 -0
  164. data/lib/pubid/components/type.rb +5 -15
  165. data/lib/pubid/components/typed_stage.rb +10 -11
  166. data/lib/pubid/components.rb +4 -1
  167. data/lib/pubid/core/update_codes.rb +28 -7
  168. data/lib/pubid/csa/identifier.rb +0 -59
  169. data/lib/pubid/csa/identifiers/base.rb +2 -122
  170. data/lib/pubid/csa/identifiers/cec.rb +2 -101
  171. data/lib/pubid/csa/identifiers/series.rb +2 -102
  172. data/lib/pubid/csa/renderer.rb +292 -0
  173. data/lib/pubid/csa/urn_generator.rb +1 -1
  174. data/lib/pubid/csa/urn_parser.rb +33 -0
  175. data/lib/pubid/csa.rb +42 -1
  176. data/lib/pubid/etsi/components/code.rb +9 -2
  177. data/lib/pubid/etsi/identifier.rb +0 -43
  178. data/lib/pubid/etsi/identifiers/base.rb +1 -4
  179. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
  180. data/lib/pubid/etsi/renderer.rb +42 -0
  181. data/lib/pubid/etsi/urn_parser.rb +34 -0
  182. data/lib/pubid/etsi.rb +42 -1
  183. data/lib/pubid/export/exporter.rb +4 -46
  184. data/lib/pubid/export/flavor_exporter.rb +111 -278
  185. data/lib/pubid/export.rb +0 -6
  186. data/lib/pubid/identifier.rb +2 -17
  187. data/lib/pubid/identifier_facade.rb +114 -0
  188. data/lib/pubid/identifier_metadata.rb +1 -1
  189. data/lib/pubid/idf/builder.rb +3 -3
  190. data/lib/pubid/idf/identifier.rb +3 -66
  191. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  192. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  193. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  194. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  195. data/lib/pubid/idf/parser.rb +3 -2
  196. data/lib/pubid/idf/renderer.rb +84 -0
  197. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  198. data/lib/pubid/idf/urn_generator.rb +4 -39
  199. data/lib/pubid/idf/urn_parser.rb +25 -0
  200. data/lib/pubid/idf.rb +51 -1
  201. data/lib/pubid/iec/builder.rb +46 -64
  202. data/lib/pubid/iec/components/code.rb +8 -32
  203. data/lib/pubid/iec/components/publisher.rb +0 -1
  204. data/lib/pubid/iec/components.rb +14 -0
  205. data/lib/pubid/iec/identifier.rb +251 -213
  206. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  207. data/lib/pubid/iec/identifiers/base.rb +8 -32
  208. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  209. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  210. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -26
  211. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -22
  213. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  214. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  215. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  216. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  217. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  218. data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -11
  219. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  220. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  221. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  222. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  223. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  224. data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
  225. data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -19
  226. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  227. data/lib/pubid/iec/identifiers/working_document.rb +4 -48
  228. data/lib/pubid/iec/identifiers.rb +30 -0
  229. data/lib/pubid/iec/parser.rb +13 -12
  230. data/lib/pubid/iec/renderer.rb +254 -0
  231. data/lib/pubid/iec/single_identifier.rb +6 -12
  232. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  233. data/lib/pubid/iec/urn_generator.rb +3 -3
  234. data/lib/pubid/iec/urn_parser.rb +3 -3
  235. data/lib/pubid/iec.rb +40 -68
  236. data/lib/pubid/ieee/builder.rb +12 -12
  237. data/lib/pubid/ieee/components/code.rb +8 -0
  238. data/lib/pubid/ieee/components/draft.rb +14 -0
  239. data/lib/pubid/ieee/components/relationship.rb +5 -149
  240. data/lib/pubid/ieee/identifier.rb +6 -41
  241. data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
  242. data/lib/pubid/ieee/identifiers/base.rb +101 -458
  243. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
  244. data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
  245. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
  246. data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
  247. data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
  248. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
  249. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
  250. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  251. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
  252. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
  253. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  254. data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
  255. data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
  256. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  257. data/lib/pubid/ieee/pre_parser.rb +301 -0
  258. data/lib/pubid/ieee/renderer.rb +307 -0
  259. data/lib/pubid/ieee/urn_parser.rb +34 -0
  260. data/lib/pubid/ieee.rb +62 -1
  261. data/lib/pubid/ieee_debug.rb +0 -1
  262. data/lib/pubid/iho/builder.rb +2 -2
  263. data/lib/pubid/iho/identifier.rb +8 -42
  264. data/lib/pubid/iho/identifiers/base.rb +49 -10
  265. data/lib/pubid/iho/parser.rb +3 -3
  266. data/lib/pubid/iho/renderer.rb +30 -0
  267. data/lib/pubid/iho/urn_generator.rb +2 -2
  268. data/lib/pubid/iho/urn_parser.rb +58 -0
  269. data/lib/pubid/iho.rb +50 -1
  270. data/lib/pubid/iso/builder.rb +55 -53
  271. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  272. data/lib/pubid/iso/components/code.rb +7 -19
  273. data/lib/pubid/iso/components/publisher.rb +10 -8
  274. data/lib/pubid/iso/components.rb +2 -4
  275. data/lib/pubid/iso/identifier.rb +218 -252
  276. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  277. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  278. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  279. data/lib/pubid/iso/identifiers/data.rb +0 -1
  280. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  281. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  282. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  283. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  284. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  285. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  286. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  287. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  288. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  289. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  290. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  291. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  292. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  293. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  294. data/lib/pubid/iso/identifiers.rb +0 -1
  295. data/lib/pubid/iso/normalizer.rb +89 -0
  296. data/lib/pubid/iso/parser.rb +22 -4
  297. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  298. data/lib/pubid/iso/urn_generator.rb +66 -182
  299. data/lib/pubid/iso/urn_parser.rb +12 -7
  300. data/lib/pubid/iso.rb +173 -2
  301. data/lib/pubid/itu/builder.rb +0 -12
  302. data/lib/pubid/itu/components/code.rb +8 -0
  303. data/lib/pubid/itu/components.rb +11 -0
  304. data/lib/pubid/itu/identifier.rb +6 -104
  305. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  306. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  307. data/lib/pubid/itu/identifiers/base.rb +0 -6
  308. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  309. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  310. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  311. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  312. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  313. data/lib/pubid/itu/urn_parser.rb +23 -0
  314. data/lib/pubid/itu.rb +42 -1
  315. data/lib/pubid/jcgm/builder.rb +16 -8
  316. data/lib/pubid/jcgm/identifier.rb +0 -43
  317. data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
  318. data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
  319. data/lib/pubid/jcgm/renderer.rb +68 -0
  320. data/lib/pubid/jcgm/single_identifier.rb +1 -5
  321. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  322. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  323. data/lib/pubid/jcgm.rb +43 -2
  324. data/lib/pubid/jis/builder.rb +44 -52
  325. data/lib/pubid/jis/identifier.rb +132 -46
  326. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  327. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  328. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  329. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  330. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  331. data/lib/pubid/jis/identifiers.rb +1 -1
  332. data/lib/pubid/jis/parser.rb +31 -5
  333. data/lib/pubid/jis/renderer.rb +69 -0
  334. data/lib/pubid/jis/single_identifier.rb +6 -12
  335. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  336. data/lib/pubid/jis/urn_parser.rb +23 -0
  337. data/lib/pubid/jis.rb +42 -2
  338. data/lib/pubid/nist/builder.rb +63 -1871
  339. data/lib/pubid/nist/caster.rb +1272 -0
  340. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  341. data/lib/pubid/nist/components/code.rb +9 -20
  342. data/lib/pubid/nist/components/supplement.rb +2 -2
  343. data/lib/pubid/nist/components.rb +0 -1
  344. data/lib/pubid/nist/identifier.rb +11 -48
  345. data/lib/pubid/nist/identifiers/base.rb +110 -47
  346. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  347. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
  348. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  349. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  350. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  351. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
  352. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  353. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
  354. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  355. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  356. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  357. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  358. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  359. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  360. data/lib/pubid/nist/identifiers/report.rb +4 -2
  361. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  362. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  363. data/lib/pubid/nist/identifiers.rb +1 -0
  364. data/lib/pubid/nist/parser.rb +62 -452
  365. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  366. data/lib/pubid/nist/preprocessor.rb +416 -0
  367. data/lib/pubid/nist/renderer.rb +43 -0
  368. data/lib/pubid/nist/router.rb +148 -0
  369. data/lib/pubid/nist/series/base.rb +58 -0
  370. data/lib/pubid/nist/series/crpl.rb +13 -0
  371. data/lib/pubid/nist/series/fips.rb +14 -0
  372. data/lib/pubid/nist/series/ir.rb +60 -0
  373. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  374. data/lib/pubid/nist/series/mono.rb +19 -0
  375. data/lib/pubid/nist/series/ncstar.rb +20 -0
  376. data/lib/pubid/nist/series.rb +49 -0
  377. data/lib/pubid/nist/supplement_identifier.rb +3 -1
  378. data/lib/pubid/nist/urn_parser.rb +67 -0
  379. data/lib/pubid/nist.rb +82 -4
  380. data/lib/pubid/oiml/components/code.rb +10 -0
  381. data/lib/pubid/oiml/identifier.rb +0 -50
  382. data/lib/pubid/oiml/identifiers/annex.rb +3 -45
  383. data/lib/pubid/oiml/identifiers/base.rb +2 -17
  384. data/lib/pubid/oiml/renderer.rb +161 -0
  385. data/lib/pubid/oiml/single_identifier.rb +6 -45
  386. data/lib/pubid/oiml/supplement_identifier.rb +4 -19
  387. data/lib/pubid/oiml/urn_generator.rb +0 -8
  388. data/lib/pubid/oiml/urn_parser.rb +22 -0
  389. data/lib/pubid/oiml.rb +42 -1
  390. data/lib/pubid/plateau/identifier.rb +7 -41
  391. data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
  392. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  393. data/lib/pubid/plateau/renderer.rb +51 -0
  394. data/lib/pubid/plateau/supplement_identifier.rb +1 -1
  395. data/lib/pubid/plateau/urn_parser.rb +43 -0
  396. data/lib/pubid/plateau.rb +43 -1
  397. data/lib/pubid/renderers/directives_renderer.rb +22 -8
  398. data/lib/pubid/renderers/guide_renderer.rb +4 -2
  399. data/lib/pubid/renderers/human_readable.rb +18 -7
  400. data/lib/pubid/rendering/context.rb +28 -19
  401. data/lib/pubid/rendering.rb +0 -3
  402. data/lib/pubid/sae/components/date.rb +8 -0
  403. data/lib/pubid/sae/components/type.rb +5 -1
  404. data/lib/pubid/sae/identifier.rb +0 -23
  405. data/lib/pubid/sae/identifiers/base.rb +2 -16
  406. data/lib/pubid/sae/renderer.rb +36 -0
  407. data/lib/pubid/sae/urn_generator.rb +2 -10
  408. data/lib/pubid/sae/urn_parser.rb +36 -0
  409. data/lib/pubid/sae.rb +42 -1
  410. data/lib/pubid/urn_generator/base.rb +12 -12
  411. data/lib/pubid/urn_parser/base.rb +81 -0
  412. data/lib/pubid/urn_parser/errors.rb +9 -0
  413. data/lib/pubid/urn_parser.rb +14 -0
  414. data/lib/pubid/version.rb +1 -1
  415. data/lib/pubid.rb +29 -7
  416. data/lib/tasks/website-data.json +1940 -1882
  417. metadata +75 -44
  418. data/lib/pubid/amca/scheme.rb +0 -16
  419. data/lib/pubid/ansi/scheme.rb +0 -15
  420. data/lib/pubid/api/scheme.rb +0 -66
  421. data/lib/pubid/ashrae/scheme.rb +0 -53
  422. data/lib/pubid/asme/scheme.rb +0 -37
  423. data/lib/pubid/astm/scheme.rb +0 -55
  424. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  425. data/lib/pubid/bsi/scheme.rb +0 -243
  426. data/lib/pubid/ccsds/scheme.rb +0 -57
  427. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  428. data/lib/pubid/cie/scheme.rb +0 -64
  429. data/lib/pubid/components/factory.rb +0 -50
  430. data/lib/pubid/csa/scheme.rb +0 -44
  431. data/lib/pubid/etsi/scheme.rb +0 -42
  432. data/lib/pubid/export/data_class_exporter.rb +0 -59
  433. data/lib/pubid/export/ieee_exporter.rb +0 -78
  434. data/lib/pubid/export/itu_exporter.rb +0 -66
  435. data/lib/pubid/export/nist_exporter.rb +0 -64
  436. data/lib/pubid/export/registry_exporter.rb +0 -90
  437. data/lib/pubid/export/scheme_exporter.rb +0 -70
  438. data/lib/pubid/identifier_registry.rb +0 -198
  439. data/lib/pubid/idf/scheme.rb +0 -61
  440. data/lib/pubid/iec/scheme.rb +0 -71
  441. data/lib/pubid/ieee/scheme.rb +0 -90
  442. data/lib/pubid/iho/scheme.rb +0 -29
  443. data/lib/pubid/iso/identifiers/base.rb +0 -115
  444. data/lib/pubid/iso/scheme.rb +0 -193
  445. data/lib/pubid/itu/scheme.rb +0 -174
  446. data/lib/pubid/jcgm/scheme.rb +0 -60
  447. data/lib/pubid/jis/components/code.rb +0 -59
  448. data/lib/pubid/jis/identifiers/base.rb +0 -72
  449. data/lib/pubid/jis/scheme.rb +0 -49
  450. data/lib/pubid/nist/components/publisher.rb +0 -24
  451. data/lib/pubid/nist/scheme.rb +0 -199
  452. data/lib/pubid/oiml/scheme.rb +0 -46
  453. data/lib/pubid/plateau/scheme.rb +0 -45
  454. data/lib/pubid/rendering/base.rb +0 -73
  455. data/lib/pubid/rendering/common.rb +0 -211
  456. data/lib/pubid/rendering/format.rb +0 -25
  457. data/lib/pubid/sae/scheme.rb +0 -47
  458. data/lib/pubid/scheme.rb +0 -219
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iho
5
+ # Parses IHO URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:iho:{type-lower}:{number}[:{part-kind}.{part}]:{version}
9
+ #
10
+ # type-lower is the lowercase series letter (s, p, m, b, c).
11
+ # part-kind is the lowercase part label (part, ap, annex, suppl).
12
+ # version is the dotted version string.
13
+ #
14
+ # Examples:
15
+ # - urn:iho:s:44:5.0.0 → IHO S-44 5.0.0
16
+ # - urn:iho:s:100:part.4a:1.0.0 → IHO S-100 Part 4a 1.0.0
17
+ # - urn:iho:s:65:ap.A:1.0.0 → IHO S-65 Ap. A 1.0.0
18
+ class UrnParser < Pubid::UrnParser::Base
19
+ PART_LABELS = {
20
+ "part" => "Part",
21
+ "ap" => "Ap.",
22
+ "annex" => "Annex",
23
+ "suppl" => "Suppl",
24
+ }.freeze
25
+
26
+ def parse_urn(urn)
27
+ body = strip_namespace(urn)
28
+ parts = split_parts(body)
29
+
30
+ type_token = parts.fetch(0).upcase
31
+ number = parts.fetch(1)
32
+ idx = 2
33
+ part_label = nil
34
+ if parts[idx] && part_kind?(parts[idx])
35
+ kind, value = parts[idx].split(".", 2)
36
+ label = PART_LABELS.fetch(kind.downcase) { kind.capitalize }
37
+ part_label = "#{label} #{value}"
38
+ idx += 1
39
+ end
40
+ version = parts[idx]
41
+
42
+ text = "IHO #{type_token}-#{number}"
43
+ text += " #{part_label}" if part_label
44
+ text += " #{version}" if version
45
+ flavor_parse(text)
46
+ end
47
+
48
+ private
49
+
50
+ # A part-kind token starts with letters followed by a dot, e.g.,
51
+ # "part.4a", "ap.A", "annex.A", "suppl.1". A version like "5.0.0"
52
+ # starts with a digit.
53
+ def part_kind?(token)
54
+ token.match?(/^[a-z]+\./i)
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/pubid/iho.rb CHANGED
@@ -6,8 +6,9 @@ module Pubid
6
6
  autoload :Identifier, "#{__dir__}/iho/identifier"
7
7
  autoload :Identifiers, "#{__dir__}/iho/identifiers"
8
8
  autoload :Parser, "#{__dir__}/iho/parser"
9
- autoload :Scheme, "#{__dir__}/iho/scheme"
9
+ autoload :Renderer, "#{__dir__}/iho/renderer"
10
10
  autoload :UrnGenerator, "#{__dir__}/iho/urn_generator"
11
+ autoload :UrnParser, "#{__dir__}/iho/urn_parser"
11
12
 
12
13
  # Parse an IHO identifier string into an identifier object
13
14
  # @param identifier [String] The IHO identifier string to parse
@@ -15,6 +16,54 @@ module Pubid
15
16
  def self.parse(identifier)
16
17
  Identifier.parse(identifier)
17
18
  end
19
+
20
+ # Per-flavor format registry: inherits global formats, overrides :human
21
+ Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
22
+ Identifiers::Base.format_registry.register(:human, renderer: Iho::Renderer)
23
+
24
+ # Auto-discover all identifier types from the Identifiers namespace.
25
+ # @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
26
+ def self.identifier_types
27
+ @identifier_types ||= Identifiers.constants
28
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
29
+ .select { |c| c.is_a?(Class) && c < Pubid::Identifier }
30
+ .reject { |c| c.name&.split("::")&.last == "Base" }
31
+ end
32
+
33
+ # Build typed stage index from identifier types
34
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
35
+ def self.all_typed_stages
36
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
37
+ if klass.const_defined?(:TYPED_STAGES)
38
+ klass.const_get(:TYPED_STAGES)
39
+ else
40
+ []
41
+ end
42
+ end
43
+ end
44
+
45
+ # Lookup: type code -> identifier class
46
+ # @param code [String, Symbol] the type key to find
47
+ # @return [Class, nil] the matching identifier class
48
+ def self.locate_type(code)
49
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
50
+ end
51
+
52
+ # Lookup: abbreviation -> typed stage
53
+ # @param abbr [String, Symbol] the abbreviation to find
54
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
55
+ def self.locate_stage(abbr)
56
+ abbr_str = abbr.to_s.upcase
57
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
58
+ end
59
+
60
+ # Look up an identifier class by its IHO series letter (S/P/M/B/C).
61
+ # @param letter [String]
62
+ # @return [Class<Identifiers::Base>]
63
+ def self.identifier_klass_for_type_letter(letter)
64
+ @by_letter ||= identifier_types.to_h { |klass| [klass.type[:short], klass] }
65
+ @by_letter.fetch(letter.to_s)
66
+ end
18
67
  end
19
68
  end
20
69
 
@@ -3,8 +3,15 @@
3
3
  module Pubid
4
4
  module Iso
5
5
  class Builder < Pubid::Builder::Base
6
- def initialize(scheme)
7
- @scheme = scheme
6
+ def initialize
7
+ # No state needed: lookups are delegated to the Pubid::Iso module.
8
+ end
9
+
10
+ # Override the base implementation to avoid relying on @scheme.
11
+ # @param typed_stage_string [String, nil]
12
+ # @return [Pubid::Components::TypedStage, nil]
13
+ def locate_typed_stage(typed_stage_string)
14
+ Pubid::Iso.locate_stage(typed_stage_string.to_s)
8
15
  end
9
16
 
10
17
  def locate_identifier_klass(parsed_hash)
@@ -25,6 +32,16 @@ module Pubid
25
32
  return Identifiers::TcDocument
26
33
  end
27
34
 
35
+ # An explicit document type (e.g. from a URN's `:tr:`/`:ts:` token) pins
36
+ # the class regardless of the stage. The stage and type are separate URN
37
+ # fields, but the stage is later folded into `:type_with_stage` (e.g.
38
+ # "WDA" for 90.93), which would otherwise mis-resolve the class to the
39
+ # stage's owning type (IS). Consume the hint here, before assign_attributes.
40
+ if (doc_type = parsed_hash.delete(:document_type))
41
+ type_stage = locate_typed_stage(doc_type)
42
+ return Pubid::Iso.locate_type(type_stage.type_code) if type_stage
43
+ end
44
+
28
45
  # Check the `:type_with_stage` to determine the identifier class
29
46
  # 1. :type_with_stage will be nil if:
30
47
  # a) It is an IS.
@@ -37,7 +54,7 @@ module Pubid
37
54
 
38
55
  typed_stage = locate_typed_stage(parsed_hash[:type_with_stage])
39
56
 
40
- @scheme.locate_identifier_klass_by_type_code(typed_stage.type_code)
57
+ Pubid::Iso.locate_type(typed_stage.type_code)
41
58
  end
42
59
 
43
60
  def build(parsed_hash)
@@ -89,7 +106,7 @@ module Pubid
89
106
  # If typed_stage, stage, or type are still nil after building,
90
107
  # set them to the default International Standard values
91
108
  if identifier.typed_stage.nil?
92
- default_typed_stage = @scheme.locate_typed_stage_by_abbr("")
109
+ default_typed_stage = Pubid::Iso.locate_stage("")
93
110
  identifier.typed_stage = default_typed_stage
94
111
  identifier.stage = default_typed_stage.to_stage
95
112
  identifier.type = default_typed_stage.to_type
@@ -108,6 +125,29 @@ module Pubid
108
125
  end
109
126
  end
110
127
 
128
+ # ISO normalizes em/en dashes, slashes, and spaces to hyphens so that
129
+ # "4037/1979", "4037-1979", and "ISO/IEC DIR 1 IEC" all split cleanly.
130
+ def normalize_number_with_part(value)
131
+ value.to_s
132
+ .tr("#{Parser::DASH_CHARS.join}/", "-")
133
+ .gsub(" ", "-")
134
+ end
135
+
136
+ # LEGACY: "ISO 4037-1979" used a hyphen where the modern form is
137
+ # "ISO 4037:1979". When the part looks like a 4-digit year in a
138
+ # plausible range, treat it as a date instead of a part number.
139
+ def extract_legacy_year(number, part, code_class)
140
+ return nil unless part&.match?(/^\d{4}$/)
141
+
142
+ year_value = part.to_i
143
+ return nil unless year_value.between?(1900, 2099)
144
+
145
+ {
146
+ number: code_class.new(value: number),
147
+ date: ::Pubid::Components::Date.new(year: part),
148
+ }
149
+ end
150
+
111
151
  def cast(type, value)
112
152
  case type
113
153
  when :base_identifier
@@ -129,7 +169,8 @@ module Pubid
129
169
  # (e.g. a TC document, which skips the copublisher merge) matches
130
170
  # the [] convention used by copublisher-merged parses and by
131
171
  # Identifier.create. Otherwise equality fails on [] vs nil.
132
- Pubid::Iso::Components::Publisher.new(publisher: value, copublisher: [])
172
+ Pubid::Iso::Components::Publisher.new(publisher: value,
173
+ copublisher: [])
133
174
  end
134
175
 
135
176
  when :copublishers
@@ -156,45 +197,7 @@ module Pubid
156
197
  # or "105/F" ('F' is part)
157
198
  # or "5843/6" ('6' is part)
158
199
  # LEGACY: "4037-1979" (number-year, year should become date)
159
-
160
- # Split the number into parts
161
- normalized_value = value.to_s.tr("#{Parser::DASH_CHARS.join}/", "-")
162
-
163
- # for "1 IEC" ('IEC' is part) (in case of "ISO/IEC DIR 1 IEC")
164
- normalized_value.gsub!(" ", "-")
165
-
166
- parts = normalized_value.split("-").reject(&:empty?)
167
- number = parts.shift # The first part is always the number
168
- part = parts.shift&.strip # The second part is the part, if present
169
- subpart = parts.any? ? parts.join("-") : nil # The remaining parts form the subpart, if present
170
-
171
- # LEGACY FORMAT FIX: If "part" is a 4-digit year (1900-2099), move it to date field
172
- # This handles legacy formats like "ISO 4037-1979" where hyphen was used instead of colon
173
- if part&.match?(/^\d{4}$/)
174
- year_value = part.to_i
175
- # Only treat as year if in reasonable year range (excludes part numbers like "1751")
176
- if year_value.between?(1900, 2099)
177
- return {
178
- number: Pubid::Iso::Components::Code.new(number: number),
179
- date: Pubid::Components::Date.new(year: part),
180
- }
181
- end
182
- end
183
-
184
- part = convert_roman_to_integer(part)
185
-
186
- code_hash = { number: Pubid::Iso::Components::Code.new(number: number) }
187
-
188
- if part
189
- code_hash[:part] = Pubid::Iso::Components::Code.new(number: part)
190
- end
191
-
192
- if subpart
193
- code_hash[:subpart] =
194
- Pubid::Iso::Components::Code.new(number: subpart)
195
- end
196
-
197
- code_hash
200
+ parse_number_with_part(value, code_class: Pubid::Iso::Components::Code)
198
201
 
199
202
  when :directives_type
200
203
  # nothing to do here, just return nil
@@ -222,7 +225,7 @@ module Pubid
222
225
  }
223
226
  when :stage_iteration
224
227
  # "1" or "2"
225
- Pubid::Iso::Components::Code.new(number: value.to_s)
228
+ Pubid::Components::Iteration.new(number: value.to_s)
226
229
 
227
230
  when :date
228
231
  parse_date(value)
@@ -232,7 +235,7 @@ module Pubid
232
235
  original_text = value.to_s
233
236
  # Extract just the digit(s) for the number field
234
237
  number_string = original_text.match(/\d+/)&.to_s
235
- number_code = number_string ? Pubid::Iso::Components::Code.new(number: number_string) : nil
238
+ number_code = number_string ? Pubid::Iso::Components::Code.new(value: number_string) : nil
236
239
  Pubid::Components::Edition.new(number: number_code,
237
240
  original_text: original_text)
238
241
 
@@ -247,14 +250,13 @@ module Pubid
247
250
  when :joint_identifier
248
251
  case value[:publisher]
249
252
  when "IDF"
250
- require_relative "../idf/builder"
251
- Idf::Builder.new.build(value)
253
+ Pubid::Idf.build_from_parse(value)
252
254
  end
253
255
 
254
256
  when :subgroup
255
257
  # Handle JTC 1 subgroup in directives (ISO/IEC JTC 1 DIR)
256
258
  # Store as a component for potential use in rendering
257
- Pubid::Iso::Components::Code.new(number: value.to_s)
259
+ Pubid::Iso::Components::Code.new(value: value.to_s)
258
260
 
259
261
  when :supplements
260
262
  # Handle bundled supplements (+ operator)
@@ -268,11 +270,11 @@ module Pubid
268
270
  # TC Document attributes
269
271
  when :tc_type, :sc_type, :wg_type
270
272
  # TC, SC, WG types are code components
271
- Pubid::Iso::Components::Code.new(number: value.to_s)
273
+ Pubid::Iso::Components::Code.new(value: value.to_s)
272
274
 
273
275
  when :tc_number, :sc_number, :wg_number
274
276
  # TC, SC, WG numbers are code components
275
- Pubid::Iso::Components::Code.new(number: value.to_s)
277
+ Pubid::Iso::Components::Code.new(value: value.to_s)
276
278
 
277
279
  when :year
278
280
  # For TC documents with year, convert to Date
@@ -283,7 +285,7 @@ module Pubid
283
285
  # For regular identifiers, this is handled in :number_with_part
284
286
  if value.is_a?(Parslet::Slice) || value.is_a?(String) ||
285
287
  value.is_a?(Integer)
286
- Pubid::Iso::Components::Code.new(number: value.to_s)
288
+ Pubid::Iso::Components::Code.new(value: value.to_s)
287
289
  else
288
290
  value
289
291
  end
@@ -292,7 +294,7 @@ module Pubid
292
294
  # Raw stage code from URN parser (e.g., "10.00", "50.00")
293
295
  # Convert to type_with_stage format for builder
294
296
  # Look up the typed stage from stage code
295
- typed_stage = Scheme.locate_typed_stage_by_stage_code(value.to_s)
297
+ typed_stage = Pubid::Iso.locate_stage_by_stage_code(value.to_s)
296
298
  if typed_stage
297
299
  typed_stage.abbr.is_a?(Array) ? typed_stage.abbr.first : typed_stage.abbr
298
300
  else
@@ -10,6 +10,57 @@ module Pubid
10
10
  collection: true
11
11
  attribute :type, :string, default: -> { "bundled_identifier" }
12
12
 
13
+ # Serialize the bundle structure. The inherited common-field maps read the
14
+ # delegated base_document values; suppress them (base_document carries
15
+ # them) and serialize base_document + the supplements collection instead,
16
+ # routing each through from_hash on load.
17
+ key_value do
18
+ # Serialized key is "base" (consistent with supplements); the attribute
19
+ # stays base_document.
20
+ map "base",
21
+ with: { to: :base_document_to_kv, from: :base_document_from_kv }
22
+ map "supplements",
23
+ with: { to: :supplements_to_kv, from: :supplements_from_kv }
24
+ end
25
+
26
+ def base_document_to_kv(model, doc)
27
+ return unless model.base_document
28
+
29
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new(
30
+ "base", model.base_document.to_hash
31
+ ))
32
+ end
33
+
34
+ def base_document_from_kv(model, value)
35
+ model.base_document = ::Pubid::Iso::Identifier.from_hash(value) if value
36
+ end
37
+
38
+ def supplements_to_kv(model, doc)
39
+ return unless model.supplements&.any?
40
+
41
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new(
42
+ "supplements", model.supplements.map(&:to_hash)
43
+ ))
44
+ end
45
+
46
+ def supplements_from_kv(model, value)
47
+ model.supplements = Array(value).map do |h|
48
+ ::Pubid::Iso::Identifier.from_hash(h)
49
+ end
50
+ end
51
+
52
+ # The delegated common fields are carried by base_document; don't duplicate
53
+ # them at the bundle level.
54
+ def number_to_kv(_model, _doc); end
55
+ def part_to_kv(_model, _doc); end
56
+ def subpart_to_kv(_model, _doc); end
57
+ def year_to_kv(_model, _doc); end
58
+ def month_to_kv(_model, _doc); end
59
+ def day_to_kv(_model, _doc); end
60
+ def publisher_to_kv(_model, _doc); end
61
+ def copublishers_to_kv(_model, _doc); end
62
+ def stage_to_kv(_model, _doc); end
63
+
13
64
  # Delegate key attributes to base_document for easier access in tests
14
65
  def publisher
15
66
  base_document&.publisher
@@ -1,34 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
-
5
3
  module Pubid
6
4
  module Iso
7
5
  module Components
6
+ # Code component for ISO identifiers.
7
+ #
8
+ # Inherits +value+ and +parts+ from the shared Code; overrides
9
+ # rendering to join parts with "-" (ISO convention). Equality and
10
+ # hash are inherited from the shared Code (compare all fields).
8
11
  class Code < ::Pubid::Components::Code
9
- attribute :number, :string
10
- attribute :parts, :string, collection: true
11
-
12
- def value
13
- number || self[:value]
14
- end
15
-
16
- def render(context: nil)
17
- result = value.to_s
18
- result += parts.map { |p| "-#{p}" }.join if parts&.any?
19
- result
20
- end
21
-
22
12
  def to_s
23
13
  result = value.to_s
24
14
  result += parts.map { |p| "-#{p}" }.join if parts&.any?
25
15
  result
26
16
  end
27
17
 
28
- def ==(other)
29
- return false unless other.is_a?(Code)
30
-
31
- value == other.value && parts == other.parts
18
+ def render(context: nil)
19
+ to_s
32
20
  end
33
21
  end
34
22
  end
@@ -16,6 +16,10 @@ module Pubid
16
16
  end
17
17
 
18
18
  def render(context: nil)
19
+ if context&.urn?
20
+ return publisher&.downcase
21
+ end
22
+
19
23
  return publisher unless copublisher&.any?
20
24
 
21
25
  publisher + copublisher.map { |cp| "/#{cp}" }.join
@@ -38,19 +42,17 @@ module Pubid
38
42
  def ==(other)
39
43
  return false unless other.is_a?(Publisher)
40
44
 
41
- publisher == other.publisher && copublisher == other.copublisher
45
+ # copublisher is a collection: parsing yields [] while building via
46
+ # .create (e.g. from an index hash) leaves it nil. Treat the empty
47
+ # collection and "no collection" as equal so both forms compare.
48
+ publisher == other.publisher &&
49
+ copublisher.to_a == other.copublisher.to_a
42
50
  end
43
51
 
44
- # Returns hash code for publisher component
45
- # @return [Integer] hash code
46
- # @note Memoized for performance
47
52
  def hash
48
- @hash ||= [publisher, copublisher].compact.map(&:hash).hash
53
+ @hash ||= [publisher, copublisher.to_a].map(&:hash).hash
49
54
  end
50
55
 
51
- # Checks equality using hash for consistency
52
- # @param other [Object] object to compare with
53
- # @return [Boolean] true if equal
54
56
  def eql?(other)
55
57
  hash == other.hash && self == other
56
58
  end
@@ -3,10 +3,8 @@
3
3
  module Pubid
4
4
  module Iso
5
5
  module Components
6
- # ISO-specific components
6
+ autoload :Code, "#{__dir__}/components/code"
7
+ autoload :Publisher, "#{__dir__}/components/publisher"
7
8
  end
8
9
  end
9
10
  end
10
-
11
- require_relative "components/code"
12
- require_relative "components/publisher"