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
@@ -1,14 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "components/code"
4
- require_relative "components/date"
5
- require_relative "components/edition"
6
- require_relative "components/language"
7
- require_relative "components/locality"
8
- require_relative "components/publisher"
9
- require_relative "components/stage"
10
- require_relative "components/type"
11
-
12
3
  module Pubid
13
4
  class Identifier < Lutaml::Model::Serializable
14
5
  class << self
@@ -23,7 +14,7 @@ module Pubid
23
14
  attribute :number, Components::Code
24
15
  attribute :part, Components::Code
25
16
  attribute :subpart, Components::Code
26
- attribute :stage_iteration, Components::Code
17
+ attribute :stage_iteration, Components::Iteration
27
18
  attribute :date, Components::Date
28
19
  attribute :edition, Components::Edition
29
20
  attribute :languages, Components::Language, collection: true
@@ -39,6 +30,11 @@ module Pubid
39
30
  nil
40
31
  end
41
32
 
33
+ # @return [String, nil] publication year from the date component
34
+ def year
35
+ date&.year&.to_s
36
+ end
37
+
42
38
  def initialize(attrs = {}, options = {})
43
39
  attrs = attrs.dup
44
40
  attrs[:_type] ||= self.class.polymorphic_name
@@ -57,12 +53,6 @@ module Pubid
57
53
  "pubid:#{flavor}:#{type_kebab}"
58
54
  end
59
55
 
60
- klass_ref = self
61
- key_value do
62
- klass_ref.attributes.each_key do |name|
63
- map name.to_s, to: name.to_sym
64
- end
65
- end
66
56
 
67
57
  def root
68
58
  return base_identifier.root if base_identifier
@@ -160,7 +150,7 @@ module Pubid
160
150
  excluded_args << :date if excluded_args.delete(:year)
161
151
 
162
152
  attrs = self.class.attributes.each_with_object({}) do |(name, _), h|
163
- h[name] = excluded_args.include?(name) ? nil : send(name)
153
+ h[name] = excluded_args.include?(name) ? nil : public_send(name)
164
154
  end
165
155
  self.class.new(attrs)
166
156
  end
@@ -207,7 +197,8 @@ module Pubid
207
197
 
208
198
  def build_rendering_context(_renderer, format:, with_edition: false,
209
199
  lang: :en, lang_single: false,
210
- stage_format_long: nil, with_date: nil)
200
+ stage_format_long: nil, with_date: nil,
201
+ annotated: false)
211
202
  if format == :mr_string
212
203
  nil
213
204
  else
@@ -215,6 +206,7 @@ module Pubid
215
206
  with_language_code: lang_single ? :single : :none,
216
207
  stage_format_long: stage_format_long || false,
217
208
  with_date: with_date.nil? || with_date,
209
+ annotated: annotated,
218
210
  )
219
211
  end
220
212
  end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ # Mixin for the per-flavor `Identifier` *module* facades (NIST, IHO, BSI,
5
+ # CEN/CENELEC, ASHRAE). The class-pattern flavors (ISO, IEC, JIS, …) expose
6
+ # their root identifier as a real class, so `id.is_a?(Pubid::Iso::Identifier)`
7
+ # and `Pubid::Iso::Identifier.from_hash` already work natively. The
8
+ # module-pattern flavors keep `Identifier` as a thin parse/factory module;
9
+ # this mixin gives that module the same two capabilities a consumer relies on
10
+ # when it is handed the module as its identifier class (e.g. relaton-index's
11
+ # `pubid_class`):
12
+ #
13
+ # * `from_hash` — polymorphic deserialization that dispatches on the
14
+ # `_type` discriminator to the correct concrete `Identifiers::*` class,
15
+ # reusing the flavor's own `identifier_types` registry rather than a
16
+ # hand-maintained map.
17
+ # * identity — `extend`ing this mixin into the `Identifier` module is paired
18
+ # with `include`-ing that module into the flavor's `Identifiers::Base`, so
19
+ # every concrete identifier descends from it. That makes
20
+ # `id.is_a?(Pubid::Nist::Identifier)` and `Pubid::Nist::Identifier === id`
21
+ # both true (`Module#===` delegates to `is_a?`) — the test a consumer
22
+ # holding the module needs to ask "is this one of my identifiers?".
23
+ #
24
+ # The flavor namespace, the `Identifiers` namespace, and the fallback `Base`
25
+ # class are all derived from the extending module's own name by convention
26
+ # (`Pubid::<Flavor>::Identifier`), so a flavor opts in with a single
27
+ # `extend Pubid::IdentifierFacade`.
28
+ #
29
+ # Opt-in is deliberately GATED to flavors whose `to_hash`/`from_hash`
30
+ # round-trips cleanly. Some module-pattern flavors (AMCA, ITU, PLATEAU, IEEE)
31
+ # have a broken `to_hash` (publisher stored as a String) or a lossy
32
+ # `from_hash`; for those the facade's identity check would route ids through a
33
+ # consumer's `to_hash` and crash or silently corrupt them, so they
34
+ # intentionally do not opt in (see the NOTE in each of their identifier.rb).
35
+ module IdentifierFacade
36
+ # Reconstruct a concrete identifier from its serialized key_value hash by
37
+ # dispatching on the `_type` discriminator. Falls back to the flavor's
38
+ # `Identifiers::Base` for an absent/unknown type, matching lutaml's own
39
+ # non-polymorphic default.
40
+ #
41
+ # @param data [Hash] the serialized identifier hash (string or symbol keys)
42
+ # @return [Pubid::Identifier] the concrete identifier instance
43
+ def from_hash(data, options = {})
44
+ type = data && (data["_type"] || data[:_type])
45
+ klass = polymorphic_type_map[type] || identifier_base_class
46
+ klass.from_hash(data, options)
47
+ end
48
+
49
+ # Map of polymorphic_name ("pubid:nist:interagency-report") => concrete
50
+ # class, built once from the flavor's identifier-type registry so it tracks
51
+ # newly registered types automatically.
52
+ # @return [Hash{String => Class}]
53
+ def polymorphic_type_map
54
+ @polymorphic_type_map ||=
55
+ (identifier_registry_classes + [identifier_base_class]).uniq
56
+ .each_with_object({}) do |klass, map|
57
+ poly_name = klass.polymorphic_name
58
+ map[poly_name] = klass if poly_name
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ # The flavor module that namespaces this facade, e.g. Pubid::Nist for
65
+ # Pubid::Nist::Identifier.
66
+ def facade_flavor_module
67
+ @facade_flavor_module ||=
68
+ Object.const_get(name.split("::")[0...-1].join("::"))
69
+ end
70
+
71
+ def facade_identifiers_namespace
72
+ @facade_identifiers_namespace ||=
73
+ facade_flavor_module.const_get(:Identifiers)
74
+ end
75
+
76
+ # Fallback class for an absent/unknown `_type`. Most flavors expose a
77
+ # concrete `Identifiers::Base`; flavors without one (e.g. BSI, whose common
78
+ # ancestor is SingleIdentifier) fall back to the shared root, which is only
79
+ # ever reached for an unrecognized `_type`.
80
+ def identifier_base_class
81
+ if facade_identifiers_namespace.const_defined?(:Base, false)
82
+ facade_identifiers_namespace.const_get(:Base)
83
+ else
84
+ ::Pubid::Identifier
85
+ end
86
+ end
87
+
88
+ # Every concrete identifier class whose `_type` may appear in a serialized
89
+ # hash. Scans the `Identifiers` namespace for descendants of
90
+ # Pubid::Identifier (the complete set, independent of whatever filtering the
91
+ # flavor's `identifier_types` applies) and unions in `identifier_types`,
92
+ # which may register classes living outside that namespace.
93
+ def identifier_registry_classes
94
+ (scanned_identifier_classes + registered_identifier_classes).uniq
95
+ end
96
+
97
+ # Concrete identifier classes found directly in the `Identifiers` namespace.
98
+ def scanned_identifier_classes
99
+ facade_identifiers_namespace.constants.filter_map do |const|
100
+ klass = facade_identifiers_namespace.const_get(const)
101
+ klass if klass.is_a?(Class) && klass < ::Pubid::Identifier
102
+ rescue NameError
103
+ nil
104
+ end
105
+ end
106
+
107
+ # Classes the flavor explicitly registers via `identifier_types`, if any.
108
+ def registered_identifier_classes
109
+ return [] unless facade_flavor_module.respond_to?(:identifier_types)
110
+
111
+ Array(facade_flavor_module.identifier_types)
112
+ end
113
+ end
114
+ end
@@ -102,7 +102,7 @@ module Pubid
102
102
  # Get the metadata for this class
103
103
  # @return [Metadata, nil]
104
104
  def metadata
105
- @metadata ||= if superclass.is_a?(Class) && superclass.respond_to?(:metadata)
105
+ @metadata ||= if superclass.is_a?(Class) && superclass.ancestors.include?(Pubid::IdentifierMetadata)
106
106
  superclass.metadata
107
107
  end
108
108
  end
@@ -13,8 +13,8 @@ module Pubid
13
13
  }.freeze
14
14
 
15
15
  def build(parsed_hash)
16
- typed_stage = Scheme.locate_typed_stage_by_abbr(parsed_hash[:type_with_stage])
17
- identifier = Scheme.locate_identifier_klass_by_type_code(typed_stage.type_code).new
16
+ typed_stage = Pubid::Idf.locate_stage(parsed_hash[:type_with_stage])
17
+ identifier = Pubid::Idf.locate_type(typed_stage.type_code).new
18
18
 
19
19
  if type_with_stage_fr = parsed_hash.delete(:type_with_stage_fr)
20
20
  parsed_hash[:type_with_stage] = type_with_stage_fr
@@ -48,7 +48,7 @@ module Pubid
48
48
  when :type_with_stage
49
49
  iteration = value.to_s.match(/(\d+)$/)
50
50
  value = value.to_s.sub(iteration.to_s, "")
51
- typed_stage = Scheme.locate_typed_stage_by_abbr(value || "")
51
+ typed_stage = Pubid::Idf.locate_stage(value || "")
52
52
  {
53
53
  stage: typed_stage.to_stage,
54
54
  type: typed_stage.to_type,
@@ -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}" : ""),
@@ -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