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
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ansi
5
+ # Parses ANSI URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits: `urn:ansi:{code}:{year}` where the code carries
8
+ # the alpha-numeric designation (e.g., "X3.4").
9
+ #
10
+ # Examples:
11
+ # - urn:ansi:X3.4:1963 → ANSI X3.4:1963
12
+ class UrnParser < Pubid::UrnParser::Base
13
+ def parse_urn(urn)
14
+ body = strip_namespace(urn)
15
+ parts = split_parts(body)
16
+ code, year = parts
17
+ text = "ANSI #{code}"
18
+ text += ":#{year}" if year
19
+ flavor_parse(text)
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/pubid/ansi.rb CHANGED
@@ -4,22 +4,57 @@ module Pubid
4
4
  module Ansi
5
5
  autoload :Builder, "#{__dir__}/ansi/builder"
6
6
  autoload :Identifier, "#{__dir__}/ansi/identifier"
7
- autoload :Identifiers, "#{__dir__}/ansi/identifiers/standard"
7
+ autoload :Identifiers, "#{__dir__}/ansi/identifiers"
8
8
  autoload :Parser, "#{__dir__}/ansi/parser"
9
- autoload :Scheme, "#{__dir__}/ansi/scheme"
9
+ autoload :Renderer, "#{__dir__}/ansi/renderer"
10
10
  autoload :SingleIdentifier, "#{__dir__}/ansi/single_identifier"
11
11
  autoload :UrnGenerator, "#{__dir__}/ansi/urn_generator"
12
+ autoload :UrnParser, "#{__dir__}/ansi/urn_parser"
12
13
 
13
14
  # Parse an ANSI identifier string
14
15
  # @param identifier [String] the identifier string to parse
15
16
  # @return [Identifier] the parsed identifier
16
17
  def self.parse(identifier)
17
18
  parser = Parser.new
18
- builder = Builder.new(Scheme)
19
+ builder = Builder.new
19
20
 
20
21
  parsed = parser.parse(identifier)
21
22
  builder.build(parsed)
22
23
  end
24
+
25
+ # Per-flavor format registry: inherits global formats, overrides :human
26
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
27
+ Identifier.format_registry.register(:human, renderer: Ansi::Renderer)
28
+
29
+ # Auto-discover all identifier types from the Identifiers namespace
30
+ # @return [Array<Class>] identifier classes that define a self.type Hash
31
+ def self.identifier_types
32
+ @identifier_types ||= Identifiers.constants
33
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
34
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
35
+ .select { |c| c.type.is_a?(Hash) }
36
+ end
37
+
38
+ # ANSI does not define typed stages; typed_stage lookup is not used by
39
+ # the builder. Provided here for API consistency with other flavors.
40
+ # @return [Array] always empty for ANSI
41
+ def self.all_typed_stages
42
+ []
43
+ end
44
+
45
+ # Lookup: type code -> identifier class
46
+ # @param code [String, Symbol] the type key to find
47
+ # @return [Class, nil] the matching identifier class
48
+ def self.locate_type(code)
49
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
50
+ end
51
+
52
+ # Lookup: abbreviation -> typed stage
53
+ # @param _abbr [String, Symbol] unused; ANSI has no typed stages
54
+ # @return [nil] always nil for ANSI
55
+ def self.locate_stage(_abbr)
56
+ nil
57
+ end
23
58
  end
24
59
  end
25
60
 
@@ -1,84 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "components/code"
4
- require_relative "identifiers/bulletin"
5
- require_relative "identifiers/mpms"
6
- require_relative "identifiers/recommended_practice"
7
- require_relative "identifiers/specification"
8
- require_relative "identifiers/standard"
9
- require_relative "identifiers/technical_report"
10
- require_relative "identifiers/continuous_operations_standard"
11
- require_relative "identifiers/publication"
12
- require_relative "identifiers/typeless_standard"
13
-
14
3
  module Pubid
15
4
  module Api
16
- class Builder
17
- def build(parsed_hash)
18
- # Determine identifier class based on type
19
- identifier_class = case parsed_hash[:type]&.to_s
20
- when "BULL"
21
- Identifiers::Bulletin
22
- when "MPMS"
23
- Identifiers::Mpms
24
- when "RP"
25
- Identifiers::RecommendedPractice
26
- when "SPEC"
27
- Identifiers::Specification
28
- when "STD"
29
- Identifiers::Standard
30
- when "TR"
31
- Identifiers::TechnicalReport
32
- when "COS"
33
- Identifiers::ContinuousOperationsStandard
34
- when "PUBL"
35
- Identifiers::Publication
36
- else
37
- # No type = typeless standard
38
- Identifiers::TypelessStandard
39
- end
40
-
41
- identifier = identifier_class.new
42
-
43
- # Number (for non-MPMS)
44
- if parsed_hash[:number]
45
- identifier.code = Components::Code.new(value: parsed_hash[:number].to_s)
46
- end
47
-
48
- # Part
49
- if parsed_hash[:part]
50
- identifier.part = parsed_hash[:part].to_s
51
- end
52
-
53
- # MPMS-specific attributes
54
- if parsed_hash[:chapter]
55
- identifier.chapter = parsed_hash[:chapter].to_s
56
- end
57
-
58
- if parsed_hash[:section]
59
- identifier.section = parsed_hash[:section].to_s
60
- end
61
-
62
- if parsed_hash[:subsection]
63
- identifier.subsection = parsed_hash[:subsection].to_s
64
- end
5
+ class Builder < Pubid::Builder::Base
6
+ TYPE_CLASS_MAP = {
7
+ "BULL" => Identifiers::Bulletin,
8
+ "MPMS" => Identifiers::Mpms,
9
+ "RP" => Identifiers::RecommendedPractice,
10
+ "SPEC" => Identifiers::Specification,
11
+ "STD" => Identifiers::Standard,
12
+ "TR" => Identifiers::TechnicalReport,
13
+ "COS" => Identifiers::ContinuousOperationsStandard,
14
+ "PUBL" => Identifiers::Publication,
15
+ }.freeze
16
+
17
+ private
18
+
19
+ def default_identifier_class
20
+ Identifiers::TypelessStandard
21
+ end
65
22
 
66
- # Year
67
- if parsed_hash[:year]
68
- identifier.year = parsed_hash[:year].to_s
69
- end
23
+ def select_class(data)
24
+ TYPE_CLASS_MAP[data[:type]&.to_s] || default_identifier_class
25
+ end
70
26
 
71
- # Reaffirmation (nested hash with year inside)
72
- if parsed_hash[:reaffirmation]
73
- reaffirm_data = parsed_hash[:reaffirmation]
74
- identifier.reaffirmation = if reaffirm_data.is_a?(Hash) && reaffirm_data[:year]
75
- reaffirm_data[:year].to_s
76
- else
77
- reaffirm_data.to_s
78
- end
27
+ def cast(key, value)
28
+ case key
29
+ when :number then Components::Code.new(value: value.to_s)
30
+ when :reaffirmation
31
+ value.is_a?(Hash) ? (value[:year] || value).to_s : value.to_s
32
+ when :part, :chapter, :section, :subsection, :year
33
+ value.to_s
34
+ else
35
+ super
79
36
  end
80
-
81
- identifier
82
37
  end
83
38
  end
84
39
  end
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "parser"
4
- require_relative "builder"
5
- require_relative "single_identifier"
6
- require_relative "scheme"
7
-
8
3
  module Pubid
9
4
  module Api
10
5
  class Identifier
@@ -17,52 +12,6 @@ module Pubid
17
12
  rescue Parslet::ParseFailed => e
18
13
  raise e
19
14
  end
20
-
21
- # Factory that builds an API identifier from a hash of primitives.
22
- # Dispatch on `:type` to the matching subclass; default is
23
- # {Identifiers::Standard}.
24
- #
25
- # API identifiers have a hardcoded "API" publisher (via
26
- # SingleIdentifier#publisher method) so the `:publisher` kwarg is
27
- # silently dropped.
28
- TYPE_KEY_TO_KLASS = {
29
- std: "Standard",
30
- rp: "RecommendedPractice",
31
- spec: "Specification",
32
- tr: "TechnicalReport",
33
- bull: "Bulletin",
34
- mpms: "Mpms",
35
- cos: "ContinuousOperationsStandard",
36
- publ: "Publication",
37
- typeless: "TypelessStandard",
38
- }.freeze
39
-
40
- def self.create(type: nil, **opts)
41
- klass = resolve_create_class(type)
42
- klass.new(**coerce_create_attrs(opts))
43
- end
44
-
45
- def self.resolve_create_class(type)
46
- return Identifiers::Standard if type.nil?
47
-
48
- klass_name = TYPE_KEY_TO_KLASS[type.to_sym]
49
- raise ArgumentError, "Unknown API type: #{type.inspect}" unless klass_name
50
-
51
- Identifiers.const_get(klass_name)
52
- end
53
-
54
- def self.coerce_create_attrs(opts)
55
- attrs = {}
56
- if (v = opts[:code] || opts[:number])
57
- attrs[:code] = Pubid::Api::Components::Code.new(value: v.to_s)
58
- end
59
- %i[part year reaffirmation].each do |k|
60
- attrs[k] = opts[k].to_s unless opts[k].nil?
61
- end
62
- # TODO(create-shim): :publisher silently dropped (API hardcoded).
63
- attrs
64
- end
65
- private_class_method :resolve_create_class, :coerce_create_attrs
66
15
  end
67
16
  end
68
17
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../single_identifier"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -15,21 +13,7 @@ module Pubid
15
13
  end
16
14
 
17
15
  def to_s
18
- parts = ["API", "MPMS"]
19
-
20
- # Add chapter
21
- parts << "CH #{chapter}" if chapter
22
-
23
- # Add section/subsection
24
- if section
25
- parts << ".#{section}"
26
- parts << ".#{subsection}" if subsection
27
- end
28
-
29
- # Add year
30
- parts << "-#{year}" if year
31
-
32
- parts.join(" ").gsub(" .", ".")
16
+ render(format: :human)
33
17
  end
34
18
 
35
19
  private
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
@@ -1,25 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Pubid
6
4
  module Api
7
5
  module Identifiers
8
6
  class TypelessStandard < Base
9
7
  # No type_string method - renders without type
10
8
  def to_s
11
- parts = ["API"]
12
-
13
- # Add code/number
14
- parts << code_portion if code_portion
15
-
16
- # Add year
17
- parts << "-#{year}" if year
18
-
19
- # Add reaffirmation
20
- parts << " (R#{reaffirmation})" if reaffirmation
21
-
22
- parts.join(" ")
9
+ render(format: :human)
23
10
  end
24
11
  end
25
12
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Api
5
+ module Identifiers
6
+ autoload :Base, "#{__dir__}/identifiers/base"
7
+ autoload :Bulletin, "#{__dir__}/identifiers/bulletin"
8
+ autoload :ContinuousOperationsStandard, "#{__dir__}/identifiers/continuous_operations_standard"
9
+ autoload :Mpms, "#{__dir__}/identifiers/mpms"
10
+ autoload :Publication, "#{__dir__}/identifiers/publication"
11
+ autoload :RecommendedPractice, "#{__dir__}/identifiers/recommended_practice"
12
+ autoload :Specification, "#{__dir__}/identifiers/specification"
13
+ autoload :Standard, "#{__dir__}/identifiers/standard"
14
+ autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
15
+ autoload :TypelessStandard, "#{__dir__}/identifiers/typeless_standard"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Api
5
+ # Human-readable renderer for API identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "API Std 650"
9
+ # "API MPMS CH 4.1"
10
+ # "API 5L-2018"
11
+ #
12
+ # The renderer is registered as the +:human+ format in the API 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 Identifiers::Mpms
20
+ render_mpms(id)
21
+ when Identifiers::TypelessStandard
22
+ render_typeless(id)
23
+ else
24
+ render_default(id)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def render_default(id)
31
+ parts = ["API"]
32
+
33
+ # Add type if available
34
+ if id.class.attributes.key?(:type_string) && id.type_string
35
+ parts << id.type_string
36
+ end
37
+
38
+ # Add code/number with part as one token
39
+ parts << code_portion(id) if code_portion(id)
40
+
41
+ result = parts.join(" ")
42
+ result += "-#{id.year}" if id.year
43
+ result += " (R#{id.reaffirmation})" if id.reaffirmation
44
+ result
45
+ end
46
+
47
+ def render_mpms(id)
48
+ parts = ["API", "MPMS"]
49
+
50
+ # Add chapter
51
+ parts << "CH #{id.chapter}" if id.chapter
52
+
53
+ # Add section/subsection
54
+ if id.section
55
+ parts << ".#{id.section}"
56
+ parts << ".#{id.subsection}" if id.subsection
57
+ end
58
+
59
+ # Add year
60
+ parts << "-#{id.year}" if id.year
61
+
62
+ parts.join(" ").gsub(" .", ".")
63
+ end
64
+
65
+ def render_typeless(id)
66
+ parts = ["API"]
67
+
68
+ # Add code/number
69
+ parts << code_portion(id) if code_portion(id)
70
+
71
+ # Add year
72
+ parts << "-#{id.year}" if id.year
73
+
74
+ # Add reaffirmation
75
+ parts << " (R#{id.reaffirmation})" if id.reaffirmation
76
+
77
+ parts.join(" ")
78
+ end
79
+
80
+ def code_portion(id)
81
+ return nil unless id.code
82
+
83
+ code_str = id.code.to_s
84
+ code_str += "-#{id.part}" if id.part
85
+ code_str
86
+ end
87
+ end
88
+ end
89
+ end
@@ -17,19 +17,7 @@ module Pubid
17
17
  attribute :reaffirmation, :string
18
18
 
19
19
  def to_s
20
- parts = ["API"]
21
-
22
- # Add type if available
23
- parts << type_string if self.class.attributes.key?(:type_string) && type_string
24
-
25
- # Add code/number with part as one token
26
- parts << code_portion if code_portion
27
-
28
- # Build result - join with space, then add dash+year as one token
29
- result = parts.join(" ")
30
- result += "-#{year}" if year
31
- result += " (R#{reaffirmation})" if reaffirmation
32
- result
20
+ render(format: :human)
33
21
  end
34
22
 
35
23
  private
@@ -7,24 +7,6 @@ module Pubid
7
7
  "std"
8
8
  end
9
9
 
10
- def urn_number
11
- return nil unless identifier.code
12
-
13
- identifier.code.value.to_s
14
- end
15
-
16
- def urn_part
17
- return nil unless identifier.part
18
-
19
- "-#{identifier.part}"
20
- end
21
-
22
- def urn_year
23
- return identifier.year.to_s if identifier.year
24
-
25
- nil
26
- end
27
-
28
10
  def generate
29
11
  parts = ["urn", "api"]
30
12
  parts << urn_type
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Api
5
+ # Parses API URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:api:{publisher}:{number}[-{part}]:{year}
9
+ # where slot[1] is the publisher (default "api"), slot[2] is the number
10
+ # with optional `-part` suffix, slot[3] is the optional year.
11
+ #
12
+ # Examples:
13
+ # - urn:api:api:1104 → API STD 1104
14
+ # - urn:api:api:1104-1:2020 → API STD 1104-1:2020
15
+ class UrnParser < Pubid::UrnParser::Base
16
+ def parse_urn(urn)
17
+ body = strip_namespace(urn)
18
+ parts = split_parts(body)
19
+
20
+ _type, number = parts
21
+ idx = 2
22
+ part = nil
23
+ if parts[idx]&.start_with?("-")
24
+ part = parts[idx]
25
+ idx += 1
26
+ end
27
+ year = parts[idx]
28
+
29
+ text = "API STD #{number}#{part}"
30
+ text += ":#{year}" if year
31
+ flavor_parse(text)
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/pubid/api.rb CHANGED
@@ -1,17 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "api/identifier"
4
- require_relative "api/scheme"
5
-
6
3
  module Pubid
7
4
  module Api
5
+ autoload :Builder, "#{__dir__}/api/builder"
6
+ autoload :Identifier, "#{__dir__}/api/identifier"
7
+ autoload :Identifiers, "#{__dir__}/api/identifiers"
8
+ autoload :Parser, "#{__dir__}/api/parser"
9
+ autoload :Renderer, "#{__dir__}/api/renderer"
10
+ autoload :SingleIdentifier, "#{__dir__}/api/single_identifier"
11
+ autoload :UrnGenerator, "#{__dir__}/api/urn_generator"
12
+ autoload :UrnParser, "#{__dir__}/api/urn_parser"
13
+
8
14
  def self.parse(input)
9
15
  Identifier.parse(input)
10
16
  end
11
- end
12
17
 
13
- # Register this flavor with the Pubid registry
18
+ # Auto-discover all identifier types from the Identifiers namespace.
19
+ # @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
20
+ def self.identifier_types
21
+ @identifier_types ||= Identifiers.constants
22
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
23
+ .select { |c| c.is_a?(Class) && c < Pubid::Identifier }
24
+ .reject { |c| c.name&.split("::")&.last == "Base" }
25
+ end
26
+
27
+ # Build typed stage index from identifier types
28
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
29
+ def self.all_typed_stages
30
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
31
+ if klass.const_defined?(:TYPED_STAGES)
32
+ klass.const_get(:TYPED_STAGES)
33
+ else
34
+ []
35
+ end
36
+ end
37
+ end
38
+
39
+ # Lookup: type code -> identifier class
40
+ # @param code [String, Symbol] the type key to find
41
+ # @return [Class, nil] the matching identifier class
42
+ def self.locate_type(code)
43
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
44
+ rescue NoMethodError
45
+ nil
46
+ end
47
+
48
+ # Lookup: abbreviation -> typed stage
49
+ # @param abbr [String, Symbol] the abbreviation to find
50
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
51
+ def self.locate_stage(abbr)
52
+ abbr_str = abbr.to_s.upcase
53
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
54
+ end
55
+ end
14
56
  end
15
57
 
16
58
  # Register Uapi flavor with the registry
17
59
  Pubid::Registry.register(:api, Pubid::Api)
60
+
61
+ # Per-flavor format registry: inherits global formats, overrides :human
62
+ Pubid::Api::Identifiers::Base.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
63
+ Pubid::Api::Identifiers::Base.format_registry.register(:human, renderer: Pubid::Api::Renderer)
@@ -3,7 +3,7 @@
3
3
  module Pubid
4
4
  module Ashrae
5
5
  # Builder class for constructing ASHRAE identifier scheme from parsed data
6
- # Single Responsibility: Transform parsed data into Scheme objects
6
+ # Single Responsibility: Transform parsed data into identifier objects
7
7
  class Builder
8
8
  attr_reader :identifier_class
9
9
 
@@ -13,7 +13,7 @@ module Pubid
13
13
 
14
14
  # Build a scheme object from parsed data
15
15
  # @param parsed [Hash, Array] the parsed identifier data
16
- # @return [Scheme] the constructed scheme object
16
+ # @return [identifier] the constructed scheme object
17
17
  def build(parsed)
18
18
  # Parslet can return array of hashes - merge them
19
19
  parsed_hash = parsed.is_a?(Array) ? merge_parsed_array(parsed) : parsed
@@ -71,7 +71,7 @@ module Pubid
71
71
 
72
72
  # Extract and normalize attributes from parsed data
73
73
  # @param parsed [Hash] the parsed data
74
- # @return [Hash] normalized attributes for Scheme
74
+ # @return [Hash] normalized attributes for identifier
75
75
  def extract_attributes(parsed)
76
76
  attributes = {}
77
77