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
@@ -0,0 +1,307 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ieee
5
+ # Human-readable renderer for IEEE identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "IEEE Std 802.11-2020"
9
+ # "IEEE Std 535-2013/Cor. 1-2017"
10
+ # "ANSI C37.61-1973 and IEEE Std 321-1973"
11
+ #
12
+ # The renderer is registered as the +:human+ format in the IEEE format
13
+ # registry and invoked via +render(format: :human)+.
14
+ #
15
+ # For wrapper types (DualPublished, AdoptedStandard, etc.) the renderer
16
+ # composes child identifiers. For simple identifiers it delegates to the
17
+ # identifier's own publisher/code/relationship helpers.
18
+ class Renderer < ::Pubid::Renderers::Base
19
+ def render(context: nil, **opts)
20
+ id = @id
21
+
22
+ case id
23
+ when Identifiers::DualPublished
24
+ render_dual_published(id)
25
+ when Identifiers::DualIdentifier
26
+ render_dual_identifier(id)
27
+ when Identifiers::AdoptedStandard
28
+ render_adopted_standard(id)
29
+ when Identifiers::RedlinedStandard
30
+ render_redlined_standard(id)
31
+ when Identifiers::Corrigendum
32
+ render_corrigendum(id)
33
+ when Identifiers::InterpretationIdentifier
34
+ render_interpretation(id)
35
+ when Identifiers::ConformanceIdentifier
36
+ render_conformance(id)
37
+ when Identifiers::MultiNumberedIdentifier
38
+ render_multi_numbered(id)
39
+ when Identifiers::ParentheticalIdentifier
40
+ render_parenthetical(id)
41
+ when Identifiers::CsaDualPublished
42
+ render_csa_dual_published(id)
43
+ when Identifiers::IecIeeeCopublished
44
+ render_iec_ieee_copublished(id)
45
+ when Identifiers::SiStandard
46
+ render_si_standard(id)
47
+ when Identifiers::JointDevelopment
48
+ id.to_s
49
+ else
50
+ render_base(id)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ # ------------------------------------------------------------------
57
+ # Base IEEE identifier rendering
58
+ # ------------------------------------------------------------------
59
+
60
+ def render_base(id)
61
+ parts = []
62
+
63
+ # Publisher(s) - handle copublisher array properly
64
+ if id.copublisher && !id.copublisher.empty?
65
+ parts << [id.publisher, *id.copublisher].join("/")
66
+ else
67
+ parts << id.publisher
68
+ end
69
+
70
+ # Draft status
71
+ parts << id.draft_status if id.draft_status
72
+
73
+ # Type - only render for IEEE/AIEE publishers, and only for non-projects
74
+ should_render_type = id.publisher&.match?(/^(IEEE|AIEE)/)
75
+
76
+ if should_render_type && !id.typed_stage&.project_status && id.type && !id.type.to_s.strip.empty? && id.type != "P"
77
+ type_str = id.type.dup
78
+ type_str = type_str.sub(/^P/, "") if type_str.start_with?("P")
79
+ parts << type_str unless type_str.strip.empty?
80
+ end
81
+
82
+ # Code - with P prefix for projects (concatenated, not separated)
83
+ if id.code_obj
84
+ result = id.code_obj.to_s
85
+
86
+ # Prepend P if this is a project AND code doesn't already have P
87
+ if id.typed_stage&.project_status && should_render_type && !result.start_with?("P")
88
+ result = "P#{result}"
89
+ end
90
+
91
+ # Only attach year to code if there's no edition, no month, and no draft
92
+ result += "-#{id.year}" if id.year && !id.draft_obj && !id.edition && !id.month
93
+
94
+ # Append draft to code - with or without space based on original format
95
+ if id.draft_obj
96
+ result += id.space_before_draft ? " #{id.draft_obj}" : id.draft_obj.to_s
97
+ end
98
+
99
+ # Append interpretation notation (/INT)
100
+ result += "/INT" if id.interpretation
101
+
102
+ # Append conformance notation (/ConformanceNN-YYYY)
103
+ if id.conf_number
104
+ result += "/Conformance#{id.conf_number}"
105
+ result += "-#{id.conf_year}" if id.conf_year
106
+ end
107
+
108
+ # Append ASHRAE joint publication (/ASHRAE Guideline NN-YYYY)
109
+ if id.ashrae_number
110
+ result += "/ASHRAE Guideline #{id.ashrae_number}"
111
+ result += "-#{id.ashrae_year}" if id.ashrae_year
112
+ end
113
+
114
+ # Append IEEE cross-reference (/C62.22.1-1996)
115
+ result += id.crossref if id.crossref
116
+
117
+ parts << result
118
+ elsif should_render_type && id.typed_stage&.project_status
119
+ # No code but is a project - add standalone P
120
+ parts << "P"
121
+ end
122
+
123
+ # Edition - with year if present (IEC style)
124
+ if id.edition
125
+ edition_str = "Edition #{id.edition}"
126
+ if id.year
127
+ edition_str += " #{id.year}"
128
+ edition_str += "-#{id.edition_month}" if id.edition_month
129
+ end
130
+ parts << edition_str
131
+ end
132
+
133
+ # Build the main identifier (without month yet)
134
+ result = parts.join(" ")
135
+
136
+ # Month/Day - append directly to avoid extra space before comma
137
+ if id.month
138
+ result += ", #{id.month}"
139
+ result += " #{id.day}" if id.day
140
+ if id.year && !id.edition
141
+ result += ", #{id.year}"
142
+ end
143
+ end
144
+
145
+ # Add parenthetical content if present
146
+ parentheticals = []
147
+
148
+ reaff = id.reaffirmed
149
+ if reaff && !reaff.to_s.strip.empty?
150
+ parentheticals << "(R#{reaff})"
151
+ end
152
+
153
+ if id.parenthetical_content
154
+ parentheticals << "(#{id.parenthetical_content})"
155
+ elsif id.relationships && !id.relationships.empty?
156
+ relationship_str = id.relationships.join(" / ")
157
+ parentheticals << "(#{relationship_str})"
158
+ elsif id.revision_of
159
+ parentheticals << "(Revision of IEEE Std #{id.revision_of})"
160
+ elsif id.amendment_to
161
+ parentheticals << "(Amendment to IEEE Std #{id.amendment_to})"
162
+ elsif id.adoption
163
+ parentheticals << "(Adoption of #{id.adoption})"
164
+ elsif id.note && !id.note.to_s.strip.empty?
165
+ parentheticals << "(#{id.note})"
166
+ end
167
+
168
+ result += " #{parentheticals.join(' ')}" unless parentheticals.empty?
169
+
170
+ # Book nickname - outside parentheses in square brackets
171
+ result += " [#{id.nickname}]" if id.nickname && !id.nickname.to_s.strip.empty?
172
+
173
+ # Redline suffix
174
+ result += " - Redline" if id.redline
175
+
176
+ result
177
+ end
178
+
179
+ # ------------------------------------------------------------------
180
+ # Wrapper types
181
+ # ------------------------------------------------------------------
182
+
183
+ def render_dual_published(id)
184
+ "#{id.first_identifier} and #{id.second_identifier}"
185
+ end
186
+
187
+ def render_dual_identifier(id)
188
+ "#{id.first_identifier} and #{id.second_identifier}"
189
+ end
190
+
191
+ def render_adopted_standard(id)
192
+ result = id.ieee_identifier.to_s
193
+ if id.adopted_identifiers && !id.adopted_identifiers.empty?
194
+ adopted_strs = id.adopted_identifiers.map(&:to_s)
195
+ result += " (#{adopted_strs.join(' and ')})"
196
+ end
197
+ result
198
+ end
199
+
200
+ def render_redlined_standard(id)
201
+ result = id.base_identifier.to_s
202
+ result += " (Revision of #{id.revision_of})" if id.revision_of
203
+ result += " - Redline" if id.redline
204
+ result
205
+ end
206
+
207
+ def render_corrigendum(id)
208
+ return render_base(id) unless id.base_identifier
209
+
210
+ result = id.base_identifier.to_s
211
+ result += "/Cor"
212
+ result += ". " if id.cor_number # Add period and space for formal format
213
+ result += id.cor_number if id.cor_number
214
+ result += "-#{id.cor_year}" if id.cor_year
215
+ result
216
+ end
217
+
218
+ def render_interpretation(id)
219
+ return render_base(id) unless id.base_identifier
220
+
221
+ result = id.base_identifier.to_s
222
+ result += "/INT"
223
+ result += "-#{id.int_year}" if id.int_year
224
+ result
225
+ end
226
+
227
+ def render_conformance(id)
228
+ return render_base(id) unless id.base_identifier
229
+
230
+ result = id.base_identifier.to_s
231
+ result += "/Conformance#{id.conf_number}" if id.conf_number
232
+ result += "-#{id.conf_year}" if id.conf_year
233
+ result
234
+ end
235
+
236
+ def render_multi_numbered(id)
237
+ return id.primary_identifier.to_s unless id.secondary_identifier
238
+
239
+ secondary_code = id.secondary_identifier.code.to_s
240
+ if secondary_code.start_with?("C") && secondary_code.match?(/^C\d+\./)
241
+ "#{id.primary_identifier}/#{id.secondary_identifier}"
242
+ else
243
+ "#{id.primary_identifier} and #{id.secondary_identifier}"
244
+ end
245
+ end
246
+
247
+ def render_parenthetical(id)
248
+ result = id.base_identifier.to_s
249
+ result += " (#{id.parenthetical_identifier})" if id.parenthetical_identifier
250
+ result
251
+ end
252
+
253
+ def render_csa_dual_published(id)
254
+ csa_str = id.csa_identifier.to_s
255
+ csa_str = "CSA #{csa_str}" unless csa_str.start_with?("CSA", "CAN/")
256
+
257
+ "#{id.ieee_identifier}/#{csa_str}"
258
+ end
259
+
260
+ def render_iec_ieee_copublished(id)
261
+ result = "IEC/IEEE"
262
+ result += " #{id.copublished_number}" if id.copublished_number
263
+ result += id.draft_info if id.draft_info
264
+ result += " IEC:#{id.iec_year}" if id.iec_year
265
+ result += " #{id.date_info}" if id.date_info
266
+ result
267
+ end
268
+
269
+ def render_si_standard(id)
270
+ parts = []
271
+
272
+ # Publisher (IEEE/ASTM)
273
+ parts << "IEEE/ASTM"
274
+
275
+ # Type (SI or PSI based on typed_stage)
276
+ parts << if id.typed_stage&.abbr&.include?("PSI")
277
+ "PSI"
278
+ else
279
+ "SI"
280
+ end
281
+
282
+ # Code (number) with draft version for PSI
283
+ code_part = id.code.to_s
284
+ if id.draft_obj
285
+ code_part += "/D#{id.draft_obj.version}"
286
+ end
287
+ parts << code_part if id.code
288
+
289
+ # Date
290
+ if id.month && id.year
291
+ parts << ", #{id.month} #{id.year}"
292
+ elsif id.year
293
+ parts << "-#{id.year}"
294
+ end
295
+
296
+ # Relationships (if present)
297
+ result = parts.join(" ")
298
+ if id.relationships && !id.relationships.empty?
299
+ rel_strs = id.relationships.map(&:to_s)
300
+ result += " (#{rel_strs.join(' / ')})"
301
+ end
302
+
303
+ result
304
+ end
305
+ end
306
+ end
307
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ieee
5
+ # Parses IEEE URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits many fields; this parser handles the common
8
+ # published-standard shape:
9
+ # urn:ieee:{publisher}:{code}:{year}
10
+ #
11
+ # publisher is the lowercase publisher (with optional copublishers
12
+ # joined by `-`). code is the alphanumeric designation (period is the
13
+ # part separator within the code). The year separator in human-readable
14
+ # form is `-`.
15
+ #
16
+ # Examples:
17
+ # - urn:ieee:ieee:802.3:2018 → IEEE Std 802.3-2018
18
+ # - urn:ieee:ieee:1018:2019 → IEEE Std 1018-2019
19
+ class UrnParser < Pubid::UrnParser::Base
20
+ PUBLISHER_LABEL = "IEEE"
21
+
22
+ def parse_urn(urn)
23
+ body = strip_namespace(urn)
24
+ parts = split_parts(body)
25
+
26
+ _publisher, code, year = parts
27
+
28
+ text = "#{PUBLISHER_LABEL} Std #{code}"
29
+ text += "-#{year}" if year
30
+ flavor_parse(text)
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/pubid/ieee.rb CHANGED
@@ -9,9 +9,11 @@ module Pubid
9
9
  autoload :Ire, "#{__dir__}/ieee/ire"
10
10
  autoload :Nesc, "#{__dir__}/ieee/nesc"
11
11
  autoload :Parser, "#{__dir__}/ieee/parser"
12
- autoload :Scheme, "#{__dir__}/ieee/scheme"
12
+ autoload :PreParser, "#{__dir__}/ieee/pre_parser"
13
+ autoload :Renderer, "#{__dir__}/ieee/renderer"
13
14
  autoload :TypedStages, "#{__dir__}/ieee/typed_stages"
14
15
  autoload :UrnGenerator, "#{__dir__}/ieee/urn_generator"
16
+ autoload :UrnParser, "#{__dir__}/ieee/urn_parser"
15
17
 
16
18
  # Components submodule
17
19
  module Components
@@ -25,8 +27,67 @@ module Pubid
25
27
  def parse(input)
26
28
  Identifier.parse(input)
27
29
  end
30
+
31
+ # Auto-discover all identifier types from the Identifiers namespace
32
+ # @return [Array<Class>] identifier classes that define a self.type Hash
33
+ def identifier_types
34
+ @identifier_types ||= Identifiers.constants
35
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
36
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
37
+ .select { |c| c.type.is_a?(Hash) }
38
+ end
39
+
40
+ # Build typed stage index from TypedStages module
41
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
42
+ def all_typed_stages
43
+ @all_typed_stages ||= TypedStages::TYPED_STAGES
44
+ end
45
+
46
+ # Lookup: type code -> identifier class
47
+ # @param code [String, Symbol] the type key to find
48
+ # @return [Class, nil] the matching identifier class
49
+ def locate_type(code)
50
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
51
+ end
52
+
53
+ # Lookup: abbreviation -> typed stage
54
+ # @param abbr [String, Symbol] the abbreviation to find
55
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
56
+ def locate_stage(abbr)
57
+ abbr_str = abbr.to_s.upcase
58
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
59
+ end
60
+
61
+ # Lookup: IEEE draft notation -> typed stage
62
+ # @param draft [String] IEEE draft notation (e.g., "D1", "D5", "P")
63
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
64
+ def locate_stage_by_ieee_draft(draft)
65
+ return nil if draft.nil? || draft.to_s.strip.empty?
66
+
67
+ draft_str = draft.to_s.strip
68
+
69
+ # Try exact match on abbreviation first
70
+ ts = all_typed_stages.find { |t| t.abbr.include?(draft_str) }
71
+ return ts if ts
72
+
73
+ # Try match on ieee_draft_equivalent
74
+ all_typed_stages.find { |t| t.ieee_draft_equivalent == draft_str }
75
+ end
76
+
77
+ # Lookup: ISO stage code -> typed stage
78
+ # @param stage [String] ISO stage code (e.g., "WD", "CD", "DIS", "FDIS")
79
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
80
+ def locate_stage_by_iso_stage(stage)
81
+ return nil if stage.nil? || stage.to_s.strip.empty?
82
+
83
+ all_typed_stages.find { |ts| ts.iso_stage_equivalent == stage.to_s.strip }
84
+ end
28
85
  end
29
86
  end
30
87
  end
31
88
 
32
89
  Pubid::Registry.register(:ieee, Pubid::Ieee)
90
+
91
+ # Per-flavor format registry: inherits global formats, overrides :human
92
+ Pubid::Ieee::Identifiers::Base.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
93
+ Pubid::Ieee::Identifiers::Base.format_registry.register(:human, renderer: Pubid::Ieee::Renderer)
@@ -10,7 +10,6 @@ module Pubid
10
10
  autoload :Ire, "#{__dir__}/ire"
11
11
  autoload :Nesc, "#{__dir__}/nesc"
12
12
  autoload :Parser, "#{__dir__}/parser"
13
- autoload :Scheme, "#{__dir__}/scheme"
14
13
  autoload :TypedStages, "#{__dir__}/typed_stages"
15
14
  autoload :UrnGenerator, "#{__dir__}/urn_generator"
16
15
 
@@ -9,7 +9,7 @@ module Pubid
9
9
  type_letter = stringify(hash[:type])
10
10
 
11
11
  attrs = {
12
- code: stringify(hash[:code]),
12
+ number: stringify(hash[:number]),
13
13
  appendix: stringify(hash[:appendix]),
14
14
  part: stringify(hash[:part]),
15
15
  annex: stringify(hash[:annex]),
@@ -17,7 +17,7 @@ module Pubid
17
17
  version: stringify(hash[:version]),
18
18
  }.compact
19
19
 
20
- Scheme.identifier_klass_for_type_letter(type_letter).new(**attrs)
20
+ Pubid::Iho.identifier_klass_for_type_letter(type_letter).new(**attrs)
21
21
  end
22
22
 
23
23
  def self.build(parsed)
@@ -3,7 +3,15 @@
3
3
  module Pubid
4
4
  module Iho
5
5
  # Entry point for parsing IHO identifiers.
6
+ #
7
+ # `extend Pubid::IdentifierFacade` provides polymorphic `from_hash` (routing
8
+ # to the concrete subclass via the `_type` discriminator) and pairs with
9
+ # `include Pubid::Iho::Identifier` in Identifiers::Base for identity
10
+ # (`is_a?`/`===`), so a consumer handed this module can both deserialize and
11
+ # identity-check IHO ids through it.
6
12
  module Identifier
13
+ extend Pubid::IdentifierFacade
14
+
7
15
  # Parse an IHO identifier string into an identifier object
8
16
  # @param identifier [String] The IHO identifier string to parse
9
17
  # @return [Pubid::Iho::Identifiers::Base] The appropriate identifier object
@@ -6,19 +6,65 @@ module Pubid
6
6
  # Base class for all IHO identifiers.
7
7
  #
8
8
  # IHO identifiers have the form:
9
- # IHO {S|P|M|B|C}-{code}[ Ap. {appendix}][ Part {part}][ Annex {annex}][ Suppl {supplement}][ {version}]
9
+ # IHO {S|P|M|B|C}-{number}[ Ap. {appendix}][ Part {part}][ Annex {annex}][ Suppl {supplement}][ {version}]
10
10
  #
11
11
  # The leading IHO publisher prefix is optional on input but always
12
12
  # emitted on output.
13
13
  class Base < Pubid::Identifier
14
+ # Identity for the Pubid::Iho::Identifier facade (see its comment).
15
+ include Pubid::Iho::Identifier
16
+
17
+ # `number` overrides the generic Components::Code attribute with a plain
18
+ # string (same pattern as `part` below); it holds the IHO document
19
+ # number (e.g. "100", "1/21"). Kept as the generic `number` so the
20
+ # relaton index sorts/binary-searches on it natively via `id.number`.
21
+ attribute :number, :string
14
22
  attribute :publisher, :string, default: "IHO"
15
- attribute :code, :string
16
23
  attribute :appendix, :string
17
24
  attribute :part, :string
18
25
  attribute :annex, :string
19
26
  attribute :supplement, :string
20
27
  attribute :version, :string
21
28
 
29
+ # Polymorphic type map for lutaml::Model key_value serialization: maps
30
+ # each subclass's polymorphic_name to its class name so `from_hash` can
31
+ # re-instantiate the concrete type from `_type`.
32
+ IHO_TYPE_MAP = {
33
+ "pubid:iho:standard" => "Pubid::Iho::Identifiers::Standard",
34
+ "pubid:iho:publication" => "Pubid::Iho::Identifiers::Publication",
35
+ "pubid:iho:miscellaneous" => "Pubid::Iho::Identifiers::Miscellaneous",
36
+ "pubid:iho:bibliographic" => "Pubid::Iho::Identifiers::Bibliographic",
37
+ "pubid:iho:circular-letter" => "Pubid::Iho::Identifiers::CircularLetter",
38
+ }.freeze
39
+
40
+ # The base Pubid::Identifier no longer auto-maps attributes, so each
41
+ # flavor's top class must declare its own key_value mapping. IHO
42
+ # attributes are plain strings, so they map directly. `publisher` is
43
+ # intentionally omitted: it is always the "IHO" default and is restored
44
+ # on load.
45
+ key_value do
46
+ map "_type", to: :_type, polymorphic_map: IHO_TYPE_MAP
47
+ map "number", to: :number
48
+ map "appendix", to: :appendix
49
+ map "part", to: :part
50
+ map "annex", to: :annex
51
+ map "supplement", to: :supplement
52
+ map "version", to: :version
53
+ end
54
+
55
+ # Re-instantiate the concrete subclass from `_type`. lutaml's
56
+ # polymorphic_map only validates `_type` on key_value deserialization;
57
+ # without this routing `from_hash` returns a bare Base (no #type, which
58
+ # breaks #to_s). Mirrors Pubid::Iso::Identifier.from_hash.
59
+ def self.from_hash(data, options = {})
60
+ klass_name = IHO_TYPE_MAP[data["_type"] || data[:_type]]
61
+ if klass_name
62
+ klass = Object.const_get(klass_name)
63
+ return klass.from_hash(data, options) unless klass == self
64
+ end
65
+ super
66
+ end
67
+
22
68
  def self.parse(string)
23
69
  Iho::Identifier.parse(string)
24
70
  end
@@ -26,14 +72,7 @@ module Pubid
26
72
  # Render the identifier as a string in canonical IHO form.
27
73
  # @return [String]
28
74
  def to_s
29
- letter = type.is_a?(Hash) ? type[:short].to_s : type.to_s
30
- rendered = "#{publisher} #{letter}-#{code}"
31
- rendered << " Ap. #{appendix}" if appendix
32
- rendered << " Part #{part}" if part
33
- rendered << " Annex #{annex}" if annex
34
- rendered << " Suppl #{supplement}" if supplement
35
- rendered << " #{version}" if version
36
- rendered
75
+ render(format: :human)
37
76
  end
38
77
  end
39
78
  end
@@ -10,10 +10,6 @@ module Pubid
10
10
  { key: :bibliographic, title: "Bibliographic Publication",
11
11
  short: "B" }
12
12
  end
13
-
14
- def type
15
- self.class.type
16
- end
17
13
  end
18
14
  end
19
15
  end
@@ -9,10 +9,6 @@ module Pubid
9
9
  def self.type
10
10
  { key: :circular_letter, title: "Circular Letter", short: "C" }
11
11
  end
12
-
13
- def type
14
- self.class.type
15
- end
16
12
  end
17
13
  end
18
14
  end
@@ -10,10 +10,6 @@ module Pubid
10
10
  { key: :miscellaneous, title: "Miscellaneous Publication",
11
11
  short: "M" }
12
12
  end
13
-
14
- def type
15
- self.class.type
16
- end
17
13
  end
18
14
  end
19
15
  end
@@ -9,10 +9,6 @@ module Pubid
9
9
  def self.type
10
10
  { key: :publication, title: "Publication", short: "P" }
11
11
  end
12
-
13
- def type
14
- self.class.type
15
- end
16
12
  end
17
13
  end
18
14
  end
@@ -9,10 +9,6 @@ module Pubid
9
9
  def self.type
10
10
  { key: :standard, title: "Standards and Specifications", short: "S" }
11
11
  end
12
-
13
- def type
14
- self.class.type
15
- end
16
12
  end
17
13
  end
18
14
  end
@@ -19,8 +19,8 @@ module Pubid
19
19
  (str(":") >> digits) | (str("/") >> digits) | (dash >> digits) | match("[A-Z]")
20
20
  end
21
21
 
22
- rule(:code) do
23
- (digits >> number_suffix.maybe).as(:code)
22
+ rule(:number) do
23
+ (digits >> number_suffix.maybe).as(:number)
24
24
  end
25
25
 
26
26
  rule(:appendix) do
@@ -54,7 +54,7 @@ module Pubid
54
54
 
55
55
  rule(:identifier) do
56
56
  (str("IHO") >> space).maybe >>
57
- series >> dash >> code >>
57
+ series >> dash >> number >>
58
58
  appendix.maybe >> part.maybe >> annex.maybe >> supplement.maybe >> version.maybe
59
59
  end
60
60
 
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iho
5
+ # Human-readable renderer for IHO identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "IHO S-44 5.0.0"
9
+ # "IHO P-1/21 1.0.0"
10
+ # "IHO S-100 Part 4a 1.0.0"
11
+ # "IHO S-65 Ap. A 1.0.0"
12
+ #
13
+ # The renderer is registered as the `:human` format in the IHO format
14
+ # registry and invoked via `render(format: :human)`.
15
+ class Renderer < ::Pubid::Renderers::Base
16
+ def render(context: nil, **opts)
17
+ id = @id
18
+
19
+ letter = id.class.type[:short]
20
+ rendered = "#{id.publisher} #{letter}-#{id.number}"
21
+ rendered << " Ap. #{id.appendix}" if id.appendix
22
+ rendered << " Part #{id.part}" if id.part
23
+ rendered << " Annex #{id.annex}" if id.annex
24
+ rendered << " Suppl #{id.supplement}" if id.supplement
25
+ rendered << " #{id.version}" if id.version
26
+ rendered
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,7 +4,7 @@ module Pubid
4
4
  module Iho
5
5
  # Generates URN strings for IHO identifiers.
6
6
  #
7
- # Format: urn:iho:{type-letter-lowercase}:{code}[:ap.{appendix}][:part.{part}][:annex.{annex}][:suppl.{supplement}][:{version}]
7
+ # Format: urn:iho:{type-letter-lowercase}:{number}[:ap.{appendix}][:part.{part}][:annex.{annex}][:suppl.{supplement}][:{version}]
8
8
  # Example: urn:iho:s:44:5.0.0 for "IHO S-44 5.0.0".
9
9
  class UrnGenerator
10
10
  attr_reader :identifier
@@ -15,8 +15,8 @@ module Pubid
15
15
 
16
16
  def generate
17
17
  parts = ["urn", "iho"]
18
- parts << identifier.type[:short].to_s.downcase
19
- parts << identifier.code.to_s
18
+ parts << identifier.class.type[:short].to_s.downcase
19
+ parts << identifier.number.to_s
20
20
  parts << "ap.#{identifier.appendix}" if identifier.appendix
21
21
  parts << "part.#{identifier.part}" if identifier.part
22
22
  parts << "annex.#{identifier.annex}" if identifier.annex