pubid 1.15.21 → 2.0.0.alpha.10

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 (863) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.adoc +2044 -53
  4. data/archived-gems/pubid-ccsds/update_codes.yaml +1 -0
  5. data/archived-gems/pubid-iec/stages.yaml +129 -0
  6. data/archived-gems/pubid-iec/update_codes.yaml +67 -0
  7. data/archived-gems/pubid-ieee/update_codes.yaml +104 -0
  8. data/archived-gems/pubid-iso/stages.yaml +106 -0
  9. data/archived-gems/pubid-iso/update_codes.yaml +4 -0
  10. data/archived-gems/pubid-itu/i18n.yaml +13 -0
  11. data/archived-gems/pubid-itu/series.yaml +42 -0
  12. data/archived-gems/pubid-nist/publishers.yaml +6 -0
  13. data/archived-gems/pubid-nist/series.yaml +121 -0
  14. data/archived-gems/pubid-nist/stages.yaml +16 -0
  15. data/archived-gems/pubid-nist/update_codes.yaml +93 -0
  16. data/archived-gems/pubid-plateau/update_codes.yaml +6 -0
  17. data/data/bipm/update_codes.yaml +9 -0
  18. data/data/ccsds/update_codes.yaml +1 -0
  19. data/data/iec/update_codes.yaml +70 -0
  20. data/data/ieee/update_codes.yaml +210 -0
  21. data/data/iso/update_codes.yaml +21 -0
  22. data/data/nist/series.yaml +155 -0
  23. data/data/nist/update_codes.yaml +122 -0
  24. data/data/plateau/update_codes.yaml +6 -0
  25. data/lib/pubid/adobe/builder.rb +52 -0
  26. data/lib/pubid/adobe/identifier.rb +47 -0
  27. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  28. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  29. data/lib/pubid/adobe/identifiers.rb +10 -0
  30. data/lib/pubid/adobe/parser.rb +136 -0
  31. data/lib/pubid/adobe/renderer.rb +39 -0
  32. data/lib/pubid/adobe/urn_generator.rb +42 -0
  33. data/lib/pubid/adobe/urn_parser.rb +69 -0
  34. data/lib/pubid/adobe.rb +60 -0
  35. data/lib/pubid/amca/builder.rb +176 -0
  36. data/lib/pubid/amca/identifier.rb +4 -0
  37. data/lib/pubid/amca/identifiers/base.rb +92 -0
  38. data/lib/pubid/amca/identifiers/interpretation.rb +38 -0
  39. data/lib/pubid/amca/identifiers/publication.rb +34 -0
  40. data/lib/pubid/amca/identifiers/standard.rb +20 -0
  41. data/lib/pubid/amca/identifiers.rb +11 -0
  42. data/lib/pubid/amca/parser.rb +153 -0
  43. data/lib/pubid/amca/renderer.rb +82 -0
  44. data/lib/pubid/amca/single_identifier.rb +10 -0
  45. data/lib/pubid/amca/urn_generator.rb +51 -0
  46. data/lib/pubid/amca/urn_parser.rb +28 -0
  47. data/lib/pubid/amca.rb +73 -0
  48. data/lib/pubid/ansi/builder.rb +54 -0
  49. data/lib/pubid/ansi/identifier.rb +31 -0
  50. data/lib/pubid/ansi/identifiers/american_national_standard.rb +13 -0
  51. data/lib/pubid/ansi/identifiers/standard.rb +15 -0
  52. data/lib/pubid/ansi/identifiers.rb +11 -0
  53. data/lib/pubid/ansi/parser.rb +91 -0
  54. data/lib/pubid/ansi/renderer.rb +53 -0
  55. data/lib/pubid/ansi/single_identifier.rb +16 -0
  56. data/lib/pubid/ansi/urn_generator.rb +41 -0
  57. data/lib/pubid/ansi/urn_parser.rb +23 -0
  58. data/lib/pubid/ansi.rb +68 -0
  59. data/lib/pubid/api/builder.rb +58 -0
  60. data/lib/pubid/api/components/code.rb +9 -0
  61. data/lib/pubid/api/identifier.rb +42 -0
  62. data/lib/pubid/api/identifiers/base.rb +12 -0
  63. data/lib/pubid/api/identifiers/bulletin.rb +13 -0
  64. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +13 -0
  65. data/lib/pubid/api/identifiers/mpms.rb +26 -0
  66. data/lib/pubid/api/identifiers/publication.rb +13 -0
  67. data/lib/pubid/api/identifiers/recommended_practice.rb +13 -0
  68. data/lib/pubid/api/identifiers/specification.rb +13 -0
  69. data/lib/pubid/api/identifiers/standard.rb +13 -0
  70. data/lib/pubid/api/identifiers/technical_report.rb +13 -0
  71. data/lib/pubid/api/identifiers/typeless_standard.rb +11 -0
  72. data/lib/pubid/api/identifiers.rb +18 -0
  73. data/lib/pubid/api/parser.rb +140 -0
  74. data/lib/pubid/api/renderer.rb +98 -0
  75. data/lib/pubid/api/single_identifier.rb +24 -0
  76. data/lib/pubid/api/urn_generator.rb +23 -0
  77. data/lib/pubid/api/urn_parser.rb +35 -0
  78. data/lib/pubid/api.rb +68 -0
  79. data/lib/pubid/ashrae/builder.rb +519 -0
  80. data/lib/pubid/ashrae/identifier.rb +8 -0
  81. data/lib/pubid/ashrae/identifiers/addenda_package.rb +42 -0
  82. data/lib/pubid/ashrae/identifiers/addendum.rb +44 -0
  83. data/lib/pubid/ashrae/identifiers/base.rb +119 -0
  84. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +43 -0
  85. data/lib/pubid/ashrae/identifiers/errata.rb +39 -0
  86. data/lib/pubid/ashrae/identifiers/guideline.rb +41 -0
  87. data/lib/pubid/ashrae/identifiers/interpretation.rb +45 -0
  88. data/lib/pubid/ashrae/identifiers/standard.rb +41 -0
  89. data/lib/pubid/ashrae/identifiers.rb +15 -0
  90. data/lib/pubid/ashrae/parser.rb +748 -0
  91. data/lib/pubid/ashrae/renderer.rb +117 -0
  92. data/lib/pubid/ashrae/single_identifier.rb +10 -0
  93. data/lib/pubid/ashrae/supplement_identifier.rb +38 -0
  94. data/lib/pubid/ashrae/urn_generator.rb +57 -0
  95. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  96. data/lib/pubid/ashrae.rb +77 -0
  97. data/lib/pubid/asme/builder.rb +162 -0
  98. data/lib/pubid/asme/components/code.rb +26 -0
  99. data/lib/pubid/asme/identifier.rb +24 -0
  100. data/lib/pubid/asme/identifiers/base.rb +10 -0
  101. data/lib/pubid/asme/identifiers/standard.rb +96 -0
  102. data/lib/pubid/asme/identifiers.rb +10 -0
  103. data/lib/pubid/asme/parser.rb +308 -0
  104. data/lib/pubid/asme/renderer.rb +66 -0
  105. data/lib/pubid/asme/single_identifier.rb +38 -0
  106. data/lib/pubid/asme/urn_generator.rb +133 -0
  107. data/lib/pubid/asme/urn_parser.rb +31 -0
  108. data/lib/pubid/asme.rb +67 -0
  109. data/lib/pubid/astm/builder.rb +166 -0
  110. data/lib/pubid/astm/components/code.rb +42 -0
  111. data/lib/pubid/astm/components.rb +9 -0
  112. data/lib/pubid/astm/identifier.rb +24 -0
  113. data/lib/pubid/astm/identifiers/adjunct.rb +28 -0
  114. data/lib/pubid/astm/identifiers/base.rb +13 -0
  115. data/lib/pubid/astm/identifiers/code_number.rb +81 -0
  116. data/lib/pubid/astm/identifiers/data_series.rb +13 -0
  117. data/lib/pubid/astm/identifiers/iso_dual_published.rb +65 -0
  118. data/lib/pubid/astm/identifiers/manual.rb +23 -0
  119. data/lib/pubid/astm/identifiers/monograph.rb +13 -0
  120. data/lib/pubid/astm/identifiers/research_report.rb +21 -0
  121. data/lib/pubid/astm/identifiers/standard.rb +23 -0
  122. data/lib/pubid/astm/identifiers/technical_report.rb +12 -0
  123. data/lib/pubid/astm/identifiers/work_in_progress.rb +12 -0
  124. data/lib/pubid/astm/identifiers.rb +19 -0
  125. data/lib/pubid/astm/parser.rb +244 -0
  126. data/lib/pubid/astm/renderer.rb +172 -0
  127. data/lib/pubid/astm/single_identifier.rb +47 -0
  128. data/lib/pubid/astm/urn_generator.rb +101 -0
  129. data/lib/pubid/astm/urn_parser.rb +30 -0
  130. data/lib/pubid/astm.rb +55 -0
  131. data/lib/pubid/bipm/builder.rb +163 -0
  132. data/lib/pubid/bipm/identifier.rb +285 -0
  133. data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
  134. data/lib/pubid/bipm/identifiers/guide.rb +35 -0
  135. data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
  136. data/lib/pubid/bipm/identifiers/mep.rb +33 -0
  137. data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
  138. data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
  139. data/lib/pubid/bipm/identifiers.rb +15 -0
  140. data/lib/pubid/bipm/parser.rb +237 -0
  141. data/lib/pubid/bipm/renderer.rb +118 -0
  142. data/lib/pubid/bipm/urn_generator.rb +58 -0
  143. data/lib/pubid/bipm/urn_parser.rb +60 -0
  144. data/lib/pubid/bipm.rb +91 -0
  145. data/lib/pubid/bsi/builder.rb +1495 -0
  146. data/lib/pubid/bsi/components/code.rb +11 -0
  147. data/lib/pubid/bsi/components/date.rb +11 -0
  148. data/lib/pubid/bsi/components/publisher.rb +11 -0
  149. data/lib/pubid/bsi/components/type.rb +11 -0
  150. data/lib/pubid/bsi/identifier.rb +6 -0
  151. data/lib/pubid/bsi/identifiers/addendum_document.rb +30 -0
  152. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +67 -0
  153. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +51 -0
  154. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +65 -0
  155. data/lib/pubid/bsi/identifiers/amendment.rb +48 -0
  156. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +21 -0
  157. data/lib/pubid/bsi/identifiers/british_standard.rb +34 -0
  158. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +40 -0
  159. data/lib/pubid/bsi/identifiers/committee_document.rb +44 -0
  160. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +84 -0
  161. data/lib/pubid/bsi/identifiers/corrigendum.rb +44 -0
  162. data/lib/pubid/bsi/identifiers/detailed_specification.rb +33 -0
  163. data/lib/pubid/bsi/identifiers/disc.rb +27 -0
  164. data/lib/pubid/bsi/identifiers/draft_document.rb +27 -0
  165. data/lib/pubid/bsi/identifiers/electronic_book.rb +16 -0
  166. data/lib/pubid/bsi/identifiers/expert_commentary.rb +36 -0
  167. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +35 -0
  168. data/lib/pubid/bsi/identifiers/flex.rb +30 -0
  169. data/lib/pubid/bsi/identifiers/handbook.rb +23 -0
  170. data/lib/pubid/bsi/identifiers/index.rb +30 -0
  171. data/lib/pubid/bsi/identifiers/method.rb +35 -0
  172. data/lib/pubid/bsi/identifiers/national_annex.rb +48 -0
  173. data/lib/pubid/bsi/identifiers/practice_guide.rb +21 -0
  174. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +27 -0
  175. data/lib/pubid/bsi/identifiers/published_document.rb +27 -0
  176. data/lib/pubid/bsi/identifiers/section.rb +32 -0
  177. data/lib/pubid/bsi/identifiers/set.rb +40 -0
  178. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +40 -0
  179. data/lib/pubid/bsi/identifiers/supplement_document.rb +29 -0
  180. data/lib/pubid/bsi/identifiers/supplementary_index.rb +35 -0
  181. data/lib/pubid/bsi/identifiers/technical_specification.rb +34 -0
  182. data/lib/pubid/bsi/identifiers/test_method.rb +35 -0
  183. data/lib/pubid/bsi/identifiers/value_added_publication.rb +37 -0
  184. data/lib/pubid/bsi/identifiers.rb +51 -0
  185. data/lib/pubid/bsi/model.rb +196 -0
  186. data/lib/pubid/bsi/parser.rb +673 -0
  187. data/lib/pubid/bsi/renderer.rb +1064 -0
  188. data/lib/pubid/bsi/single_identifier.rb +141 -0
  189. data/lib/pubid/bsi/urn_generator.rb +92 -0
  190. data/lib/pubid/bsi/urn_parser.rb +52 -0
  191. data/lib/pubid/bsi.rb +282 -0
  192. data/lib/pubid/builder/base.rb +187 -0
  193. data/lib/pubid/bundled_identifier.rb +134 -0
  194. data/lib/pubid/calconnect/builder.rb +38 -0
  195. data/lib/pubid/calconnect/identifier.rb +121 -0
  196. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  197. data/lib/pubid/calconnect/identifiers.rb +9 -0
  198. data/lib/pubid/calconnect/parser.rb +54 -0
  199. data/lib/pubid/calconnect/renderer.rb +36 -0
  200. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  201. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  202. data/lib/pubid/calconnect.rb +82 -0
  203. data/lib/pubid/ccsds/builder.rb +57 -0
  204. data/lib/pubid/ccsds/identifier.rb +76 -0
  205. data/lib/pubid/ccsds/identifiers/base.rb +41 -0
  206. data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +70 -0
  207. data/lib/pubid/ccsds/identifiers/corrigendum.rb +40 -0
  208. data/lib/pubid/ccsds/identifiers.rb +10 -0
  209. data/lib/pubid/ccsds/parser.rb +73 -0
  210. data/lib/pubid/ccsds/single_identifier.rb +77 -0
  211. data/lib/pubid/ccsds/supplement_identifier.rb +37 -0
  212. data/lib/pubid/ccsds/urn_generator.rb +115 -0
  213. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  214. data/lib/pubid/ccsds.rb +64 -0
  215. data/lib/pubid/cen_cenelec/builder.rb +362 -0
  216. data/lib/pubid/cen_cenelec/identifier.rb +38 -0
  217. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +45 -0
  218. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +19 -0
  219. data/lib/pubid/cen_cenelec/identifiers/base.rb +34 -0
  220. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +29 -0
  221. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +28 -0
  222. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +28 -0
  223. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +40 -0
  224. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +20 -0
  225. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +99 -0
  226. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +50 -0
  227. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +29 -0
  228. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +18 -0
  229. data/lib/pubid/cen_cenelec/identifiers/guide.rb +27 -0
  230. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +28 -0
  231. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +28 -0
  232. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +36 -0
  233. data/lib/pubid/cen_cenelec/identifiers.rb +32 -0
  234. data/lib/pubid/cen_cenelec/parser.rb +144 -0
  235. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  236. data/lib/pubid/cen_cenelec/single_identifier.rb +49 -0
  237. data/lib/pubid/cen_cenelec/supplement_identifier.rb +47 -0
  238. data/lib/pubid/cen_cenelec/urn_generator.rb +129 -0
  239. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  240. data/lib/pubid/cen_cenelec.rb +208 -0
  241. data/lib/pubid/cie/builder.rb +524 -0
  242. data/lib/pubid/cie/components/language.rb +58 -0
  243. data/lib/pubid/cie/identifier.rb +33 -0
  244. data/lib/pubid/cie/identifiers/bundle.rb +50 -0
  245. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  246. data/lib/pubid/cie/identifiers/conference.rb +37 -0
  247. data/lib/pubid/cie/identifiers/corrigendum.rb +34 -0
  248. data/lib/pubid/cie/identifiers/dual_published.rb +41 -0
  249. data/lib/pubid/cie/identifiers/identical.rb +64 -0
  250. data/lib/pubid/cie/identifiers/joint_published.rb +52 -0
  251. data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
  252. data/lib/pubid/cie/identifiers/standard.rb +93 -0
  253. data/lib/pubid/cie/identifiers/supplement.rb +47 -0
  254. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +24 -0
  255. data/lib/pubid/cie/identifiers.rb +19 -0
  256. data/lib/pubid/cie/parser.rb +396 -0
  257. data/lib/pubid/cie/single_identifier.rb +69 -0
  258. data/lib/pubid/cie/supplement_identifier.rb +39 -0
  259. data/lib/pubid/cie/urn_generator.rb +126 -0
  260. data/lib/pubid/cie/urn_parser.rb +28 -0
  261. data/lib/pubid/cie.rb +83 -0
  262. data/lib/pubid/components/adoption.rb +104 -0
  263. data/lib/pubid/components/code.rb +47 -0
  264. data/lib/pubid/components/date.rb +72 -0
  265. data/lib/pubid/components/edition.rb +35 -0
  266. data/lib/pubid/components/iteration.rb +32 -0
  267. data/lib/pubid/components/language.rb +39 -0
  268. data/lib/pubid/components/locality.rb +19 -0
  269. data/lib/pubid/components/publisher.rb +39 -0
  270. data/lib/pubid/components/relationship.rb +151 -0
  271. data/lib/pubid/components/stage.rb +45 -0
  272. data/lib/pubid/components/supplement.rb +184 -0
  273. data/lib/pubid/components/type.rb +48 -0
  274. data/lib/pubid/components/typed_stage.rb +58 -0
  275. data/lib/pubid/components.rb +19 -0
  276. data/lib/pubid/core/pattern_doc_generator.rb +272 -0
  277. data/lib/pubid/core/update_codes.rb +98 -0
  278. data/lib/pubid/core.rb +8 -0
  279. data/lib/pubid/csa/builder.rb +671 -0
  280. data/lib/pubid/csa/components/code.rb +9 -0
  281. data/lib/pubid/csa/components.rb +9 -0
  282. data/lib/pubid/csa/composite_identifier.rb +38 -0
  283. data/lib/pubid/csa/identifier.rb +570 -0
  284. data/lib/pubid/csa/identifiers/base.rb +10 -0
  285. data/lib/pubid/csa/identifiers/bundled.rb +141 -0
  286. data/lib/pubid/csa/identifiers/canadian_adopted.rb +82 -0
  287. data/lib/pubid/csa/identifiers/cec.rb +66 -0
  288. data/lib/pubid/csa/identifiers/combined.rb +158 -0
  289. data/lib/pubid/csa/identifiers/csa_adopted.rb +78 -0
  290. data/lib/pubid/csa/identifiers/package.rb +65 -0
  291. data/lib/pubid/csa/identifiers/series.rb +23 -0
  292. data/lib/pubid/csa/identifiers/standard.rb +10 -0
  293. data/lib/pubid/csa/identifiers.rb +17 -0
  294. data/lib/pubid/csa/parser.rb +449 -0
  295. data/lib/pubid/csa/renderer.rb +300 -0
  296. data/lib/pubid/csa/single_identifier.rb +119 -0
  297. data/lib/pubid/csa/urn_generator.rb +87 -0
  298. data/lib/pubid/csa/urn_parser.rb +33 -0
  299. data/lib/pubid/csa/wrapper_identifier.rb +64 -0
  300. data/lib/pubid/csa.rb +80 -0
  301. data/lib/pubid/doi/builder.rb +18 -0
  302. data/lib/pubid/doi/identifier.rb +49 -0
  303. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  304. data/lib/pubid/doi/identifiers.rb +9 -0
  305. data/lib/pubid/doi/parser.rb +52 -0
  306. data/lib/pubid/doi/renderer.rb +13 -0
  307. data/lib/pubid/doi.rb +55 -0
  308. data/lib/pubid/easc/builder.rb +55 -0
  309. data/lib/pubid/easc/identifier.rb +59 -0
  310. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  311. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  312. data/lib/pubid/easc/identifiers.rb +10 -0
  313. data/lib/pubid/easc/parser.rb +88 -0
  314. data/lib/pubid/easc/renderer.rb +48 -0
  315. data/lib/pubid/easc/urn_generator.rb +46 -0
  316. data/lib/pubid/easc/urn_parser.rb +57 -0
  317. data/lib/pubid/easc.rb +52 -0
  318. data/lib/pubid/ecma/builder.rb +45 -0
  319. data/lib/pubid/ecma/identifier.rb +147 -0
  320. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  321. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  322. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  323. data/lib/pubid/ecma/identifiers.rb +11 -0
  324. data/lib/pubid/ecma/parser.rb +76 -0
  325. data/lib/pubid/ecma/renderer.rb +67 -0
  326. data/lib/pubid/ecma/urn_generator.rb +46 -0
  327. data/lib/pubid/ecma/urn_parser.rb +51 -0
  328. data/lib/pubid/ecma.rb +67 -0
  329. data/lib/pubid/errors.rb +79 -0
  330. data/lib/pubid/etsi/builder.rb +142 -0
  331. data/lib/pubid/etsi/components/code.rb +43 -0
  332. data/lib/pubid/etsi/components/version.rb +32 -0
  333. data/lib/pubid/etsi/components.rb +10 -0
  334. data/lib/pubid/etsi/identifier.rb +4 -0
  335. data/lib/pubid/etsi/identifiers/amendment.rb +15 -0
  336. data/lib/pubid/etsi/identifiers/base.rb +74 -0
  337. data/lib/pubid/etsi/identifiers/corrigendum.rb +15 -0
  338. data/lib/pubid/etsi/identifiers/etsi_standard.rb +222 -0
  339. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +123 -0
  340. data/lib/pubid/etsi/identifiers.rb +13 -0
  341. data/lib/pubid/etsi/parser.rb +139 -0
  342. data/lib/pubid/etsi/renderer.rb +48 -0
  343. data/lib/pubid/etsi/urn_generator.rb +76 -0
  344. data/lib/pubid/etsi/urn_parser.rb +34 -0
  345. data/lib/pubid/etsi.rb +71 -0
  346. data/lib/pubid/export/auditor.rb +89 -0
  347. data/lib/pubid/export/exporter.rb +33 -0
  348. data/lib/pubid/export/flavor_exporter.rb +250 -0
  349. data/lib/pubid/export/result.rb +97 -0
  350. data/lib/pubid/export.rb +12 -0
  351. data/lib/pubid/format_detector.rb +16 -0
  352. data/lib/pubid/format_registry.rb +42 -0
  353. data/lib/pubid/gb/builder.rb +45 -0
  354. data/lib/pubid/gb/identifier.rb +67 -0
  355. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  356. data/lib/pubid/gb/identifiers.rb +9 -0
  357. data/lib/pubid/gb/parser.rb +63 -0
  358. data/lib/pubid/gb/renderer.rb +35 -0
  359. data/lib/pubid/gb.rb +87 -0
  360. data/lib/pubid/gost/builder.rb +148 -0
  361. data/lib/pubid/gost/identifier.rb +47 -0
  362. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  363. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  364. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  365. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  366. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  367. data/lib/pubid/gost/identifiers.rb +13 -0
  368. data/lib/pubid/gost/parser.rb +105 -0
  369. data/lib/pubid/gost/renderer.rb +48 -0
  370. data/lib/pubid/gost/urn_generator.rb +46 -0
  371. data/lib/pubid/gost/urn_parser.rb +52 -0
  372. data/lib/pubid/gost.rb +49 -0
  373. data/lib/pubid/iala/builder.rb +102 -0
  374. data/lib/pubid/iala/identifier.rb +90 -0
  375. data/lib/pubid/iala/identifiers/advice.rb +15 -0
  376. data/lib/pubid/iala/identifiers/annex.rb +57 -0
  377. data/lib/pubid/iala/identifiers/general_assembly.rb +19 -0
  378. data/lib/pubid/iala/identifiers/guideline.rb +17 -0
  379. data/lib/pubid/iala/identifiers/letter.rb +16 -0
  380. data/lib/pubid/iala/identifiers/manual.rb +18 -0
  381. data/lib/pubid/iala/identifiers/model_course.rb +17 -0
  382. data/lib/pubid/iala/identifiers/recommendation.rb +17 -0
  383. data/lib/pubid/iala/identifiers/report.rb +16 -0
  384. data/lib/pubid/iala/identifiers/resolution.rb +16 -0
  385. data/lib/pubid/iala/identifiers/standard.rb +17 -0
  386. data/lib/pubid/iala/identifiers.rb +19 -0
  387. data/lib/pubid/iala/parser.rb +138 -0
  388. data/lib/pubid/iala/renderer.rb +36 -0
  389. data/lib/pubid/iala/urn_generator.rb +49 -0
  390. data/lib/pubid/iala/urn_parser.rb +67 -0
  391. data/lib/pubid/iala.rb +71 -0
  392. data/lib/pubid/iana/builder.rb +22 -0
  393. data/lib/pubid/iana/identifier.rb +140 -0
  394. data/lib/pubid/iana/identifiers/registry.rb +69 -0
  395. data/lib/pubid/iana/identifiers.rb +9 -0
  396. data/lib/pubid/iana/parser.rb +38 -0
  397. data/lib/pubid/iana/renderer.rb +32 -0
  398. data/lib/pubid/iana/urn_generator.rb +19 -0
  399. data/lib/pubid/iana/urn_parser.rb +24 -0
  400. data/lib/pubid/iana.rb +69 -0
  401. data/lib/pubid/identifier.rb +1118 -0
  402. data/lib/pubid/identifier_metadata.rb +148 -0
  403. data/lib/pubid/idf/builder.rb +82 -0
  404. data/lib/pubid/idf/identifier.rb +79 -0
  405. data/lib/pubid/idf/identifiers/amendment.rb +28 -0
  406. data/lib/pubid/idf/identifiers/corrigendum.rb +28 -0
  407. data/lib/pubid/idf/identifiers/international_standard.rb +124 -0
  408. data/lib/pubid/idf/identifiers/reviewed_method.rb +101 -0
  409. data/lib/pubid/idf/identifiers.rb +13 -0
  410. data/lib/pubid/idf/parser.rb +144 -0
  411. data/lib/pubid/idf/renderer.rb +84 -0
  412. data/lib/pubid/idf/single_identifier.rb +19 -0
  413. data/lib/pubid/idf/supplement_identifier.rb +35 -0
  414. data/lib/pubid/idf/urn_generator.rb +49 -0
  415. data/lib/pubid/idf/urn_parser.rb +25 -0
  416. data/lib/pubid/idf.rb +89 -0
  417. data/lib/pubid/iec/builder.rb +458 -0
  418. data/lib/pubid/iec/components/code.rb +36 -0
  419. data/lib/pubid/iec/components/consolidated_amendment.rb +59 -0
  420. data/lib/pubid/iec/components/publisher.rb +35 -0
  421. data/lib/pubid/iec/components/sheet.rb +32 -0
  422. data/lib/pubid/iec/components/trf_info.rb +38 -0
  423. data/lib/pubid/iec/components/vap_suffix.rb +41 -0
  424. data/lib/pubid/iec/components.rb +14 -0
  425. data/lib/pubid/iec/identifier.rb +341 -0
  426. data/lib/pubid/iec/identifiers/amendment.rb +97 -0
  427. data/lib/pubid/iec/identifiers/base.rb +54 -0
  428. data/lib/pubid/iec/identifiers/component_specification.rb +29 -0
  429. data/lib/pubid/iec/identifiers/conformity_assessment.rb +28 -0
  430. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +85 -0
  431. data/lib/pubid/iec/identifiers/corrigendum.rb +93 -0
  432. data/lib/pubid/iec/identifiers/fragment_identifier.rb +148 -0
  433. data/lib/pubid/iec/identifiers/guide.rb +86 -0
  434. data/lib/pubid/iec/identifiers/international_standard.rb +162 -0
  435. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +103 -0
  436. data/lib/pubid/iec/identifiers/operational_document.rb +29 -0
  437. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +88 -0
  438. data/lib/pubid/iec/identifiers/sheet_identifier.rb +68 -0
  439. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +30 -0
  440. data/lib/pubid/iec/identifiers/systems_reference_document.rb +29 -0
  441. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  442. data/lib/pubid/iec/identifiers/technical_report.rb +114 -0
  443. data/lib/pubid/iec/identifiers/technical_specification.rb +114 -0
  444. data/lib/pubid/iec/identifiers/technology_report.rb +28 -0
  445. data/lib/pubid/iec/identifiers/test_report_form.rb +35 -0
  446. data/lib/pubid/iec/identifiers/vap_identifier.rb +76 -0
  447. data/lib/pubid/iec/identifiers/white_paper.rb +29 -0
  448. data/lib/pubid/iec/identifiers/working_document.rb +62 -0
  449. data/lib/pubid/iec/identifiers.rb +31 -0
  450. data/lib/pubid/iec/parser.rb +443 -0
  451. data/lib/pubid/iec/renderer.rb +267 -0
  452. data/lib/pubid/iec/rendering_style.rb +113 -0
  453. data/lib/pubid/iec/single_identifier.rb +72 -0
  454. data/lib/pubid/iec/supplement_identifier.rb +178 -0
  455. data/lib/pubid/iec/urn_generator.rb +245 -0
  456. data/lib/pubid/iec/urn_parser.rb +128 -0
  457. data/lib/pubid/iec.rb +64 -0
  458. data/lib/pubid/ieee/aiee/builder.rb +85 -0
  459. data/lib/pubid/ieee/aiee/identifier.rb +89 -0
  460. data/lib/pubid/ieee/aiee/parser.rb +130 -0
  461. data/lib/pubid/ieee/aiee.rb +11 -0
  462. data/lib/pubid/ieee/builder.rb +1554 -0
  463. data/lib/pubid/ieee/compaction.rb +121 -0
  464. data/lib/pubid/ieee/components/code.rb +110 -0
  465. data/lib/pubid/ieee/components/draft.rb +147 -0
  466. data/lib/pubid/ieee/components/relationship.rb +13 -0
  467. data/lib/pubid/ieee/components/typed_stage.rb +100 -0
  468. data/lib/pubid/ieee/identifier.rb +5 -0
  469. data/lib/pubid/ieee/identifiers/adopted_standard.rb +81 -0
  470. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  471. data/lib/pubid/ieee/identifiers/base.rb +384 -0
  472. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  473. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +29 -0
  474. data/lib/pubid/ieee/identifiers/corrigendum.rb +40 -0
  475. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +62 -0
  476. data/lib/pubid/ieee/identifiers/dual_identifier.rb +14 -0
  477. data/lib/pubid/ieee/identifiers/dual_published.rb +79 -0
  478. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +115 -0
  479. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +48 -0
  480. data/lib/pubid/ieee/identifiers/joint_development.rb +223 -0
  481. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +85 -0
  482. data/lib/pubid/ieee/identifiers/nesc/base.rb +127 -0
  483. data/lib/pubid/ieee/identifiers/nesc/draft.rb +43 -0
  484. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  485. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +43 -0
  486. data/lib/pubid/ieee/identifiers/nesc/redline.rb +35 -0
  487. data/lib/pubid/ieee/identifiers/nesc/standard.rb +41 -0
  488. data/lib/pubid/ieee/identifiers/nesc.rb +16 -0
  489. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +14 -0
  490. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +49 -0
  491. data/lib/pubid/ieee/identifiers/redlined_standard.rb +26 -0
  492. data/lib/pubid/ieee/identifiers/si_standard.rb +38 -0
  493. data/lib/pubid/ieee/identifiers/standard.rb +44 -0
  494. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +42 -0
  495. data/lib/pubid/ieee/identifiers.rb +34 -0
  496. data/lib/pubid/ieee/ire/builder.rb +62 -0
  497. data/lib/pubid/ieee/ire/identifier.rb +73 -0
  498. data/lib/pubid/ieee/ire/parser.rb +91 -0
  499. data/lib/pubid/ieee/ire.rb +11 -0
  500. data/lib/pubid/ieee/nesc/builder.rb +114 -0
  501. data/lib/pubid/ieee/nesc/parser.rb +155 -0
  502. data/lib/pubid/ieee/nesc.rb +10 -0
  503. data/lib/pubid/ieee/parser.rb +1644 -0
  504. data/lib/pubid/ieee/pre_parser.rb +301 -0
  505. data/lib/pubid/ieee/renderer.rb +408 -0
  506. data/lib/pubid/ieee/typed_stages.rb +183 -0
  507. data/lib/pubid/ieee/urn_generator.rb +215 -0
  508. data/lib/pubid/ieee/urn_parser.rb +34 -0
  509. data/lib/pubid/ieee.rb +163 -0
  510. data/lib/pubid/ieee_debug.rb +30 -0
  511. data/lib/pubid/ietf/builder.rb +78 -0
  512. data/lib/pubid/ietf/identifier.rb +5 -0
  513. data/lib/pubid/ietf/identifiers/base.rb +72 -0
  514. data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
  515. data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
  516. data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
  517. data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
  518. data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
  519. data/lib/pubid/ietf/identifiers/std.rb +36 -0
  520. data/lib/pubid/ietf/identifiers.rb +14 -0
  521. data/lib/pubid/ietf/parser.rb +61 -0
  522. data/lib/pubid/ietf/renderer.rb +64 -0
  523. data/lib/pubid/ietf/urn_generator.rb +37 -0
  524. data/lib/pubid/ietf/urn_parser.rb +43 -0
  525. data/lib/pubid/ietf.rb +85 -0
  526. data/lib/pubid/iho/builder.rb +37 -0
  527. data/lib/pubid/iho/identifier.rb +7 -0
  528. data/lib/pubid/iho/identifiers/base.rb +75 -0
  529. data/lib/pubid/iho/identifiers/bibliographic.rb +16 -0
  530. data/lib/pubid/iho/identifiers/circular_letter.rb +15 -0
  531. data/lib/pubid/iho/identifiers/miscellaneous.rb +16 -0
  532. data/lib/pubid/iho/identifiers/publication.rb +15 -0
  533. data/lib/pubid/iho/identifiers/standard.rb +15 -0
  534. data/lib/pubid/iho/identifiers.rb +13 -0
  535. data/lib/pubid/iho/parser.rb +68 -0
  536. data/lib/pubid/iho/renderer.rb +30 -0
  537. data/lib/pubid/iho/urn_generator.rb +29 -0
  538. data/lib/pubid/iho/urn_parser.rb +58 -0
  539. data/lib/pubid/iho.rb +77 -0
  540. data/lib/pubid/isbn/builder.rb +44 -0
  541. data/lib/pubid/isbn/check_digit.rb +53 -0
  542. data/lib/pubid/isbn/identifier.rb +81 -0
  543. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  544. data/lib/pubid/isbn/identifiers.rb +9 -0
  545. data/lib/pubid/isbn/parser.rb +45 -0
  546. data/lib/pubid/isbn/renderer.rb +16 -0
  547. data/lib/pubid/isbn.rb +52 -0
  548. data/lib/pubid/iso/builder.rb +316 -0
  549. data/lib/pubid/iso/bundled_identifier.rb +138 -0
  550. data/lib/pubid/iso/combined_identifier.rb +24 -0
  551. data/lib/pubid/iso/components/code.rb +24 -0
  552. data/lib/pubid/iso/components/publisher.rb +62 -0
  553. data/lib/pubid/iso/components.rb +10 -0
  554. data/lib/pubid/iso/format_resolver.rb +45 -0
  555. data/lib/pubid/iso/identifier.rb +318 -0
  556. data/lib/pubid/iso/identifiers/addendum.rb +107 -0
  557. data/lib/pubid/iso/identifiers/amendment.rb +132 -0
  558. data/lib/pubid/iso/identifiers/corrigendum.rb +108 -0
  559. data/lib/pubid/iso/identifiers/data.rb +75 -0
  560. data/lib/pubid/iso/identifiers/directives.rb +65 -0
  561. data/lib/pubid/iso/identifiers/directives_supplement.rb +148 -0
  562. data/lib/pubid/iso/identifiers/extract.rb +30 -0
  563. data/lib/pubid/iso/identifiers/guide.rb +99 -0
  564. data/lib/pubid/iso/identifiers/international_standard.rb +168 -0
  565. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +94 -0
  566. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +95 -0
  567. data/lib/pubid/iso/identifiers/pas.rb +93 -0
  568. data/lib/pubid/iso/identifiers/recommendation.rb +45 -0
  569. data/lib/pubid/iso/identifiers/supplement.rb +95 -0
  570. data/lib/pubid/iso/identifiers/tc_document.rb +137 -0
  571. data/lib/pubid/iso/identifiers/technical_report.rb +103 -0
  572. data/lib/pubid/iso/identifiers/technical_specification.rb +102 -0
  573. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +95 -0
  574. data/lib/pubid/iso/identifiers.rb +32 -0
  575. data/lib/pubid/iso/normalizer.rb +89 -0
  576. data/lib/pubid/iso/parser.rb +534 -0
  577. data/lib/pubid/iso/rendering_style.rb +120 -0
  578. data/lib/pubid/iso/single_identifier.rb +60 -0
  579. data/lib/pubid/iso/supplement_identifier.rb +53 -0
  580. data/lib/pubid/iso/urn_generator.rb +313 -0
  581. data/lib/pubid/iso/urn_parser.rb +442 -0
  582. data/lib/pubid/iso/utilities.rb +86 -0
  583. data/lib/pubid/iso.rb +236 -0
  584. data/lib/pubid/itu/builder.rb +360 -0
  585. data/lib/pubid/itu/components/code.rb +84 -0
  586. data/lib/pubid/itu/components/designation.rb +35 -0
  587. data/lib/pubid/itu/components/sector.rb +46 -0
  588. data/lib/pubid/itu/components/series.rb +25 -0
  589. data/lib/pubid/itu/components.rb +12 -0
  590. data/lib/pubid/itu/i18n.rb +9 -0
  591. data/lib/pubid/itu/i18n.yaml +30 -0
  592. data/lib/pubid/itu/identifier.rb +4 -0
  593. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  594. data/lib/pubid/itu/identifiers/amendment.rb +19 -0
  595. data/lib/pubid/itu/identifiers/annex.rb +83 -0
  596. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  597. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  598. data/lib/pubid/itu/identifiers/base.rb +482 -0
  599. data/lib/pubid/itu/identifiers/combined_identifier.rb +121 -0
  600. data/lib/pubid/itu/identifiers/corrigendum.rb +35 -0
  601. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  602. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  603. data/lib/pubid/itu/identifiers/question.rb +63 -0
  604. data/lib/pubid/itu/identifiers/recommendation.rb +15 -0
  605. data/lib/pubid/itu/identifiers/report.rb +39 -0
  606. data/lib/pubid/itu/identifiers/special_publication.rb +31 -0
  607. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  608. data/lib/pubid/itu/identifiers/supplement.rb +149 -0
  609. data/lib/pubid/itu/identifiers.rb +25 -0
  610. data/lib/pubid/itu/model.rb +111 -0
  611. data/lib/pubid/itu/parser.rb +679 -0
  612. data/lib/pubid/itu/urn_generator.rb +135 -0
  613. data/lib/pubid/itu/urn_parser.rb +31 -0
  614. data/lib/pubid/itu.rb +78 -0
  615. data/lib/pubid/jcgm/builder.rb +106 -0
  616. data/lib/pubid/jcgm/components/publisher.rb +20 -0
  617. data/lib/pubid/jcgm/components.rb +9 -0
  618. data/lib/pubid/jcgm/identifier.rb +21 -0
  619. data/lib/pubid/jcgm/identifiers/amendment.rb +24 -0
  620. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  621. data/lib/pubid/jcgm/identifiers/guide.rb +21 -0
  622. data/lib/pubid/jcgm/identifiers/gum_guide.rb +39 -0
  623. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  624. data/lib/pubid/jcgm/identifiers.rb +13 -0
  625. data/lib/pubid/jcgm/parser.rb +151 -0
  626. data/lib/pubid/jcgm/renderer.rb +89 -0
  627. data/lib/pubid/jcgm/single_identifier.rb +118 -0
  628. data/lib/pubid/jcgm/supplement_identifier.rb +51 -0
  629. data/lib/pubid/jcgm/urn_generator.rb +116 -0
  630. data/lib/pubid/jcgm/urn_parser.rb +177 -0
  631. data/lib/pubid/jcgm.rb +86 -0
  632. data/lib/pubid/jis/builder.rb +116 -0
  633. data/lib/pubid/jis/identifier.rb +194 -0
  634. data/lib/pubid/jis/identifiers/amendment.rb +16 -0
  635. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  636. data/lib/pubid/jis/identifiers/explanation.rb +22 -0
  637. data/lib/pubid/jis/identifiers/japanese_industrial_standard.rb +16 -0
  638. data/lib/pubid/jis/identifiers/standard.rb +28 -0
  639. data/lib/pubid/jis/identifiers/technical_report.rb +32 -0
  640. data/lib/pubid/jis/identifiers/technical_specification.rb +32 -0
  641. data/lib/pubid/jis/identifiers.rb +17 -0
  642. data/lib/pubid/jis/parser.rb +135 -0
  643. data/lib/pubid/jis/renderer.rb +69 -0
  644. data/lib/pubid/jis/single_identifier.rb +31 -0
  645. data/lib/pubid/jis/supplement_identifier.rb +50 -0
  646. data/lib/pubid/jis/urn_generator.rb +25 -0
  647. data/lib/pubid/jis/urn_parser.rb +23 -0
  648. data/lib/pubid/jis.rb +69 -0
  649. data/lib/pubid/lutaml/no_store_registration.rb +30 -0
  650. data/lib/pubid/nist/builder.rb +481 -0
  651. data/lib/pubid/nist/caster.rb +1234 -0
  652. data/lib/pubid/nist/circular_supplement_builder.rb +293 -0
  653. data/lib/pubid/nist/components/code.rb +27 -0
  654. data/lib/pubid/nist/components/edition.rb +134 -0
  655. data/lib/pubid/nist/components/issue_number.rb +28 -0
  656. data/lib/pubid/nist/components/part.rb +77 -0
  657. data/lib/pubid/nist/components/stage.rb +53 -0
  658. data/lib/pubid/nist/components/supplement.rb +191 -0
  659. data/lib/pubid/nist/components/translation.rb +42 -0
  660. data/lib/pubid/nist/components/update.rb +103 -0
  661. data/lib/pubid/nist/components/version.rb +35 -0
  662. data/lib/pubid/nist/components/volume.rb +32 -0
  663. data/lib/pubid/nist/components.rb +18 -0
  664. data/lib/pubid/nist/configuration.rb +87 -0
  665. data/lib/pubid/nist/identifier.rb +8 -0
  666. data/lib/pubid/nist/identifiers/base.rb +744 -0
  667. data/lib/pubid/nist/identifiers/circular.rb +80 -0
  668. data/lib/pubid/nist/identifiers/circular_supplement.rb +60 -0
  669. data/lib/pubid/nist/identifiers/commercial_standard.rb +42 -0
  670. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +58 -0
  671. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +69 -0
  672. data/lib/pubid/nist/identifiers/crpl_report.rb +138 -0
  673. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  674. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +95 -0
  675. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +36 -0
  676. data/lib/pubid/nist/identifiers/handbook.rb +58 -0
  677. data/lib/pubid/nist/identifiers/internal_report.rb +64 -0
  678. data/lib/pubid/nist/identifiers/letter_circular.rb +46 -0
  679. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +74 -0
  680. data/lib/pubid/nist/identifiers/monograph.rb +80 -0
  681. data/lib/pubid/nist/identifiers/ncstar.rb +41 -0
  682. data/lib/pubid/nist/identifiers/nsrds.rb +41 -0
  683. data/lib/pubid/nist/identifiers/owmwp.rb +35 -0
  684. data/lib/pubid/nist/identifiers/report.rb +77 -0
  685. data/lib/pubid/nist/identifiers/special_publication.rb +46 -0
  686. data/lib/pubid/nist/identifiers/technical_note.rb +91 -0
  687. data/lib/pubid/nist/identifiers.rb +33 -0
  688. data/lib/pubid/nist/parser.rb +752 -0
  689. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  690. data/lib/pubid/nist/preprocessor.rb +443 -0
  691. data/lib/pubid/nist/renderer.rb +43 -0
  692. data/lib/pubid/nist/router.rb +149 -0
  693. data/lib/pubid/nist/series/base.rb +58 -0
  694. data/lib/pubid/nist/series/crpl.rb +13 -0
  695. data/lib/pubid/nist/series/fips.rb +14 -0
  696. data/lib/pubid/nist/series/ir.rb +57 -0
  697. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  698. data/lib/pubid/nist/series/mono.rb +19 -0
  699. data/lib/pubid/nist/series/ncstar.rb +20 -0
  700. data/lib/pubid/nist/series.rb +49 -0
  701. data/lib/pubid/nist/supplement_identifier.rb +84 -0
  702. data/lib/pubid/nist/urn_generator.rb +133 -0
  703. data/lib/pubid/nist/urn_parser.rb +67 -0
  704. data/lib/pubid/nist.rb +138 -0
  705. data/lib/pubid/oasis/builder.rb +79 -0
  706. data/lib/pubid/oasis/identifier.rb +160 -0
  707. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  708. data/lib/pubid/oasis/identifiers.rb +9 -0
  709. data/lib/pubid/oasis/parser.rb +34 -0
  710. data/lib/pubid/oasis/renderer.rb +29 -0
  711. data/lib/pubid/oasis/urn_generator.rb +25 -0
  712. data/lib/pubid/oasis/urn_parser.rb +22 -0
  713. data/lib/pubid/oasis.rb +79 -0
  714. data/lib/pubid/ogc/builder.rb +33 -0
  715. data/lib/pubid/ogc/identifier.rb +81 -0
  716. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  717. data/lib/pubid/ogc/identifiers.rb +10 -0
  718. data/lib/pubid/ogc/parser.rb +40 -0
  719. data/lib/pubid/ogc/renderer.rb +33 -0
  720. data/lib/pubid/ogc/urn_generator.rb +14 -0
  721. data/lib/pubid/ogc/urn_parser.rb +22 -0
  722. data/lib/pubid/ogc.rb +71 -0
  723. data/lib/pubid/oiml/builder.rb +270 -0
  724. data/lib/pubid/oiml/components/code.rb +37 -0
  725. data/lib/pubid/oiml/components.rb +9 -0
  726. data/lib/pubid/oiml/identifier.rb +64 -0
  727. data/lib/pubid/oiml/identifiers/amendment.rb +13 -0
  728. data/lib/pubid/oiml/identifiers/annex.rb +29 -0
  729. data/lib/pubid/oiml/identifiers/basic_publication.rb +15 -0
  730. data/lib/pubid/oiml/identifiers/bulletin.rb +137 -0
  731. data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
  732. data/lib/pubid/oiml/identifiers/document.rb +15 -0
  733. data/lib/pubid/oiml/identifiers/errata.rb +15 -0
  734. data/lib/pubid/oiml/identifiers/expert_report.rb +15 -0
  735. data/lib/pubid/oiml/identifiers/guide.rb +15 -0
  736. data/lib/pubid/oiml/identifiers/recommendation.rb +15 -0
  737. data/lib/pubid/oiml/identifiers/seminar_report.rb +15 -0
  738. data/lib/pubid/oiml/identifiers/vocabulary.rb +15 -0
  739. data/lib/pubid/oiml/identifiers.rb +20 -0
  740. data/lib/pubid/oiml/parser.rb +274 -0
  741. data/lib/pubid/oiml/renderer.rb +232 -0
  742. data/lib/pubid/oiml/single_identifier.rb +113 -0
  743. data/lib/pubid/oiml/supplement_identifier.rb +88 -0
  744. data/lib/pubid/oiml/urn_generator.rb +78 -0
  745. data/lib/pubid/oiml/urn_parser.rb +39 -0
  746. data/lib/pubid/oiml.rb +81 -0
  747. data/lib/pubid/omg/builder.rb +19 -0
  748. data/lib/pubid/omg/identifier.rb +47 -0
  749. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  750. data/lib/pubid/omg/identifiers.rb +9 -0
  751. data/lib/pubid/omg/parser.rb +40 -0
  752. data/lib/pubid/omg/renderer.rb +19 -0
  753. data/lib/pubid/omg.rb +51 -0
  754. data/lib/pubid/parser/common_parse_methods.rb +13 -0
  755. data/lib/pubid/parser/common_parse_rules.rb +56 -0
  756. data/lib/pubid/parser/grammar.rb +74 -0
  757. data/lib/pubid/parser.rb +9 -0
  758. data/lib/pubid/parsers/base.rb +11 -0
  759. data/lib/pubid/parsers/mr_string.rb +206 -0
  760. data/lib/pubid/plateau/builder.rb +54 -0
  761. data/lib/pubid/plateau/identifier.rb +4 -0
  762. data/lib/pubid/plateau/identifiers/annex.rb +16 -0
  763. data/lib/pubid/plateau/identifiers/base.rb +55 -0
  764. data/lib/pubid/plateau/identifiers/handbook.rb +28 -0
  765. data/lib/pubid/plateau/identifiers/technical_report.rb +16 -0
  766. data/lib/pubid/plateau/identifiers.rb +11 -0
  767. data/lib/pubid/plateau/parser.rb +73 -0
  768. data/lib/pubid/plateau/renderer.rb +51 -0
  769. data/lib/pubid/plateau/supplement_identifier.rb +68 -0
  770. data/lib/pubid/plateau/urn_generator.rb +29 -0
  771. data/lib/pubid/plateau/urn_parser.rb +43 -0
  772. data/lib/pubid/plateau.rb +82 -0
  773. data/lib/pubid/prefixes_support.rb +51 -0
  774. data/lib/pubid/renderers/annotator.rb +233 -0
  775. data/lib/pubid/renderers/base.rb +66 -0
  776. data/lib/pubid/renderers/directives_renderer.rb +75 -0
  777. data/lib/pubid/renderers/guide_renderer.rb +26 -0
  778. data/lib/pubid/renderers/human_readable.rb +83 -0
  779. data/lib/pubid/renderers/iwa_renderer.rb +20 -0
  780. data/lib/pubid/renderers/mr_string.rb +64 -0
  781. data/lib/pubid/renderers/supplement_renderer.rb +36 -0
  782. data/lib/pubid/renderers/urn.rb +11 -0
  783. data/lib/pubid/renderers.rb +15 -0
  784. data/lib/pubid/rendering/context.rb +168 -0
  785. data/lib/pubid/rendering/date.rb +27 -0
  786. data/lib/pubid/rendering/language.rb +21 -0
  787. data/lib/pubid/rendering/numbering.rb +42 -0
  788. data/lib/pubid/rendering/publisher.rb +25 -0
  789. data/lib/pubid/rendering/stage.rb +38 -0
  790. data/lib/pubid/rendering/supplement.rb +46 -0
  791. data/lib/pubid/rendering.rb +13 -0
  792. data/lib/pubid/sae/builder.rb +32 -0
  793. data/lib/pubid/sae/components/code.rb +9 -0
  794. data/lib/pubid/sae/components/date.rb +27 -0
  795. data/lib/pubid/sae/components/type.rb +23 -0
  796. data/lib/pubid/sae/components.rb +11 -0
  797. data/lib/pubid/sae/identifier.rb +4 -0
  798. data/lib/pubid/sae/identifiers/base.rb +47 -0
  799. data/lib/pubid/sae/identifiers.rb +8 -0
  800. data/lib/pubid/sae/parser.rb +55 -0
  801. data/lib/pubid/sae/renderer.rb +36 -0
  802. data/lib/pubid/sae/urn_generator.rb +30 -0
  803. data/lib/pubid/sae/urn_parser.rb +36 -0
  804. data/lib/pubid/sae.rb +66 -0
  805. data/lib/pubid/tgpp/builder.rb +41 -0
  806. data/lib/pubid/tgpp/identifier.rb +107 -0
  807. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  808. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  809. data/lib/pubid/tgpp/identifiers.rb +11 -0
  810. data/lib/pubid/tgpp/parser.rb +78 -0
  811. data/lib/pubid/tgpp/renderer.rb +52 -0
  812. data/lib/pubid/tgpp/urn_generator.rb +39 -0
  813. data/lib/pubid/tgpp/urn_parser.rb +30 -0
  814. data/lib/pubid/tgpp.rb +83 -0
  815. data/lib/pubid/type_resolver.rb +59 -0
  816. data/lib/pubid/un/builder.rb +42 -0
  817. data/lib/pubid/un/identifier.rb +40 -0
  818. data/lib/pubid/un/identifiers/document.rb +24 -0
  819. data/lib/pubid/un/identifiers.rb +9 -0
  820. data/lib/pubid/un/parser.rb +25 -0
  821. data/lib/pubid/un/renderer.rb +11 -0
  822. data/lib/pubid/un.rb +46 -0
  823. data/lib/pubid/urn_generator/base.rb +110 -0
  824. data/lib/pubid/urn_parser/base.rb +81 -0
  825. data/lib/pubid/urn_parser/errors.rb +16 -0
  826. data/lib/pubid/urn_parser.rb +14 -0
  827. data/lib/pubid/utils/string_normalizer.rb +196 -0
  828. data/lib/pubid/utils.rb +7 -0
  829. data/lib/pubid/version.rb +3 -1
  830. data/lib/pubid/w3c/builder.rb +55 -0
  831. data/lib/pubid/w3c/identifier.rb +130 -0
  832. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  833. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  834. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  835. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  836. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  837. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  838. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  839. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  840. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  841. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  842. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  843. data/lib/pubid/w3c/identifiers.rb +25 -0
  844. data/lib/pubid/w3c/parser.rb +43 -0
  845. data/lib/pubid/w3c/renderer.rb +35 -0
  846. data/lib/pubid/w3c/urn_generator.rb +18 -0
  847. data/lib/pubid/w3c/urn_parser.rb +36 -0
  848. data/lib/pubid/w3c.rb +67 -0
  849. data/lib/pubid/xsf/builder.rb +17 -0
  850. data/lib/pubid/xsf/identifier.rb +66 -0
  851. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  852. data/lib/pubid/xsf/identifiers.rb +9 -0
  853. data/lib/pubid/xsf/parser.rb +25 -0
  854. data/lib/pubid/xsf/renderer.rb +23 -0
  855. data/lib/pubid/xsf/urn_generator.rb +13 -0
  856. data/lib/pubid/xsf/urn_parser.rb +18 -0
  857. data/lib/pubid/xsf.rb +81 -0
  858. data/lib/pubid.rb +551 -13
  859. data/lib/tasks/docs.rake +37 -0
  860. data/lib/tasks/export.rake +39 -0
  861. data/lib/tasks/website-data.json +7546 -0
  862. metadata +875 -171
  863. data/lib/pubid/registry.rb +0 -30
@@ -0,0 +1,673 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Bsi
7
+ class Parser < ::Pubid::Parser::Grammar
8
+ # Case-insensitive string match (Parslet 2.0 has no built-in `stri`).
9
+ # Each character becomes a two-case character class; other characters
10
+ # (spaces, punctuation) match verbatim.
11
+ def stri(string)
12
+ string.each_char.map do |char|
13
+ if char =~ /[a-z]/i
14
+ match["#{char.upcase}#{char.downcase}"]
15
+ else
16
+ str(char)
17
+ end
18
+ end.reduce(:>>)
19
+ end
20
+
21
+ rule(:digit) { match["0-9"] }
22
+ rule(:digits) { digit.repeat(1) }
23
+ rule(:space) { str(" ") }
24
+ rule(:dash) { str("-") }
25
+ rule(:slash) { str("/") }
26
+ rule(:plus) { str("+") }
27
+ rule(:colon) { str(":") }
28
+
29
+ # BSI publisher
30
+ rule(:bs) { str("BS") | str("BSI") }
31
+
32
+ # Specialized prefixes - Multi-letter BEFORE single-letter (longest match first)
33
+ rule(:multi_letter_prefix) do
34
+ # Flex type prefixes for supplement/addendum documents (5-character first)
35
+ str("E9111") |
36
+ # CECC (4-character)
37
+ str("CECC") |
38
+ # 5-character prefixes
39
+ str("CISPR") |
40
+ # 4-character prefixes
41
+ str("2HC") | str("2HR") | str("2SP") | str("2TA") |
42
+ str("3HR") | str("3TA") |
43
+ # 3-character prefixes
44
+ str("2A") | str("2B") | str("2C") | str("2F") | str("2G") |
45
+ str("2L") | str("2M") | str("2S") |
46
+ str("3B") | str("3F") | str("3G") | str("3J") | str("3L") | str("3S") |
47
+ str("4F") | str("4L") | str("4S") |
48
+ str("5S") | str("7S") |
49
+ # 2-character prefixes
50
+ str("SP")
51
+ end
52
+
53
+ rule(:single_letter_prefix) do
54
+ # Two-letter prefixes BEFORE single-letter
55
+ str("AU") | str("HC") | str("MA") | str("PL") | str("QC") | str("TA") |
56
+ # Single-letter prefixes
57
+ str("A") | str("B") | str("C") | str("F") | str("G") |
58
+ str("L") | str("M") | str("S") | str("X")
59
+ end
60
+
61
+ rule(:specialized_prefix) do
62
+ (multi_letter_prefix | single_letter_prefix).as(:prefix)
63
+ end
64
+
65
+ # Flex documents (BSI Flex or just Flex) - BSI is already normalized to BS
66
+ rule(:flex) { str("BSI Flex") | str("BS Flex") | str("Flex") }
67
+
68
+ # Types for native BSI standards
69
+ rule(:dd) { str("DD") }
70
+ rule(:pd) { str("PD") }
71
+ rule(:pas) { str("PAS") }
72
+ rule(:na) { str("NA") }
73
+ rule(:ts) { str("TS") }
74
+ rule(:handbook) { str("Handbook") | str("HB") }
75
+ rule(:pp) { str("PP") }
76
+ rule(:bip) { str("BIP") }
77
+ rule(:ep_type) { str("EP") | str("ep") }
78
+
79
+ # Index suffix - handles three formats:
80
+ # 1. Colon format: BS 5000:Index:1981
81
+ # 2. Space format: BS 185 Index:1964
82
+ # 3. Issue format: BS 5000 Index Issue 4:1980
83
+ rule(:index_suffix) do
84
+ # Issue format: " Index Issue N" (must be before colon format to match correctly)
85
+ (space >> str("Index") >> space >> str("Issue") >> space >> digits.as(:issue_number)) |
86
+ # Colon format: ":Index"
87
+ (colon.as(:colon_sep) >> str("Index")) |
88
+ # Space format: " Index" (year rule includes the colon)
89
+ (space >> str("Index"))
90
+ end
91
+
92
+ # Supplementary Index suffix - handles one format:
93
+ # Space format: " Supplementary Index" (year rule includes the colon)
94
+ rule(:supplementary_index_suffix) do
95
+ space >> str("Supplementary Index")
96
+ end
97
+
98
+ # Explanatory Supplement suffix - handles one format:
99
+ # Colon format: ":Explanatory Supplement" (year rule includes the second colon)
100
+ rule(:explanatory_supplement_suffix) do
101
+ colon >> str("Explanatory Supplement")
102
+ end
103
+
104
+ # Method suffix - handles three formats:
105
+ # 1. Basic (singular): BS 2782-1:Method 131B:1983
106
+ # 2. Range (plural): BS 2782-4:Methods 451F to 451J:1978
107
+ # 3. And (plural): BS 2782-8:Methods 823A and 823B:1978
108
+ rule(:method_suffix) do
109
+ # Range format (plural): ":Methods X to Y" (must be first to match the "to" keyword)
110
+ (colon >> str("Methods") >> space >> method_code.as(:method_code) >> space >> str("to") >> space >> method_code.as(:method_to)) |
111
+ # And format (plural): ":Methods X and Y"
112
+ (colon >> str("Methods") >> space >> method_code.as(:method_code) >> space >> str("and") >> space >> method_code.as(:method_and)) |
113
+ # Basic format (singular): ":Method X"
114
+ (colon >> str("Method") >> space >> method_code.as(:method_code))
115
+ end
116
+
117
+ # Method code - alphanumeric like "131B", "451F", "823A", "1006"
118
+ rule(:method_code) { match["0-9A-Z"].repeat(1) }
119
+
120
+ # Test Method suffix - format: ":TEST:TESTID"
121
+ # Examples: BS 1006:B01C:LFS1:1982
122
+ rule(:test_method_suffix) do
123
+ colon >> match["0-9A-Z"].repeat(1).as(:test_series) >> colon >> match["0-9A-Z"].repeat(1).as(:test_id)
124
+ end
125
+
126
+ # Set separator - plus sign with optional spaces
127
+ # Handles: " + ", "+", " +", "+ "
128
+ rule(:set_separator) { space.maybe >> str("+") >> space.maybe }
129
+
130
+ # Set pattern - capture identifiers separated by +
131
+ # We'll parse each part separately in the builder
132
+ # Use a different approach to avoid key collision
133
+ rule(:set_item) do
134
+ # Wrap the item in a unique key to avoid merging
135
+ (bs.as(:publisher) >> space >>
136
+ (adopted_org_prefix.as(:adopted_org) >> space).maybe >>
137
+ number >> parts.maybe >>
138
+ year.maybe).as(:set_item)
139
+ end
140
+
141
+ # Parse a sequence of set items separated by +
142
+ rule(:set_items) do
143
+ # First item
144
+ set_item >> (set_separator >> set_item).repeat(1)
145
+ end
146
+
147
+ rule(:set_identifier) do
148
+ # Use as() on the whole sequence to capture the set structure
149
+ set_items.as(:set)
150
+ end
151
+
152
+ # Section suffix - handles two formats:
153
+ # 1. Colon format (DD): "DD 51:Section 0:1977"
154
+ # 2. Space format (BS): "BS 3224 Section B2:1970"
155
+ rule(:section_suffix) do
156
+ # Colon format: ":Section N" (DD format)
157
+ (colon.as(:colon_sep) >> str("Section") >> space >> section_id.as(:section_id)) |
158
+ # Space format: " Section N" (BS format)
159
+ (space >> str("Section") >> space >> section_id.as(:section_id))
160
+ end
161
+
162
+ # Section ID - can be numeric (0-7) or alphanumeric (B2, C1, D1, etc.)
163
+ rule(:section_id) { match["0-9A-Za-z"].repeat(1) }
164
+
165
+ # Detailed Specification suffix - N or C notation
166
+ # Formats: "BS 9074 N002:1974", "BS 9210 N0009-1:1978", "BS 9300 C155-168:1971"
167
+ # N notation: N<number> or N<number>-<part>
168
+ # C notation: C<start>-<end> (range)
169
+ rule(:detailed_spec_suffix) do
170
+ space >> (
171
+ # C notation with range: C155-168
172
+ (str("C") >> match["0-9"].repeat(1,
173
+ 3) >> dash >> match["0-9"].repeat(1,
174
+ 3)).as(:spec_code) |
175
+ # N notation with optional part: N002 or N0009-1
176
+ (str("N") >> match["0-9"].repeat(1,
177
+ 4) >> (dash >> match["0-9"].repeat(1)).maybe).as(:spec_code)
178
+ )
179
+ end
180
+
181
+ # Committee Document identifier
182
+ # Format: "YY/NNNNNNNN DC" (2-digit year, 8-digit number, DC suffix)
183
+ rule(:committee_document) do
184
+ (digit.repeat(2,
185
+ 2).as(:year) >> slash >> match["0-9"].repeat(8).as(:document_number) >> space >> str("DC")).as(:committee_document)
186
+ end
187
+
188
+ # Standalone Amendment identifier
189
+ # Formats: "AMD 11015", "(AMD 10971)", "AMD Corrigendum 14716"
190
+ rule(:standalone_amendment) do
191
+ # Parenthesized format: "(AMD 10971)" or "(AMD Corrigendum 14716)"
192
+ (str("(") >> str("AMD") >> space >> str("Corrigendum").as(:corrigendum) >> space >> digits.as(:amendment_number) >> str(")")).as(:parenthesized_amd) |
193
+ (str("(") >> str("AMD") >> space >> digits.as(:amendment_number) >> str(")")).as(:parenthesized_amd) |
194
+ # Regular format with corrigendum: "AMD Corrigendum 14716"
195
+ (str("AMD") >> space >> str("Corrigendum").as(:corrigendum) >> space >> digits.as(:amendment_number)).as(:standalone_amendment) |
196
+ # Basic format: "AMD 11015"
197
+ (str("AMD") >> space >> digits.as(:amendment_number)).as(:standalone_amendment)
198
+ end
199
+
200
+ # DISC identifier - "DISC PD <number>[-<part>]:<year>"
201
+ rule(:disc_prefix) { str("DISC PD ") }
202
+
203
+ # Stage prefixes
204
+ rule(:draft) { str("Draft BS") | str("DBS") }
205
+
206
+ # Adopted organizations - order matters!
207
+ rule(:en) { str("EN") }
208
+ rule(:iso) { str("ISO") }
209
+ rule(:iec) { str("IEC") }
210
+ rule(:cispr) { str("CISPR") }
211
+ rule(:cen) { str("CEN") }
212
+ rule(:clc) { str("CLC") }
213
+
214
+ # National Annex prefix (special case: "NA to BS..." or "NA+A1:2012 to BS...")
215
+ rule(:na_with_supplements) do
216
+ str("NA") >> supplement.repeat(1).as(:na_supplements) >> space >> str("to ")
217
+ end
218
+
219
+ rule(:na_simple) do
220
+ str("NA to ")
221
+ end
222
+
223
+ rule(:na_prefix) do
224
+ (na_with_supplements | na_simple).as(:na_prefix)
225
+ end
226
+
227
+ # Publisher/Type - longer patterns first
228
+ rule(:publisher_or_type) do
229
+ (na_prefix >>
230
+ (draft.as(:stage) |
231
+ dd.as(:type) |
232
+ pd.as(:type) |
233
+ bs.as(:publisher))) |
234
+ flex.as(:flex_type) |
235
+ handbook.as(:type) |
236
+ bip.as(:type) |
237
+ ts.as(:type) |
238
+ ep_type.as(:type) |
239
+ draft.as(:stage) |
240
+ dd.as(:type) |
241
+ pd.as(:type) |
242
+ pas.as(:type) |
243
+ pp.as(:type) |
244
+ na.as(:type) |
245
+ (bs.as(:publisher) >> space >> specialized_prefix) |
246
+ bs.as(:publisher)
247
+ end
248
+
249
+ # Number (with optional bracket notation for iterations like 1000[9])
250
+ # Allow alphanumeric for codes like E9111
251
+ rule(:number) { match["0-9A-Z"].repeat(1).as(:number) }
252
+
253
+ # Bracket notation for iterations (e.g., 1000[9])
254
+ rule(:bracket_iteration) do
255
+ str("[") >> match["0-9"].repeat(1).as(:iteration) >> str("]")
256
+ end
257
+
258
+ # Part with subpart (multi-level like 1-2)
259
+ # Must match before general :part rule
260
+ rule(:part_with_subpart) do
261
+ dash >> digits.as(:part) >> dash >> digits.as(:subpart)
262
+ end
263
+
264
+ # Part (can be multi-level like 1-2 or 2.3 with dots, or with letters like F3, or ampersand like 3A & B)
265
+ rule(:part) { dash >> match["0-9A-Za-z.& "].repeat(1).as(:part) }
266
+ rule(:parts) { (part_with_subpart | part).repeat(0).as(:parts) }
267
+
268
+ # Part with optional letter suffix edition for aerospace standards (e.g., "200-1a" or "50-1.1.1a")
269
+ # Must match before the regular part rule
270
+ rule(:part_with_letter_edition) do
271
+ # Part number (digits, dots) followed by single letter edition
272
+ (dash >> match["0-9."].repeat(1).as(:part) >> letter_edition.as(:letter_edition)) |
273
+ # Just part number (no edition)
274
+ (dash >> match["0-9."].repeat(1).as(:part))
275
+ end
276
+
277
+ # Number with optional letter suffix edition for aerospace standards (e.g., "145e" or "159G")
278
+ rule(:number_with_letter_edition) do
279
+ (match["0-9"].repeat(1).as(:number) >> letter_edition.as(:letter_edition)) |
280
+ match["0-9"].repeat(1).as(:number)
281
+ end
282
+
283
+ # Space-separated alphanumeric part (for bundled patterns like "9113 N001")
284
+ rule(:space_separated_part) do
285
+ space >> (match["A-Z"].repeat(1) >> match["0-9"].repeat(1)).as(:part)
286
+ end
287
+
288
+ # Iteration (for formats like BS 1000[9])
289
+ rule(:iteration) { bracket_iteration.repeat(0).as(:iteration) }
290
+
291
+ # Year (3 or 4 digits - some old standards have 3-digit years like :197)
292
+ rule(:year) { colon >> digit.repeat(3, 4).as(:year) }
293
+
294
+ # Base year (year in the base identifier, used when there's a supplement/addendum)
295
+ rule(:base_year) { colon >> digit.repeat(4, 4).as(:base_year) }
296
+
297
+ # Month (optional, like :2020-01)
298
+ rule(:month) { dash >> digit.repeat(2, 2).as(:month) }
299
+
300
+ # Edition (v1.0, v2.0, etc.) for Flex - lowercase v
301
+ rule(:flex_edition) do
302
+ space >> str("v") >> match["0-9."].repeat(1).as(:edition)
303
+ end
304
+
305
+ # Edition for IEC/ISO standards (ED2, ED3, etc.) - space before ED, uppercase
306
+ rule(:edition) { space >> str("ED") >> digits.as(:edition) }
307
+
308
+ # Letter suffix edition for aerospace/specialized standards (e.g., BS AU 145e:2018)
309
+ # Single letter (a-z or A-Z) that comes immediately after number or part
310
+ rule(:letter_edition) { match["a-zA-Z"].as(:letter_edition) }
311
+
312
+ # Amendment (+A1:2008 or /A2:2019 or /Amd 1:2020 or +A1:15 for short year,
313
+ # or +A2 / /A2 without a year — mirrors the optional-year corrigendum rule)
314
+ rule(:amendment) do
315
+ ((plus.as(:amd_sep_plus) | slash.as(:amd_sep_slash)) >>
316
+ str("A") >> digits.as(:amd_number) >>
317
+ (colon >> digit.repeat(2, 4).as(:amd_year)).maybe) |
318
+ ((plus.as(:amd_sep_plus) | slash.as(:amd_sep_slash)) >>
319
+ str("Amd") >> space >> digits.as(:amd_number) >>
320
+ (colon >> digit.repeat(4, 4).as(:amd_year)).maybe)
321
+ end
322
+
323
+ # Corrigendum (+AC:2009 or +AC1:2008 or /AC1:2005 or +C1:2018 or +C1 without year)
324
+ rule(:corrigendum) do
325
+ ((plus.as(:amd_sep_plus) | slash.as(:amd_sep_slash)) >>
326
+ str("AC") >> digits.maybe.as(:cor_number) >>
327
+ (colon >> digit.repeat(2, 4).as(:cor_year)).maybe) |
328
+ ((plus.as(:amd_sep_plus) | slash.as(:amd_sep_slash)) >>
329
+ str("C") >> digits.as(:cor_number) >>
330
+ (colon >> digit.repeat(2, 4).as(:cor_year)).maybe)
331
+ end
332
+
333
+ # AMD suffix without year - "AMD5", "AMD AA", "AMD11"
334
+ # Used after number/year on BS identifiers and adopted EN identifiers
335
+ rule(:amd_suffix) do
336
+ space >> str("AMD") >> space.maybe >>
337
+ (match["0-9"].repeat(1).as(:amd_number) | match["A-Z"].repeat(1).as(:amd_letter))
338
+ end
339
+
340
+ # AMD verbose form - "Amd 1 (09/15)" or "Amendment 2:August 2013"
341
+ rule(:amd_verbose) do
342
+ space >> (str("Amd") | str("Amendment")).as(:amd_verbose_type) >> space >>
343
+ match["0-9"].repeat(1).as(:amd_number) >>
344
+ (space >> str("(") >> match["0-9/"].repeat(1).as(:amd_date) >> str(")")).maybe >>
345
+ (colon >> match["A-Za-z"].repeat(1).as(:amd_month) >> space >> digit.repeat(
346
+ 4, 4
347
+ ).as(:amd_year)).maybe
348
+ end
349
+
350
+ # Supplements Document (not amendment/corrigendum supplements, but standalone supplement documents)
351
+ # Forward format: "BS NUMBER:Supplement No. N:YEAR" or "BS NUMBER Supplement N:YEAR"
352
+ # Also handles flex types: "BS CECC 50000:Supplement" or "BS M 31:Supplement"
353
+ # Reverse format: "Supplement No. N (YEAR) to BS NUMBER:YEAR"
354
+ rule(:supplement_document_forward) do
355
+ # With multi-letter flex type prefix (CECC, E9111, etc.)
356
+ (bs.as(:publisher) >> space >> multi_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
357
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >> str("No.").as(:supp_no_prefix) >> space >>
358
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
359
+ 4).as(:supplement_year)
360
+ ).as(:supplement_document) |
361
+ (bs.as(:publisher) >> space >> multi_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
362
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >>
363
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
364
+ 4).as(:supplement_year)
365
+ ).as(:supplement_document) |
366
+ # With single-letter flex type prefix (M, etc.)
367
+ (bs.as(:publisher) >> space >> single_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
368
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >> str("No.").as(:supp_no_prefix) >> space >>
369
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
370
+ 4).as(:supplement_year)
371
+ ).as(:supplement_document) |
372
+ (bs.as(:publisher) >> space >> single_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
373
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >>
374
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
375
+ 4).as(:supplement_year)
376
+ ).as(:supplement_document) |
377
+ # Without flex type prefix - with "No." prefix
378
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
379
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >> str("No.").as(:supp_no_prefix) >> space >>
380
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
381
+ 4).as(:supplement_year)
382
+ ).as(:supplement_document) |
383
+ # Without "No." prefix
384
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
385
+ (colon | space).as(:supp_sep) >> str("Supplement") >> space >>
386
+ digits.as(:supplement_number) >> colon >> digit.repeat(4,
387
+ 4).as(:supplement_year)
388
+ ).as(:supplement_document)
389
+ end
390
+
391
+ rule(:supplement_document_reverse) do
392
+ # With "No." prefix
393
+ (str("Supplement") >> space >> str("No.").as(:supp_no_prefix) >> space >>
394
+ digits.as(:supplement_number) >> space >> str("(") >> digit.repeat(4,
395
+ 4).as(:supplement_year) >>
396
+ str(")") >> space >> str("to ") >> bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
397
+ colon >> digit.repeat(4, 4).as(:base_year)
398
+ ).as(:supplement_document) |
399
+ # Without "No." prefix
400
+ (str("Supplement") >> space >>
401
+ digits.as(:supplement_number) >> space >> str("(") >> digit.repeat(4,
402
+ 4).as(:supplement_year) >>
403
+ str(")") >> space >> str("to ") >> bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
404
+ colon >> digit.repeat(4, 4).as(:base_year)
405
+ ).as(:supplement_document)
406
+ end
407
+
408
+ # Addendum Document
409
+ # Format: "BS NUMBER:Addendum No. N:YEAR" or "BS NUMBER Addendum N:YEAR"
410
+ # Also: "BS NUMBER:YEAR:Addendum No. N:YEAR" or "BS NUMBER:YEARAddendum No. N:YEAR" (space before Addendum)
411
+ # Also handles flex types: "BS CECC 90000:Addendum"
412
+ rule(:addendum_document) do
413
+ # With multi-letter flex type prefix (CECC, E9111, etc.)
414
+ (bs.as(:publisher) >> space >> multi_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
415
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >> str("No.").as(:add_no_prefix) >> space >>
416
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
417
+ 4).as(:addendum_year)
418
+ ).as(:addendum_document) |
419
+ (bs.as(:publisher) >> space >> multi_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
420
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >>
421
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
422
+ 4).as(:addendum_year)
423
+ ).as(:addendum_document) |
424
+ # With single-letter flex type prefix (M, etc.)
425
+ (bs.as(:publisher) >> space >> single_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
426
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >> str("No.").as(:add_no_prefix) >> space >>
427
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
428
+ 4).as(:addendum_year)
429
+ ).as(:addendum_document) |
430
+ (bs.as(:publisher) >> space >> single_letter_prefix.as(:flex_prefix) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
431
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >>
432
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
433
+ 4).as(:addendum_year)
434
+ ).as(:addendum_document) |
435
+ # With year before Addendum and SPACE separator: "BS NUMBER:YEAR Addendum No. N:YEAR"
436
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
437
+ colon >> digit.repeat(4,
438
+ 4).as(:base_year) >> space.as(:add_sep) >> str("Addendum") >> space >> str("No.").as(:add_no_prefix) >> space >>
439
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
440
+ 4).as(:addendum_year)
441
+ ).as(:addendum_document) |
442
+ # With year before Addendum and COLON separator: "BS NUMBER:YEAR:Addendum No. N:YEAR"
443
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
444
+ colon >> digit.repeat(4,
445
+ 4).as(:base_year) >> colon.as(:add_sep) >> str("Addendum") >> space >> str("No.").as(:add_no_prefix) >> space >>
446
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
447
+ 4).as(:addendum_year)
448
+ ).as(:addendum_document) |
449
+ # Without flex type prefix - with "No." prefix
450
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
451
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >> str("No.").as(:add_no_prefix) >> space >>
452
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
453
+ 4).as(:addendum_year)
454
+ ).as(:addendum_document) |
455
+ # Without "No." prefix
456
+ (bs.as(:publisher) >> space >> number.as(:number) >> iteration.as(:iteration) >> parts.as(:parts) >>
457
+ (colon | space).as(:add_sep) >> str("Addendum") >> space >>
458
+ digits.as(:addendum_number) >> colon >> digit.repeat(4,
459
+ 4).as(:addendum_year)
460
+ ).as(:addendum_document)
461
+ end
462
+
463
+ # Bundled Identifiers - Collections of standards published together
464
+ # Separators for bundles
465
+ rule(:bundle_sep_and) { space >> str("and") >> space }
466
+ rule(:bundle_sep_to) do
467
+ space >> (str("TO") | str("to")).as(:to_case) >> space
468
+ end
469
+ rule(:bundle_sep_ampersand) { space >> str("&") >> space }
470
+ rule(:bundle_sep_semicolon) { str(";") >> space }
471
+ rule(:bundle_sep_comma) { str(",") }
472
+
473
+ rule(:bundle_separator) do
474
+ bundle_sep_and.as(:sep_and) |
475
+ bundle_sep_to.as(:sep_to) |
476
+ bundle_sep_ampersand.as(:sep_ampersand) |
477
+ bundle_sep_semicolon.as(:sep_semicolon) |
478
+ bundle_sep_comma.as(:sep_comma)
479
+ end
480
+
481
+ # Parts/Sections bundle like "BS 4048:Parts 1 and 2:1966"
482
+ rule(:parts_bundle) do
483
+ (str("Parts") | str("Sections")).as(:bundle_type) >> space >>
484
+ match["0-9"].repeat(1).as(:part1) >>
485
+ bundle_sep_and >>
486
+ match["0-9."].repeat(1).as(:part2)
487
+ end
488
+
489
+ # Single identifier for bundling (without year in some cases)
490
+ # Enhanced to handle space-separated alphanumeric like "9113 N001"
491
+ # IMPORTANT: Order from most specific to least specific
492
+ rule(:bundle_item) do
493
+ # With full BS prefix and multi-letter specialized prefix (for "to" ranges like "BS 2SP 68 to BS 2SP 71")
494
+ (bs.as(:publisher) >> space >> multi_letter_prefix.as(:prefix) >> space >> number >> parts).as(:bundle_item) |
495
+ # With full BS prefix and single-letter specialized prefix
496
+ (bs.as(:publisher) >> space >> single_letter_prefix.as(:prefix) >> space >> number >> parts).as(:bundle_item) |
497
+ # With full BS prefix, number, and space-separated alphanumeric part
498
+ (bs.as(:publisher) >> space >> number >> space_separated_part).as(:bundle_item) |
499
+ # With full BS prefix only
500
+ (bs.as(:publisher) >> space >> number >> parts).as(:bundle_item) |
501
+ # Without BS prefix but with multi-letter prefix (continuing same type)
502
+ (multi_letter_prefix.as(:prefix) >> space >> number >> parts).as(:bundle_item) |
503
+ # Without BS prefix but with single-letter prefix
504
+ (single_letter_prefix.as(:prefix) >> space >> number >> parts).as(:bundle_item) |
505
+ # Number with space-separated alphanumeric part (BEFORE simple number+parts)
506
+ (number >> space_separated_part).as(:bundle_item) |
507
+ # Space-separated alphanumeric parts like "N001" (standalone, for abbreviated forms)
508
+ (match["A-Z"].repeat(1) >> match["0-9"].repeat(1)).as(:bundle_item) |
509
+ # Just number and parts (minimal form - LAST to avoid consuming space-separated)
510
+ (number >> parts).as(:bundle_item)
511
+ end
512
+
513
+ # Bundled identifier patterns
514
+ rule(:bundled_identifier) do
515
+ # Parts/Sections format: "BS NUMBER:Parts/Sections N and N:YEAR"
516
+ (publisher_or_type >> space >> number >> colon >> parts_bundle >> year).as(:bundled_parts) |
517
+ # List format with multiple separators: "BS SP 13; 14; 15 and 16:1949"
518
+ (publisher_or_type >> space >> bundle_item >>
519
+ (bundle_separator >> bundle_item).repeat(1) >>
520
+ year.maybe).as(:bundled_list)
521
+ end
522
+
523
+ # Supplements
524
+ rule(:supplement) do
525
+ (amendment | corrigendum | amd_suffix | amd_verbose).as(:supplement)
526
+ end
527
+ rule(:supplements) { supplement.repeat(0).as(:supplements) }
528
+
529
+ # Expert Commentary suffix - three formats:
530
+ # 1. "Expert Commentary" (full form)
531
+ # 2. "ExComm" (abbreviated form)
532
+ # 3. "ExComm (Fire)" (with optional topic suffix)
533
+ rule(:expert_commentary) do
534
+ space >> (
535
+ stri("Expert Commentary").as(:expert_commentary_full) |
536
+ (stri("ExComm") >> (space >> str("(") >> match["A-Za-z"].repeat(1).as(:expert_commentary_topic) >> str(")")).maybe).as(:expert_commentary)
537
+ )
538
+ end
539
+
540
+ # Tracked Changes suffix
541
+ rule(:tracked_changes) do
542
+ space >> dash >> space >> str("TC").as(:tracked_changes)
543
+ end
544
+
545
+ # PDF suffix
546
+ rule(:pdf_suffix) { space >> str("PDF").as(:pdf) }
547
+
548
+ # Translation (captures language name from various formats)
549
+ rule(:translation) do
550
+ (space >> str("(") >>
551
+ (
552
+ match["A-Za-z"].repeat(1).as(:translation_lang) >>
553
+ (space >> (str("Translation") | str("version"))).maybe
554
+ ) >>
555
+ str(")")) |
556
+ # All-caps format: " SPANISH TRANSLATION" (supplements already parsed)
557
+ (space >> (str("SPANISH") | str("FRENCH") | str("GERMAN") | str("ITALIAN")).as(:translation_upper) >> space >> str("TRANSLATION"))
558
+ end
559
+
560
+ # Collection number (second number after slash like 2035/2030)
561
+ rule(:collection_number) { slash >> digits.as(:second_number) }
562
+
563
+ # Adopted standard as opaque string
564
+ # Captures: "EN ISO 8601:2019", "EN IEC 62600:2020", "ISO 8601:2019", "IEC 62600:2020", "EN 10077-1:2006"
565
+ # Also CEN types: "CR 13933:2000", "ES 59008:2000", "ENV 41112:1991", "HD 60269-3", "CWA 13620-5:1999"
566
+ # IMPORTANT: Must NOT capture expert_commentary suffixes - let them be captured separately
567
+ rule(:adopted_org_prefix) do
568
+ str("EN") | str("ISO") | str("IEC") | str("CISPR") | str("CEN") | str("CLC") |
569
+ str("CR") | str("ES") | str("ENV") | str("HD") | str("CWA")
570
+ end
571
+
572
+ # Simple adopted string without expert commentary checks (for use in adopted_with_expert_commentary)
573
+ # Use character class that excludes "E" (first letter of "Expert Commentary" and "ExComm")
574
+ # This stops matching before expert commentary suffixes
575
+ rule(:adopted_string_no_expert) do
576
+ adopted_org_prefix >> match("[^E\n]").repeat(1).as(:adopted_string_no_expert)
577
+ end
578
+
579
+ # Match content that stops before expert commentary patterns and AMD suffixes
580
+ rule(:adopted_string_content) do
581
+ (supplement.absent? >> amd_suffix.absent? >> amd_verbose.absent? >> expert_commentary.absent? >> tracked_changes.absent? >> pdf_suffix.absent? >> translation.absent?) >>
582
+ match("[^\n]").repeat(1)
583
+ end
584
+
585
+ rule(:adopted_string) do
586
+ (adopted_org_prefix >> adopted_string_content).as(:adopted_string)
587
+ end
588
+
589
+ # Bare adopted identifier (no BSI prefix) - starts with ISO/IEC/CISPR
590
+ # IMPORTANT: Order in identifier rule handles this - bare_adopted is tried BEFORE publisher_or_type
591
+ # So we don't need to check for expert_commentary here
592
+ rule(:bare_adopted) do
593
+ (bs.absent? >> adopted_org_prefix >>
594
+ (supplement.absent? >> amd_suffix.absent? >> amd_verbose.absent? >> tracked_changes.absent? >> pdf_suffix.absent? >> translation.absent? >> match("[^\n]")).repeat(0)).as(:adopted_string)
595
+ end
596
+
597
+ # Value-Added Publication suffixes (wrapper pattern, not attributes)
598
+ rule(:vapSuffix) do
599
+ (space >> str("PDF").as(:pdf_format)) |
600
+ (space >> str("BOOK").as(:book_format)) |
601
+ (space >> dash >> space >> str("TC").as(:tc_format))
602
+ end
603
+
604
+ # Identifier patterns - try most specific first
605
+ rule(:identifier) do
606
+ # Standalone Amendment - must be first as it starts with "AMD"
607
+ standalone_amendment |
608
+ # Committee Document - must be before bare adopted as it starts with digits
609
+ committee_document |
610
+ # Index identifier - must be before regular identifier
611
+ (bs.as(:publisher) >> space >> number >> index_suffix.as(:index_suffix) >> year).as(:index_identifier) |
612
+ # Supplementary Index identifier - must be before regular identifier
613
+ (bs.as(:publisher) >> space >> number >> supplementary_index_suffix.as(:supplementary_index_suffix) >> year).as(:supplementary_index_identifier) |
614
+ # Explanatory Supplement identifier - must be before regular identifier
615
+ (bs.as(:publisher) >> space >> number >> parts >> explanatory_supplement_suffix.as(:explanatory_supplement_suffix) >> year).as(:explanatory_supplement_identifier) |
616
+ # Method identifier - must be before regular identifier
617
+ (bs.as(:publisher) >> space >> number >> parts >> method_suffix.as(:method_suffix) >> year).as(:method_identifier) |
618
+ # Test Method identifier - BS {number}:{test_series}:{test_id}:{year}
619
+ (bs.as(:publisher) >> space >> number >> test_method_suffix.as(:test_method_suffix) >> year).as(:test_method_identifier) |
620
+ # Section identifier - must be before regular identifier
621
+ (publisher_or_type >> space >> number >> section_suffix.as(:section_suffix) >> year).as(:section_identifier) |
622
+ # Detailed Specification identifier - must be before regular identifier
623
+ (bs.as(:publisher) >> space >> number >> detailed_spec_suffix.as(:detailed_spec_suffix) >> year).as(:detailed_specification) |
624
+ # Aerospace/Specialized identifier with letter suffix edition (e.g., BS AU 145e:2018)
625
+ # Must be before DISC and regular identifiers
626
+ # Supports supplements (+A1:2012, +C1:2020, etc.)
627
+ (bs.as(:publisher) >> space >> (single_letter_prefix | multi_letter_prefix).as(:prefix) >> space >>
628
+ number_with_letter_edition >> part_with_letter_edition.maybe >> iteration.as(:iteration).maybe >>
629
+ year >> supplements).as(:aerospace_identifier) |
630
+ # DISC identifier - "DISC PD <number>[-<part>]:<year>"
631
+ (disc_prefix >> number >> parts.maybe >> year).as(:disc_identifier) |
632
+ # Supplement Document - reverse format (Supplement No. N (YEAR) to BS...)
633
+ supplement_document_reverse.as(:supplement_document) |
634
+ # Supplement Document - forward format (BS NUMBER:Supplement No. N:YEAR)
635
+ supplement_document_forward |
636
+ # Addendum Document (BS NUMBER:Addendum No. N:YEAR)
637
+ addendum_document |
638
+ # Set identifier - multiple identifiers joined by +
639
+ # Must be BEFORE bare_adopted and regular identifier with adopted_string
640
+ set_identifier.as(:set) |
641
+ # Bundled Identifiers (must be before regular identifiers)
642
+ bundled_identifier |
643
+ # Bare adopted identifier (ISO, IEC without BSI prefix) - check BEFORE adopted_string
644
+ bare_adopted.as(:adopted_string) |
645
+ # Flex with v-style edition before date
646
+ (flex.as(:flex_type) >> space >> number >> parts >> flex_edition.maybe >> (year >> month.maybe).maybe >> supplements) |
647
+ # Regular BSI identifier - VAP suffix at the end
648
+ (publisher_or_type >>
649
+ (space >> adopted_string).maybe >>
650
+ (space >> number >> parts >> collection_number.maybe >>
651
+ (year >> month.maybe).maybe >>
652
+ flex_edition.maybe).maybe >>
653
+ supplements.maybe >>
654
+ edition.maybe >>
655
+ expert_commentary.maybe >>
656
+ translation.maybe >>
657
+ vapSuffix.maybe)
658
+ end
659
+
660
+ rule(:root) { identifier }
661
+
662
+ def self.parse(input)
663
+ # Normalize "BSI " to "BS " for consistency, but NOT for "BSI Flex"
664
+ normalized = if input.start_with?("BSI Flex")
665
+ input # Keep as is
666
+ else
667
+ input.gsub(/\bBSI\s+/, "BS ")
668
+ end
669
+ new.parse(normalized)
670
+ end
671
+ end
672
+ end
673
+ end