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
data/lib/pubid/astm.rb CHANGED
@@ -1,38 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "parslet"
4
- require "lutaml/model"
5
- require_relative "identifier"
6
- require_relative "astm/identifier"
7
- require_relative "astm/components/code"
8
- require_relative "astm/single_identifier"
9
- require_relative "astm/parser"
10
- require_relative "astm/builder"
11
-
12
- # Identifier classes
13
- require_relative "astm/identifiers/base"
14
- require_relative "astm/identifiers/standard"
15
- require_relative "astm/identifiers/iso_dual_published"
16
- require_relative "astm/identifiers/manual"
17
- require_relative "astm/identifiers/research_report"
18
- require_relative "astm/identifiers/data_series"
19
- require_relative "astm/identifiers/technical_report"
20
- require_relative "astm/identifiers/monograph"
21
- require_relative "astm/identifiers/adjunct"
22
- require_relative "astm/identifiers/work_in_progress"
23
-
24
- # Scheme (must be loaded after identifiers)
25
- require_relative "astm/scheme"
26
-
27
3
  module Pubid
28
4
  module Astm
5
+ autoload :Components, "#{__dir__}/astm/components"
6
+ autoload :Identifier, "#{__dir__}/astm/identifier"
7
+ autoload :Identifiers, "#{__dir__}/astm/identifiers"
8
+ autoload :SingleIdentifier, "#{__dir__}/astm/single_identifier"
9
+ autoload :Parser, "#{__dir__}/astm/parser"
10
+ autoload :Builder, "#{__dir__}/astm/builder"
11
+ autoload :Renderer, "#{__dir__}/astm/renderer"
12
+ autoload :UrnGenerator, "#{__dir__}/astm/urn_generator"
13
+ autoload :UrnParser, "#{__dir__}/astm/urn_parser"
14
+
29
15
  def self.parse(str)
30
16
  Identifier.parse(str)
31
17
  end
32
- end
33
18
 
34
- # Register this flavor with the Pubid registry
19
+ def self.identifier_types
20
+ @identifier_types ||= Identifiers.constants
21
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
22
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
23
+ .select { |c| c.type.is_a?(Hash) }
24
+ end
25
+
26
+ def self.all_typed_stages
27
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
28
+ if klass.const_defined?(:TYPED_STAGES)
29
+ klass.const_get(:TYPED_STAGES)
30
+ else
31
+ []
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.locate_type(code)
37
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
38
+ end
39
+
40
+ def self.locate_stage(abbr)
41
+ abbr_str = abbr.to_s.upcase
42
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
43
+ end
44
+ end
35
45
  end
36
46
 
37
- # Register Uastm flavor with the registry
38
47
  Pubid::Registry.register(:astm, Pubid::Astm)
48
+
49
+ Pubid::Astm::SingleIdentifier.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
50
+ Pubid::Astm::SingleIdentifier.format_registry.register(:human, renderer: Pubid::Astm::Renderer)
@@ -3,12 +3,19 @@
3
3
  module Pubid
4
4
  module Bsi
5
5
  class Builder < Pubid::Builder::Base
6
- def initialize(scheme)
7
- @scheme = scheme
8
- end
9
-
10
- def self.build(parsed_data, scheme = Scheme.new)
11
- new(scheme).build(parsed_data)
6
+ # Default typed stage used when an abbreviation lookup yields no match.
7
+ # Empty/unknown abbreviations fall back to the published British Standard.
8
+ DEFAULT_TYPED_STAGE = Pubid::Components::TypedStage.new(
9
+ code: :pubbs,
10
+ stage_code: :published,
11
+ type_code: :bs,
12
+ abbr: ["BS"],
13
+ name: "British Standard",
14
+ harmonized_stages: %w[60.00 60.60],
15
+ ).freeze
16
+
17
+ def self.build(parsed_data)
18
+ new.build(parsed_data)
12
19
  end
13
20
 
14
21
  def build(data)
@@ -122,7 +129,7 @@ module Pubid
122
129
  return identifier
123
130
  end
124
131
 
125
- # Determine identifier class using Scheme
132
+ # Determine identifier class using the module's lookup helpers
126
133
  identifier = locate_identifier_klass(data).new
127
134
  assign_attributes(identifier, data)
128
135
 
@@ -934,17 +941,19 @@ module Pubid
934
941
  return Identifiers::AdoptedEuropeanNorm if parsed_hash[:adopted_string]&.match?(/^EN\s+\d/)
935
942
  return Identifiers::AdoptedInternationalStandard if parsed_hash[:adopted_string]
936
943
 
937
- # Use type to determine class via Scheme
944
+ # Use type to determine class via Pubid::Bsi.locate_stage / locate_type.
945
+ # Unknown abbreviations fall back to DEFAULT_TYPED_STAGE (published BS).
938
946
  type_str = parsed_hash[:type] || parsed_hash[:stage] || ""
939
- typed_stage = @scheme.locate_typed_stage_by_abbr(type_str)
940
- @scheme.locate_identifier_klass_by_type_code(typed_stage.type_code)
947
+ typed_stage = Bsi.locate_stage(type_str.to_s.upcase) || DEFAULT_TYPED_STAGE
948
+ Bsi.locate_type(typed_stage.type_code) || Identifiers::BritishStandard
941
949
  end
942
950
 
943
951
  def cast(type, value)
944
952
  case type
945
953
  when :type
946
- # Lookup from register
947
- typed_stage = @scheme.locate_typed_stage_by_abbr(value || "")
954
+ # Lookup from register via Pubid::Bsi.locate_stage.
955
+ # Unknown abbreviations fall back to DEFAULT_TYPED_STAGE (published BS).
956
+ typed_stage = Bsi.locate_stage(value.to_s.upcase) || DEFAULT_TYPED_STAGE
948
957
  {
949
958
  stage: typed_stage.to_stage,
950
959
  type: typed_stage.to_type,
@@ -2,7 +2,14 @@
2
2
 
3
3
  module Pubid
4
4
  module Bsi
5
+ # `extend Pubid::IdentifierFacade` adds polymorphic `from_hash` and pairs
6
+ # with `include Pubid::Bsi::Identifier` in SingleIdentifier (BSI's common
7
+ # ancestor — there is no Identifiers::Base) for identity (`is_a?`/`===`), so
8
+ # a consumer handed this module can deserialize and identity-check BSI ids
9
+ # through it.
5
10
  module Identifier
11
+ extend Pubid::IdentifierFacade
12
+
6
13
  def self.parse(string)
7
14
  # Delegate to IEC for bare IEC identifiers
8
15
  # This handles IEC-specific features like VAP suffixes (CSV, RLV, etc.)
@@ -15,73 +22,12 @@ module Pubid
15
22
  end
16
23
 
17
24
  parser = Parser.new
18
- scheme = Scheme.new
19
25
 
20
26
  parsed = parser.parse(string)
21
- Builder.build(parsed, scheme)
27
+ Builder.build(parsed)
22
28
  rescue Parslet::ParseFailed => e
23
29
  raise StandardError, "Failed to parse '#{string}': #{e.message}"
24
30
  end
25
-
26
- # Factory mirroring pubid 1.x's `Pubid::Bsi::Identifier.create` API.
27
- # Dispatches via {Pubid::Bsi::Scheme}'s IDENTIFIER_CLASS_MAP and
28
- # TYPED_STAGES_REGISTRY; default subclass is BritishStandard.
29
- #
30
- # BSI's renderer requires BSI-namespaced Component subclasses
31
- # (`Bsi::Components::*`), so coercion is inlined rather than reusing
32
- # {Pubid::Components::Factory}.
33
- def self.create(type: nil, stage: nil, **opts)
34
- klass = resolve_create_class(type: type, stage: stage)
35
- attrs = coerce_create_attrs(opts)
36
- ts = resolve_create_typed_stage(klass, stage)
37
- attrs[:typed_stage] = ts if ts
38
- klass.new(**attrs)
39
- end
40
-
41
- def self.resolve_create_class(type:, stage:)
42
- scheme = Scheme.new
43
- klass = nil
44
- if type
45
- klass = scheme.locate_identifier_klass_by_type_code(type)
46
- elsif stage
47
- ts = scheme.locate_typed_stage_by_abbr(stage.to_s)
48
- klass = scheme.locate_identifier_klass_by_type_code(ts.type_code) if ts
49
- end
50
- klass || Identifiers::BritishStandard
51
- end
52
-
53
- def self.resolve_create_typed_stage(klass, stage)
54
- if stage
55
- Scheme.new.locate_typed_stage_by_abbr(stage.to_s)
56
- elsif klass.const_defined?(:TYPED_STAGES)
57
- klass.const_get(:TYPED_STAGES).find do |ts|
58
- ts.stage_code.to_sym == :published
59
- end
60
- end
61
- end
62
-
63
- def self.coerce_create_attrs(opts)
64
- attrs = {}
65
- if (v = opts[:publisher])
66
- attrs[:publisher] = Components::Publisher.new(body: v.to_s)
67
- end
68
- %i[number part subpart].each do |k|
69
- v = opts[k]
70
- attrs[k] = Components::Code.new(value: v.to_s) unless v.nil?
71
- end
72
- if (v = opts[:year])
73
- attrs[:date] = Components::Date.new(year: v.to_s)
74
- end
75
- # BSI :edition is a plain string attribute (not a Component).
76
- attrs[:edition] = opts[:edition].to_s if opts[:edition]
77
- # TODO(create-shim): BSI also has prefix, flex_prefix, iteration,
78
- # second_number, month, translation_lang/upper attributes that
79
- # aren't yet wired through. Add as call sites require them.
80
- attrs
81
- end
82
- private_class_method :resolve_create_class,
83
- :resolve_create_typed_stage,
84
- :coerce_create_attrs
85
31
  end
86
32
  end
87
33
  end
@@ -10,8 +10,8 @@ module Pubid
10
10
  # "BS 1902-2.3:Addendum No. 1:1976"
11
11
  # "BS 2000-0:Addendum 1:1983"
12
12
  # "BS 6034:1981:Addendum No. 1:1986"
13
- class AddendumDocument < Base
14
- attribute :base_identifier, Base, polymorphic: true
13
+ class AddendumDocument < SingleIdentifier
14
+ attribute :base_identifier, ::Pubid::Identifier, polymorphic: true
15
15
  attribute :addendum_number, :string
16
16
  attribute :addendum_year, :integer
17
17
  attribute :addendum_type, :string, default: -> {
@@ -22,37 +22,7 @@ module Pubid
22
22
  } # Separator before Addendum (":" or " ")
23
23
 
24
24
  def to_s(lang: :en, lang_single: false)
25
- result = base_identifier.to_s(lang: lang, lang_single: lang_single)
26
-
27
- # Determine separator - if separator is explicitly ":", use it
28
- # Otherwise if base has year and doesn't already have double colon, use space
29
- base_has_year = base_identifier.to_s =~ /:(\d{4})$/
30
-
31
- sep = if separator == ":"
32
- ":"
33
- elsif base_has_year && base_identifier.to_s !~ /:\d{4}:/
34
- " "
35
- else
36
- separator
37
- end
38
-
39
- # Format: "BASE:Addendum No. N:YEAR" or "BASE Addendum No. N:YEAR" or "BASE:Addendum N:YEAR"
40
- result += sep
41
- result += "Addendum"
42
-
43
- # Add space after "Addendum" if there's a type prefix (like "No.")
44
- if addendum_type.empty?
45
- # No type prefix, but still need space before number
46
- else
47
- result += " #{addendum_type}"
48
- end
49
- result += " "
50
- result += " "
51
-
52
- result += addendum_number.to_s
53
- result += ":#{addendum_year}" if addendum_year
54
-
55
- result
25
+ render(format: :human, lang: lang, lang_single: lang_single)
56
26
  end
57
27
 
58
28
  def publisher
@@ -7,7 +7,7 @@ module Pubid
7
7
  # Example: "BS EN 10077-1:2006" where EN 10077-1:2006 is a CEN identifier object
8
8
  # Example: "BS EN ISO 8601:2019" where EN ISO 8601:2019 is a CEN AdoptedEuropeanNorm wrapping ISO
9
9
  class AdoptedEuropeanNorm < BritishStandard
10
- attribute :adopted_identifier, Base, polymorphic: true # CEN object
10
+ attribute :adopted_identifier, ::Pubid::Identifier, polymorphic: true # CEN object
11
11
  attribute :edition, :string
12
12
  attribute :translation_lang, :string
13
13
  attribute :translation_upper, :string
@@ -16,53 +16,17 @@ module Pubid
16
16
  attribute :expert_commentary, :boolean
17
17
  attribute :expert_commentary_topic, :string
18
18
 
19
- def to_s(lang: :en, lang_single: false)
20
- # Get the BSI prefix (BS, PD, DD)
21
- prefix = case publisher
22
- when Components::Publisher
23
- publisher.body
24
- when Array
25
- publisher.join("/")
26
- when String
27
- publisher
28
- else
29
- "BS"
30
- end
31
-
32
- result = prefix
33
- result += " #{adopted_identifier}" if adopted_identifier
34
- result += " ED#{edition}" if edition
35
-
36
- # Reaffirmation notation like (R2004)
37
- result += " (R#{reaffirmation_year})" if reaffirmation_year
38
-
39
- # Translation - preserve the "version" or "Translation" suffix if present
40
- if translation_lang
41
- result += if translation_suffix_type == "version"
42
- " (#{translation_lang} version)"
43
- elsif translation_suffix_type == "Translation"
44
- " (#{translation_lang} Translation)"
45
- else
46
- " (#{translation_lang})"
47
- end
48
- elsif translation_upper
49
- result += if translation_suffix_type == "Translation"
50
- " (#{translation_upper} Translation)"
51
- else
52
- " (#{translation_upper})"
53
- end
54
- end
55
-
56
- # ExpertCommentary suffix
57
- if expert_commentary
58
- result += if expert_commentary_topic
59
- " ExComm (#{expert_commentary_topic})"
60
- else
61
- " ExComm"
62
- end
63
- end
19
+ # Override self.type to return nil so this polymorphic wrapper is not
20
+ # registered as a base type. Inherits `:bs` from BritishStandard which
21
+ # would otherwise shadow it in Bsi.locate_type(:bs) auto-discovery.
22
+ # AdoptedEuropeanNorm is constructed explicitly by the builder, not
23
+ # selected by type-code lookup.
24
+ def self.type
25
+ nil
26
+ end
64
27
 
65
- result
28
+ def to_s(lang: :en, lang_single: false)
29
+ render(format: :human, lang: lang, lang_single: lang_single)
66
30
  end
67
31
 
68
32
  # Delegate common methods to adopted identifier
@@ -7,7 +7,7 @@ module Pubid
7
7
  # Example: "BS ISO 8601:2019" where ISO 8601:2019 is an ISO identifier object
8
8
  # Example: "BS IEC 62600:2020" where IEC 62600:2020 is an IEC identifier object
9
9
  class AdoptedInternationalStandard < BritishStandard
10
- attribute :adopted_identifier, Base, polymorphic: true # ISO/IEC object
10
+ attribute :adopted_identifier, ::Pubid::Identifier, polymorphic: true # ISO/IEC object
11
11
  attribute :edition, :string
12
12
  attribute :translation_lang, :string
13
13
  attribute :translation_upper, :string
@@ -16,44 +16,17 @@ module Pubid
16
16
  attribute :expert_commentary, :boolean
17
17
  attribute :expert_commentary_topic, :string
18
18
 
19
- def to_s
20
- # Get the BSI prefix (BS, PD, DD)
21
- prefix = case publisher
22
- when Components::Publisher
23
- publisher.body
24
- when Array
25
- publisher.join("/")
26
- when String
27
- publisher
28
- else
29
- "BS"
30
- end
31
-
32
- result = prefix
33
- result += " #{adopted_identifier}" if adopted_identifier
34
- result += " ED#{edition}" if edition
35
-
36
- # Reaffirmation notation like (R2004)
37
- result += " (R#{reaffirmation_year})" if reaffirmation_year
38
-
39
- # Translation - normalize to just "(Language)" format
40
- # "(French version)", "(French Translation)", "(French)" all become "(French)"
41
- if translation_lang
42
- result += " (#{translation_lang})"
43
- elsif translation_upper
44
- result += " (#{translation_upper})"
45
- end
46
-
47
- # ExpertCommentary suffix
48
- if expert_commentary
49
- result += if expert_commentary_topic
50
- " ExComm (#{expert_commentary_topic})"
51
- else
52
- " ExComm"
53
- end
54
- end
19
+ # Override self.type to return nil so this polymorphic wrapper is not
20
+ # registered as a base type. Inherits `:bs` from BritishStandard which
21
+ # would otherwise shadow it in Bsi.locate_type(:bs) auto-discovery.
22
+ # AdoptedInternationalStandard is constructed explicitly by the builder,
23
+ # not selected by type-code lookup.
24
+ def self.type
25
+ nil
26
+ end
55
27
 
56
- result
28
+ def to_s
29
+ render(format: :human)
57
30
  end
58
31
 
59
32
  # Delegate common methods to adopted identifier
@@ -54,63 +54,13 @@ module Pubid
54
54
  ].freeze
55
55
 
56
56
  def self.type
57
- { key: :aerospace, title: "Aerospace/Specialized Standard",
57
+ { key: :aerospace,
58
+ web: :aerospace_standard, title: "Aerospace/Specialized Standard",
58
59
  short: "BS" }
59
60
  end
60
61
 
61
62
  def to_s(lang: :en, lang_single: false)
62
- parts = []
63
- parts << "BS" # Always BS for aerospace
64
- parts << prefix if prefix
65
-
66
- # Number with part/subpart and letter suffix edition
67
- if number
68
- number_str = number.is_a?(Components::Code) ? number.value.to_s : number.to_s
69
-
70
- # Part and subpart
71
- if part
72
- part_val = part.is_a?(Components::Code) ? part.value : part
73
- number_str += "-#{part_val}"
74
- end
75
- if subpart
76
- subpart_val = subpart.is_a?(Components::Code) ? subpart.value : subpart
77
- number_str += "-#{subpart_val}"
78
- end
79
-
80
- parts << number_str
81
- end
82
-
83
- result = parts.join(" ")
84
-
85
- # Letter suffix edition (for aerospace/specialized standards)
86
- # Append directly to number/part without space or v prefix
87
- # e.g., BS AU 145e:2018, BS AU 200-1a:1984
88
- if edition&.match?(/^[a-zA-Z]$/)
89
- result += edition
90
- end
91
-
92
- # Date
93
- if date
94
- year_val = date.is_a?(Components::Date) ? date.year : date.to_i
95
- result += ":#{year_val}"
96
- # Month if present
97
- result += "-#{format('%02d', month)}" if month
98
- end
99
-
100
- # Regular edition (non-letter suffix, like v1.0)
101
- # Only add if edition is not a single letter (already handled above)
102
- if edition && !edition.match?(/^[a-zA-Z]$/)
103
- result += " v#{edition}"
104
- end
105
-
106
- # Translation
107
- if translation_lang
108
- result += " (#{translation_lang})"
109
- elsif translation_upper
110
- result += " (#{translation_upper})"
111
- end
112
-
113
- result
63
+ render(format: :human, lang: lang, lang_single: lang_single)
114
64
  end
115
65
  end
116
66
  end
@@ -5,30 +5,14 @@ module Pubid
5
5
  module Identifiers
6
6
  # Amendment Identifier
7
7
  # Contains a base identifier plus amendment parameters
8
- class Amendment < Base
9
- attribute :base_identifier, Base, polymorphic: true
8
+ class Amendment < SingleIdentifier
9
+ attribute :base_identifier, ::Pubid::Identifier, polymorphic: true
10
10
  attribute :amendment_number, :string
11
11
  attribute :amendment_year, :integer
12
12
  attribute :separator, :string, default: -> { "+" }
13
13
 
14
14
  def to_s
15
- if base_identifier
16
- if amendment_year
17
- "#{base_identifier}#{separator}A#{amendment_number}:#{amendment_year}"
18
- elsif amendment_number&.match?(/^[A-Z]+$/)
19
- # Letter suffixes (AA, AB, etc.) have a space, numeric suffixes don't
20
- "#{base_identifier} AMD #{amendment_number}"
21
- else
22
- "#{base_identifier} AMD#{amendment_number}"
23
- end
24
- elsif amendment_year
25
- "#{separator}A#{amendment_number}:#{amendment_year}"
26
- elsif amendment_number&.match?(/^[A-Z]+$/)
27
- # Letter suffixes (AA, AB, etc.) have a space, numeric suffixes don't
28
- "AMD #{amendment_number}"
29
- else
30
- "AMD#{amendment_number}"
31
- end
15
+ render(format: :human)
32
16
  end
33
17
 
34
18
  def publisher
@@ -5,7 +5,7 @@ module Pubid
5
5
  module Identifiers
6
6
  # British Industrial Practice (BIP)
7
7
  # Examples: "BIP 2225:2022", "BIP 0142:2014", "BIP 0009:2020"
8
- class BritishIndustrialPractice < Base
8
+ class BritishIndustrialPractice < SingleIdentifier
9
9
  attribute :number, Bsi::Components::Code
10
10
  attribute :date, Bsi::Components::Date
11
11
 
@@ -17,9 +17,7 @@ module Pubid
17
17
  end
18
18
 
19
19
  def to_s(lang: :en, lang_single: false)
20
- result = "BIP #{number}"
21
- result += ":#{date.year}" if date
22
- result
20
+ render(format: :human, lang: lang, lang_single: lang_single)
23
21
  end
24
22
  end
25
23
  end
@@ -25,7 +25,8 @@ module Pubid
25
25
  ].freeze
26
26
 
27
27
  def self.type
28
- { key: :bs, title: "British Standard", short: "BS" }
28
+ { key: :bs,
29
+ web: :british_standard, title: "British Standard", short: "BS" }
29
30
  end
30
31
  end
31
32
  end
@@ -11,95 +11,14 @@ module Pubid
11
11
  # BS 2SP 68 to BS 2SP 71:1973
12
12
  # BS SP 13; 14; 15 and 16:1949
13
13
  # BS 4048:Parts 1 and 2:1966
14
- class BundledIdentifier < Base
15
- attribute :identifiers, Base, collection: true, polymorphic: true
14
+ class BundledIdentifier < SingleIdentifier
15
+ attribute :identifiers, ::Pubid::Identifier, collection: true, polymorphic: true
16
16
  attribute :separators, :string, collection: true # Separators between identifiers
17
17
  attribute :common_year, Bsi::Components::Date # Year applied to all if present
18
18
  attribute :bundle_type, :string # "Parts", "Sections", or nil for regular bundles
19
19
 
20
20
  def to_s(lang: :en, lang_single: false)
21
- return "" if identifiers.nil? || identifiers.empty?
22
-
23
- # Special case: Parts/Sections bundles like "BS 4048:Parts 1 and 2:1966"
24
- if bundle_type
25
- base_id = identifiers.first
26
- parts_list = identifiers[1..].map do |id|
27
- # Extract just the part number
28
- part_val = id.class.attributes.key?(:part) ? id.part : nil
29
- if part_val
30
- pv = part_val.is_a?(Components::Code) ? part_val.value : part_val
31
- pv.to_s
32
- else
33
- id.to_s
34
- end
35
- end.join(" and ")
36
-
37
- result = "#{base_id.to_s.sub(/:.*$/,
38
- '')}:#{bundle_type} #{parts_list}"
39
- result += ":#{common_year.year}" if common_year
40
- return result
41
- end
42
-
43
- # Regular bundle: render based on explicit markers
44
- parts = []
45
-
46
- identifiers.each_with_index do |id, i|
47
- # Check metadata flags for how item was parsed
48
- explicit_prefix = id.explicit_prefix
49
- explicit_publisher = id.explicit_publisher
50
-
51
- if i.zero?
52
- # First item always uses full form
53
- parts << id.to_s
54
- elsif explicit_publisher
55
- # Full form: has explicit publisher (e.g., "BS SP 50")
56
- parts << id.to_s
57
- elsif explicit_prefix
58
- # Prefix-only form: has explicit prefix but no publisher (e.g., "SP 138")
59
- abbrev_str = ""
60
- prefix = id.class.attributes.key?(:prefix) ? id.prefix : nil
61
- if prefix && !prefix.to_s.empty?
62
- abbrev_str = prefix.to_s
63
- end
64
- if id.number
65
- number_val = id.number.is_a?(Components::Code) ? id.number.value : id.number
66
- abbrev_str += " " if !abbrev_str.empty?
67
- abbrev_str += number_val.to_s
68
- end
69
- if id.part
70
- part_val = id.part.is_a?(Components::Code) ? id.part.value : id.part
71
- abbrev_str += "-#{part_val}"
72
- end
73
- parts << abbrev_str
74
- else
75
- # Minimal form: no explicit markers (e.g., "125")
76
- abbrev_str = ""
77
- if id.number
78
- number_val = id.number.is_a?(Components::Code) ? id.number.value : id.number
79
- abbrev_str = number_val.to_s
80
- end
81
- if id.part
82
- part_val = id.part.is_a?(Components::Code) ? id.part.value : id.part
83
- abbrev_str += "-#{part_val}"
84
- end
85
- parts << abbrev_str
86
- end
87
-
88
- # Add separator - preserve original spacing
89
- if i < identifiers.length - 1
90
- sep = separators[i] || " and "
91
- parts << sep
92
- end
93
- end
94
-
95
- result = parts.join
96
-
97
- # Add common year if present and not already in last identifier
98
- if common_year && !result.match?(/:#{common_year.year}$/)
99
- result += ":#{common_year.year}"
100
- end
101
-
102
- result
21
+ render(format: :human, lang: lang, lang_single: lang_single)
103
22
  end
104
23
 
105
24
  def <=>(other)
@@ -30,20 +30,7 @@ module Pubid
30
30
  end
31
31
 
32
32
  def to_s(lang: :en, lang_single: false)
33
- # Committee documents use a unique format: YY/NNNNNNNN DC
34
- # The year is 2-digit (extracted from date or use current date format)
35
- # Note: Assumes 2000s for years 00-99 (Y2K assumption)
36
- year_str = if date
37
- if date.is_a?(Components::Date)
38
- date.year.to_s[-2, 2]
39
- else
40
- date.to_s[-2, 2]
41
- end
42
- else
43
- "00" # Default if no date
44
- end
45
-
46
- "#{year_str}/#{document_number} DC"
33
+ render(format: :human, lang: lang, lang_single: lang_single)
47
34
  end
48
35
  end
49
36
  end