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
data/lib/pubid/nist.rb CHANGED
@@ -3,13 +3,51 @@
3
3
  module Pubid
4
4
  module Nist
5
5
  autoload :Builder, "#{__dir__}/nist/builder"
6
+ autoload :Caster, "#{__dir__}/nist/caster"
7
+ autoload :CircularSupplementBuilder, "#{__dir__}/nist/circular_supplement_builder"
6
8
  autoload :Components, "#{__dir__}/nist/components"
7
9
  autoload :Configuration, "#{__dir__}/nist/configuration"
10
+ autoload :Identifier, "#{__dir__}/nist/identifier"
8
11
  autoload :Identifiers, "#{__dir__}/nist/identifiers"
9
12
  autoload :Parser, "#{__dir__}/nist/parser"
10
- autoload :Scheme, "#{__dir__}/nist/scheme"
13
+ autoload :ParserOutputNormalizer, "#{__dir__}/nist/parser_output_normalizer"
14
+ autoload :Preprocessor, "#{__dir__}/nist/preprocessor"
15
+ autoload :Renderer, "#{__dir__}/nist/renderer"
16
+ autoload :Router, "#{__dir__}/nist/router"
17
+ autoload :Series, "#{__dir__}/nist/series"
11
18
  autoload :SupplementIdentifier, "#{__dir__}/nist/supplement_identifier"
12
19
  autoload :UrnGenerator, "#{__dir__}/nist/urn_generator"
20
+ autoload :UrnParser, "#{__dir__}/nist/urn_parser"
21
+
22
+ # Explicit registry of NIST identifier classes.
23
+ #
24
+ # NIST identifier classes use `typed_stages` (not the `self.type` Hash
25
+ # pattern used by CEN/JCGM/ANSI), so they cannot be auto-discovered.
26
+ # Identifiers::Base is the fallback for unmapped series (e.g. AMS, VTS)
27
+ # and must be excluded from typed-stage aggregation.
28
+ IDENTIFIER_TYPES = [
29
+ Identifiers::SpecialPublication,
30
+ Identifiers::FederalInformationProcessingStandards,
31
+ Identifiers::InteragencyReport,
32
+ Identifiers::Handbook,
33
+ Identifiers::TechnicalNote,
34
+ Identifiers::Circular,
35
+ Identifiers::CircularSupplement,
36
+ Identifiers::CrplReport,
37
+ Identifiers::Report,
38
+ Identifiers::Monograph,
39
+ Identifiers::MiscellaneousPublication,
40
+ Identifiers::GrantContractorReport,
41
+ Identifiers::Ncstar,
42
+ Identifiers::Owmwp,
43
+ Identifiers::Nsrds,
44
+ Identifiers::LetterCircular,
45
+ Identifiers::CommercialStandard,
46
+ Identifiers::CommercialStandardEmergency,
47
+ Identifiers::CommercialStandardsMonthly,
48
+ Identifiers::DatedDocument,
49
+ Identifiers::Base, # Fallback for unmapped series
50
+ ].freeze
13
51
 
14
52
  # Parse a NIST identifier string
15
53
  # @param identifier [String] the identifier string to parse
@@ -19,9 +57,8 @@ module Pubid
19
57
  # Note: We call the class method directly to ensure preprocessing is applied
20
58
  parsed = Parser.class_parse_with_preprocessing(identifier)
21
59
 
22
- # Use Scheme and Builder for clean architecture
23
- # ONE CLASS PER SERIES TYPE (like ISO)
24
- builder = Builder.new(Scheme)
60
+ # Builder is stateless lookups go through this module (Pubid::Nist)
61
+ builder = Builder.new
25
62
  builder.build(parsed)
26
63
  end
27
64
 
@@ -30,6 +67,48 @@ module Pubid
30
67
  def self.configuration
31
68
  @configuration ||= Configuration.new
32
69
  end
70
+
71
+ # Per-flavor format registry: inherits global formats, overrides :human
72
+ Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
73
+ Identifiers::Base.format_registry.register(:human, renderer: Nist::Renderer)
74
+
75
+ # All identifier classes for external consumption (export, website).
76
+ # Identifiers::Base is the fallback for unmapped series and is excluded
77
+ # from external type listings.
78
+ # @return [Array<Class>] identifier classes
79
+ def self.identifier_types
80
+ IDENTIFIER_TYPES.reject { |klass| klass == Identifiers::Base }
81
+ end
82
+
83
+ # Aggregate TYPED_STAGES from all identifier classes.
84
+ # Identifiers::Base is excluded because it has no typed stages and acts
85
+ # as the fallback for unmapped series.
86
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
87
+ def self.all_typed_stages
88
+ @all_typed_stages ||= identifier_types
89
+ .reject { |klass| klass == Identifiers::Base }
90
+ .flat_map(&:typed_stages)
91
+ .freeze
92
+ end
93
+
94
+ # Lookup: type code -> identifier class.
95
+ # Identifiers::Base is excluded so it never gets selected by type code.
96
+ # @param code [String, Symbol] the type code to find
97
+ # @return [Class, nil] the matching identifier class, or nil
98
+ def self.locate_type(code)
99
+ type_str = code.to_s
100
+ identifier_types
101
+ .reject { |klass| klass == Identifiers::Base }
102
+ .find { |klass| klass.typed_stages.any? { |ts| ts.type_code.to_s == type_str } }
103
+ end
104
+
105
+ # Lookup: abbreviation -> typed stage
106
+ # @param abbr [String, Symbol] the abbreviation to find
107
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
108
+ def self.locate_stage(abbr)
109
+ abbr_str = abbr.to_s.upcase
110
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
111
+ end
33
112
  end
34
113
  end
35
114
 
@@ -3,6 +3,12 @@
3
3
  module Pubid
4
4
  module Oiml
5
5
  module Components
6
+ # Code component for OIML identifiers.
7
+ #
8
+ # Stays independent of Pubid::Components::Code because OIML uses
9
+ # +number+ as the primary field (shared Code uses +value+). The
10
+ # shape is otherwise compatible; a future rename of +number+ →
11
+ # +value+ would let this become a subclass.
6
12
  class Code < Lutaml::Model::Serializable
7
13
  attribute :number, :string
8
14
  attribute :part, :string
@@ -14,6 +20,10 @@ module Pubid
14
20
  result += "-#{subpart}" if subpart
15
21
  result
16
22
  end
23
+
24
+ def render(context: nil)
25
+ to_s
26
+ end
17
27
  end
18
28
  end
19
29
  end
@@ -10,51 +10,9 @@ module Pubid
10
10
  letter ? "Annex #{letter}" : "Annexes"
11
11
  end
12
12
 
13
- def to_s(format: nil)
14
- # Determine base format from its parsed_format
15
- base_format = if base_identifier.class.attributes.key?(:parsed_format) && base_identifier.parsed_format == "long"
16
- :long
17
- else
18
- :short
19
- end
20
-
21
- # Use format parameter or annex's own parsed_format
22
- annex_format = if format
23
- format
24
- elsif self.class.attributes.key?(:parsed_format) && parsed_format == "long"
25
- :long
26
- else
27
- :short
28
- end
29
-
30
- # Annexes have different pattern than amendments
31
- base_str = base_identifier.to_s(format: base_format)
32
- result = base_str.sub(/:.*/, "").sub(/\s+Edition\s+\d{4}/, "").sub(
33
- /\(.*\)/, ""
34
- ).strip
35
- if letter
36
- # Specific annex: "OIML R 60 Annex A Edition 2013 (E)"
37
- result += " Annex #{letter}"
38
-
39
- result += " Edition #{year}" if year
40
-
41
- # Supplements ALWAYS use space before language
42
-
43
- else
44
- # General annexes: "OIML R 60 Annexes Edition 2021 (E)" or "OIML R 60 Annexes:2021 (E)"
45
- result += " Annexes"
46
-
47
- if year
48
- result += annex_format == :long ? " Edition #{year}" : ":#{year}"
49
- elsif base_identifier.date
50
- result += annex_format == :long ? " Edition #{base_identifier.date.year}" : ":#{base_identifier.date.year}"
51
- end
52
-
53
- # Supplements ALWAYS use space before language
54
-
55
- end
56
- result += " (#{language})" if language
57
- result
13
+ def to_s(format: nil, **opts)
14
+ @requested_format = format
15
+ render(format: :human, **opts)
58
16
  end
59
17
  end
60
18
  end
@@ -12,23 +12,8 @@ module Pubid
12
12
  attribute :iteration, :string
13
13
  attribute :language, :string
14
14
 
15
- def to_s
16
- result = "#{publisher} #{type} #{code}"
17
-
18
- # Add date if present
19
- result += ":#{date.year}" if date
20
-
21
- # Add draft stage if present (iteration + stage)
22
- if stage || iteration
23
- result += " "
24
- result += iteration.to_s if iteration
25
- result += stage.to_s if stage
26
- end
27
-
28
- # Add language portion if present
29
- result += "(#{language})" if language
30
-
31
- result
15
+ def to_s(**opts)
16
+ render(format: :human, **opts)
32
17
  end
33
18
  end
34
19
  end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Oiml
5
+ # Human-readable renderer for OIML identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "OIML R 60:2000"
9
+ # "OIML R 60 Edition 2013"
10
+ # "OIML R 60 Annex A Edition 2013 (E)"
11
+ # "OIML R 60 Annexes:2021 (E)"
12
+ #
13
+ # The renderer is registered as the `:human` format in the OIML 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
+ @context = context
19
+
20
+ case id
21
+ when Identifiers::Annex
22
+ render_annex(id)
23
+ when SupplementIdentifier
24
+ render_supplement(id)
25
+ when SingleIdentifier
26
+ render_single(id)
27
+ when Identifiers::Base
28
+ render_base_identifier(id)
29
+ else
30
+ id.to_s
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def effective_format(id)
37
+ id.requested_format ||
38
+ (id.parsed_format == "long" ? :long : :short)
39
+ end
40
+
41
+ def render_single(id)
42
+ format = effective_format(id)
43
+
44
+ result = "#{id.publisher} #{id.type_string} #{id.code}"
45
+
46
+ using_edition_format = false
47
+
48
+ if id.edition && id.date
49
+ result += " #{id.edition} Edition #{id.date.render(context: @context)}"
50
+ using_edition_format = true
51
+ elsif id.edition
52
+ result += " #{id.edition}"
53
+ using_edition_format = true
54
+ elsif id.date
55
+ if format == :long
56
+ result += " Edition #{id.date.render(context: @context)}"
57
+ using_edition_format = true
58
+ else
59
+ result += ":#{id.date.render(context: @context)}"
60
+ end
61
+ end
62
+
63
+ if id.stage || id.iteration
64
+ result += " "
65
+ result += id.iteration.to_s if id.iteration
66
+ result += id.stage.to_s if id.stage
67
+ end
68
+
69
+ if id.language
70
+ result += if using_edition_format || id.parsed_format == "short_with_space"
71
+ " (#{id.language})"
72
+ else
73
+ "(#{id.language})"
74
+ end
75
+ end
76
+
77
+ result
78
+ end
79
+
80
+ def render_supplement(id)
81
+ format = effective_format(id)
82
+
83
+ base_format = if format && format != :short
84
+ format
85
+ elsif id.base_identifier.class.attributes.key?(:parsed_format) && id.base_identifier.parsed_format == "long"
86
+ :long
87
+ else
88
+ :short
89
+ end
90
+
91
+ base_str = if id.base_identifier.is_a?(SingleIdentifier)
92
+ id.base_identifier.to_s(format: base_format)
93
+ else
94
+ id.base_identifier.to_s
95
+ end
96
+ base_str = base_str.sub(/\s*\([^)]+\)\s*$/, "").strip
97
+
98
+ result = "#{id.supplement_type} (#{id.year}) to #{base_str}"
99
+ result += " (#{id.language})" if id.language
100
+
101
+ result
102
+ end
103
+
104
+ def render_annex(id)
105
+ format = effective_format(id)
106
+
107
+ base_format = if id.base_identifier.class.attributes.key?(:parsed_format) && id.base_identifier.parsed_format == "long"
108
+ :long
109
+ else
110
+ :short
111
+ end
112
+
113
+ annex_format = if format
114
+ format
115
+ elsif id.class.attributes.key?(:parsed_format) && id.parsed_format == "long"
116
+ :long
117
+ else
118
+ :short
119
+ end
120
+
121
+ base_str = if id.base_identifier.is_a?(SingleIdentifier)
122
+ id.base_identifier.to_s(format: base_format)
123
+ else
124
+ id.base_identifier.to_s
125
+ end
126
+ result = base_str.sub(/:.*/, "").sub(/\s+Edition\s+\d{4}/, "").sub(
127
+ /\(.*\)/, ""
128
+ ).strip
129
+
130
+ if id.letter
131
+ result += " Annex #{id.letter}"
132
+ result += " Edition #{id.year}" if id.year
133
+ else
134
+ result += " Annexes"
135
+ if id.year
136
+ result += annex_format == :long ? " Edition #{id.year}" : ":#{id.year}"
137
+ elsif id.base_identifier.date
138
+ result += annex_format == :long ? " Edition #{id.base_identifier.date.render(context: @context)}" : ":#{id.base_identifier.date.render(context: @context)}"
139
+ end
140
+ end
141
+
142
+ result += " (#{id.language})" if id.language
143
+ result
144
+ end
145
+
146
+ def render_base_identifier(id)
147
+ result = "#{id.publisher} #{id.type} #{id.code}"
148
+ result += ":#{id.date.render(context: @context)}" if id.date
149
+
150
+ if id.stage || id.iteration
151
+ result += " "
152
+ result += id.iteration.to_s if id.iteration
153
+ result += id.stage.to_s if id.stage
154
+ end
155
+
156
+ result += "(#{id.language})" if id.language
157
+ result
158
+ end
159
+ end
160
+ end
161
+ end
@@ -15,56 +15,17 @@ module Pubid
15
15
  "short"
16
16
  } # Track parsed format
17
17
 
18
+ attr_reader :requested_format
19
+
18
20
  # Type is determined by the subclass
19
21
  def type
20
22
  type_string
21
23
  end
22
24
 
23
- def to_s(format: nil)
24
- # Use parsed format if not explicitly overridden
25
- format ||= (parsed_format == "long" ? :long : :short)
26
-
27
- result = "#{publisher} #{type_string} #{code}"
28
-
29
- # Track if we're using Edition format for language spacing
30
- using_edition_format = false
31
-
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
50
-
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
57
-
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
66
-
67
- result
25
+ def to_s(format: nil, **opts)
26
+ # Store requested format so the renderer can access it
27
+ @requested_format = format
28
+ render(format: :human, **opts)
68
29
  end
69
30
 
70
31
  def edition_portion
@@ -12,26 +12,11 @@ module Pubid
12
12
  "short"
13
13
  } # Track supplement's parsed format
14
14
 
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
15
+ attr_reader :requested_format
24
16
 
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
28
-
29
- result = "#{supplement_type} (#{year}) to #{base_str}"
30
-
31
- # Supplements ALWAYS add space before their language
32
- result += " (#{language})" if language
33
-
34
- result
17
+ def to_s(format: nil, **opts)
18
+ @requested_format = format
19
+ render(format: :human, **opts)
35
20
  end
36
21
 
37
22
  # 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
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
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
+ #
9
+ # NOTE: intentionally does NOT `extend Pubid::IdentifierFacade`. PLATEAU's
10
+ # `to_hash` currently raises (publisher stored as a String, not a Publisher
11
+ # component), so enabling the facade's identity check would route PLATEAU
12
+ # ids through a consumer's `to_hash` (e.g. relaton-index#save) and crash.
13
+ # Re-enable once PLATEAU serialization round-trips cleanly. See
14
+ # identifier_facade.rb.
15
+ module Identifier
16
+ # Delegate to the flavor module so callers can use
17
+ # `Pubid::Plateau::Identifier.parse` consistently with other flavors.
18
+ def self.parse(identifier)
19
+ Pubid::Plateau.parse(identifier)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -14,9 +14,7 @@ module Pubid
14
14
  end
15
15
 
16
16
  def to_s
17
- result = "#{publisher} #{type_string} #{formatted_number}#{formatted_annex}"
18
- result += " #{formatted_edition}" if edition
19
- result
17
+ render(format: :human)
20
18
  end
21
19
 
22
20
  def formatted_edition
@@ -12,7 +12,7 @@ module Pubid
12
12
  end
13
13
 
14
14
  def to_s
15
- "#{publisher} #{type_string} #{formatted_number}#{formatted_annex}"
15
+ render(format: :human)
16
16
  end
17
17
  end
18
18
  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
@@ -20,7 +20,7 @@ module Pubid
20
20
  end
21
21
 
22
22
  def to_s
23
- "#{base_identifier} #{supplement_string}"
23
+ render(format: :human)
24
24
  end
25
25
 
26
26
  # Override base_hash to extract edition, type, and annex from base_identifier