pubid 2.0.0.pre.alpha.2 → 2.0.0.pre.alpha.4

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 (473) 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 +4 -55
  6. data/lib/pubid/amca/identifiers/base.rb +58 -47
  7. data/lib/pubid/amca/identifiers/interpretation.rb +0 -21
  8. data/lib/pubid/amca/identifiers/publication.rb +0 -17
  9. data/lib/pubid/amca/identifiers/standard.rb +0 -4
  10. data/lib/pubid/amca/renderer.rb +82 -0
  11. data/lib/pubid/amca/single_identifier.rb +0 -23
  12. data/lib/pubid/amca/urn_generator.rb +2 -1
  13. data/lib/pubid/amca/urn_parser.rb +28 -0
  14. data/lib/pubid/amca.rb +42 -1
  15. data/lib/pubid/ansi/builder.rb +5 -3
  16. data/lib/pubid/ansi/identifier.rb +1 -43
  17. data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
  18. data/lib/pubid/ansi/identifiers/standard.rb +2 -3
  19. data/lib/pubid/ansi/renderer.rb +53 -0
  20. data/lib/pubid/ansi/single_identifier.rb +2 -31
  21. data/lib/pubid/ansi/urn_generator.rb +3 -38
  22. data/lib/pubid/ansi/urn_parser.rb +23 -0
  23. data/lib/pubid/ansi.rb +38 -3
  24. data/lib/pubid/api/builder.rb +33 -74
  25. data/lib/pubid/api/identifier.rb +5 -52
  26. data/lib/pubid/api/identifiers/base.rb +2 -14
  27. data/lib/pubid/api/identifiers/bulletin.rb +0 -2
  28. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
  29. data/lib/pubid/api/identifiers/mpms.rb +0 -20
  30. data/lib/pubid/api/identifiers/publication.rb +0 -2
  31. data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
  32. data/lib/pubid/api/identifiers/specification.rb +0 -2
  33. data/lib/pubid/api/identifiers/standard.rb +0 -2
  34. data/lib/pubid/api/identifiers/technical_report.rb +0 -2
  35. data/lib/pubid/api/identifiers/typeless_standard.rb +0 -16
  36. data/lib/pubid/api/identifiers.rb +18 -0
  37. data/lib/pubid/api/renderer.rb +89 -0
  38. data/lib/pubid/api/single_identifier.rb +5 -20
  39. data/lib/pubid/api/urn_generator.rb +0 -18
  40. data/lib/pubid/api/urn_parser.rb +35 -0
  41. data/lib/pubid/api.rb +51 -5
  42. data/lib/pubid/ashrae/builder.rb +3 -3
  43. data/lib/pubid/ashrae/identifier.rb +7 -55
  44. data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
  45. data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
  46. data/lib/pubid/ashrae/identifiers/base.rb +29 -15
  47. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
  48. data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
  49. data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
  50. data/lib/pubid/ashrae/parser.rb +4 -0
  51. data/lib/pubid/ashrae/renderer.rb +117 -0
  52. data/lib/pubid/ashrae/single_identifier.rb +0 -13
  53. data/lib/pubid/ashrae/urn_generator.rb +0 -8
  54. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  55. data/lib/pubid/ashrae.rb +46 -1
  56. data/lib/pubid/asme/components/code.rb +10 -2
  57. data/lib/pubid/asme/identifier.rb +0 -46
  58. data/lib/pubid/asme/identifiers/base.rb +0 -60
  59. data/lib/pubid/asme/renderer.rb +66 -0
  60. data/lib/pubid/asme/single_identifier.rb +3 -1
  61. data/lib/pubid/asme/urn_parser.rb +31 -0
  62. data/lib/pubid/asme.rb +42 -1
  63. data/lib/pubid/astm/components/code.rb +9 -0
  64. data/lib/pubid/{jis → astm}/components.rb +1 -1
  65. data/lib/pubid/astm/identifier.rb +0 -77
  66. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  67. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  68. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  69. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  70. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  71. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  72. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  73. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  74. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  75. data/lib/pubid/astm/identifiers.rb +18 -0
  76. data/lib/pubid/astm/renderer.rb +172 -0
  77. data/lib/pubid/astm/single_identifier.rb +3 -11
  78. data/lib/pubid/astm/urn_parser.rb +30 -0
  79. data/lib/pubid/astm.rb +39 -27
  80. data/lib/pubid/bsi/builder.rb +21 -12
  81. data/lib/pubid/bsi/identifier.rb +5 -85
  82. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -36
  83. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +8 -48
  84. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +8 -39
  85. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +2 -55
  86. data/lib/pubid/bsi/identifiers/amendment.rb +2 -22
  87. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +1 -6
  88. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  89. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -87
  90. data/lib/pubid/bsi/identifiers/committee_document.rb +0 -16
  91. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -87
  92. data/lib/pubid/bsi/identifiers/corrigendum.rb +2 -10
  93. data/lib/pubid/bsi/identifiers/detailed_specification.rb +0 -36
  94. data/lib/pubid/bsi/identifiers/disc.rb +0 -29
  95. data/lib/pubid/bsi/identifiers/draft_document.rb +2 -46
  96. data/lib/pubid/bsi/identifiers/electronic_book.rb +2 -38
  97. data/lib/pubid/bsi/identifiers/expert_commentary.rb +2 -18
  98. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +0 -47
  99. data/lib/pubid/bsi/identifiers/flex.rb +0 -35
  100. data/lib/pubid/bsi/identifiers/handbook.rb +1 -15
  101. data/lib/pubid/bsi/identifiers/index.rb +0 -32
  102. data/lib/pubid/bsi/identifiers/method.rb +0 -41
  103. data/lib/pubid/bsi/identifiers/national_annex.rb +4 -29
  104. data/lib/pubid/bsi/identifiers/practice_guide.rb +1 -6
  105. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +2 -54
  106. data/lib/pubid/bsi/identifiers/published_document.rb +2 -54
  107. data/lib/pubid/bsi/identifiers/section.rb +0 -30
  108. data/lib/pubid/bsi/identifiers/set.rb +3 -20
  109. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +0 -9
  110. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -24
  111. data/lib/pubid/bsi/identifiers/supplementary_index.rb +0 -46
  112. data/lib/pubid/bsi/identifiers/technical_specification.rb +2 -47
  113. data/lib/pubid/bsi/identifiers/test_method.rb +0 -32
  114. data/lib/pubid/bsi/identifiers/value_added_publication.rb +2 -17
  115. data/lib/pubid/bsi/identifiers.rb +0 -1
  116. data/lib/pubid/bsi/renderer.rb +1050 -0
  117. data/lib/pubid/bsi/single_identifier.rb +33 -78
  118. data/lib/pubid/bsi/urn_generator.rb +2 -3
  119. data/lib/pubid/bsi/urn_parser.rb +52 -0
  120. data/lib/pubid/bsi.rb +232 -2
  121. data/lib/pubid/builder/base.rb +57 -10
  122. data/lib/pubid/bundled_identifier.rb +0 -1
  123. data/lib/pubid/ccsds/builder.rb +4 -3
  124. data/lib/pubid/ccsds/identifier.rb +53 -68
  125. data/lib/pubid/ccsds/identifiers/base.rb +11 -61
  126. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  127. data/lib/pubid/ccsds/parser.rb +4 -2
  128. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  129. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  130. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  131. data/lib/pubid/ccsds.rb +39 -1
  132. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  133. data/lib/pubid/cen_cenelec/identifier.rb +11 -40
  134. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +9 -4
  135. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +0 -10
  136. data/lib/pubid/cen_cenelec/identifiers/base.rb +2 -45
  137. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  138. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  139. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +0 -27
  140. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +0 -15
  141. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +2 -8
  143. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  144. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +0 -4
  145. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  146. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  147. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  148. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  149. data/lib/pubid/cen_cenelec/single_identifier.rb +9 -90
  150. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  151. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  152. data/lib/pubid/cen_cenelec.rb +172 -1
  153. data/lib/pubid/cie/components/code.rb +8 -0
  154. data/lib/pubid/cie/identifier.rb +10 -57
  155. data/lib/pubid/cie/single_identifier.rb +4 -4
  156. data/lib/pubid/cie/urn_parser.rb +28 -0
  157. data/lib/pubid/cie.rb +47 -1
  158. data/lib/pubid/components/adoption.rb +104 -0
  159. data/lib/pubid/components/code.rb +22 -8
  160. data/lib/pubid/components/date.rb +23 -16
  161. data/lib/pubid/components/edition.rb +9 -6
  162. data/lib/pubid/components/iteration.rb +32 -0
  163. data/lib/pubid/components/language.rb +6 -4
  164. data/lib/pubid/components/locality.rb +10 -1
  165. data/lib/pubid/components/publisher.rb +9 -6
  166. data/lib/pubid/components/relationship.rb +151 -0
  167. data/lib/pubid/components/stage.rb +5 -14
  168. data/lib/pubid/components/supplement.rb +184 -0
  169. data/lib/pubid/components/type.rb +5 -15
  170. data/lib/pubid/components/typed_stage.rb +10 -11
  171. data/lib/pubid/components.rb +4 -1
  172. data/lib/pubid/core/update_codes.rb +28 -7
  173. data/lib/pubid/csa/identifier.rb +9 -59
  174. data/lib/pubid/csa/identifiers/base.rb +0 -123
  175. data/lib/pubid/csa/identifiers/cec.rb +0 -103
  176. data/lib/pubid/csa/identifiers/series.rb +0 -104
  177. data/lib/pubid/csa/renderer.rb +292 -0
  178. data/lib/pubid/csa/single_identifier.rb +1 -1
  179. data/lib/pubid/csa/urn_generator.rb +1 -1
  180. data/lib/pubid/csa/urn_parser.rb +33 -0
  181. data/lib/pubid/csa.rb +46 -1
  182. data/lib/pubid/etsi/components/code.rb +10 -9
  183. data/lib/pubid/etsi/components/version.rb +0 -5
  184. data/lib/pubid/etsi/identifier.rb +4 -55
  185. data/lib/pubid/etsi/identifiers/base.rb +31 -27
  186. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +1 -11
  187. data/lib/pubid/etsi/renderer.rb +42 -0
  188. data/lib/pubid/etsi/urn_parser.rb +34 -0
  189. data/lib/pubid/etsi.rb +44 -1
  190. data/lib/pubid/export/exporter.rb +4 -46
  191. data/lib/pubid/export/flavor_exporter.rb +111 -278
  192. data/lib/pubid/export.rb +0 -6
  193. data/lib/pubid/identifier.rb +92 -18
  194. data/lib/pubid/identifier_metadata.rb +1 -1
  195. data/lib/pubid/idf/builder.rb +3 -3
  196. data/lib/pubid/idf/identifier.rb +7 -66
  197. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  198. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  199. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  200. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  201. data/lib/pubid/idf/parser.rb +3 -2
  202. data/lib/pubid/idf/renderer.rb +84 -0
  203. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  204. data/lib/pubid/idf/urn_generator.rb +4 -39
  205. data/lib/pubid/idf/urn_parser.rb +25 -0
  206. data/lib/pubid/idf.rb +55 -1
  207. data/lib/pubid/iec/builder.rb +46 -64
  208. data/lib/pubid/iec/components/code.rb +8 -32
  209. data/lib/pubid/iec/components/publisher.rb +0 -1
  210. data/lib/pubid/iec/components.rb +14 -0
  211. data/lib/pubid/iec/identifier.rb +251 -213
  212. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  213. data/lib/pubid/iec/identifiers/base.rb +5 -33
  214. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  215. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  216. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +23 -26
  217. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  218. data/lib/pubid/iec/identifiers/fragment_identifier.rb +35 -24
  219. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  220. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  221. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  222. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  223. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  224. data/lib/pubid/iec/identifiers/sheet_identifier.rb +17 -11
  225. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  226. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  227. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  228. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  229. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  230. data/lib/pubid/iec/identifiers/test_report_form.rb +3 -35
  231. data/lib/pubid/iec/identifiers/vap_identifier.rb +24 -21
  232. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  233. data/lib/pubid/iec/identifiers/working_document.rb +2 -50
  234. data/lib/pubid/iec/identifiers.rb +30 -0
  235. data/lib/pubid/iec/parser.rb +13 -12
  236. data/lib/pubid/iec/renderer.rb +254 -0
  237. data/lib/pubid/iec/single_identifier.rb +6 -12
  238. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  239. data/lib/pubid/iec/urn_generator.rb +3 -3
  240. data/lib/pubid/iec/urn_parser.rb +3 -3
  241. data/lib/pubid/iec.rb +43 -67
  242. data/lib/pubid/ieee/builder.rb +12 -12
  243. data/lib/pubid/ieee/components/code.rb +8 -0
  244. data/lib/pubid/ieee/components/draft.rb +14 -0
  245. data/lib/pubid/ieee/components/relationship.rb +5 -149
  246. data/lib/pubid/ieee/identifier.rb +5 -52
  247. data/lib/pubid/ieee/identifiers/adopted_standard.rb +0 -9
  248. data/lib/pubid/ieee/identifiers/base.rb +221 -556
  249. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +0 -10
  250. data/lib/pubid/ieee/identifiers/corrigendum.rb +0 -12
  251. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +0 -10
  252. data/lib/pubid/ieee/identifiers/dual_identifier.rb +0 -4
  253. data/lib/pubid/ieee/identifiers/dual_published.rb +0 -4
  254. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +0 -9
  255. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +0 -10
  256. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  257. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +0 -18
  258. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +0 -6
  259. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  260. data/lib/pubid/ieee/identifiers/redlined_standard.rb +0 -7
  261. data/lib/pubid/ieee/identifiers/si_standard.rb +0 -38
  262. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  263. data/lib/pubid/ieee/pre_parser.rb +301 -0
  264. data/lib/pubid/ieee/renderer.rb +307 -0
  265. data/lib/pubid/ieee/urn_parser.rb +34 -0
  266. data/lib/pubid/ieee.rb +66 -1
  267. data/lib/pubid/ieee_debug.rb +0 -1
  268. data/lib/pubid/iho/builder.rb +2 -2
  269. data/lib/pubid/iho/identifier.rb +7 -59
  270. data/lib/pubid/iho/identifiers/base.rb +64 -31
  271. data/lib/pubid/iho/parser.rb +3 -3
  272. data/lib/pubid/iho/renderer.rb +30 -0
  273. data/lib/pubid/iho/urn_generator.rb +2 -2
  274. data/lib/pubid/iho/urn_parser.rb +58 -0
  275. data/lib/pubid/iho.rb +52 -1
  276. data/lib/pubid/iso/builder.rb +55 -53
  277. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  278. data/lib/pubid/iso/components/code.rb +7 -19
  279. data/lib/pubid/iso/components/publisher.rb +10 -8
  280. data/lib/pubid/iso/components.rb +2 -4
  281. data/lib/pubid/iso/identifier.rb +219 -252
  282. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  283. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  284. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  285. data/lib/pubid/iso/identifiers/data.rb +0 -1
  286. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  287. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  288. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  289. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  290. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  291. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  292. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  293. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  294. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  295. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  296. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  297. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  298. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  299. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  300. data/lib/pubid/iso/identifiers.rb +0 -1
  301. data/lib/pubid/iso/normalizer.rb +89 -0
  302. data/lib/pubid/iso/parser.rb +22 -4
  303. data/lib/pubid/iso/single_identifier.rb +0 -4
  304. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  305. data/lib/pubid/iso/urn_generator.rb +66 -182
  306. data/lib/pubid/iso/urn_parser.rb +12 -7
  307. data/lib/pubid/iso.rb +177 -2
  308. data/lib/pubid/itu/builder.rb +0 -12
  309. data/lib/pubid/itu/components/code.rb +9 -7
  310. data/lib/pubid/itu/components/sector.rb +15 -4
  311. data/lib/pubid/itu/components/series.rb +0 -4
  312. data/lib/pubid/itu/components.rb +11 -0
  313. data/lib/pubid/itu/identifier.rb +4 -116
  314. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  315. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  316. data/lib/pubid/itu/identifiers/base.rb +124 -128
  317. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  318. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  319. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  320. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  321. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  322. data/lib/pubid/itu/urn_parser.rb +23 -0
  323. data/lib/pubid/itu.rb +44 -1
  324. data/lib/pubid/jcgm/builder.rb +16 -8
  325. data/lib/pubid/jcgm/identifier.rb +0 -43
  326. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -9
  327. data/lib/pubid/jcgm/identifiers/gum_guide.rb +0 -12
  328. data/lib/pubid/jcgm/renderer.rb +68 -0
  329. data/lib/pubid/jcgm/single_identifier.rb +0 -8
  330. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  331. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  332. data/lib/pubid/jcgm.rb +43 -2
  333. data/lib/pubid/jis/builder.rb +44 -52
  334. data/lib/pubid/jis/identifier.rb +120 -46
  335. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  336. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  337. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  338. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  339. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  340. data/lib/pubid/jis/identifiers.rb +1 -1
  341. data/lib/pubid/jis/parser.rb +31 -5
  342. data/lib/pubid/jis/renderer.rb +69 -0
  343. data/lib/pubid/jis/single_identifier.rb +6 -12
  344. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  345. data/lib/pubid/jis/urn_parser.rb +23 -0
  346. data/lib/pubid/jis.rb +42 -2
  347. data/lib/pubid/nist/builder.rb +63 -1871
  348. data/lib/pubid/nist/caster.rb +1272 -0
  349. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  350. data/lib/pubid/nist/components/code.rb +9 -20
  351. data/lib/pubid/nist/components/supplement.rb +2 -2
  352. data/lib/pubid/nist/components.rb +0 -1
  353. data/lib/pubid/nist/identifier.rb +8 -60
  354. data/lib/pubid/nist/identifiers/base.rb +564 -492
  355. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  356. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  358. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  359. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  360. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
  361. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  362. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
  363. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  364. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  365. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  366. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  367. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  368. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  369. data/lib/pubid/nist/identifiers/report.rb +4 -2
  370. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  371. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  372. data/lib/pubid/nist/identifiers.rb +1 -0
  373. data/lib/pubid/nist/parser.rb +62 -452
  374. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  375. data/lib/pubid/nist/preprocessor.rb +428 -0
  376. data/lib/pubid/nist/renderer.rb +43 -0
  377. data/lib/pubid/nist/router.rb +148 -0
  378. data/lib/pubid/nist/series/base.rb +58 -0
  379. data/lib/pubid/nist/series/crpl.rb +13 -0
  380. data/lib/pubid/nist/series/fips.rb +14 -0
  381. data/lib/pubid/nist/series/ir.rb +60 -0
  382. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  383. data/lib/pubid/nist/series/mono.rb +19 -0
  384. data/lib/pubid/nist/series/ncstar.rb +20 -0
  385. data/lib/pubid/nist/series.rb +49 -0
  386. data/lib/pubid/nist/supplement_identifier.rb +3 -1
  387. data/lib/pubid/nist/urn_parser.rb +67 -0
  388. data/lib/pubid/nist.rb +86 -4
  389. data/lib/pubid/oiml/builder.rb +21 -3
  390. data/lib/pubid/oiml/components/code.rb +17 -0
  391. data/lib/pubid/oiml/identifier.rb +40 -46
  392. data/lib/pubid/oiml/identifiers/annex.rb +13 -46
  393. data/lib/pubid/oiml/identifiers/errata.rb +15 -0
  394. data/lib/pubid/oiml/identifiers.rb +1 -1
  395. data/lib/pubid/oiml/parser.rb +59 -12
  396. data/lib/pubid/oiml/renderer.rb +171 -0
  397. data/lib/pubid/oiml/single_identifier.rb +61 -42
  398. data/lib/pubid/oiml/supplement_identifier.rb +31 -17
  399. data/lib/pubid/oiml/urn_generator.rb +0 -8
  400. data/lib/pubid/oiml/urn_parser.rb +22 -0
  401. data/lib/pubid/oiml.rb +42 -1
  402. data/lib/pubid/plateau/identifier.rb +4 -55
  403. data/lib/pubid/plateau/identifiers/base.rb +45 -36
  404. data/lib/pubid/plateau/identifiers/handbook.rb +0 -6
  405. data/lib/pubid/plateau/identifiers/technical_report.rb +0 -4
  406. data/lib/pubid/plateau/renderer.rb +51 -0
  407. data/lib/pubid/plateau/supplement_identifier.rb +0 -4
  408. data/lib/pubid/plateau/urn_parser.rb +43 -0
  409. data/lib/pubid/plateau.rb +43 -1
  410. data/lib/pubid/renderers/directives_renderer.rb +22 -8
  411. data/lib/pubid/renderers/guide_renderer.rb +4 -2
  412. data/lib/pubid/renderers/human_readable.rb +18 -7
  413. data/lib/pubid/rendering/context.rb +28 -19
  414. data/lib/pubid/rendering.rb +0 -3
  415. data/lib/pubid/sae/components/date.rb +8 -0
  416. data/lib/pubid/sae/components/type.rb +5 -1
  417. data/lib/pubid/sae/identifier.rb +4 -35
  418. data/lib/pubid/sae/identifiers/base.rb +26 -31
  419. data/lib/pubid/sae/renderer.rb +36 -0
  420. data/lib/pubid/sae/urn_generator.rb +2 -10
  421. data/lib/pubid/sae/urn_parser.rb +36 -0
  422. data/lib/pubid/sae.rb +42 -1
  423. data/lib/pubid/urn_generator/base.rb +12 -12
  424. data/lib/pubid/urn_parser/base.rb +81 -0
  425. data/lib/pubid/urn_parser/errors.rb +9 -0
  426. data/lib/pubid/urn_parser.rb +14 -0
  427. data/lib/pubid/version.rb +1 -1
  428. data/lib/pubid.rb +45 -7
  429. data/lib/tasks/export.rake +6 -5
  430. data/lib/tasks/website-data.json +1940 -1882
  431. metadata +75 -45
  432. data/lib/pubid/amca/scheme.rb +0 -16
  433. data/lib/pubid/ansi/scheme.rb +0 -15
  434. data/lib/pubid/api/scheme.rb +0 -66
  435. data/lib/pubid/ashrae/scheme.rb +0 -53
  436. data/lib/pubid/asme/scheme.rb +0 -37
  437. data/lib/pubid/astm/scheme.rb +0 -55
  438. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  439. data/lib/pubid/bsi/scheme.rb +0 -243
  440. data/lib/pubid/ccsds/scheme.rb +0 -57
  441. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  442. data/lib/pubid/cie/scheme.rb +0 -64
  443. data/lib/pubid/components/factory.rb +0 -50
  444. data/lib/pubid/csa/scheme.rb +0 -44
  445. data/lib/pubid/etsi/scheme.rb +0 -42
  446. data/lib/pubid/export/data_class_exporter.rb +0 -59
  447. data/lib/pubid/export/ieee_exporter.rb +0 -78
  448. data/lib/pubid/export/itu_exporter.rb +0 -66
  449. data/lib/pubid/export/nist_exporter.rb +0 -64
  450. data/lib/pubid/export/registry_exporter.rb +0 -90
  451. data/lib/pubid/export/scheme_exporter.rb +0 -70
  452. data/lib/pubid/identifier_registry.rb +0 -198
  453. data/lib/pubid/idf/scheme.rb +0 -61
  454. data/lib/pubid/iec/scheme.rb +0 -71
  455. data/lib/pubid/ieee/scheme.rb +0 -90
  456. data/lib/pubid/iho/scheme.rb +0 -29
  457. data/lib/pubid/iso/identifiers/base.rb +0 -115
  458. data/lib/pubid/iso/scheme.rb +0 -193
  459. data/lib/pubid/itu/scheme.rb +0 -174
  460. data/lib/pubid/jcgm/scheme.rb +0 -60
  461. data/lib/pubid/jis/components/code.rb +0 -59
  462. data/lib/pubid/jis/identifiers/base.rb +0 -72
  463. data/lib/pubid/jis/scheme.rb +0 -49
  464. data/lib/pubid/nist/components/publisher.rb +0 -24
  465. data/lib/pubid/nist/scheme.rb +0 -199
  466. data/lib/pubid/oiml/identifiers/base.rb +0 -36
  467. data/lib/pubid/oiml/scheme.rb +0 -46
  468. data/lib/pubid/plateau/scheme.rb +0 -45
  469. data/lib/pubid/rendering/base.rb +0 -73
  470. data/lib/pubid/rendering/common.rb +0 -211
  471. data/lib/pubid/rendering/format.rb +0 -25
  472. data/lib/pubid/sae/scheme.rb +0 -47
  473. data/lib/pubid/scheme.rb +0 -219
@@ -15,56 +15,75 @@ module Pubid
15
15
  "short"
16
16
  } # Track parsed format
17
17
 
18
- # Type is determined by the subclass
19
- def type
20
- type_string
18
+ # Serialization delta on top of Oiml::Identifier's shared block. The
19
+ # `code` (number/part/subpart/suffix) and `date` (year) components are
20
+ # flattened to top-level keys rather than nested hashes, mirroring ISO
21
+ # (lib/pubid/iso/identifier.rb). `type` is intentionally omitted
22
+ # (recomputed from the class on load).
23
+ key_value do
24
+ map "publisher", to: :publisher
25
+ map "number", with: { to: :number_to_kv, from: :number_from_kv }
26
+ map "part", with: { to: :part_to_kv, from: :part_from_kv }
27
+ map "subpart", with: { to: :subpart_to_kv, from: :subpart_from_kv }
28
+ map "suffix", with: { to: :suffix_to_kv, from: :suffix_from_kv }
29
+ map "space_suffix",
30
+ with: { to: :space_suffix_to_kv, from: :space_suffix_from_kv }
31
+ map "year", with: { to: :year_to_kv, from: :year_from_kv }
32
+ map "edition", to: :edition
33
+ map "stage", to: :stage
34
+ map "iteration", to: :iteration
21
35
  end
22
36
 
23
- def to_s(format: nil)
24
- # Use parsed format if not explicitly overridden
25
- format ||= (parsed_format == "long" ? :long : :short)
37
+ # --- code components flattened to top-level keys ---
38
+ def number_to_kv(model, doc) = emit_kv(doc, "number", model.code&.number)
39
+ def number_from_kv(model, value) = code_for(model).number = value.to_s
40
+ def part_to_kv(model, doc) = emit_kv(doc, "part", model.code&.part)
41
+ def part_from_kv(model, value) = code_for(model).part = value.to_s
42
+ def subpart_to_kv(model, doc) = emit_kv(doc, "subpart", model.code&.subpart)
43
+ def subpart_from_kv(model, value) = code_for(model).subpart = value.to_s
44
+ def suffix_to_kv(model, doc) = emit_kv(doc, "suffix", model.code&.suffix)
45
+ def suffix_from_kv(model, value) = code_for(model).suffix = value.to_s
26
46
 
27
- result = "#{publisher} #{type_string} #{code}"
47
+ def space_suffix_to_kv(model, doc)
48
+ return unless model.code&.space_suffix
28
49
 
29
- # Track if we're using Edition format for language spacing
30
- using_edition_format = false
50
+ doc.add_child(
51
+ Lutaml::KeyValue::DataModel::Element.new("space_suffix", true),
52
+ )
53
+ end
31
54
 
32
- # Add edition/date portion
33
- if edition && date
34
- # Has edition number: "6th Edition 2015"
35
- result += " #{edition} Edition #{date.year}"
36
- using_edition_format = true
37
- elsif edition
38
- # Edition without year (shouldn't happen but handle it)
39
- result += " #{edition}"
40
- using_edition_format = true
41
- elsif date
42
- # Date without edition number
43
- if format == :long
44
- result += " Edition #{date.year}"
45
- using_edition_format = true
46
- else
47
- result += ":#{date.year}"
48
- end
49
- end
55
+ def space_suffix_from_kv(model, value)
56
+ code_for(model).space_suffix = value
57
+ end
50
58
 
51
- # Add draft stage if present (iteration + stage)
52
- if stage || iteration
53
- result += " "
54
- result += iteration.to_s if iteration
55
- result += stage.to_s if stage
56
- end
59
+ # --- date flattened to a top-level year ---
60
+ def year_to_kv(model, doc) = emit_kv(doc, "year", model.date&.year)
57
61
 
58
- # Add language portion - depends on format
59
- if language
60
- result += if using_edition_format || parsed_format == "short_with_space"
61
- " (#{language})"
62
- else
63
- "(#{language})"
64
- end
65
- end
62
+ def year_from_kv(model, value)
63
+ (model.date ||= Pubid::Components::Date.new).year = value.to_s
64
+ end
65
+
66
+ def emit_kv(doc, key, value)
67
+ return if value.nil? || value.to_s.empty?
68
+
69
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, value.to_s))
70
+ end
71
+
72
+ def code_for(model)
73
+ model.code ||= Components::Code.new
74
+ end
75
+
76
+ attr_reader :requested_format
77
+
78
+ # Type is determined by the subclass
79
+ def type
80
+ type_string
81
+ end
66
82
 
67
- result
83
+ def to_s(format: nil, **opts)
84
+ # Store requested format so the renderer can access it
85
+ @requested_format = format
86
+ render(format: :human, **opts)
68
87
  end
69
88
 
70
89
  def edition_portion
@@ -5,33 +5,47 @@ module Pubid
5
5
  class SupplementIdentifier < Identifier
6
6
  # Base class for OIML supplements (amendments, annexes)
7
7
  # These wrap a base identifier like ISO amendments
8
- attribute :base_identifier, Oiml::Identifier
8
+ attribute :base_identifier, Oiml::Identifier, polymorphic: true
9
9
  attribute :year, :string
10
10
  attribute :language, :string
11
+ # True for the trailing-word shorthand ("OIML R 138:2009 Amendment"),
12
+ # where the supplement word is appended after a dated base instead of the
13
+ # "Amendment (YYYY) to BASE" prose form. The word itself comes from the
14
+ # concrete class (#supplement_type), so only this flag is stored.
15
+ attribute :trailing, :boolean, default: false
11
16
  attribute :parsed_format, :string, default: -> {
12
17
  "short"
13
18
  } # Track supplement's parsed format
14
19
 
15
- def to_s(format: :short)
16
- # Determine base format: explicit parameter takes priority, else use parsed format
17
- base_format = if format && format != :short
18
- format # Use explicit override
19
- elsif base_identifier.class.attributes.key?(:parsed_format) && base_identifier.parsed_format == "long"
20
- :long
21
- else
22
- :short
23
- end
20
+ # Serialization delta on top of Oiml::Identifier's shared block. The
21
+ # nested base_identifier is (de)serialized recursively through the
22
+ # polymorphic router so its own `_type` selects the right subclass.
23
+ key_value do
24
+ map "base_identifier",
25
+ with: { to: :base_identifier_to_kv, from: :base_identifier_from_kv }
26
+ map "year", to: :year
27
+ map "trailing", to: :trailing
28
+ end
29
+
30
+ def base_identifier_to_kv(model, doc)
31
+ base = model.base_identifier
32
+ return unless base
24
33
 
25
- # Render base with determined format (preserves Edition vs colon)
26
- base_str = base_identifier.to_s(format: base_format)
27
- base_str = base_str.sub(/\s*\([^)]+\)\s*$/, "").strip # Remove language from base
34
+ doc.add_child(
35
+ Lutaml::KeyValue::DataModel::Element.new("base_identifier",
36
+ base.to_hash),
37
+ )
38
+ end
28
39
 
29
- result = "#{supplement_type} (#{year}) to #{base_str}"
40
+ def base_identifier_from_kv(model, value)
41
+ model.base_identifier = ::Pubid::Oiml::Identifier.from_hash(value) if value
42
+ end
30
43
 
31
- # Supplements ALWAYS add space before their language
32
- result += " (#{language})" if language
44
+ attr_reader :requested_format
33
45
 
34
- result
46
+ def to_s(format: nil, **opts)
47
+ @requested_format = format
48
+ render(format: :human, **opts)
35
49
  end
36
50
 
37
51
  # Subclasses override this
@@ -15,14 +15,6 @@ module Pubid
15
15
  identifier.code.to_s
16
16
  end
17
17
 
18
- def urn_year
19
- if identifier.date&.year
20
- return identifier.date.year.to_s
21
- end
22
-
23
- nil
24
- end
25
-
26
18
  def urn_stage
27
19
  identifier.stage&.to_s&.downcase
28
20
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ # Parses OIML URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits: `urn:oiml:{type}:{number}[-{part}]` where type
8
+ # is the lowercase document class (r for Recommendation, d for Document).
9
+ #
10
+ # Examples:
11
+ # - urn:oiml:r:111-1 → OIML R 111-1
12
+ # - urn:oiml:d:1 → OIML D 1
13
+ class UrnParser < Pubid::UrnParser::Base
14
+ def parse_urn(urn)
15
+ body = strip_namespace(urn)
16
+ parts = split_parts(body)
17
+ type_token, number = parts
18
+ flavor_parse("OIML #{type_token.upcase} #{number}")
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/pubid/oiml.rb CHANGED
@@ -7,10 +7,11 @@ module Pubid
7
7
  autoload :Identifier, "#{__dir__}/oiml/identifier"
8
8
  autoload :Identifiers, "#{__dir__}/oiml/identifiers"
9
9
  autoload :Parser, "#{__dir__}/oiml/parser"
10
- autoload :Scheme, "#{__dir__}/oiml/scheme"
10
+ autoload :Renderer, "#{__dir__}/oiml/renderer"
11
11
  autoload :SingleIdentifier, "#{__dir__}/oiml/single_identifier"
12
12
  autoload :SupplementIdentifier, "#{__dir__}/oiml/supplement_identifier"
13
13
  autoload :UrnGenerator, "#{__dir__}/oiml/urn_generator"
14
+ autoload :UrnParser, "#{__dir__}/oiml/urn_parser"
14
15
 
15
16
  def self.parse(identifier)
16
17
  parser = Parser.new
@@ -19,6 +20,46 @@ module Pubid
19
20
  parsed = parser.parse(identifier)
20
21
  builder.build(parsed)
21
22
  end
23
+
24
+ # Per-flavor format registry: inherits global formats, overrides :human
25
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
26
+ Identifier.format_registry.register(:human, renderer: Oiml::Renderer)
27
+
28
+ # Auto-discover all identifier types from the Identifiers namespace
29
+ # @return [Array<Class>] identifier classes that define a self.type Hash
30
+ def self.identifier_types
31
+ @identifier_types ||= Identifiers.constants
32
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
33
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
34
+ .select { |c| c.type.is_a?(Hash) }
35
+ end
36
+
37
+ # Build typed stage index from identifier types
38
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
39
+ def self.all_typed_stages
40
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
41
+ if klass.const_defined?(:TYPED_STAGES)
42
+ klass.const_get(:TYPED_STAGES)
43
+ else
44
+ []
45
+ end
46
+ end
47
+ end
48
+
49
+ # Lookup: type code -> identifier class
50
+ # @param code [String, Symbol] the type key to find
51
+ # @return [Class, nil] the matching identifier class
52
+ def self.locate_type(code)
53
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
54
+ end
55
+
56
+ # Lookup: abbreviation -> typed stage
57
+ # @param abbr [String, Symbol] the abbreviation to find
58
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
59
+ def self.locate_stage(abbr)
60
+ abbr_str = abbr.to_s.upcase
61
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
62
+ end
22
63
  end
23
64
  end
24
65
 
@@ -1,57 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Pubid
4
- module Plateau
5
- # Plateau factory entry point. `.parse` lives on `Pubid::Plateau`
6
- # itself for historical reasons; this module hosts `.create` for API
7
- # consistency with the other pubid flavors.
8
- module Identifier
9
- # Delegate to the flavor module so callers can use
10
- # `Pubid::Plateau::Identifier.parse` consistently with other flavors.
11
- def self.parse(identifier)
12
- Pubid::Plateau.parse(identifier)
13
- end
14
-
15
- # Factory that builds a PLATEAU identifier from a hash of primitives.
16
- #
17
- # Dispatch on `:type`:
18
- # * `:handbook` (default) → Identifiers::Handbook
19
- # * `:technical_report` / `:tr` → Identifiers::TechnicalReport
20
- # * `:annex` → Identifiers::Annex
21
- #
22
- # Attributes are plain integers/strings — no Component wrapping.
23
- # `:publisher` is silently ignored (PLATEAU is hardcoded).
24
- def self.create(type: nil, **opts)
25
- klass = resolve_create_class(type)
26
- klass.new(**coerce_create_attrs(opts, klass: klass))
27
- end
28
-
29
- def self.resolve_create_class(type)
30
- case type&.to_sym
31
- when nil, :handbook
32
- Identifiers::Handbook
33
- when :technical_report, :tr
34
- Identifiers::TechnicalReport
35
- when :annex
36
- Identifiers::Annex
37
- else
38
- raise ArgumentError, "Unknown PLATEAU type: #{type.inspect}"
39
- end
40
- end
41
-
42
- def self.coerce_create_attrs(opts, klass:)
43
- attrs = {}
44
- attrs[:number] = opts[:number].to_i if opts[:number]
45
- attrs[:annex] = opts[:annex].to_i if opts[:annex]
46
- # :edition exists only on Handbook (and possibly TechnicalReport);
47
- # silently drop on Annex.
48
- if opts[:edition] && klass.attributes.key?(:edition)
49
- attrs[:edition] = opts[:edition].to_s
50
- end
51
- # TODO(create-shim): :publisher silently ignored (PLATEAU hardcoded).
52
- attrs
53
- end
54
- private_class_method :resolve_create_class, :coerce_create_attrs
55
- end
56
- end
57
- end
3
+ # Pubid::Plateau::Identifier is the PLATEAU base class (a real Pubid::Identifier
4
+ # subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
5
+ # live in identifiers/base.rb. This file just ensures it is loaded.
6
+ require_relative "identifiers/base"
@@ -2,50 +2,59 @@
2
2
 
3
3
  module Pubid
4
4
  module Plateau
5
- module Identifiers
6
- # Base class for all PLATEAU identifiers
7
- class Base < Pubid::Identifier
8
- # Generate URN for this identifier
9
- #
10
- # @return [String] URN representation
11
- attribute :number, :integer
12
- attribute :annex, :integer, default: -> {}
13
-
14
- def publisher
15
- "PLATEAU"
16
- end
5
+ # Base class for all PLATEAU identifiers. Canonical name
6
+ # Pubid::Plateau::Identifier (Identifiers::Base is a back-compat alias).
7
+ class Identifier < ::Pubid::Identifier
8
+ # Delegate to the flavor module so callers can use
9
+ # `Pubid::Plateau::Identifier.parse` consistently with other flavors.
10
+ def self.parse(identifier)
11
+ Pubid::Plateau.parse(identifier)
12
+ end
17
13
 
18
- # Subclasses must implement type_string
19
- def type_string
20
- raise NotImplementedError, "Subclasses must implement type_string"
21
- end
14
+ attribute :number, :integer
15
+ attribute :annex, :integer, default: -> {}
22
16
 
23
- def formatted_number
24
- "#%02d" % number
25
- end
17
+ # Stored as a plain string (always "PLATEAU") so it round-trips through
18
+ # to_hash/from_hash. Was a `def publisher` method, which made lutaml
19
+ # serialize a String against the Components::Publisher attribute.
20
+ attribute :publisher, :string, default: -> { "PLATEAU" }
26
21
 
27
- def formatted_annex
28
- annex ? "-#{annex}" : ""
29
- end
22
+ # Subclasses must implement type_string
23
+ def type_string
24
+ raise NotImplementedError, "Subclasses must implement type_string"
25
+ end
26
+
27
+ def formatted_number
28
+ "#%02d" % number
29
+ end
30
+
31
+ def formatted_annex
32
+ annex ? "-#{annex}" : ""
33
+ end
30
34
 
31
- def ==(other)
32
- return false unless other.class == self.class
35
+ def ==(other)
36
+ return false unless other.class == self.class
33
37
 
34
- number == other.number &&
35
- annex == other.annex
36
- end
38
+ number == other.number &&
39
+ annex == other.annex
40
+ end
37
41
 
38
- # Include type_string and annex in serialization for round-trip compatibility
39
- def base_hash
40
- hash = super
41
- if self.class.attributes.key?(:type_string) && type_string
42
- hash[:type] =
43
- type_string
44
- end
45
- hash[:annex] = annex if annex
46
- hash
42
+ # Include type_string and annex in serialization for round-trip compatibility
43
+ def base_hash
44
+ hash = super
45
+ if self.class.attributes.key?(:type_string) && type_string
46
+ hash[:type] =
47
+ type_string
47
48
  end
49
+ hash[:annex] = annex if annex
50
+ hash
48
51
  end
49
52
  end
53
+
54
+ module Identifiers
55
+ # Backward-compatible alias: PLATEAU's base class used to be
56
+ # Pubid::Plateau::Identifiers::Base. It is now Pubid::Plateau::Identifier.
57
+ Base = Pubid::Plateau::Identifier
58
+ end
50
59
  end
51
60
  end
@@ -13,12 +13,6 @@ module Pubid
13
13
  "Handbook"
14
14
  end
15
15
 
16
- def to_s
17
- result = "#{publisher} #{type_string} #{formatted_number}#{formatted_annex}"
18
- result += " #{formatted_edition}" if edition
19
- result
20
- end
21
-
22
16
  def formatted_edition
23
17
  "第#{edition}版"
24
18
  end
@@ -10,10 +10,6 @@ module Pubid
10
10
  def type_string
11
11
  "Technical Report"
12
12
  end
13
-
14
- def to_s
15
- "#{publisher} #{type_string} #{formatted_number}#{formatted_annex}"
16
- end
17
13
  end
18
14
  end
19
15
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Plateau
5
+ # Human-readable renderer for PLATEAU identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "PLATEAU Technical Report #01"
9
+ # "PLATEAU Handbook #00 第1.0版"
10
+ # "PLATEAU Handbook #01-1 Annex A"
11
+ #
12
+ # The renderer is registered as the `:human` format in the PLATEAU format
13
+ # registry and invoked via `render(format: :human)`.
14
+ class Renderer < ::Pubid::Renderers::Base
15
+ def render(context: nil, **opts)
16
+ id = @id
17
+
18
+ case id
19
+ when SupplementIdentifier
20
+ render_supplement(id)
21
+ when Identifiers::Handbook
22
+ render_handbook(id)
23
+ when Identifiers::TechnicalReport
24
+ render_technical_report(id)
25
+ else
26
+ render_base(id)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def render_base(id)
33
+ "#{id.publisher} #{id.type_string} #{id.formatted_number}#{id.formatted_annex}"
34
+ end
35
+
36
+ def render_technical_report(id)
37
+ "#{id.publisher} #{id.type_string} #{id.formatted_number}#{id.formatted_annex}"
38
+ end
39
+
40
+ def render_handbook(id)
41
+ result = "#{id.publisher} #{id.type_string} #{id.formatted_number}#{id.formatted_annex}"
42
+ result += " #{id.formatted_edition}" if id.edition
43
+ result
44
+ end
45
+
46
+ def render_supplement(id)
47
+ "#{id.base_identifier} #{id.supplement_string}"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -19,10 +19,6 @@ module Pubid
19
19
  raise NotImplementedError, "Subclasses must implement supplement_string"
20
20
  end
21
21
 
22
- def to_s
23
- "#{base_identifier} #{supplement_string}"
24
- end
25
-
26
22
  # Override base_hash to extract edition, type, and annex from base_identifier
27
23
  def base_hash
28
24
  hash = super
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Plateau
5
+ # Parses Plateau URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:plateau:{type}:{number}[:{annex}]
9
+ #
10
+ # type is one of: handbook, tr (technical report), an (annex), or another
11
+ # lowercase type string. Annex is a zero-padded 2-digit string when present.
12
+ #
13
+ # Examples:
14
+ # - urn:plateau:handbook:00 → PLATEAU Handbook #00
15
+ # - urn:plateau:tr:01 → PLATEAU Technical Report #01
16
+ class UrnParser < Pubid::UrnParser::Base
17
+ TYPE_MAP = {
18
+ "handbook" => "Handbook",
19
+ "tr" => "Technical Report",
20
+ "an" => "Annex",
21
+ }.freeze
22
+
23
+ def parse_urn(urn)
24
+ body = strip_namespace(urn)
25
+ parts = split_parts(body)
26
+
27
+ type_token = parts.fetch(0)
28
+ number = parts.fetch(1)
29
+ annex = parts[2]
30
+
31
+ text = "PLATEAU #{display_type(type_token)} ##{number}"
32
+ text += "-#{annex}" if annex
33
+ flavor_parse(text)
34
+ end
35
+
36
+ private
37
+
38
+ def display_type(token)
39
+ TYPE_MAP.fetch(token) { token.capitalize }
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/pubid/plateau.rb CHANGED
@@ -8,9 +8,10 @@ module Pubid
8
8
  autoload :Identifier, "#{__dir__}/plateau/identifier"
9
9
  autoload :Identifiers, "#{__dir__}/plateau/identifiers"
10
10
  autoload :Parser, "#{__dir__}/plateau/parser"
11
- autoload :Scheme, "#{__dir__}/plateau/scheme"
11
+ autoload :Renderer, "#{__dir__}/plateau/renderer"
12
12
  autoload :SupplementIdentifier, "#{__dir__}/plateau/supplement_identifier"
13
13
  autoload :UrnGenerator, "#{__dir__}/plateau/urn_generator"
14
+ autoload :UrnParser, "#{__dir__}/plateau/urn_parser"
14
15
 
15
16
  def self.parse(input)
16
17
  # Apply legacy update_codes normalization first
@@ -19,6 +20,47 @@ module Pubid
19
20
  parsed = parser.parse(normalized)
20
21
  Builder.build(parsed)
21
22
  end
23
+
24
+ # Per-flavor format registry: inherits global formats, overrides :human
25
+ Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
26
+ Identifiers::Base.format_registry.register(:human, renderer: Plateau::Renderer)
27
+ SupplementIdentifier.format_registry = Identifiers::Base.format_registry
28
+
29
+ # Auto-discover all identifier types from the Identifiers namespace
30
+ # @return [Array<Class>] identifier classes that define a self.type Hash
31
+ def self.identifier_types
32
+ @identifier_types ||= Identifiers.constants
33
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
34
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
35
+ .select { |c| c.type.is_a?(Hash) }
36
+ end
37
+
38
+ # Build typed stage index from identifier types
39
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
40
+ def self.all_typed_stages
41
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
42
+ if klass.const_defined?(:TYPED_STAGES)
43
+ klass.const_get(:TYPED_STAGES)
44
+ else
45
+ []
46
+ end
47
+ end
48
+ end
49
+
50
+ # Lookup: type code -> identifier class
51
+ # @param code [String, Symbol] the type key to find
52
+ # @return [Class, nil] the matching identifier class
53
+ def self.locate_type(code)
54
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
55
+ end
56
+
57
+ # Lookup: abbreviation -> typed stage
58
+ # @param abbr [String, Symbol] the abbreviation to find
59
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
60
+ def self.locate_stage(abbr)
61
+ abbr_str = abbr.to_s.upcase
62
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
63
+ end
22
64
  end
23
65
  end
24
66