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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e650437c35c0d8e6ba019b07ae835ca224bd620415bd9c9d27c20a36a1b82589
4
- data.tar.gz: 3d8d15f420d6cff7dbba69007218d670cde06511fc00df7b7dcfd957493600cb
3
+ metadata.gz: 296a51f39ef14271b7b66a8403042c4a35b214eb3e858c2a926ab9104e74acfa
4
+ data.tar.gz: 9dcdd6b5082ea2cc6b866078f7c749e687fd4f76ad767b94ed77347700f2a6c2
5
5
  SHA512:
6
- metadata.gz: f231838d92fd52c9d8fb298899a6f62018c29872d0d67104ea064ea70ea5cd4e115490876e2e83ba9601da87aeb9060d9f28e34535d0495ca680bc93ad6801ec
7
- data.tar.gz: de691a34d6783e9df75f4304315d6791eb30e68b7788177f8e04285aa8f88372e38ce9754527eb8479db0926ef9276ddef7c6fae1ede170380541459c150a823
6
+ metadata.gz: 974c5db378c9461c7636b47525054a7351fd136de2493710767abbb198e40fdadf7e21a9c9273d3bbe79707c301509e21aaea30eeae3d09931b11029e5cf69ae
7
+ data.tar.gz: 16d304dcd9a960da1386e46d692425e3c9a7153be96130187def4c02c9fc22e192bd4374956ee526678bbfe04add13ab50c71d625b860e0d6c65cd157ef12248
data/README.adoc CHANGED
@@ -1729,9 +1729,13 @@ The V2 implementation strictly follows these design principles:
1729
1729
 
1730
1730
  Object-Oriented Design:: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
1731
1731
  MECE Organization:: Mutually Exclusive (no overlap), Collectively Exhaustive (full coverage), clear boundaries
1732
- Separation of Concerns:: Parser handles syntax only, Builder handles transformation only, Identifier handles rendering only
1732
+ Separation of Concerns:: Parser handles syntax only, Builder handles transformation only, Renderer handles formatting only
1733
+ Self-Describing Types:: Each identifier class IS the type definition — no central registry required for type metadata
1734
+ Renderer Pattern:: Dedicated per-flavor Renderer classes handle human-readable output; identifier `to_s` delegates to `render(format: :human)` via `FormatRegistry`
1735
+ Single Source of Truth:: Series matching, type metadata, and rendering logic live in exactly one place per concern
1733
1736
  Extensibility:: Use inheritance and polymorphism, plugin/registry architecture, avoid hardcoding
1734
1737
  Test Quality:: Each class has dedicated spec file, no lowering pass thresholds, test actual behavior
1738
+ Autoload Everywhere:: Ruby autoload replaces `require_relative` for internal library code — lazy loading, no circular dependency risk
1735
1739
 
1736
1740
  === Pre-parser Normalization (update_codes.yaml)
1737
1741
 
@@ -1,3 +1,28 @@
1
+ # NIST pre-parser normalization rules.
2
+ #
3
+ # This file is applied to every NIST identifier string BEFORE any Ruby
4
+ # preprocessing (see lib/pubid/nist/preprocessor.rb). Each entry is one
5
+ # of:
6
+ #
7
+ # "plain string": "replacement"
8
+ # Full-line match (^...$), literal. Use for specific malformed IDs
9
+ # that have a single canonical form.
10
+ #
11
+ # "/regex/": "replacement" (no flags)
12
+ # "/regex/imx": "replacement" (i = IGNORECASE, m = MULTILINE,
13
+ # x = EXTENDED)
14
+ # Applied via gsub. Use for general patterns that are pure
15
+ # string→string substitutions.
16
+ #
17
+ # Design split (MECE):
18
+ # - This file: data-driven lookups and pure subs that any maintainer
19
+ # (including non-Rubyists) can extend safely.
20
+ # - Preprocessor (Ruby): stateful or interdependent transformations
21
+ # where stage order, conditional logic, or external state (e.g.,
22
+ # Roman numeral conversion, year-range reverts) make YAML unsuitable.
23
+ #
24
+ # Reorder entries with care — later entries often match patterns produced
25
+ # by earlier ones. Run `bundle exec rspec spec/pubid/nist/` after edits.
1
26
  NBS MN: NBS MONO
2
27
  NIST MN: NIST MONO
3
28
  NIST MP: NBS MP
@@ -26,7 +51,9 @@ NIST.CSWP.01162020pt: NIST.CSWP.01162020(por)
26
51
  FIPS PUB: FIPS
27
52
  NBS CRPL c4-4: NBS CRPL 4-4
28
53
  NIST AMS 300-8r1 (February 2021 update): NIST AMS 300-8r1/Upd1-202102
54
+ NIST AMS 300-8r1/upd: NIST AMS 300-8r1/Upd1-202102
29
55
  NIST IR 8115r1-upd: NIST IR 8115r1/Upd1-202103
56
+ NIST IR 8170-upd: NIST IR 8170/Upd1-202003
30
57
  NIST TN 2150-upd: NIST TN 2150/Upd1-202102
31
58
  NBS IR 73-197r: NBS IR 73-197r1
32
59
  NBS.HB.105-1r1990: NIST.HB.105-1r1990
@@ -3,7 +3,7 @@
3
3
  module Pubid
4
4
  module Amca
5
5
  # Builder class for constructing ACMA 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
@@ -2,6 +2,13 @@
2
2
 
3
3
  module Pubid
4
4
  module Amca
5
+ # NOTE: this flavor intentionally does NOT `extend Pubid::IdentifierFacade`
6
+ # (nor include it in Identifiers::Base). The facade's identity check makes
7
+ # `is_a?(<Flavor>::Identifier)` true, which routes the object through a
8
+ # consumer's `to_hash` (e.g. relaton-index#save) — but AMCA's `to_hash`
9
+ # currently raises (publisher is stored as a String, not a Publisher
10
+ # component). Enabling the facade here would turn a non-crashing path into a
11
+ # crash. Re-enable once AMCA serialization round-trips cleanly.
5
12
  module Identifier
6
13
  # Parse an ACMA identifier string into an identifier object
7
14
  # @param identifier [String] The ACMA identifier string to parse
@@ -25,37 +25,11 @@ module Pubid
25
25
  "AMCA"
26
26
  end
27
27
 
28
- # Render the identifier as a string
29
- def to_s
30
- parts = []
31
- parts << copublisher if copublisher
32
- # type is a hash, get the title
33
- t = self.class.attributes.key?(:type) ? type : nil
34
- if t.is_a?(Hash) && t[:title]
35
- parts << t[:title].to_s
36
- end
37
- parts << code.to_s
38
- parts << "-#{year}" if year
39
-
40
- result = parts.compact.join(" ")
41
-
42
- # Handle additional copublisher after year (e.g., /ASHRAE 51-16)
43
- if copublisher&.include?("/") && year
44
- type_title = t.is_a?(Hash) ? t[:title].to_s : ""
45
- result = "#{copublisher} #{type_title} #{code}-#{year}"
46
- end
47
-
48
- result += " (#{reaffirmed})" if reaffirmed
49
-
50
- result
51
- end
52
-
53
28
  def self.parse(string)
54
29
  Amca::Identifier.parse(string)
55
30
  end
56
31
 
57
32
  def to_urn
58
- require_relative "../urn_generator"
59
33
  UrnGenerator.new(self).generate
60
34
  end
61
35
  end
@@ -28,23 +28,6 @@ reaffirmed: nil, interpretation_code: nil)
28
28
  def type
29
29
  Interpretation.type
30
30
  end
31
-
32
- # @return [String] the rendered interpretation identifier
33
- def to_s
34
- parts = []
35
- parts << @copublisher if @copublisher
36
- parts << @code.to_s
37
-
38
- if @interpretation_code
39
- parts << "– #{@interpretation_code}"
40
- elsif @year
41
- parts << "-#{@year}"
42
- end
43
-
44
- parts << " #{@suffix}" if @suffix
45
-
46
- parts.join(" ").squeeze(" ")
47
- end
48
31
  end
49
32
  end
50
33
  end
@@ -28,19 +28,6 @@ reaffirmed: nil, revision: nil)
28
28
  def type
29
29
  Publication.type
30
30
  end
31
-
32
- # @return [String] the rendered publication identifier
33
- def to_s
34
- parts = []
35
- parts << @copublisher if @copublisher
36
- parts << "Publication"
37
- parts << @code.to_s
38
- parts << "-#{@year}" if @year
39
- parts << " (Rev. #{@revision})" if @revision
40
- parts << " (#{@reaffirmed})" if @reaffirmed && !@revision
41
-
42
- parts.join(" ").squeeze(" ")
43
- end
44
31
  end
45
32
  end
46
33
  end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Amca
5
+ # Human-readable renderer for AMCA identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "AMCA Standard 210-16"
9
+ # "AMCA Publication 211-22 (Rev. 01-23)"
10
+ # "ANSI/AMCA 204 Interp"
11
+ # "AMCA 99 JW Interp"
12
+ #
13
+ # The renderer is registered as the `:human` format in the AMCA format
14
+ # registry and invoked via `render(format: :human)`.
15
+ class Renderer < ::Pubid::Renderers::Base
16
+ def render(context: nil, **opts)
17
+ id = @id
18
+
19
+ case id
20
+ when Identifiers::Publication
21
+ render_publication(id)
22
+ when Identifiers::Interpretation
23
+ render_interpretation(id)
24
+ else
25
+ render_base(id)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def render_base(id)
32
+ parts = []
33
+ parts << id.copublisher if id.copublisher
34
+ t = id.class.attributes.key?(:type) ? id.type : nil
35
+ if t.is_a?(Hash) && t[:title]
36
+ parts << t[:title].to_s
37
+ end
38
+ parts << id.code.to_s
39
+ parts << "-#{id.year}" if id.year
40
+
41
+ result = parts.compact.join(" ")
42
+
43
+ if id.copublisher&.include?("/") && id.year
44
+ type_title = t.is_a?(Hash) ? t[:title].to_s : ""
45
+ result = "#{id.copublisher} #{type_title} #{id.code}-#{id.year}"
46
+ end
47
+
48
+ result += " (#{id.reaffirmed})" if id.reaffirmed
49
+
50
+ result
51
+ end
52
+
53
+ def render_publication(id)
54
+ parts = []
55
+ parts << id.copublisher if id.copublisher
56
+ parts << "Publication"
57
+ parts << id.code.to_s
58
+ parts << "-#{id.year}" if id.year
59
+ parts << " (Rev. #{id.revision})" if id.revision
60
+ parts << " (#{id.reaffirmed})" if id.reaffirmed && !id.revision
61
+
62
+ parts.join(" ").squeeze(" ")
63
+ end
64
+
65
+ def render_interpretation(id)
66
+ parts = []
67
+ parts << id.copublisher if id.copublisher
68
+ parts << id.code.to_s
69
+
70
+ if id.interpretation_code
71
+ parts << "– #{id.interpretation_code}"
72
+ elsif id.year
73
+ parts << "-#{id.year}"
74
+ end
75
+
76
+ parts << " #{id.suffix}" if id.suffix
77
+
78
+ parts.join(" ").squeeze(" ")
79
+ end
80
+ end
81
+ end
82
+ end
@@ -5,29 +5,6 @@ module Pubid
5
5
  # Base class for single (non-supplement) ACMA identifiers
6
6
  # Includes: Standard, Publication
7
7
  class SingleIdentifier < Identifiers::Base
8
- def to_s
9
- parts = []
10
- parts << copublisher if copublisher
11
- # type is a hash, get the title
12
- t = self.class.attributes.key?(:type) ? type : nil
13
- if t.is_a?(Hash) && t[:title]
14
- parts << t[:title].to_s
15
- end
16
- parts << code.to_s
17
- parts << "-#{year}" if year
18
-
19
- result = parts.compact.join(" ")
20
-
21
- # Handle additional copublisher after year (e.g., /ASHRAE 51-16)
22
- if copublisher&.include?("/") && year
23
- type_title = t.is_a?(Hash) ? t[:title].to_s : ""
24
- result = "#{copublisher} #{type_title} #{code}-#{year}"
25
- end
26
-
27
- result += " (#{reaffirmed})" if reaffirmed
28
-
29
- result
30
- end
31
8
  end
32
9
  end
33
10
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Amca
5
+ # Parses AMCA URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:amca:{number}:{year}[:{copub.publisher}[:{other tokens}]]
9
+ #
10
+ # The current generator can leak the Type Hash literal into the URN
11
+ # (e.g., `copub.amca:{:key => :standard, ...}`). This parser filters
12
+ # any token containing `{` so round-trip works for the common case.
13
+ #
14
+ # Examples:
15
+ # - urn:amca:210:08 → AMCA 210-08
16
+ class UrnParser < Pubid::UrnParser::Base
17
+ def parse_urn(urn)
18
+ body = strip_namespace(urn)
19
+ parts = split_parts(body).reject { |p| p.include?("{") }
20
+
21
+ number, year = parts
22
+ text = "AMCA #{number}"
23
+ text += "-#{year}" if year
24
+ flavor_parse(text)
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/pubid/amca.rb CHANGED
@@ -6,9 +6,10 @@ module Pubid
6
6
  autoload :Identifiers, "#{__dir__}/amca/identifiers"
7
7
  autoload :Builder, "#{__dir__}/amca/builder"
8
8
  autoload :Parser, "#{__dir__}/amca/parser"
9
- autoload :Scheme, "#{__dir__}/amca/scheme"
9
+ autoload :Renderer, "#{__dir__}/amca/renderer"
10
10
  autoload :SingleIdentifier, "#{__dir__}/amca/single_identifier"
11
11
  autoload :UrnGenerator, "#{__dir__}/amca/urn_generator"
12
+ autoload :UrnParser, "#{__dir__}/amca/urn_parser"
12
13
 
13
14
  # Parse an ACMA identifier string into an identifier object
14
15
  # @param identifier [String] The ACMA identifier string to parse
@@ -17,6 +18,46 @@ module Pubid
17
18
  def self.parse(identifier)
18
19
  Identifier.parse(identifier)
19
20
  end
21
+
22
+ # Per-flavor format registry: inherits global formats, overrides :human
23
+ Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
24
+ Identifiers::Base.format_registry.register(:human, renderer: Amca::Renderer)
25
+
26
+ # Auto-discover all identifier types from the Identifiers namespace
27
+ # @return [Array<Class>] identifier classes that define a self.type Hash
28
+ def self.identifier_types
29
+ @identifier_types ||= Identifiers.constants
30
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
31
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
32
+ .select { |c| c.type.is_a?(Hash) }
33
+ end
34
+
35
+ # Build typed stage index from identifier types
36
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
37
+ def self.all_typed_stages
38
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
39
+ if klass.const_defined?(:TYPED_STAGES)
40
+ klass.const_get(:TYPED_STAGES)
41
+ else
42
+ []
43
+ end
44
+ end
45
+ end
46
+
47
+ # Lookup: type code -> identifier class
48
+ # @param code [String, Symbol] the type key to find
49
+ # @return [Class, nil] the matching identifier class
50
+ def self.locate_type(code)
51
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
52
+ end
53
+
54
+ # Lookup: abbreviation -> typed stage
55
+ # @param abbr [String, Symbol] the abbreviation to find
56
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
57
+ def self.locate_stage(abbr)
58
+ abbr_str = abbr.to_s.upcase
59
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
60
+ end
20
61
  end
21
62
 
22
63
  # Register this flavor with the Pubid registry
@@ -3,9 +3,11 @@
3
3
  module Pubid
4
4
  module Ansi
5
5
  class Builder < Pubid::Builder::Base
6
- def initialize(scheme)
7
- @scheme = scheme
8
- super(Identifiers::Standard)
6
+ def build(data)
7
+ data = flatten_array(data) if data.is_a?(Array)
8
+ identifier = default_identifier_class.new
9
+ assign_attributes(identifier, data)
10
+ identifier
9
11
  end
10
12
 
11
13
  private
@@ -6,7 +6,7 @@ module Pubid
6
6
  class Identifier < ::Pubid::Identifier
7
7
  def self.parse(string)
8
8
  parsed = Pubid::Ansi::Parser.new.parse(string)
9
- Pubid::Ansi::Builder.new(Pubid::Ansi::Scheme).build(parsed)
9
+ Pubid::Ansi::Builder.new.build(parsed)
10
10
  end
11
11
  end
12
12
  end
@@ -4,7 +4,8 @@ module Pubid
4
4
  # American National Standard identifier
5
5
  class AmericanNationalStandard < SingleIdentifier
6
6
  def self.type
7
- { key: :ans, title: "American National Standard", short: "ANS" }
7
+ { key: :ans, web: :american_national_standard,
8
+ title: "American National Standard", short: "ANS" }
8
9
  end
9
10
  end
10
11
  end
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "american_national_standard"
4
-
5
3
  module Pubid
6
4
  module Ansi
7
5
  module Identifiers
8
6
  # American National Standard identifier
9
7
  class Standard < SingleIdentifier
10
8
  def self.type
11
- { key: :ans, title: "American National Standard", short: "ANS" }
9
+ { key: :ans, web: :standard,
10
+ title: "American National Standard", short: "ANS" }
12
11
  end
13
12
  end
14
13
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ansi
5
+ # Human-readable renderer for ANSI identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "ANSI X3.4"
9
+ # "ANSI/ISO 9899"
10
+ # "ANSI X9.8-1:2007"
11
+ #
12
+ # The renderer is registered as the `:human` format in the ANSI 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
+ parts = []
19
+ parts << publisher_portion(id, context)
20
+ parts << number_portion(id, context)
21
+ result = parts.compact.join(" ")
22
+
23
+ result << language_portion(id) if id.languages&.any?
24
+
25
+ result
26
+ end
27
+
28
+ private
29
+
30
+ def publisher_portion(id, context)
31
+ if id.copublishers&.any?
32
+ ([id.publisher] + id.copublishers).map { |p| p.render(context:) }.join("/")
33
+ else
34
+ id.publisher.render(context:)
35
+ end
36
+ end
37
+
38
+ def number_portion(id, context)
39
+ [
40
+ id.number.render(context:),
41
+ (id.part ? "-#{id.part.render(context:)}" : ""),
42
+ (id.date ? ":#{id.date.render(context:)}" : ""),
43
+ ].join
44
+ end
45
+
46
+ def language_portion(id)
47
+ return "" unless id.languages&.any?
48
+
49
+ "(#{id.languages.map(&:code).join(',')})"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -8,37 +8,8 @@ module Pubid
8
8
  #
9
9
  # @return [String] URN representation
10
10
 
11
- def to_s(lang: :en)
12
- [].tap do |parts|
13
- parts << publisher_portion
14
- parts << number_portion
15
- end.compact.join(" ").tap do |s|
16
- s << language_portion if languages&.any?
17
- end
18
- end
19
-
20
- def publisher_portion
21
- if copublishers&.any?
22
- # ANSI/ISO 9899
23
- ([publisher] + copublishers).map(&:body).join("/")
24
- else
25
- # ANSI X3.4
26
- publisher.body
27
- end
28
- end
29
-
30
- def number_portion
31
- [
32
- number.value,
33
- (part ? "-#{part.value}" : ""),
34
- (date ? ":#{date.year}" : ""),
35
- ].join
36
- end
37
-
38
- def language_portion
39
- return "" unless languages&.any?
40
-
41
- "(#{languages.map(&:code).join(',')})"
11
+ def to_s(**opts)
12
+ render(format: :human, **opts)
42
13
  end
43
14
  end
44
15
  end
@@ -3,41 +3,6 @@
3
3
  module Pubid
4
4
  module Ansi
5
5
  class UrnGenerator < Pubid::UrnGenerator::Base
6
- def urn_number
7
- return nil unless identifier.number
8
-
9
- identifier.number.value.to_s
10
- end
11
-
12
- def urn_part
13
- return nil unless identifier.part
14
-
15
- "-#{identifier.part.value}"
16
- end
17
-
18
- def urn_subpart
19
- return nil unless identifier.subpart
20
-
21
- "-#{identifier.subpart.value}"
22
- end
23
-
24
- def urn_year
25
- if identifier.date&.year
26
- return identifier.date.year.to_s
27
- end
28
-
29
- identifier.year&.to_s
30
- end
31
-
32
- def urn_edition
33
- return nil unless identifier.edition
34
-
35
- num = identifier.edition.number
36
- return nil unless num
37
-
38
- "ed.#{num}"
39
- end
40
-
41
6
  def urn_typed_stage
42
7
  return nil unless identifier.typed_stage
43
8
 
@@ -57,12 +22,12 @@ module Pubid
57
22
  parts << urn_typed_stage if urn_typed_stage
58
23
 
59
24
  if identifier.publisher
60
- parts[1] = identifier.publisher.body.to_s.downcase
25
+ parts[1] = identifier.publisher.render(context: URN_CONTEXT)
61
26
  end
62
27
 
63
28
  if identifier.copublishers&.any?
64
- copubs = identifier.copublishers.map(&:body)
65
- parts[1] = "#{parts[1]}-#{copubs.join('-').downcase}"
29
+ copubs = identifier.copublishers.map { |cp| cp.render(context: URN_CONTEXT) }
30
+ parts[1] = "#{parts[1]}-#{copubs.join('-')}"
66
31
  end
67
32
 
68
33
  if identifier.languages&.any?
@@ -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