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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16698d2e32777261efbf6842754351b03a2a0d272992ca1525ebd3fbedaf648d
4
- data.tar.gz: 46d2aa4fb40d9f9ab3fcf7f42bdc3c9b2662637653a9e5c98f26baebecaea0cd
3
+ metadata.gz: 296a51f39ef14271b7b66a8403042c4a35b214eb3e858c2a926ab9104e74acfa
4
+ data.tar.gz: 9dcdd6b5082ea2cc6b866078f7c749e687fd4f76ad767b94ed77347700f2a6c2
5
5
  SHA512:
6
- metadata.gz: 638b16ccaed8a371fecee3ec8372a9790ae4649d689d0aeafa306b4b1681e0df42365d5ede2da46da743f8b42e7a70ddcc882774a6c6c333a1a2fec8d30255e4
7
- data.tar.gz: 2d55ed5b29d6121665c808d697832307bcea629345b7782308c5c0fe76ffc9baae849f752a8f75b5d77c7b3aaed782be9e15dcc9e1dc85e7c229ae77cf4431b8
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
@@ -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
@@ -13,45 +20,6 @@ module Pubid
13
20
  rescue Parslet::ParseFailed => e
14
21
  raise "Failed to parse ACMA identifier '#{identifier}': #{e.message}"
15
22
  end
16
-
17
- # Factory that builds an AMCA identifier from a hash of primitives.
18
- #
19
- # Dispatch on `:type`:
20
- # * `:standard` (default) → Identifiers::Standard
21
- # * `:publication` → Identifiers::Publication
22
- # * `:interpretation` → Identifiers::Interpretation
23
- #
24
- # AMCA stores the "AMCA" prefix in the `copublisher` string
25
- # attribute (matching parsed output); `.create` defaults it to
26
- # "AMCA" unless the caller supplies one.
27
- def self.create(type: nil, **opts)
28
- klass = resolve_create_class(type)
29
- klass.new(**coerce_create_attrs(opts))
30
- end
31
-
32
- def self.resolve_create_class(type)
33
- case type&.to_sym
34
- when nil, :standard then Identifiers::Standard
35
- when :publication then Identifiers::Publication
36
- when :interpretation then Identifiers::Interpretation
37
- else
38
- raise ArgumentError, "Unknown AMCA type: #{type.inspect}"
39
- end
40
- end
41
-
42
- def self.coerce_create_attrs(opts)
43
- attrs = { copublisher: (opts[:copublisher] || "AMCA").to_s }
44
- if (v = opts[:code] || opts[:number])
45
- attrs[:code] = Pubid::Components::Code.new(value: v.to_s)
46
- end
47
- if (v = opts[:year])
48
- attrs[:year] = Pubid::Components::Date.new(year: v.to_s)
49
- end
50
- attrs[:suffix] = opts[:suffix].to_s if opts[:suffix]
51
- attrs[:reaffirmed] = opts[:reaffirmed].to_s if opts[:reaffirmed]
52
- attrs
53
- end
54
- private_class_method :resolve_create_class, :coerce_create_attrs
55
23
  end
56
24
  end
57
25
  end
@@ -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,50 +6,8 @@ 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
-
12
- # Factory that builds an ANSI identifier from a hash of primitives.
13
- #
14
- # Defaults to {Identifiers::Standard} (ANSI has Standard and
15
- # AmericanNationalStandard, both sharing the same type key `:ans`).
16
- #
17
- # ANSI quirk: the parser stores the publication year in the `part`
18
- # attribute, not `date`. `.create` mirrors that — `:year` is coerced
19
- # into `part` so the rendered output matches a parsed identifier.
20
- def self.create(type: nil, **opts)
21
- klass = resolve_create_class(type)
22
- klass.new(**coerce_create_attrs(opts))
23
- end
24
-
25
- def self.resolve_create_class(type)
26
- case type&.to_sym
27
- when nil, :ans, :standard
28
- Identifiers::Standard
29
- when :american_national_standard
30
- Identifiers::AmericanNationalStandard
31
- else
32
- raise ArgumentError, "Unknown ANSI type: #{type.inspect}"
33
- end
34
- end
35
-
36
- def self.coerce_create_attrs(opts)
37
- attrs = {
38
- publisher: Pubid::Components::Publisher.new(
39
- body: (opts[:publisher] || "ANSI").to_s,
40
- ),
41
- }
42
- if (v = opts[:number])
43
- attrs[:number] = Pubid::Components::Code.new(value: v.to_s)
44
- end
45
- # ANSI parser stores year in part; mirror that here.
46
- year_or_part = opts[:year] || opts[:part]
47
- if year_or_part
48
- attrs[:part] = Pubid::Components::Code.new(value: year_or_part.to_s)
49
- end
50
- attrs
51
- end
52
- private_class_method :resolve_create_class, :coerce_create_attrs
53
11
  end
54
12
  end
55
13
  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?