pubid 2.0.0.pre.alpha.2 → 2.0.0.pre.alpha.4

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 (473) 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 +4 -55
  6. data/lib/pubid/amca/identifiers/base.rb +58 -47
  7. data/lib/pubid/amca/identifiers/interpretation.rb +0 -21
  8. data/lib/pubid/amca/identifiers/publication.rb +0 -17
  9. data/lib/pubid/amca/identifiers/standard.rb +0 -4
  10. data/lib/pubid/amca/renderer.rb +82 -0
  11. data/lib/pubid/amca/single_identifier.rb +0 -23
  12. data/lib/pubid/amca/urn_generator.rb +2 -1
  13. data/lib/pubid/amca/urn_parser.rb +28 -0
  14. data/lib/pubid/amca.rb +42 -1
  15. data/lib/pubid/ansi/builder.rb +5 -3
  16. data/lib/pubid/ansi/identifier.rb +1 -43
  17. data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
  18. data/lib/pubid/ansi/identifiers/standard.rb +2 -3
  19. data/lib/pubid/ansi/renderer.rb +53 -0
  20. data/lib/pubid/ansi/single_identifier.rb +2 -31
  21. data/lib/pubid/ansi/urn_generator.rb +3 -38
  22. data/lib/pubid/ansi/urn_parser.rb +23 -0
  23. data/lib/pubid/ansi.rb +38 -3
  24. data/lib/pubid/api/builder.rb +33 -74
  25. data/lib/pubid/api/identifier.rb +5 -52
  26. data/lib/pubid/api/identifiers/base.rb +2 -14
  27. data/lib/pubid/api/identifiers/bulletin.rb +0 -2
  28. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
  29. data/lib/pubid/api/identifiers/mpms.rb +0 -20
  30. data/lib/pubid/api/identifiers/publication.rb +0 -2
  31. data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
  32. data/lib/pubid/api/identifiers/specification.rb +0 -2
  33. data/lib/pubid/api/identifiers/standard.rb +0 -2
  34. data/lib/pubid/api/identifiers/technical_report.rb +0 -2
  35. data/lib/pubid/api/identifiers/typeless_standard.rb +0 -16
  36. data/lib/pubid/api/identifiers.rb +18 -0
  37. data/lib/pubid/api/renderer.rb +89 -0
  38. data/lib/pubid/api/single_identifier.rb +5 -20
  39. data/lib/pubid/api/urn_generator.rb +0 -18
  40. data/lib/pubid/api/urn_parser.rb +35 -0
  41. data/lib/pubid/api.rb +51 -5
  42. data/lib/pubid/ashrae/builder.rb +3 -3
  43. data/lib/pubid/ashrae/identifier.rb +7 -55
  44. data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
  45. data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
  46. data/lib/pubid/ashrae/identifiers/base.rb +29 -15
  47. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
  48. data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
  49. data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
  50. data/lib/pubid/ashrae/parser.rb +4 -0
  51. data/lib/pubid/ashrae/renderer.rb +117 -0
  52. data/lib/pubid/ashrae/single_identifier.rb +0 -13
  53. data/lib/pubid/ashrae/urn_generator.rb +0 -8
  54. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  55. data/lib/pubid/ashrae.rb +46 -1
  56. data/lib/pubid/asme/components/code.rb +10 -2
  57. data/lib/pubid/asme/identifier.rb +0 -46
  58. data/lib/pubid/asme/identifiers/base.rb +0 -60
  59. data/lib/pubid/asme/renderer.rb +66 -0
  60. data/lib/pubid/asme/single_identifier.rb +3 -1
  61. data/lib/pubid/asme/urn_parser.rb +31 -0
  62. data/lib/pubid/asme.rb +42 -1
  63. data/lib/pubid/astm/components/code.rb +9 -0
  64. data/lib/pubid/{jis → astm}/components.rb +1 -1
  65. data/lib/pubid/astm/identifier.rb +0 -77
  66. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  67. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  68. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  69. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  70. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  71. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  72. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  73. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  74. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  75. data/lib/pubid/astm/identifiers.rb +18 -0
  76. data/lib/pubid/astm/renderer.rb +172 -0
  77. data/lib/pubid/astm/single_identifier.rb +3 -11
  78. data/lib/pubid/astm/urn_parser.rb +30 -0
  79. data/lib/pubid/astm.rb +39 -27
  80. data/lib/pubid/bsi/builder.rb +21 -12
  81. data/lib/pubid/bsi/identifier.rb +5 -85
  82. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -36
  83. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +8 -48
  84. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +8 -39
  85. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +2 -55
  86. data/lib/pubid/bsi/identifiers/amendment.rb +2 -22
  87. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +1 -6
  88. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  89. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -87
  90. data/lib/pubid/bsi/identifiers/committee_document.rb +0 -16
  91. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -87
  92. data/lib/pubid/bsi/identifiers/corrigendum.rb +2 -10
  93. data/lib/pubid/bsi/identifiers/detailed_specification.rb +0 -36
  94. data/lib/pubid/bsi/identifiers/disc.rb +0 -29
  95. data/lib/pubid/bsi/identifiers/draft_document.rb +2 -46
  96. data/lib/pubid/bsi/identifiers/electronic_book.rb +2 -38
  97. data/lib/pubid/bsi/identifiers/expert_commentary.rb +2 -18
  98. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +0 -47
  99. data/lib/pubid/bsi/identifiers/flex.rb +0 -35
  100. data/lib/pubid/bsi/identifiers/handbook.rb +1 -15
  101. data/lib/pubid/bsi/identifiers/index.rb +0 -32
  102. data/lib/pubid/bsi/identifiers/method.rb +0 -41
  103. data/lib/pubid/bsi/identifiers/national_annex.rb +4 -29
  104. data/lib/pubid/bsi/identifiers/practice_guide.rb +1 -6
  105. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +2 -54
  106. data/lib/pubid/bsi/identifiers/published_document.rb +2 -54
  107. data/lib/pubid/bsi/identifiers/section.rb +0 -30
  108. data/lib/pubid/bsi/identifiers/set.rb +3 -20
  109. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +0 -9
  110. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -24
  111. data/lib/pubid/bsi/identifiers/supplementary_index.rb +0 -46
  112. data/lib/pubid/bsi/identifiers/technical_specification.rb +2 -47
  113. data/lib/pubid/bsi/identifiers/test_method.rb +0 -32
  114. data/lib/pubid/bsi/identifiers/value_added_publication.rb +2 -17
  115. data/lib/pubid/bsi/identifiers.rb +0 -1
  116. data/lib/pubid/bsi/renderer.rb +1050 -0
  117. data/lib/pubid/bsi/single_identifier.rb +33 -78
  118. data/lib/pubid/bsi/urn_generator.rb +2 -3
  119. data/lib/pubid/bsi/urn_parser.rb +52 -0
  120. data/lib/pubid/bsi.rb +232 -2
  121. data/lib/pubid/builder/base.rb +57 -10
  122. data/lib/pubid/bundled_identifier.rb +0 -1
  123. data/lib/pubid/ccsds/builder.rb +4 -3
  124. data/lib/pubid/ccsds/identifier.rb +53 -68
  125. data/lib/pubid/ccsds/identifiers/base.rb +11 -61
  126. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  127. data/lib/pubid/ccsds/parser.rb +4 -2
  128. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  129. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  130. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  131. data/lib/pubid/ccsds.rb +39 -1
  132. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  133. data/lib/pubid/cen_cenelec/identifier.rb +11 -40
  134. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +9 -4
  135. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +0 -10
  136. data/lib/pubid/cen_cenelec/identifiers/base.rb +2 -45
  137. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  138. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  139. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +0 -27
  140. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +0 -15
  141. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +2 -8
  143. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  144. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +0 -4
  145. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  146. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  147. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  148. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  149. data/lib/pubid/cen_cenelec/single_identifier.rb +9 -90
  150. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  151. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  152. data/lib/pubid/cen_cenelec.rb +172 -1
  153. data/lib/pubid/cie/components/code.rb +8 -0
  154. data/lib/pubid/cie/identifier.rb +10 -57
  155. data/lib/pubid/cie/single_identifier.rb +4 -4
  156. data/lib/pubid/cie/urn_parser.rb +28 -0
  157. data/lib/pubid/cie.rb +47 -1
  158. data/lib/pubid/components/adoption.rb +104 -0
  159. data/lib/pubid/components/code.rb +22 -8
  160. data/lib/pubid/components/date.rb +23 -16
  161. data/lib/pubid/components/edition.rb +9 -6
  162. data/lib/pubid/components/iteration.rb +32 -0
  163. data/lib/pubid/components/language.rb +6 -4
  164. data/lib/pubid/components/locality.rb +10 -1
  165. data/lib/pubid/components/publisher.rb +9 -6
  166. data/lib/pubid/components/relationship.rb +151 -0
  167. data/lib/pubid/components/stage.rb +5 -14
  168. data/lib/pubid/components/supplement.rb +184 -0
  169. data/lib/pubid/components/type.rb +5 -15
  170. data/lib/pubid/components/typed_stage.rb +10 -11
  171. data/lib/pubid/components.rb +4 -1
  172. data/lib/pubid/core/update_codes.rb +28 -7
  173. data/lib/pubid/csa/identifier.rb +9 -59
  174. data/lib/pubid/csa/identifiers/base.rb +0 -123
  175. data/lib/pubid/csa/identifiers/cec.rb +0 -103
  176. data/lib/pubid/csa/identifiers/series.rb +0 -104
  177. data/lib/pubid/csa/renderer.rb +292 -0
  178. data/lib/pubid/csa/single_identifier.rb +1 -1
  179. data/lib/pubid/csa/urn_generator.rb +1 -1
  180. data/lib/pubid/csa/urn_parser.rb +33 -0
  181. data/lib/pubid/csa.rb +46 -1
  182. data/lib/pubid/etsi/components/code.rb +10 -9
  183. data/lib/pubid/etsi/components/version.rb +0 -5
  184. data/lib/pubid/etsi/identifier.rb +4 -55
  185. data/lib/pubid/etsi/identifiers/base.rb +31 -27
  186. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +1 -11
  187. data/lib/pubid/etsi/renderer.rb +42 -0
  188. data/lib/pubid/etsi/urn_parser.rb +34 -0
  189. data/lib/pubid/etsi.rb +44 -1
  190. data/lib/pubid/export/exporter.rb +4 -46
  191. data/lib/pubid/export/flavor_exporter.rb +111 -278
  192. data/lib/pubid/export.rb +0 -6
  193. data/lib/pubid/identifier.rb +92 -18
  194. data/lib/pubid/identifier_metadata.rb +1 -1
  195. data/lib/pubid/idf/builder.rb +3 -3
  196. data/lib/pubid/idf/identifier.rb +7 -66
  197. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  198. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  199. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  200. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  201. data/lib/pubid/idf/parser.rb +3 -2
  202. data/lib/pubid/idf/renderer.rb +84 -0
  203. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  204. data/lib/pubid/idf/urn_generator.rb +4 -39
  205. data/lib/pubid/idf/urn_parser.rb +25 -0
  206. data/lib/pubid/idf.rb +55 -1
  207. data/lib/pubid/iec/builder.rb +46 -64
  208. data/lib/pubid/iec/components/code.rb +8 -32
  209. data/lib/pubid/iec/components/publisher.rb +0 -1
  210. data/lib/pubid/iec/components.rb +14 -0
  211. data/lib/pubid/iec/identifier.rb +251 -213
  212. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  213. data/lib/pubid/iec/identifiers/base.rb +5 -33
  214. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  215. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  216. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +23 -26
  217. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  218. data/lib/pubid/iec/identifiers/fragment_identifier.rb +35 -24
  219. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  220. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  221. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  222. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  223. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  224. data/lib/pubid/iec/identifiers/sheet_identifier.rb +17 -11
  225. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  226. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  227. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  228. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  229. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  230. data/lib/pubid/iec/identifiers/test_report_form.rb +3 -35
  231. data/lib/pubid/iec/identifiers/vap_identifier.rb +24 -21
  232. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  233. data/lib/pubid/iec/identifiers/working_document.rb +2 -50
  234. data/lib/pubid/iec/identifiers.rb +30 -0
  235. data/lib/pubid/iec/parser.rb +13 -12
  236. data/lib/pubid/iec/renderer.rb +254 -0
  237. data/lib/pubid/iec/single_identifier.rb +6 -12
  238. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  239. data/lib/pubid/iec/urn_generator.rb +3 -3
  240. data/lib/pubid/iec/urn_parser.rb +3 -3
  241. data/lib/pubid/iec.rb +43 -67
  242. data/lib/pubid/ieee/builder.rb +12 -12
  243. data/lib/pubid/ieee/components/code.rb +8 -0
  244. data/lib/pubid/ieee/components/draft.rb +14 -0
  245. data/lib/pubid/ieee/components/relationship.rb +5 -149
  246. data/lib/pubid/ieee/identifier.rb +5 -52
  247. data/lib/pubid/ieee/identifiers/adopted_standard.rb +0 -9
  248. data/lib/pubid/ieee/identifiers/base.rb +221 -556
  249. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +0 -10
  250. data/lib/pubid/ieee/identifiers/corrigendum.rb +0 -12
  251. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +0 -10
  252. data/lib/pubid/ieee/identifiers/dual_identifier.rb +0 -4
  253. data/lib/pubid/ieee/identifiers/dual_published.rb +0 -4
  254. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +0 -9
  255. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +0 -10
  256. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  257. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +0 -18
  258. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +0 -6
  259. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  260. data/lib/pubid/ieee/identifiers/redlined_standard.rb +0 -7
  261. data/lib/pubid/ieee/identifiers/si_standard.rb +0 -38
  262. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  263. data/lib/pubid/ieee/pre_parser.rb +301 -0
  264. data/lib/pubid/ieee/renderer.rb +307 -0
  265. data/lib/pubid/ieee/urn_parser.rb +34 -0
  266. data/lib/pubid/ieee.rb +66 -1
  267. data/lib/pubid/ieee_debug.rb +0 -1
  268. data/lib/pubid/iho/builder.rb +2 -2
  269. data/lib/pubid/iho/identifier.rb +7 -59
  270. data/lib/pubid/iho/identifiers/base.rb +64 -31
  271. data/lib/pubid/iho/parser.rb +3 -3
  272. data/lib/pubid/iho/renderer.rb +30 -0
  273. data/lib/pubid/iho/urn_generator.rb +2 -2
  274. data/lib/pubid/iho/urn_parser.rb +58 -0
  275. data/lib/pubid/iho.rb +52 -1
  276. data/lib/pubid/iso/builder.rb +55 -53
  277. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  278. data/lib/pubid/iso/components/code.rb +7 -19
  279. data/lib/pubid/iso/components/publisher.rb +10 -8
  280. data/lib/pubid/iso/components.rb +2 -4
  281. data/lib/pubid/iso/identifier.rb +219 -252
  282. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  283. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  284. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  285. data/lib/pubid/iso/identifiers/data.rb +0 -1
  286. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  287. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  288. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  289. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  290. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  291. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  292. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  293. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  294. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  295. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  296. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  297. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  298. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  299. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  300. data/lib/pubid/iso/identifiers.rb +0 -1
  301. data/lib/pubid/iso/normalizer.rb +89 -0
  302. data/lib/pubid/iso/parser.rb +22 -4
  303. data/lib/pubid/iso/single_identifier.rb +0 -4
  304. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  305. data/lib/pubid/iso/urn_generator.rb +66 -182
  306. data/lib/pubid/iso/urn_parser.rb +12 -7
  307. data/lib/pubid/iso.rb +177 -2
  308. data/lib/pubid/itu/builder.rb +0 -12
  309. data/lib/pubid/itu/components/code.rb +9 -7
  310. data/lib/pubid/itu/components/sector.rb +15 -4
  311. data/lib/pubid/itu/components/series.rb +0 -4
  312. data/lib/pubid/itu/components.rb +11 -0
  313. data/lib/pubid/itu/identifier.rb +4 -116
  314. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  315. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  316. data/lib/pubid/itu/identifiers/base.rb +124 -128
  317. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  318. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  319. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  320. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  321. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  322. data/lib/pubid/itu/urn_parser.rb +23 -0
  323. data/lib/pubid/itu.rb +44 -1
  324. data/lib/pubid/jcgm/builder.rb +16 -8
  325. data/lib/pubid/jcgm/identifier.rb +0 -43
  326. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -9
  327. data/lib/pubid/jcgm/identifiers/gum_guide.rb +0 -12
  328. data/lib/pubid/jcgm/renderer.rb +68 -0
  329. data/lib/pubid/jcgm/single_identifier.rb +0 -8
  330. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  331. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  332. data/lib/pubid/jcgm.rb +43 -2
  333. data/lib/pubid/jis/builder.rb +44 -52
  334. data/lib/pubid/jis/identifier.rb +120 -46
  335. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  336. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  337. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  338. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  339. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  340. data/lib/pubid/jis/identifiers.rb +1 -1
  341. data/lib/pubid/jis/parser.rb +31 -5
  342. data/lib/pubid/jis/renderer.rb +69 -0
  343. data/lib/pubid/jis/single_identifier.rb +6 -12
  344. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  345. data/lib/pubid/jis/urn_parser.rb +23 -0
  346. data/lib/pubid/jis.rb +42 -2
  347. data/lib/pubid/nist/builder.rb +63 -1871
  348. data/lib/pubid/nist/caster.rb +1272 -0
  349. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  350. data/lib/pubid/nist/components/code.rb +9 -20
  351. data/lib/pubid/nist/components/supplement.rb +2 -2
  352. data/lib/pubid/nist/components.rb +0 -1
  353. data/lib/pubid/nist/identifier.rb +8 -60
  354. data/lib/pubid/nist/identifiers/base.rb +564 -492
  355. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  356. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  358. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  359. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  360. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
  361. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  362. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
  363. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  364. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  365. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  366. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  367. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  368. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  369. data/lib/pubid/nist/identifiers/report.rb +4 -2
  370. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  371. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  372. data/lib/pubid/nist/identifiers.rb +1 -0
  373. data/lib/pubid/nist/parser.rb +62 -452
  374. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  375. data/lib/pubid/nist/preprocessor.rb +428 -0
  376. data/lib/pubid/nist/renderer.rb +43 -0
  377. data/lib/pubid/nist/router.rb +148 -0
  378. data/lib/pubid/nist/series/base.rb +58 -0
  379. data/lib/pubid/nist/series/crpl.rb +13 -0
  380. data/lib/pubid/nist/series/fips.rb +14 -0
  381. data/lib/pubid/nist/series/ir.rb +60 -0
  382. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  383. data/lib/pubid/nist/series/mono.rb +19 -0
  384. data/lib/pubid/nist/series/ncstar.rb +20 -0
  385. data/lib/pubid/nist/series.rb +49 -0
  386. data/lib/pubid/nist/supplement_identifier.rb +3 -1
  387. data/lib/pubid/nist/urn_parser.rb +67 -0
  388. data/lib/pubid/nist.rb +86 -4
  389. data/lib/pubid/oiml/builder.rb +21 -3
  390. data/lib/pubid/oiml/components/code.rb +17 -0
  391. data/lib/pubid/oiml/identifier.rb +40 -46
  392. data/lib/pubid/oiml/identifiers/annex.rb +13 -46
  393. data/lib/pubid/oiml/identifiers/errata.rb +15 -0
  394. data/lib/pubid/oiml/identifiers.rb +1 -1
  395. data/lib/pubid/oiml/parser.rb +59 -12
  396. data/lib/pubid/oiml/renderer.rb +171 -0
  397. data/lib/pubid/oiml/single_identifier.rb +61 -42
  398. data/lib/pubid/oiml/supplement_identifier.rb +31 -17
  399. data/lib/pubid/oiml/urn_generator.rb +0 -8
  400. data/lib/pubid/oiml/urn_parser.rb +22 -0
  401. data/lib/pubid/oiml.rb +42 -1
  402. data/lib/pubid/plateau/identifier.rb +4 -55
  403. data/lib/pubid/plateau/identifiers/base.rb +45 -36
  404. data/lib/pubid/plateau/identifiers/handbook.rb +0 -6
  405. data/lib/pubid/plateau/identifiers/technical_report.rb +0 -4
  406. data/lib/pubid/plateau/renderer.rb +51 -0
  407. data/lib/pubid/plateau/supplement_identifier.rb +0 -4
  408. data/lib/pubid/plateau/urn_parser.rb +43 -0
  409. data/lib/pubid/plateau.rb +43 -1
  410. data/lib/pubid/renderers/directives_renderer.rb +22 -8
  411. data/lib/pubid/renderers/guide_renderer.rb +4 -2
  412. data/lib/pubid/renderers/human_readable.rb +18 -7
  413. data/lib/pubid/rendering/context.rb +28 -19
  414. data/lib/pubid/rendering.rb +0 -3
  415. data/lib/pubid/sae/components/date.rb +8 -0
  416. data/lib/pubid/sae/components/type.rb +5 -1
  417. data/lib/pubid/sae/identifier.rb +4 -35
  418. data/lib/pubid/sae/identifiers/base.rb +26 -31
  419. data/lib/pubid/sae/renderer.rb +36 -0
  420. data/lib/pubid/sae/urn_generator.rb +2 -10
  421. data/lib/pubid/sae/urn_parser.rb +36 -0
  422. data/lib/pubid/sae.rb +42 -1
  423. data/lib/pubid/urn_generator/base.rb +12 -12
  424. data/lib/pubid/urn_parser/base.rb +81 -0
  425. data/lib/pubid/urn_parser/errors.rb +9 -0
  426. data/lib/pubid/urn_parser.rb +14 -0
  427. data/lib/pubid/version.rb +1 -1
  428. data/lib/pubid.rb +45 -7
  429. data/lib/tasks/export.rake +6 -5
  430. data/lib/tasks/website-data.json +1940 -1882
  431. metadata +75 -45
  432. data/lib/pubid/amca/scheme.rb +0 -16
  433. data/lib/pubid/ansi/scheme.rb +0 -15
  434. data/lib/pubid/api/scheme.rb +0 -66
  435. data/lib/pubid/ashrae/scheme.rb +0 -53
  436. data/lib/pubid/asme/scheme.rb +0 -37
  437. data/lib/pubid/astm/scheme.rb +0 -55
  438. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  439. data/lib/pubid/bsi/scheme.rb +0 -243
  440. data/lib/pubid/ccsds/scheme.rb +0 -57
  441. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  442. data/lib/pubid/cie/scheme.rb +0 -64
  443. data/lib/pubid/components/factory.rb +0 -50
  444. data/lib/pubid/csa/scheme.rb +0 -44
  445. data/lib/pubid/etsi/scheme.rb +0 -42
  446. data/lib/pubid/export/data_class_exporter.rb +0 -59
  447. data/lib/pubid/export/ieee_exporter.rb +0 -78
  448. data/lib/pubid/export/itu_exporter.rb +0 -66
  449. data/lib/pubid/export/nist_exporter.rb +0 -64
  450. data/lib/pubid/export/registry_exporter.rb +0 -90
  451. data/lib/pubid/export/scheme_exporter.rb +0 -70
  452. data/lib/pubid/identifier_registry.rb +0 -198
  453. data/lib/pubid/idf/scheme.rb +0 -61
  454. data/lib/pubid/iec/scheme.rb +0 -71
  455. data/lib/pubid/ieee/scheme.rb +0 -90
  456. data/lib/pubid/iho/scheme.rb +0 -29
  457. data/lib/pubid/iso/identifiers/base.rb +0 -115
  458. data/lib/pubid/iso/scheme.rb +0 -193
  459. data/lib/pubid/itu/scheme.rb +0 -174
  460. data/lib/pubid/jcgm/scheme.rb +0 -60
  461. data/lib/pubid/jis/components/code.rb +0 -59
  462. data/lib/pubid/jis/identifiers/base.rb +0 -72
  463. data/lib/pubid/jis/scheme.rb +0 -49
  464. data/lib/pubid/nist/components/publisher.rb +0 -24
  465. data/lib/pubid/nist/scheme.rb +0 -199
  466. data/lib/pubid/oiml/identifiers/base.rb +0 -36
  467. data/lib/pubid/oiml/scheme.rb +0 -46
  468. data/lib/pubid/plateau/scheme.rb +0 -45
  469. data/lib/pubid/rendering/base.rb +0 -73
  470. data/lib/pubid/rendering/common.rb +0 -211
  471. data/lib/pubid/rendering/format.rb +0 -25
  472. data/lib/pubid/sae/scheme.rb +0 -47
  473. 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: fd077b48356a46dfb52d7b95e932c29e91e5fe1a7859c1128ddda22d768b4a96
4
+ data.tar.gz: 4e8059d20bed9297393f54bb894958a6c0ab8d92bef895fcb7528c291b3ff349
5
5
  SHA512:
6
- metadata.gz: 638b16ccaed8a371fecee3ec8372a9790ae4649d689d0aeafa306b4b1681e0df42365d5ede2da46da743f8b42e7a70ddcc882774a6c6c333a1a2fec8d30255e4
7
- data.tar.gz: 2d55ed5b29d6121665c808d697832307bcea629345b7782308c5c0fe76ffc9baae849f752a8f75b5d77c7b3aaed782be9e15dcc9e1dc85e7c229ae77cf4431b8
6
+ metadata.gz: 329f3776c53f4021bfd2d25bd8698fb9c01309a66f56e9334d815aee3fde8ce25b509637f97ffc4ef91f0dfb67d10768a33505a939109a305d34b2e917af8f6c
7
+ data.tar.gz: 79c43b4e3ca83fe379a588f20490850e6a88757e382f0f9b9fc88d9f31923aff8fd8a5d48670c33a0d0705747820c6b3548260334ebf4e63a09b60dab82ad4ec
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
@@ -1,57 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Pubid
4
- module Amca
5
- module Identifier
6
- # Parse an ACMA identifier string into an identifier object
7
- # @param identifier [String] The ACMA identifier string to parse
8
- # @return [Pubid::Amca::Identifier] The appropriate identifier object
9
- # @raise [Parslet::ParseFailed] If parsing fails
10
- def self.parse(identifier)
11
- parsed = Parser.parse(identifier)
12
- Builder.build(parsed)
13
- rescue Parslet::ParseFailed => e
14
- raise "Failed to parse ACMA identifier '#{identifier}': #{e.message}"
15
- 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
- end
56
- end
57
- end
3
+ # Pubid::Amca::Identifier is the AMCA base class (a real Pubid::Identifier
4
+ # subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
5
+ # live in identifiers/base.rb. This file just ensures it is loaded.
6
+ require_relative "identifiers/base"
@@ -2,63 +2,74 @@
2
2
 
3
3
  module Pubid
4
4
  module Amca
5
- module Identifiers
6
- # Base identifier class for ACMA identifiers
7
- # Single Responsibility: Common functionality for all ACMA identifier types
8
- class Base < Pubid::Identifier
9
- # Override base_hash to handle AMCA-specific copublisher format (string, not array)
10
- def base_hash
11
- hash = super
12
- # AMCA's copublisher is a string, not an array, so remove it from copublishers
13
- hash.delete(:copublishers) if hash[:copublishers]
14
- hash
15
- end
5
+ # Base identifier class for AMCA identifiers. Canonical name
6
+ # Pubid::Amca::Identifier (Identifiers::Base is a back-compat alias); common
7
+ # functionality for all AMCA identifier types.
8
+ class Identifier < ::Pubid::Identifier
9
+ # @raise [Parslet::ParseFailed] If parsing fails
10
+ def self.parse(identifier)
11
+ parsed = Parser.parse(identifier)
12
+ Builder.build(parsed)
13
+ rescue Parslet::ParseFailed => e
14
+ raise "Failed to parse ACMA identifier '#{identifier}': #{e.message}"
15
+ end
16
16
 
17
- attribute :copublisher, :string
18
- attribute :code, Components::Code
19
- attribute :year, Components::Date
20
- attribute :suffix, :string
21
- attribute :reaffirmed, :string
17
+ # Stored as a plain string (always "AMCA") so it round-trips through
18
+ # to_hash/from_hash. Was a `def publisher` method, which made lutaml
19
+ # serialize a String against the Components::Publisher attribute and raise.
20
+ attribute :publisher, :string, default: -> { "AMCA" }
21
+ attribute :copublisher, :string
22
+ attribute :code, Components::Code
23
+ attribute :year, Components::Date
24
+ attribute :suffix, :string
25
+ attribute :reaffirmed, :string
22
26
 
23
- # AMCA uses a fixed publisher string
24
- def publisher
25
- "AMCA"
26
- end
27
+ # Explicit key_value mapping: only these keys serialize (the inherited
28
+ # Pubid::Identifier attributes — including :type, which subclasses expose
29
+ # as a class-metadata Hash via `self.type` — are intentionally dropped).
30
+ # code/year are flattened to their scalar value and rebuilt on load, since
31
+ # the Builder may store them as either a String or a component.
32
+ key_value do
33
+ map "_type", to: :_type
34
+ map "publisher", to: :publisher
35
+ map "copublisher", to: :copublisher
36
+ map "code", with: { to: :code_to_kv, from: :code_from_kv }
37
+ map "year", with: { to: :year_to_kv, from: :year_from_kv }
38
+ map "suffix", to: :suffix
39
+ map "reaffirmed", to: :reaffirmed
40
+ end
27
41
 
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
42
+ def to_urn
43
+ UrnGenerator.new(self).generate
44
+ end
39
45
 
40
- result = parts.compact.join(" ")
46
+ def code_to_kv(model, doc)
47
+ v = model.code.is_a?(::Pubid::Components::Code) ? model.code.value : model.code
48
+ return if v.nil? || v.to_s.empty?
41
49
 
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
50
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("code", v.to_s))
51
+ end
47
52
 
48
- result += " (#{reaffirmed})" if reaffirmed
53
+ def code_from_kv(model, value)
54
+ model.code = ::Pubid::Components::Code.new(value: value.to_s)
55
+ end
49
56
 
50
- result
51
- end
57
+ def year_to_kv(model, doc)
58
+ y = model.year.is_a?(::Pubid::Components::Date) ? model.year.year : model.year
59
+ return if y.nil? || y.to_s.empty?
52
60
 
53
- def self.parse(string)
54
- Amca::Identifier.parse(string)
55
- end
61
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("year", y.to_s))
62
+ end
56
63
 
57
- def to_urn
58
- require_relative "../urn_generator"
59
- UrnGenerator.new(self).generate
60
- end
64
+ def year_from_kv(model, value)
65
+ model.year = ::Pubid::Components::Date.new(year: value.to_s)
61
66
  end
62
67
  end
68
+
69
+ module Identifiers
70
+ # Backward-compatible alias: AMCA's base class used to be
71
+ # Pubid::Amca::Identifiers::Base. It is now Pubid::Amca::Identifier.
72
+ Base = Pubid::Amca::Identifier
73
+ end
63
74
  end
64
75
  end
@@ -24,27 +24,6 @@ reaffirmed: nil, interpretation_code: nil)
24
24
  def self.type
25
25
  { key: :interpretation, title: "Interpretation", short: "Interp" }
26
26
  end
27
-
28
- def type
29
- Interpretation.type
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
27
  end
49
28
  end
50
29
  end
@@ -24,23 +24,6 @@ reaffirmed: nil, revision: nil)
24
24
  def self.type
25
25
  { key: :publication, title: "Publication", short: nil }
26
26
  end
27
-
28
- def type
29
- Publication.type
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
27
  end
45
28
  end
46
29
  end
@@ -12,10 +12,6 @@ module Pubid
12
12
  def self.type
13
13
  { key: :standard, title: "Standard", short: nil }
14
14
  end
15
-
16
- def type
17
- Standard.type
18
- end
19
15
  end
20
16
  end
21
17
  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.respond_to?(:type) ? id.class.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
@@ -28,7 +28,8 @@ module Pubid
28
28
  end
29
29
 
30
30
  def urn_type
31
- identifier.type&.to_s&.downcase
31
+ (identifier.class.respond_to?(:type) ? identifier.class.type : nil)
32
+ &.to_s&.downcase
32
33
  end
33
34
 
34
35
  def generate
@@ -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