pubid 2.0.0.pre.alpha.2 → 2.0.0.pre.alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +5 -1
  3. data/data/nist/update_codes.yaml +25 -0
  4. data/lib/pubid/amca/builder.rb +2 -2
  5. data/lib/pubid/amca/identifier.rb +7 -39
  6. data/lib/pubid/amca/identifiers/base.rb +0 -26
  7. data/lib/pubid/amca/identifiers/interpretation.rb +0 -17
  8. data/lib/pubid/amca/identifiers/publication.rb +0 -13
  9. data/lib/pubid/amca/renderer.rb +82 -0
  10. data/lib/pubid/amca/single_identifier.rb +0 -23
  11. data/lib/pubid/amca/urn_parser.rb +28 -0
  12. data/lib/pubid/amca.rb +42 -1
  13. data/lib/pubid/ansi/builder.rb +5 -3
  14. data/lib/pubid/ansi/identifier.rb +1 -43
  15. data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
  16. data/lib/pubid/ansi/identifiers/standard.rb +2 -3
  17. data/lib/pubid/ansi/renderer.rb +53 -0
  18. data/lib/pubid/ansi/single_identifier.rb +2 -31
  19. data/lib/pubid/ansi/urn_generator.rb +3 -38
  20. data/lib/pubid/ansi/urn_parser.rb +23 -0
  21. data/lib/pubid/ansi.rb +38 -3
  22. data/lib/pubid/api/builder.rb +29 -74
  23. data/lib/pubid/api/identifier.rb +0 -51
  24. data/lib/pubid/api/identifiers/base.rb +0 -2
  25. data/lib/pubid/api/identifiers/bulletin.rb +0 -2
  26. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
  27. data/lib/pubid/api/identifiers/mpms.rb +1 -17
  28. data/lib/pubid/api/identifiers/publication.rb +0 -2
  29. data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
  30. data/lib/pubid/api/identifiers/specification.rb +0 -2
  31. data/lib/pubid/api/identifiers/standard.rb +0 -2
  32. data/lib/pubid/api/identifiers/technical_report.rb +0 -2
  33. data/lib/pubid/api/identifiers/typeless_standard.rb +1 -14
  34. data/lib/pubid/api/identifiers.rb +18 -0
  35. data/lib/pubid/api/renderer.rb +89 -0
  36. data/lib/pubid/api/single_identifier.rb +1 -13
  37. data/lib/pubid/api/urn_generator.rb +0 -18
  38. data/lib/pubid/api/urn_parser.rb +35 -0
  39. data/lib/pubid/api.rb +51 -5
  40. data/lib/pubid/ashrae/builder.rb +3 -3
  41. data/lib/pubid/ashrae/identifier.rb +6 -39
  42. data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
  43. data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
  44. data/lib/pubid/ashrae/identifiers/base.rb +3 -0
  45. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
  46. data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
  47. data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
  48. data/lib/pubid/ashrae/renderer.rb +117 -0
  49. data/lib/pubid/ashrae/single_identifier.rb +0 -13
  50. data/lib/pubid/ashrae/urn_generator.rb +0 -8
  51. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  52. data/lib/pubid/ashrae.rb +42 -1
  53. data/lib/pubid/asme/components/code.rb +10 -2
  54. data/lib/pubid/asme/identifier.rb +0 -46
  55. data/lib/pubid/asme/identifiers/base.rb +0 -60
  56. data/lib/pubid/asme/renderer.rb +66 -0
  57. data/lib/pubid/asme/urn_parser.rb +31 -0
  58. data/lib/pubid/asme.rb +42 -1
  59. data/lib/pubid/astm/components/code.rb +9 -0
  60. data/lib/pubid/{jis → astm}/components.rb +1 -1
  61. data/lib/pubid/astm/identifier.rb +0 -77
  62. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  63. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  64. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  65. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  66. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  67. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  68. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  69. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  70. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  71. data/lib/pubid/astm/identifiers.rb +18 -0
  72. data/lib/pubid/astm/renderer.rb +172 -0
  73. data/lib/pubid/astm/single_identifier.rb +0 -10
  74. data/lib/pubid/astm/urn_parser.rb +30 -0
  75. data/lib/pubid/astm.rb +39 -27
  76. data/lib/pubid/bsi/builder.rb +21 -12
  77. data/lib/pubid/bsi/identifier.rb +8 -62
  78. data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
  79. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
  80. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
  81. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
  82. data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
  83. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
  84. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  85. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
  86. data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
  87. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
  88. data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
  89. data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
  90. data/lib/pubid/bsi/identifiers/disc.rb +1 -27
  91. data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
  92. data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
  93. data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
  94. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
  95. data/lib/pubid/bsi/identifiers/flex.rb +1 -33
  96. data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
  97. data/lib/pubid/bsi/identifiers/index.rb +1 -30
  98. data/lib/pubid/bsi/identifiers/method.rb +1 -39
  99. data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
  100. data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
  101. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
  102. data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
  103. data/lib/pubid/bsi/identifiers/section.rb +1 -28
  104. data/lib/pubid/bsi/identifiers/set.rb +3 -17
  105. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
  106. data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
  107. data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
  108. data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
  109. data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
  110. data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
  111. data/lib/pubid/bsi/identifiers.rb +0 -1
  112. data/lib/pubid/bsi/renderer.rb +1050 -0
  113. data/lib/pubid/bsi/single_identifier.rb +6 -70
  114. data/lib/pubid/bsi/urn_generator.rb +2 -3
  115. data/lib/pubid/bsi/urn_parser.rb +52 -0
  116. data/lib/pubid/bsi.rb +224 -1
  117. data/lib/pubid/builder/base.rb +57 -10
  118. data/lib/pubid/bundled_identifier.rb +0 -1
  119. data/lib/pubid/ccsds/builder.rb +4 -3
  120. data/lib/pubid/ccsds/identifier.rb +63 -66
  121. data/lib/pubid/ccsds/identifiers/base.rb +11 -61
  122. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  123. data/lib/pubid/ccsds/parser.rb +4 -2
  124. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  125. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  126. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  127. data/lib/pubid/ccsds.rb +39 -1
  128. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  129. data/lib/pubid/cen_cenelec/identifier.rb +7 -38
  130. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
  131. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
  132. data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
  133. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  134. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  135. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
  136. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
  137. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  138. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
  139. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  140. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  141. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  143. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  144. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  145. data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
  146. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  147. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  148. data/lib/pubid/cen_cenelec.rb +168 -1
  149. data/lib/pubid/cie/components/code.rb +8 -0
  150. data/lib/pubid/cie/identifier.rb +6 -57
  151. data/lib/pubid/cie/urn_parser.rb +28 -0
  152. data/lib/pubid/cie.rb +43 -1
  153. data/lib/pubid/components/adoption.rb +104 -0
  154. data/lib/pubid/components/code.rb +22 -8
  155. data/lib/pubid/components/date.rb +23 -16
  156. data/lib/pubid/components/edition.rb +9 -6
  157. data/lib/pubid/components/iteration.rb +32 -0
  158. data/lib/pubid/components/language.rb +6 -4
  159. data/lib/pubid/components/locality.rb +10 -1
  160. data/lib/pubid/components/publisher.rb +9 -6
  161. data/lib/pubid/components/relationship.rb +151 -0
  162. data/lib/pubid/components/stage.rb +5 -14
  163. data/lib/pubid/components/supplement.rb +184 -0
  164. data/lib/pubid/components/type.rb +5 -15
  165. data/lib/pubid/components/typed_stage.rb +10 -11
  166. data/lib/pubid/components.rb +4 -1
  167. data/lib/pubid/core/update_codes.rb +28 -7
  168. data/lib/pubid/csa/identifier.rb +0 -59
  169. data/lib/pubid/csa/identifiers/base.rb +2 -122
  170. data/lib/pubid/csa/identifiers/cec.rb +2 -101
  171. data/lib/pubid/csa/identifiers/series.rb +2 -102
  172. data/lib/pubid/csa/renderer.rb +292 -0
  173. data/lib/pubid/csa/urn_generator.rb +1 -1
  174. data/lib/pubid/csa/urn_parser.rb +33 -0
  175. data/lib/pubid/csa.rb +42 -1
  176. data/lib/pubid/etsi/components/code.rb +9 -2
  177. data/lib/pubid/etsi/identifier.rb +0 -43
  178. data/lib/pubid/etsi/identifiers/base.rb +1 -4
  179. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
  180. data/lib/pubid/etsi/renderer.rb +42 -0
  181. data/lib/pubid/etsi/urn_parser.rb +34 -0
  182. data/lib/pubid/etsi.rb +42 -1
  183. data/lib/pubid/export/exporter.rb +4 -46
  184. data/lib/pubid/export/flavor_exporter.rb +111 -278
  185. data/lib/pubid/export.rb +0 -6
  186. data/lib/pubid/identifier.rb +2 -17
  187. data/lib/pubid/identifier_facade.rb +114 -0
  188. data/lib/pubid/identifier_metadata.rb +1 -1
  189. data/lib/pubid/idf/builder.rb +3 -3
  190. data/lib/pubid/idf/identifier.rb +3 -66
  191. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  192. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  193. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  194. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  195. data/lib/pubid/idf/parser.rb +3 -2
  196. data/lib/pubid/idf/renderer.rb +84 -0
  197. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  198. data/lib/pubid/idf/urn_generator.rb +4 -39
  199. data/lib/pubid/idf/urn_parser.rb +25 -0
  200. data/lib/pubid/idf.rb +51 -1
  201. data/lib/pubid/iec/builder.rb +46 -64
  202. data/lib/pubid/iec/components/code.rb +8 -32
  203. data/lib/pubid/iec/components/publisher.rb +0 -1
  204. data/lib/pubid/iec/components.rb +14 -0
  205. data/lib/pubid/iec/identifier.rb +251 -213
  206. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  207. data/lib/pubid/iec/identifiers/base.rb +8 -32
  208. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  209. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  210. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -26
  211. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -22
  213. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  214. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  215. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  216. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  217. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  218. data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -11
  219. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  220. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  221. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  222. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  223. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  224. data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
  225. data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -19
  226. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  227. data/lib/pubid/iec/identifiers/working_document.rb +4 -48
  228. data/lib/pubid/iec/identifiers.rb +30 -0
  229. data/lib/pubid/iec/parser.rb +13 -12
  230. data/lib/pubid/iec/renderer.rb +254 -0
  231. data/lib/pubid/iec/single_identifier.rb +6 -12
  232. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  233. data/lib/pubid/iec/urn_generator.rb +3 -3
  234. data/lib/pubid/iec/urn_parser.rb +3 -3
  235. data/lib/pubid/iec.rb +40 -68
  236. data/lib/pubid/ieee/builder.rb +12 -12
  237. data/lib/pubid/ieee/components/code.rb +8 -0
  238. data/lib/pubid/ieee/components/draft.rb +14 -0
  239. data/lib/pubid/ieee/components/relationship.rb +5 -149
  240. data/lib/pubid/ieee/identifier.rb +6 -41
  241. data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
  242. data/lib/pubid/ieee/identifiers/base.rb +101 -458
  243. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
  244. data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
  245. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
  246. data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
  247. data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
  248. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
  249. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
  250. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  251. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
  252. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
  253. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  254. data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
  255. data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
  256. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  257. data/lib/pubid/ieee/pre_parser.rb +301 -0
  258. data/lib/pubid/ieee/renderer.rb +307 -0
  259. data/lib/pubid/ieee/urn_parser.rb +34 -0
  260. data/lib/pubid/ieee.rb +62 -1
  261. data/lib/pubid/ieee_debug.rb +0 -1
  262. data/lib/pubid/iho/builder.rb +2 -2
  263. data/lib/pubid/iho/identifier.rb +8 -42
  264. data/lib/pubid/iho/identifiers/base.rb +49 -10
  265. data/lib/pubid/iho/parser.rb +3 -3
  266. data/lib/pubid/iho/renderer.rb +30 -0
  267. data/lib/pubid/iho/urn_generator.rb +2 -2
  268. data/lib/pubid/iho/urn_parser.rb +58 -0
  269. data/lib/pubid/iho.rb +50 -1
  270. data/lib/pubid/iso/builder.rb +55 -53
  271. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  272. data/lib/pubid/iso/components/code.rb +7 -19
  273. data/lib/pubid/iso/components/publisher.rb +10 -8
  274. data/lib/pubid/iso/components.rb +2 -4
  275. data/lib/pubid/iso/identifier.rb +218 -252
  276. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  277. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  278. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  279. data/lib/pubid/iso/identifiers/data.rb +0 -1
  280. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  281. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  282. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  283. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  284. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  285. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  286. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  287. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  288. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  289. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  290. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  291. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  292. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  293. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  294. data/lib/pubid/iso/identifiers.rb +0 -1
  295. data/lib/pubid/iso/normalizer.rb +89 -0
  296. data/lib/pubid/iso/parser.rb +22 -4
  297. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  298. data/lib/pubid/iso/urn_generator.rb +66 -182
  299. data/lib/pubid/iso/urn_parser.rb +12 -7
  300. data/lib/pubid/iso.rb +173 -2
  301. data/lib/pubid/itu/builder.rb +0 -12
  302. data/lib/pubid/itu/components/code.rb +8 -0
  303. data/lib/pubid/itu/components.rb +11 -0
  304. data/lib/pubid/itu/identifier.rb +6 -104
  305. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  306. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  307. data/lib/pubid/itu/identifiers/base.rb +0 -6
  308. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  309. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  310. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  311. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  312. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  313. data/lib/pubid/itu/urn_parser.rb +23 -0
  314. data/lib/pubid/itu.rb +42 -1
  315. data/lib/pubid/jcgm/builder.rb +16 -8
  316. data/lib/pubid/jcgm/identifier.rb +0 -43
  317. data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
  318. data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
  319. data/lib/pubid/jcgm/renderer.rb +68 -0
  320. data/lib/pubid/jcgm/single_identifier.rb +1 -5
  321. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  322. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  323. data/lib/pubid/jcgm.rb +43 -2
  324. data/lib/pubid/jis/builder.rb +44 -52
  325. data/lib/pubid/jis/identifier.rb +132 -46
  326. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  327. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  328. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  329. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  330. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  331. data/lib/pubid/jis/identifiers.rb +1 -1
  332. data/lib/pubid/jis/parser.rb +31 -5
  333. data/lib/pubid/jis/renderer.rb +69 -0
  334. data/lib/pubid/jis/single_identifier.rb +6 -12
  335. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  336. data/lib/pubid/jis/urn_parser.rb +23 -0
  337. data/lib/pubid/jis.rb +42 -2
  338. data/lib/pubid/nist/builder.rb +63 -1871
  339. data/lib/pubid/nist/caster.rb +1272 -0
  340. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  341. data/lib/pubid/nist/components/code.rb +9 -20
  342. data/lib/pubid/nist/components/supplement.rb +2 -2
  343. data/lib/pubid/nist/components.rb +0 -1
  344. data/lib/pubid/nist/identifier.rb +11 -48
  345. data/lib/pubid/nist/identifiers/base.rb +110 -47
  346. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  347. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
  348. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  349. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  350. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  351. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
  352. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  353. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
  354. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  355. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  356. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  357. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  358. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  359. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  360. data/lib/pubid/nist/identifiers/report.rb +4 -2
  361. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  362. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  363. data/lib/pubid/nist/identifiers.rb +1 -0
  364. data/lib/pubid/nist/parser.rb +62 -452
  365. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  366. data/lib/pubid/nist/preprocessor.rb +416 -0
  367. data/lib/pubid/nist/renderer.rb +43 -0
  368. data/lib/pubid/nist/router.rb +148 -0
  369. data/lib/pubid/nist/series/base.rb +58 -0
  370. data/lib/pubid/nist/series/crpl.rb +13 -0
  371. data/lib/pubid/nist/series/fips.rb +14 -0
  372. data/lib/pubid/nist/series/ir.rb +60 -0
  373. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  374. data/lib/pubid/nist/series/mono.rb +19 -0
  375. data/lib/pubid/nist/series/ncstar.rb +20 -0
  376. data/lib/pubid/nist/series.rb +49 -0
  377. data/lib/pubid/nist/supplement_identifier.rb +3 -1
  378. data/lib/pubid/nist/urn_parser.rb +67 -0
  379. data/lib/pubid/nist.rb +82 -4
  380. data/lib/pubid/oiml/components/code.rb +10 -0
  381. data/lib/pubid/oiml/identifier.rb +0 -50
  382. data/lib/pubid/oiml/identifiers/annex.rb +3 -45
  383. data/lib/pubid/oiml/identifiers/base.rb +2 -17
  384. data/lib/pubid/oiml/renderer.rb +161 -0
  385. data/lib/pubid/oiml/single_identifier.rb +6 -45
  386. data/lib/pubid/oiml/supplement_identifier.rb +4 -19
  387. data/lib/pubid/oiml/urn_generator.rb +0 -8
  388. data/lib/pubid/oiml/urn_parser.rb +22 -0
  389. data/lib/pubid/oiml.rb +42 -1
  390. data/lib/pubid/plateau/identifier.rb +7 -41
  391. data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
  392. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  393. data/lib/pubid/plateau/renderer.rb +51 -0
  394. data/lib/pubid/plateau/supplement_identifier.rb +1 -1
  395. data/lib/pubid/plateau/urn_parser.rb +43 -0
  396. data/lib/pubid/plateau.rb +43 -1
  397. data/lib/pubid/renderers/directives_renderer.rb +22 -8
  398. data/lib/pubid/renderers/guide_renderer.rb +4 -2
  399. data/lib/pubid/renderers/human_readable.rb +18 -7
  400. data/lib/pubid/rendering/context.rb +28 -19
  401. data/lib/pubid/rendering.rb +0 -3
  402. data/lib/pubid/sae/components/date.rb +8 -0
  403. data/lib/pubid/sae/components/type.rb +5 -1
  404. data/lib/pubid/sae/identifier.rb +0 -23
  405. data/lib/pubid/sae/identifiers/base.rb +2 -16
  406. data/lib/pubid/sae/renderer.rb +36 -0
  407. data/lib/pubid/sae/urn_generator.rb +2 -10
  408. data/lib/pubid/sae/urn_parser.rb +36 -0
  409. data/lib/pubid/sae.rb +42 -1
  410. data/lib/pubid/urn_generator/base.rb +12 -12
  411. data/lib/pubid/urn_parser/base.rb +81 -0
  412. data/lib/pubid/urn_parser/errors.rb +9 -0
  413. data/lib/pubid/urn_parser.rb +14 -0
  414. data/lib/pubid/version.rb +1 -1
  415. data/lib/pubid.rb +29 -7
  416. data/lib/tasks/website-data.json +1940 -1882
  417. metadata +75 -44
  418. data/lib/pubid/amca/scheme.rb +0 -16
  419. data/lib/pubid/ansi/scheme.rb +0 -15
  420. data/lib/pubid/api/scheme.rb +0 -66
  421. data/lib/pubid/ashrae/scheme.rb +0 -53
  422. data/lib/pubid/asme/scheme.rb +0 -37
  423. data/lib/pubid/astm/scheme.rb +0 -55
  424. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  425. data/lib/pubid/bsi/scheme.rb +0 -243
  426. data/lib/pubid/ccsds/scheme.rb +0 -57
  427. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  428. data/lib/pubid/cie/scheme.rb +0 -64
  429. data/lib/pubid/components/factory.rb +0 -50
  430. data/lib/pubid/csa/scheme.rb +0 -44
  431. data/lib/pubid/etsi/scheme.rb +0 -42
  432. data/lib/pubid/export/data_class_exporter.rb +0 -59
  433. data/lib/pubid/export/ieee_exporter.rb +0 -78
  434. data/lib/pubid/export/itu_exporter.rb +0 -66
  435. data/lib/pubid/export/nist_exporter.rb +0 -64
  436. data/lib/pubid/export/registry_exporter.rb +0 -90
  437. data/lib/pubid/export/scheme_exporter.rb +0 -70
  438. data/lib/pubid/identifier_registry.rb +0 -198
  439. data/lib/pubid/idf/scheme.rb +0 -61
  440. data/lib/pubid/iec/scheme.rb +0 -71
  441. data/lib/pubid/ieee/scheme.rb +0 -90
  442. data/lib/pubid/iho/scheme.rb +0 -29
  443. data/lib/pubid/iso/identifiers/base.rb +0 -115
  444. data/lib/pubid/iso/scheme.rb +0 -193
  445. data/lib/pubid/itu/scheme.rb +0 -174
  446. data/lib/pubid/jcgm/scheme.rb +0 -60
  447. data/lib/pubid/jis/components/code.rb +0 -59
  448. data/lib/pubid/jis/identifiers/base.rb +0 -72
  449. data/lib/pubid/jis/scheme.rb +0 -49
  450. data/lib/pubid/nist/components/publisher.rb +0 -24
  451. data/lib/pubid/nist/scheme.rb +0 -199
  452. data/lib/pubid/oiml/scheme.rb +0 -46
  453. data/lib/pubid/plateau/scheme.rb +0 -45
  454. data/lib/pubid/rendering/base.rb +0 -73
  455. data/lib/pubid/rendering/common.rb +0 -211
  456. data/lib/pubid/rendering/format.rb +0 -25
  457. data/lib/pubid/sae/scheme.rb +0 -47
  458. data/lib/pubid/scheme.rb +0 -219
@@ -7,11 +7,8 @@ module Pubid
7
7
  class Identifier < ::Pubid::Identifier
8
8
  attribute :typed_stage, Components::TypedStage
9
9
 
10
- def to_s(lang: :en, lang_single: false, with_edition: false)
11
- [
12
- publisher_portion(lang: lang),
13
- number_portion(lang_single: lang_single),
14
- ].join
10
+ def to_s(**opts)
11
+ render(format: :human, **opts)
15
12
  end
16
13
 
17
14
  def publisher_portion(lang: :en)
@@ -31,7 +28,7 @@ module Pubid
31
28
  (subpart ? "-#{subpart.value}" : ""),
32
29
 
33
30
  # Stage iteration is optional
34
- (stage_iteration ? ".#{stage_iteration.value}" : ""),
31
+ (stage_iteration ? ".#{stage_iteration.number}" : ""),
35
32
 
36
33
  # Date is optional
37
34
  (date ? ":#{date.year}" : ""),
@@ -64,66 +61,6 @@ module Pubid
64
61
 
65
62
  Pubid::Idf::Builder.new.build(parsed)
66
63
  end
67
-
68
- # Factory mirroring pubid 1.x's `Pubid::Idf::Identifier.create` API.
69
- # Default subclass is {Identifiers::InternationalStandard}.
70
- #
71
- # IDF's renderer requires `typed_stage` to be set (calls
72
- # `.abbreviation` without a nil check); factory auto-resolves the
73
- # "published" TypedStage for the chosen subclass.
74
- TYPE_KEY_TO_KLASS = {
75
- is: "InternationalStandard",
76
- reviewed_method: "ReviewedMethod",
77
- }.freeze
78
-
79
- def self.create(type: nil, stage: nil, **opts)
80
- klass = resolve_create_class(type)
81
- attrs = coerce_create_attrs(opts)
82
- ts = resolve_create_typed_stage(klass, stage)
83
- attrs[:typed_stage] = ts if ts
84
- klass.new(**attrs)
85
- end
86
-
87
- def self.resolve_create_class(type)
88
- return Identifiers::InternationalStandard if type.nil?
89
-
90
- klass_name = TYPE_KEY_TO_KLASS[type.to_sym]
91
- raise ArgumentError, "Unknown IDF type: #{type.inspect}" unless klass_name
92
-
93
- Identifiers.const_get(klass_name)
94
- end
95
-
96
- def self.resolve_create_typed_stage(klass, stage)
97
- return nil unless klass.const_defined?(:TYPED_STAGES)
98
-
99
- if stage
100
- klass.const_get(:TYPED_STAGES).find do |ts|
101
- ts.abbr.include?(stage.to_s)
102
- end
103
- else
104
- klass.const_get(:TYPED_STAGES).find do |ts|
105
- ts.stage_code&.to_sym == :published
106
- end
107
- end
108
- end
109
-
110
- def self.coerce_create_attrs(opts)
111
- attrs = {
112
- publisher: Pubid::Components::Publisher.new(
113
- body: (opts[:publisher] || "IDF").to_s,
114
- ),
115
- }
116
- if (v = opts[:number])
117
- attrs[:number] = Pubid::Components::Code.new(value: v.to_s)
118
- end
119
- if (v = opts[:year])
120
- attrs[:date] = Pubid::Components::Date.new(year: v.to_s)
121
- end
122
- attrs
123
- end
124
- private_class_method :resolve_create_class,
125
- :resolve_create_typed_stage,
126
- :coerce_create_attrs
127
64
  end
128
65
  end
129
66
  end
@@ -19,7 +19,8 @@ module Pubid
19
19
  ].freeze
20
20
 
21
21
  def self.type
22
- { key: :amd, title: "Amendment", short: "AMD" }
22
+ { key: :amd,
23
+ web: :amendment, title: "Amendment", short: "AMD" }
23
24
  end
24
25
  end
25
26
  end
@@ -19,7 +19,8 @@ module Pubid
19
19
  ].freeze
20
20
 
21
21
  def self.type
22
- { key: :cor, title: "Corrigendum", short: "COR" }
22
+ { key: :cor,
23
+ web: :corrigendum, title: "Corrigendum", short: "COR" }
23
24
  end
24
25
  end
25
26
  end
@@ -115,7 +115,8 @@ module Pubid
115
115
  ].freeze
116
116
 
117
117
  def self.type
118
- { key: :is, title: "International Standard", short: nil }
118
+ { key: :is,
119
+ web: :international_standard, title: "International Standard", short: nil }
119
120
  end
120
121
  end
121
122
  end
@@ -92,7 +92,8 @@ module Pubid
92
92
  ].freeze
93
93
 
94
94
  def self.type
95
- { key: :rm, title: "Reviewed Method", short: "RM" }
95
+ { key: :rm,
96
+ web: :reviewed_method, title: "Reviewed Method", short: "RM" }
96
97
  end
97
98
  end
98
99
  end
@@ -9,9 +9,10 @@ module Pubid
9
9
  include ::Pubid::Parser::CommonParseMethods
10
10
 
11
11
  # We need to sort by length to match longest first because that's how Parslet works
12
- TYPED_STAGES = Pubid::Idf::Scheme.typed_stages
12
+ TYPED_STAGES = Pubid::Idf.all_typed_stages
13
13
  .map(&:abbr).flatten.sort_by(&:length).reverse
14
- TYPED_STAGES_SUPPLEMENTS = Pubid::Idf::Scheme.supplement_typed_stages
14
+ TYPED_STAGES_SUPPLEMENTS = Pubid::Idf.all_typed_stages
15
+ .select { |ts| %w[amd cor].include?(ts.type_code.to_s) }
15
16
  .map(&:abbr).flatten.sort_by(&:length).reverse
16
17
 
17
18
  root :identifier
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Idf
5
+ # Human-readable renderer for IDF identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "IDF 125:1988"
9
+ # "IDF/AMD 1:2023"
10
+ # "IDF 125:1988/AMD 1:2023"
11
+ #
12
+ # The renderer is registered as the `:human` format in the IDF 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, opts, context)
21
+ else
22
+ render_single(id, opts, context)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def render_single(id, opts, context)
29
+ [
30
+ publisher_portion(id, context),
31
+ number_portion(id, opts, context),
32
+ ].join
33
+ end
34
+
35
+ def publisher_portion(id, context)
36
+ [
37
+ id.publisher.render(context:),
38
+ (id.typed_stage.abbreviation.empty? ? "" : "/#{id.typed_stage.abbreviation}"),
39
+ ].join
40
+ end
41
+
42
+ def number_portion(id, opts, context)
43
+ lang_single = opts[:lang_single] || false
44
+
45
+ [
46
+ (id.number ? " #{id.number.render(context:)}" : ""),
47
+ (id.part ? "-#{id.part.render(context:)}" : ""),
48
+ (id.subpart ? "-#{id.subpart.render(context:)}" : ""),
49
+ (id.stage_iteration ? ".#{id.stage_iteration.render(context:)}" : ""),
50
+ (id.date ? ":#{id.date.render(context:)}" : ""),
51
+ language_portion(id, lang_single: lang_single),
52
+ ].join
53
+ end
54
+
55
+ def language_portion(id, lang_single: false)
56
+ return "" unless id.languages&.any?
57
+
58
+ [
59
+ "(",
60
+ id.languages.map do |lang|
61
+ lang.to_s(lang_single: lang_single)
62
+ end.join(lang_single ? "/" : ","),
63
+ ")",
64
+ ].join
65
+ end
66
+
67
+ def render_supplement(id, opts, context)
68
+ lang = opts[:lang] || :en
69
+ lang_single = opts[:lang_single] || false
70
+ with_edition = opts[:with_edition] || false
71
+
72
+ [
73
+ id.base_identifier.to_s(lang: lang, lang_single: lang_single,
74
+ with_edition: with_edition),
75
+ "/",
76
+ id.typed_stage.abbreviation,
77
+ " ",
78
+ id.number.render(context:),
79
+ (id.date ? ":#{id.date.render(context:)}" : ""),
80
+ ].join
81
+ end
82
+ end
83
+ end
84
+ end
@@ -27,16 +27,8 @@ module Pubid
27
27
  # @param lang_single [Boolean] Use single-char language codes (default: false)
28
28
  # @param with_edition [Boolean] Include edition (default: false)
29
29
  # @return [String] String representation of supplement
30
- def to_s(lang: :en, lang_single: false, with_edition: false)
31
- [
32
- base_identifier.to_s(lang: lang, lang_single: lang_single,
33
- with_edition: with_edition),
34
- "/",
35
- typed_stage.abbreviation,
36
- " ",
37
- number.value,
38
- (date ? ":#{date.year}" : ""),
39
- ].join
30
+ def to_s(**opts)
31
+ render(format: :human, **opts)
40
32
  end
41
33
  end
42
34
  end
@@ -9,41 +9,6 @@ module Pubid
9
9
  identifier.type.abbr.to_s.downcase
10
10
  end
11
11
 
12
- def urn_number
13
- return nil unless identifier.number
14
-
15
- identifier.number.value.to_s
16
- end
17
-
18
- def urn_part
19
- return nil unless identifier.part
20
-
21
- "-#{identifier.part.value}"
22
- end
23
-
24
- def urn_subpart
25
- return nil unless identifier.subpart
26
-
27
- "-#{identifier.subpart.value}"
28
- end
29
-
30
- def urn_year
31
- if identifier.date&.year
32
- return identifier.date.year.to_s
33
- end
34
-
35
- identifier.year&.to_s
36
- end
37
-
38
- def urn_edition
39
- return nil unless identifier.edition
40
-
41
- num = identifier.edition.number
42
- return nil unless num
43
-
44
- "ed.#{num}"
45
- end
46
-
47
12
  def generate
48
13
  parts = ["urn", "idf"]
49
14
  parts << urn_number if urn_number
@@ -54,12 +19,12 @@ module Pubid
54
19
  parts << urn_type if urn_type
55
20
 
56
21
  if identifier.publisher
57
- parts[1] = identifier.publisher.body.to_s.downcase
22
+ parts[1] = identifier.publisher.render(context: URN_CONTEXT)
58
23
  end
59
24
 
60
25
  if identifier.copublishers&.any?
61
- copubs = identifier.copublishers.map(&:body)
62
- parts[1] = "#{parts[1]}-#{copubs.join('-').downcase}"
26
+ copubs = identifier.copublishers.map { |cp| cp.render(context: URN_CONTEXT) }
27
+ parts[1] = "#{parts[1]}-#{copubs.join('-')}"
63
28
  end
64
29
 
65
30
  if identifier.languages&.any?
@@ -73,7 +38,7 @@ module Pubid
73
38
  end
74
39
 
75
40
  if identifier.number
76
- parts << identifier.number.value.to_s
41
+ parts << identifier.number.render(context: URN_CONTEXT)
77
42
  end
78
43
  end
79
44
 
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Idf
5
+ # Parses IDF URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits: `urn:idf:{number}:{year}:` with a trailing empty
8
+ # field (a known quirk of the generator).
9
+ #
10
+ # Examples:
11
+ # - urn:idf:87:2019: → IDF 87:2019
12
+ # - urn:idf:100: → IDF 100
13
+ class UrnParser < Pubid::UrnParser::Base
14
+ def parse_urn(urn)
15
+ body = strip_namespace(urn)
16
+ parts = split_parts(body).reject(&:empty?)
17
+
18
+ number, year = parts
19
+ text = "IDF #{number}"
20
+ text += ":#{year}" if year
21
+ flavor_parse(text)
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/pubid/idf.rb CHANGED
@@ -6,10 +6,11 @@ module Pubid
6
6
  autoload :Identifier, "#{__dir__}/idf/identifier"
7
7
  autoload :Identifiers, "#{__dir__}/idf/identifiers"
8
8
  autoload :Parser, "#{__dir__}/idf/parser"
9
- autoload :Scheme, "#{__dir__}/idf/scheme"
9
+ autoload :Renderer, "#{__dir__}/idf/renderer"
10
10
  autoload :SingleIdentifier, "#{__dir__}/idf/single_identifier"
11
11
  autoload :SupplementIdentifier, "#{__dir__}/idf/supplement_identifier"
12
12
  autoload :UrnGenerator, "#{__dir__}/idf/urn_generator"
13
+ autoload :UrnParser, "#{__dir__}/idf/urn_parser"
13
14
 
14
15
  def self.parse(identifier)
15
16
  parser = Parser.new
@@ -18,6 +19,55 @@ module Pubid
18
19
  parsed = parser.parse(identifier)
19
20
  builder.build(parsed)
20
21
  end
22
+
23
+ # Build an IDF identifier from a parse-tree hash (used by ISO joint-identifier
24
+ # parsing). This is the public seam: callers should never reach into
25
+ # `Idf::Builder` directly.
26
+ # @param hash [Hash] parse tree for the joint identifier
27
+ # @return [Pubid::Idf::Identifier]
28
+ def self.build_from_parse(hash)
29
+ Builder.new.build(hash)
30
+ end
31
+
32
+ # Per-flavor format registry: inherits global formats, overrides :human
33
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
34
+ Identifier.format_registry.register(:human, renderer: Idf::Renderer)
35
+
36
+ # Auto-discover all identifier types from the Identifiers namespace
37
+ # @return [Array<Class>] identifier classes that define a self.type Hash
38
+ def self.identifier_types
39
+ @identifier_types ||= Identifiers.constants
40
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
41
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
42
+ .select { |c| c.type.is_a?(Hash) }
43
+ end
44
+
45
+ # Build typed stage index from identifier types
46
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
47
+ def self.all_typed_stages
48
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
49
+ if klass.const_defined?(:TYPED_STAGES)
50
+ klass.const_get(:TYPED_STAGES)
51
+ else
52
+ []
53
+ end
54
+ end
55
+ end
56
+
57
+ # Lookup: type code -> identifier class
58
+ # @param code [String, Symbol] the type key to find
59
+ # @return [Class, nil] the matching identifier class
60
+ def self.locate_type(code)
61
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
62
+ end
63
+
64
+ # Lookup: abbreviation -> typed stage
65
+ # @param abbr [String, Symbol] the abbreviation to find
66
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
67
+ def self.locate_stage(abbr)
68
+ abbr_str = abbr.to_s.upcase
69
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
70
+ end
21
71
  end
22
72
  end
23
73
 
@@ -1,25 +1,16 @@
1
- require_relative "../components/publisher"
2
1
  # frozen_string_literal: true
3
- require_relative "../components/code"
4
- require_relative "../components/date"
5
2
 
6
3
  module Pubid
7
4
  module Iec
8
5
  class Builder < Pubid::Builder::Base
9
- def initialize(scheme)
10
- @scheme = scheme
11
- end
12
-
13
6
  def locate_identifier_klass(parsed_hash)
14
7
  # Check for working programme
15
8
  if parsed_hash[:wp_stage]
16
- require_relative "identifiers/working_document"
17
9
  return Identifiers::WorkingDocument
18
10
  end
19
11
 
20
12
  # Check for working document
21
13
  if parsed_hash[:technical_committee] && parsed_hash[:wd_number]
22
- require_relative "identifiers/working_document"
23
14
  return Identifiers::WorkingDocument
24
15
  end
25
16
 
@@ -27,7 +18,8 @@ module Pubid
27
18
  # :type_with_stage will be nil if it is an IS.
28
19
  typed_stage = locate_typed_stage(parsed_hash[:type_with_stage])
29
20
 
30
- @scheme.locate_identifier_klass_by_type_code(typed_stage.type_code)
21
+ Pubid::Iec.locate_type(typed_stage.type_code) ||
22
+ raise(ArgumentError, "Unknown type code: #{typed_stage.type_code}")
31
23
  end
32
24
 
33
25
  def build(parsed_hash)
@@ -55,7 +47,8 @@ module Pubid
55
47
 
56
48
  # Locate the supplement identifier class
57
49
  typed_stage = locate_typed_stage(supplement_type)
58
- identifier_class = @scheme.locate_identifier_klass_by_type_code(typed_stage.type_code)
50
+ identifier_class = Pubid::Iec.locate_type(typed_stage.type_code) ||
51
+ raise(ArgumentError, "Unknown type code: #{typed_stage.type_code}")
59
52
 
60
53
  # Create the supplement identifier
61
54
  supplement = identifier_class.new
@@ -96,14 +89,11 @@ module Pubid
96
89
 
97
90
  if is_fragment
98
91
  # For FRAG typed stages, look up the fragment's own typed stage
99
- begin
100
- fragment_typed_stage = @scheme.locate_typed_stage_by_abbr(
101
- parsed_hash[:type_with_stage].to_s,
102
- )
103
- rescue ArgumentError
104
- # FRAGC is a rendering notation, not a typed stage abbreviation
105
- fragment_typed_stage = @scheme.locate_typed_stage_by_abbr("FRAG")
106
- end
92
+ fragment_typed_stage = Pubid::Iec.locate_stage(parsed_hash[:type_with_stage])
93
+
94
+ # FRAGC is a rendering notation, not a typed stage abbreviation;
95
+ # fall back to the canonical "FRAG" typed stage
96
+ fragment_typed_stage ||= Pubid::Iec.locate_stage("FRAG")
107
97
 
108
98
  # For FRAG/FRAGC, we need to build the base Amendment/Corrigendum
109
99
  # then wrap it with FragmentIdentifier
@@ -158,7 +148,6 @@ module Pubid
158
148
 
159
149
  # Detect rendering style from parsed abbreviation
160
150
  if identifier.class.attributes.key?(:rendering_style) && identifier.typed_stage
161
- require_relative "rendering_style"
162
151
  ts = identifier.typed_stage
163
152
 
164
153
  # Detect IEC format from parsed abbreviation
@@ -179,7 +168,7 @@ module Pubid
179
168
  with_language_code = if langs&.any?
180
169
  # Check if original_code was single-char (E, F, R, A, S, D)
181
170
  first_lang = langs.first
182
- if first_lang.is_a?(Components::Language) && first_lang.original_code && first_lang.original_code.length == 1
171
+ if first_lang.is_a?(::Pubid::Components::Language) && first_lang.original_code && first_lang.original_code.length == 1
183
172
  :single
184
173
  else
185
174
  :iso # 2-char codes (en, fr, ru, ar, es, de)
@@ -202,7 +191,7 @@ module Pubid
202
191
 
203
192
  # After building base identifier, apply wrappers
204
193
  if fragment_type_data && fragment_number_data
205
- frag_ts = @scheme.locate_typed_stage_by_abbr("FRAG")
194
+ frag_ts = Pubid::Iec.locate_stage("FRAG")
206
195
  identifier = wrap_with_fragment(identifier, fragment_number_data.to_s,
207
196
  nil, frag_ts)
208
197
  end
@@ -229,11 +218,25 @@ module Pubid
229
218
  end
230
219
  end
231
220
 
221
+ # The IEC builder's own `build` method drives identifier construction
222
+ # (it locates the right class per parsed hash), so the parent class's
223
+ # `@identifier_class` slot is never read. Provide a placeholder so
224
+ # `Builder.new` doesn't fail with NotImplementedError.
225
+ def default_identifier_class
226
+ Identifiers::InternationalStandard
227
+ end
228
+
229
+ # Look up a typed stage by abbreviation via the self-describing
230
+ # `Pubid::Iec` module instead of an injected scheme instance.
231
+ def locate_typed_stage(typed_stage_string)
232
+ typed_stage_string = "" if typed_stage_string.nil?
233
+ Pubid::Iec.locate_stage(typed_stage_string) ||
234
+ raise(ArgumentError, "Unknown type abbreviation: '#{typed_stage_string}'")
235
+ end
236
+
232
237
  # Wrap identifier with FragmentIdentifier for /FRAGN notation
233
238
  def wrap_with_fragment(base_identifier, fragment_number,
234
- edition_data = nil, typed_stage = nil)
235
- require_relative "identifiers/fragment_identifier"
236
-
239
+ edition_data = nil, typed_stage = nil)
237
240
  fragment = Identifiers::FragmentIdentifier.new(
238
241
  base_identifier: base_identifier,
239
242
  fragment_number: fragment_number,
@@ -252,8 +255,6 @@ edition_data = nil, typed_stage = nil)
252
255
 
253
256
  # Wrap identifier with SheetIdentifier for /N:YEAR notation
254
257
  def wrap_with_sheet(base_identifier, sheet_number, sheet_year)
255
- require_relative "identifiers/sheet_identifier"
256
-
257
258
  # Only pass year if it's present
258
259
  year_value = sheet_year&.to_s
259
260
 
@@ -272,10 +273,6 @@ edition_data = nil, typed_stage = nil)
272
273
 
273
274
  # Wrap identifier with ConsolidatedIdentifier for +AMD chains
274
275
  def wrap_with_consolidated(base_identifier, supplements_data)
275
- require_relative "identifiers/consolidated_identifier"
276
- require_relative "identifiers/amendment"
277
- require_relative "identifiers/corrigendum"
278
-
279
276
  supplements = supplements_data.filter_map do |supp|
280
277
  type = supp[:supplement_type].to_s
281
278
  number = supp[:supplement_number].to_s
@@ -302,13 +299,10 @@ edition_data = nil, typed_stage = nil)
302
299
  )
303
300
  end
304
301
 
305
- # Wrap identifier with VapIdentifier for CSV/CMV/RLV/SER suffix
302
+ # Wrap identifier with VapIdentifier for one or more VAP codes
303
+ # (e.g. "CSV" or "EXV-CMV").
306
304
  def wrap_with_vap(base_identifier, vap_suffix_data)
307
- require_relative "identifiers/vap_identifier"
308
- require_relative "identifiers/consolidated_identifier"
309
- require_relative "components/vap_suffix"
310
-
311
- vap_suffix = Components::VapSuffix.new(code: vap_suffix_data.to_s)
305
+ vap = vap_suffix_data.to_s.split("-")
312
306
 
313
307
  # Extract edition - need to go deep for ConsolidatedIdentifier
314
308
  edition = nil
@@ -326,7 +320,7 @@ edition_data = nil, typed_stage = nil)
326
320
 
327
321
  Identifiers::VapIdentifier.new(
328
322
  base_identifier: base_identifier,
329
- vap_suffix: vap_suffix,
323
+ vap: vap,
330
324
  edition: edition,
331
325
  )
332
326
  end
@@ -337,6 +331,12 @@ edition_data = nil, typed_stage = nil)
337
331
  super
338
332
  end
339
333
 
334
+ # IEC normalizes em/en dashes to hyphens but preserves slashes and
335
+ # spaces, which can be semantically meaningful in IEC identifiers.
336
+ def normalize_number_with_part(value)
337
+ value.to_s.tr(Parser::DASH_CHARS.join, "-")
338
+ end
339
+
340
340
  def cast(type, value)
341
341
  case type
342
342
  when :base_identifier
@@ -374,28 +374,7 @@ edition_data = nil, typed_stage = nil)
374
374
  # or "60038-1" ('1' is part)
375
375
  # or "60038-1-2" ('1' is part, '2' is subpart)
376
376
  # or "29110-5-1-1" ('5' is part, '1-1' is subpart)
377
-
378
- # Split the number into parts
379
- normalized_value = value.to_s.tr(Parser::DASH_CHARS.join, "-")
380
-
381
- parts = normalized_value.split("-")
382
- number = parts.shift # The first part is always the number
383
- part = parts.shift # The second part is the part, if present
384
- subpart = parts.any? ? parts.join("-") : nil # The remaining parts form the subpart, if present
385
-
386
- part = convert_roman_to_integer(part)
387
-
388
- code_hash = { number: Components::Code.new(value: number) }
389
-
390
- if part
391
- code_hash[:part] = Components::Code.new(value: part)
392
- end
393
-
394
- if subpart
395
- code_hash[:subpart] = Components::Code.new(value: subpart)
396
- end
397
-
398
- code_hash
377
+ parse_number_with_part(value, code_class: Components::Code)
399
378
 
400
379
  when :type_with_stage
401
380
  # "WD"
@@ -416,13 +395,17 @@ edition_data = nil, typed_stage = nil)
416
395
  }
417
396
  when :stage_iteration
418
397
  # "1" or "2"
419
- Components::Code.new(value: value.to_s)
398
+ Pubid::Components::Iteration.new(number: value.to_s)
420
399
 
421
400
  when :date
422
401
  parse_date(value)
423
402
 
424
403
  when :edition
425
- Pubid::Components::Edition.new(number: value)
404
+ # Coerce to String: the parsed value may be a Parslet::Slice, which
405
+ # Edition.number (Type::Value) would store verbatim and serialize as a
406
+ # !ruby/object:Parslet::Slice node — unloadable by the index reader's
407
+ # YAML.safe_load(permitted_classes: [Symbol]).
408
+ Pubid::Components::Edition.new(number: value&.to_s)
426
409
 
427
410
  when :sheet_number
428
411
  value.to_s
@@ -445,8 +428,7 @@ edition_data = nil, typed_stage = nil)
445
428
  when :joint_identifier
446
429
  case value[:publisher]
447
430
  when "ISO"
448
- require_relative "../iso/builder"
449
- Iso::Builder.new(Iso::Scheme).build(value)
431
+ Pubid::Iso.build_from_parse(value)
450
432
  end
451
433
 
452
434
  else