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
data/lib/pubid.rb CHANGED
@@ -1,15 +1,553 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require "parslet"
5
+
6
+ # Eagerly load the Lutaml::Model patch (disables reference store to avoid
7
+ # unbounded memory growth during bulk parsing, and adds a default +to_urn+
8
+ # implementation to every Serializable). This must apply before any Pubid
9
+ # code runs.
10
+ require "pubid/lutaml/no_store_registration"
11
+
12
+ # Uniform, static per-flavor prefix API (Pubid::<Flavor>.prefixes). Required
13
+ # before the flavor autoloads below so each flavor file can `extend` it and the
14
+ # central JOINT_PREFIXES constant is visible when its PREFIXES is defined.
15
+ require "pubid/prefixes_support"
16
+
1
17
  module Pubid
2
- end
18
+ # Upper bound on the length of an identifier string accepted by any +parse+
19
+ # entry point. Real-world standards identifiers are well under 200 characters;
20
+ # this limit exists purely to keep pathological, attacker-controlled inputs
21
+ # away from the flavors' backtracking-capable normalization regexes
22
+ # (CodeQL rb/polynomial-redos). The inline `.length` checks in every public
23
+ # +parse+ method are recognized by CodeQL as a barrier that bounds the input
24
+ # before it can reach those regexes. Ruby 3.2+ already memoizes the flagged
25
+ # regexes to linear time, so this guard is defense-in-depth, not a fix for a
26
+ # live exploit; it must therefore never reject a legitimate identifier.
27
+ MAX_INPUT_LENGTH = 1000
28
+
29
+ # Raised (as an ArgumentError) when an input string exceeds MAX_INPUT_LENGTH.
30
+ INPUT_TOO_LONG_MESSAGE =
31
+ "identifier string exceeds maximum length of #{MAX_INPUT_LENGTH} characters"
32
+
33
+ # Raised (as an ArgumentError) when +parse+ gets something that is not a
34
+ # String. Without this check the input reaches +.length+ and the caller gets a
35
+ # NoMethodError ("undefined method 'length' for nil"), a Ruby internal error
36
+ # that says nothing about the identifier contract. Every public +parse+ entry
37
+ # point rejects a non-String before it measures the length.
38
+ INPUT_NOT_A_STRING_MESSAGE = "identifier must be a String"
39
+
40
+ # Registry for tracking all loaded flavors
41
+ class Registry
42
+ @flavors = {}
43
+
44
+ class << self
45
+ attr_reader :flavors
46
+
47
+ # Register a flavor with the registry
48
+ # @param name [String, Symbol] Flavor name (e.g., :iso, :iec)
49
+ # @param flavor_module [Module] The flavor module (e.g., Pubid::Iso)
50
+ def register(name, flavor_module)
51
+ @flavors[name.to_s.downcase] = flavor_module
52
+ end
53
+
54
+ # Get all registered flavor names
55
+ # @return [Array<String>] Array of flavor names
56
+ def flavor_names
57
+ @flavors.keys.sort
58
+ end
59
+
60
+ # Get flavor module by name
61
+ # @param name [String, Symbol] Flavor name
62
+ # @return [Module, nil] The flavor module or nil if not found
63
+ def get(name)
64
+ @flavors[name.to_s.downcase]
65
+ end
66
+
67
+ # Check if a flavor is registered
68
+ # @param name [String, Symbol] Flavor name
69
+ # @return [Boolean]
70
+ def registered?(name)
71
+ @flavors.key?(name.to_s.downcase)
72
+ end
73
+
74
+ # Parse an identifier without naming its flavor.
75
+ #
76
+ # The pubid 1.x entry point, kept because consumers still call it —
77
+ # isodoc's +std_docid_semantic_parse+ among them. It delegates to
78
+ # {Pubid.parse}; it is not a second implementation.
79
+ #
80
+ # @param string [String] the identifier string
81
+ # @return [Pubid::Identifier]
82
+ # @raise [Parslet::ParseFailed] when no flavor can parse it
83
+ def parse(string, **opts)
84
+ Pubid.parse(string, **opts)
85
+ end
86
+ end
87
+ end
88
+
89
+ # Canonical joint / co-publication leading tokens, injected symmetrically into
90
+ # every participating flavor's +prefixes+ (see {PrefixesSupport}). Single
91
+ # source of truth: editing an entry here updates both sides at once
92
+ # (e.g. +"ISO/IEC"+ appears in +Pubid::Iso.prefixes+ and +Pubid::Iec.prefixes+),
93
+ # so co-publication symmetry can never drift. Keyed by
94
+ # {PrefixesSupport#prefix_flavor_key}.
95
+ JOINT_PREFIXES = {
96
+ iso: ["ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"],
97
+ iec: ["ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"],
98
+ ieee: ["ISO/IEC/IEEE"],
99
+ ansi: ["ANSI/ASHRAE", "ANSI/AMCA"],
100
+ ashrae: ["ANSI/ASHRAE"],
101
+ amca: ["ANSI/AMCA"],
102
+ }.freeze
103
+
104
+ autoload :Errors, "pubid/errors"
105
+ autoload :Parser, "pubid/parser"
106
+ autoload :Components, "pubid/components"
107
+ autoload :BundledIdentifier, "pubid/bundled_identifier"
108
+ autoload :Identifier, "pubid/identifier"
109
+ autoload :IdentifierMetadata, "pubid/identifier_metadata"
110
+ autoload :Rendering, "pubid/rendering"
111
+ autoload :Renderers, "pubid/renderers"
112
+ autoload :FormatDetector, "pubid/format_detector"
113
+ autoload :FormatRegistry, "pubid/format_registry"
114
+
115
+ autoload :UrnGenerator, "pubid/urn_generator/base"
116
+ autoload :UrnParser, "pubid/urn_parser"
117
+ autoload :Builder, "pubid/builder/base"
118
+ autoload :Utils, "pubid/utils"
119
+ autoload :Version, "pubid/version"
120
+ autoload :Core, "pubid/core"
121
+ autoload :TypeResolver, "pubid/type_resolver"
122
+
123
+
124
+ # Require all flavor modules
125
+ autoload :Adobe, "pubid/adobe"
126
+ autoload :Amca, "pubid/amca"
127
+ autoload :Ansi, "pubid/ansi"
128
+ autoload :Api, "pubid/api"
129
+ autoload :Ashrae, "pubid/ashrae"
130
+ autoload :Asme, "pubid/asme"
131
+ autoload :Doi, "pubid/doi"
132
+ autoload :Easc, "pubid/easc"
133
+ autoload :Astm, "pubid/astm"
134
+ autoload :Bipm, "pubid/bipm"
135
+ autoload :Bsi, "pubid/bsi"
136
+ autoload :Calconnect, "pubid/calconnect"
137
+ autoload :Ccsds, "pubid/ccsds"
138
+ autoload :CenCenelec, "pubid/cen_cenelec"
139
+ autoload :Cie, "pubid/cie"
140
+ autoload :Csa, "pubid/csa"
141
+ autoload :Ecma, "pubid/ecma"
142
+ autoload :Etsi, "pubid/etsi"
143
+ autoload :Gost, "pubid/gost"
144
+ autoload :Gb, "pubid/gb"
145
+ autoload :Idf, "pubid/idf"
146
+ autoload :Iec, "pubid/iec"
147
+ autoload :Ieee, "pubid/ieee"
148
+ autoload :Ietf, "pubid/ietf"
149
+ autoload :Isbn, "pubid/isbn"
150
+ autoload :Iala, "pubid/iala"
151
+ autoload :Iana, "pubid/iana"
152
+ autoload :Iho, "pubid/iho"
153
+ autoload :Iso, "pubid/iso"
154
+ autoload :Itu, "pubid/itu"
155
+ autoload :Jcgm, "pubid/jcgm"
156
+ autoload :Jis, "pubid/jis"
157
+ autoload :Nist, "pubid/nist"
158
+ autoload :Oasis, "pubid/oasis"
159
+ autoload :Ogc, "pubid/ogc"
160
+ autoload :Oiml, "pubid/oiml"
161
+ autoload :Omg, "pubid/omg"
162
+ autoload :Plateau, "pubid/plateau"
163
+ autoload :Export, "pubid/export"
164
+ autoload :Sae, "pubid/sae"
165
+ autoload :Tgpp, "pubid/tgpp"
166
+ autoload :Un, "pubid/un"
167
+ autoload :Xsf, "pubid/xsf"
168
+ autoload :W3c, "pubid/w3c"
169
+
170
+ # Format infrastructure (loaded eagerly so Pubid::Renderers / Pubid::Parsers are always available)
171
+ require "pubid/renderers/base"
172
+ require "pubid/renderers/mr_string"
173
+ require "pubid/renderers/urn"
174
+ require "pubid/parsers/base"
175
+ require "pubid/parsers/mr_string"
176
+
177
+ # Initialize global format registry
178
+ Identifier.format_registry = FormatRegistry.new
179
+ Identifier.format_registry.register(:human, renderer: Renderers::HumanReadable)
180
+ Identifier.format_registry.register(:mr_string, renderer: Renderers::MrString)
181
+ Identifier.format_registry.register(:urn, renderer: Renderers::Urn)
182
+
183
+ # Unified parse entry point with auto-detection
184
+ #
185
+ # A human-readable string is routed to its owning flavor by leading prefix
186
+ # token, using the {prefix_flavors} table. This restores the pubid 1.x
187
+ # +Pubid::Registry.parse+ capability, which isodoc still calls; before it,
188
+ # this method raised +No flavor specified+ for every human-readable string,
189
+ # so a reference whose flavor the caller did not already know could not be
190
+ # parsed at all.
191
+ #
192
+ # @param string [String] The identifier string to parse
193
+ # @param format [Symbol] :auto, :human, :mr_string, or :urn
194
+ # @return [Identifier] The parsed identifier
195
+ # @raise [ArgumentError] for a non-String, or one over {MAX_INPUT_LENGTH}
196
+ # @raise [Parslet::ParseFailed] when no flavor can parse the string — the
197
+ # class every flavor's own +parse+ raises (see the parse-failure contract)
198
+ def self.parse(string, format: :auto)
199
+ unless string.is_a?(String)
200
+ raise Pubid::Errors::InvalidInputError,
201
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
202
+ end
203
+ if string.length > MAX_INPUT_LENGTH
204
+ raise Pubid::Errors::InvalidInputError,
205
+ Pubid::INPUT_TOO_LONG_MESSAGE
206
+ end
207
+
208
+ format = FormatDetector.detect(string) if format == :auto
209
+
210
+ case format
211
+ when :mr_string
212
+ # The MR detector is a shape heuristic (`/\A[A-Z]{2,}[.-]/`), and some
213
+ # human-readable identifiers have that shape — "ITU-T G.711" is the
214
+ # standing example. Fall through to prefix routing when the MR parse
215
+ # fails, rather than reporting an MR error for a string that was never
216
+ # an MR string. A genuine MR failure still surfaces, from the second
217
+ # attempt, as Parslet::ParseFailed.
218
+ #
219
+ # Narrow, for the reason spelled out on {parse_by_prefix}: only a parse
220
+ # failure means "wrong shape". Anything else is a defect and propagates.
221
+ begin
222
+ Parsers::MrString.parse(string)
223
+ rescue Parslet::ParseFailed
224
+ parse_by_prefix(string)
225
+ end
226
+ when :urn
227
+ eager_load_flavors!
228
+ flavor = detect_flavor_from_urn(string)
229
+ flavor_module = Registry.get(flavor)
230
+ unless flavor_module
231
+ raise ArgumentError,
232
+ "Unknown flavor in URN: #{flavor}"
233
+ end
234
+
235
+ urn_parser = flavor_module.const_get(:UrnParser)
236
+ urn_parser.parse(string)
237
+ else
238
+ parse_by_prefix(string)
239
+ end
240
+ end
241
+
242
+ # Route a human-readable identifier to its flavor by leading prefix token.
243
+ #
244
+ # Three passes, widening each time — the pubid 1.x +Registry.parse+ shape:
245
+ #
246
+ # 1. flavors owning the longest matching prefix ("ISO/IEC" before "ISO")
247
+ # 2. every other flavor, in registry order
248
+ #
249
+ # A longest-match-first order matters because prefixes nest: "ISO/IEC 2131"
250
+ # must not be handed to the flavor that merely owns "ISO".
251
+ #
252
+ # @param string [String] a human-readable identifier
253
+ # @return [Identifier]
254
+ # @raise [Parslet::ParseFailed] when no flavor accepts the string
255
+ # @api private
256
+ def self.parse_by_prefix(string)
257
+ eager_load_flavors!
258
+
259
+ first_error = nil
260
+ fallback = nil
261
+
262
+ prefix_owners = candidates_by_prefix(string)
263
+ (prefix_owners + other_candidates(prefix_owners)).each do |mod|
264
+ begin
265
+ parsed = mod.parse(string)
266
+ rescue Parslet::ParseFailed => e
267
+ # ONLY a parse failure means "not this flavor's identifier". Every
268
+ # other exception is a defect in that flavor and must propagate.
269
+ #
270
+ # A blanket `rescue StandardError` here would swallow exactly the
271
+ # `ArgumentError: unknown attribute…` that the constructor contract on
272
+ # `Identifier` now raises — the error that turned three silent
273
+ # data-loss bugs (CIE `s_prefix`, IEEE `adopted_identifier`,
274
+ # IEEE `csa_identifier`) into visible ones. Catching it one layer up
275
+ # would hand it straight back its disguise: a real builder bug in any
276
+ # flavor would read as "this string is not an identifier".
277
+ first_error ||= e
278
+ next
279
+ end
3
280
 
4
- require_relative "pubid/registry"
5
-
6
- require "pubid-core"
7
- require "pubid-iso"
8
- require "pubid-ieee"
9
- require "pubid-nist"
10
- require "pubid-iec"
11
- require "pubid-cen"
12
- require "pubid-bsi"
13
- require "pubid-ccsds"
14
- require "pubid-itu"
15
- require "pubid-jis"
281
+ # An exact round trip is the strongest evidence the string belongs to
282
+ # this flavor. It matters because some grammars accept anything by
283
+ # design — adobe and iana take any slug — so without it the first such
284
+ # flavor in registry order claims every unclaimed string and invents
285
+ # structure that was not in the input. Same test isodoc applies before
286
+ # it will annotate a parsed id.
287
+ return parsed if parsed.to_s == string
288
+
289
+ # A non-exact parse is still usable — several flavors legitimately
290
+ # normalise on render, so the round trip is a preference, not a
291
+ # requirement (OGC prints `06-121r9` for `OGC 06-121r9`, and 32 ASHRAE /
292
+ # ASME / CSA / IEEE identifiers route only this way). What it must NOT
293
+ # come from is a flavor that accepts anything: that is how `iec.60050`
294
+ # came back as `IANA iec.60050`. Reporting that no flavor could be
295
+ # determined beats inventing one.
296
+ fallback ||= parsed unless accepts_anything?(mod)
297
+ end
298
+
299
+ return fallback if fallback
300
+ raise first_error if first_error
301
+
302
+ raise Parslet::ParseFailed,
303
+ "no registered flavor could parse #{string.inspect}"
304
+ end
305
+ private_class_method :parse_by_prefix
306
+
307
+ # Flavor modules that own a prefix +string+ starts with, longest prefix
308
+ # first. Deduplicated by module identity, so an alias registration is not
309
+ # tried twice.
310
+ #
311
+ # These are the flavors with an actual claim on the string; a parse from one
312
+ # of them is trusted even when the flavor normalises on render.
313
+ #
314
+ # @param string [String] a human-readable identifier
315
+ # @return [Array<Module>]
316
+ # @api private
317
+ def self.candidates_by_prefix(string)
318
+ ordered = []
319
+ routing_table.each do |prefix, modules|
320
+ ordered.concat(modules) if prefix_match?(string, prefix)
321
+ end
322
+ ordered.compact.uniq
323
+ end
324
+ private_class_method :candidates_by_prefix
325
+
326
+ # Every other registered flavor, for the exhaustive second pass.
327
+ #
328
+ # @param exclude [Array<Module>] modules already tried
329
+ # @return [Array<Module>]
330
+ # @api private
331
+ def self.other_candidates(exclude)
332
+ ordered = []
333
+ each_prefix_flavor_module { |mod| ordered << mod }
334
+ ordered.compact.uniq - exclude
335
+ end
336
+ private_class_method :other_candidates
337
+
338
+ # A meaningless string no real identifier scheme should claim. Used to find
339
+ # the flavors whose grammar accepts anything.
340
+ ROUTING_PROBE = "zzqx-nonsense-9714"
341
+ private_constant :ROUTING_PROBE
342
+
343
+ # True when +mod+'s grammar accepts an arbitrary slug.
344
+ #
345
+ # `adobe` and `iana` do, by design — their identifiers genuinely are free
346
+ # text. That makes them unsafe as a fallback: whichever came first in
347
+ # registry order would claim every string no other flavor matched, and
348
+ # answer with structure the input never had.
349
+ #
350
+ # Detected by probing rather than by a hardcoded list, so a flavor that
351
+ # acquires (or loses) an anything-goes grammar is classified correctly
352
+ # without anyone remembering to edit a constant. Computed once per module.
353
+ #
354
+ # @param mod [Module] a flavor module
355
+ # @return [Boolean]
356
+ # @api private
357
+ def self.accepts_anything?(mod)
358
+ @accepts_anything ||= {}
359
+ return @accepts_anything[mod] if @accepts_anything.key?(mod)
360
+
361
+ @accepts_anything[mod] =
362
+ begin
363
+ mod.parse(ROUTING_PROBE)
364
+ true
365
+ rescue StandardError, Parslet::ParseFailed
366
+ false
367
+ end
368
+ end
369
+ private_class_method :accepts_anything?
370
+
371
+ # Prefix => flavor modules, longest prefix first, built once.
372
+ #
373
+ # {prefix_flavors} rebuilds its index on every call, iterating every
374
+ # registered flavor; routing consulted it twice per parse. The registry is
375
+ # static once +eager_load_flavors!+ has run, so the table is memoised here
376
+ # rather than making the public method's cost implicit.
377
+ #
378
+ # The memo is never invalidated, which is safe for every flavor shipped in
379
+ # this gem — they are all +Pubid+-namespace constants that
380
+ # +eager_load_flavors!+ loads before the first parse. A flavor registered
381
+ # from OUTSIDE that namespace after the first {parse} call would miss its
382
+ # prefix priority (it is still tried in the exhaustive second pass, so it is
383
+ # reachable, just not preferred). Bust the memo in +Registry.register+ if
384
+ # out-of-namespace flavors ever become a supported extension point.
385
+ #
386
+ # @return [Hash{String => Array<Module>}]
387
+ # @api private
388
+ def self.routing_table
389
+ @routing_table ||= begin
390
+ index = prefix_flavors
391
+ index.keys
392
+ .sort_by { |prefix| -prefix.length }
393
+ .to_h { |prefix| [prefix, index[prefix].map { |key| Registry.get(key) }] }
394
+ end
395
+ end
396
+ private_class_method :routing_table
397
+
398
+ # True when +string+ starts with +prefix+ at a token boundary, so "ISO" does
399
+ # not claim "ISOFIX" and "BS" does not claim "BSI".
400
+ # @api private
401
+ def self.prefix_match?(string, prefix)
402
+ return false unless string.start_with?(prefix)
403
+
404
+ rest = string[prefix.length]
405
+ rest.nil? || !/[A-Za-z0-9]/.match?(rest)
406
+ end
407
+ private_class_method :prefix_match?
408
+
409
+ def self.detect_flavor_from_urn(urn)
410
+ # urn:iso:std:... → "iso"
411
+ # urn:iec:std:... → "iec"
412
+ parts = urn.downcase.split(":")
413
+ parts[1] # The namespace part after "urn"
414
+ end
415
+
416
+ # Trigger autoloads for every declared flavor module so that
417
+ # Registry is populated before URN dispatch needs it. Safe to call
418
+ # repeatedly; no-op after the first invocation.
419
+ #
420
+ # The constant filter allows a digit inside the name (the +0-9+ in the regex)
421
+ # so digit-bearing flavor modules such as +W3c+ are loaded/registered too —
422
+ # without it +W3c+ is silently dropped from the registry enumeration and thus
423
+ # from every registry-driven cross-flavor spec.
424
+ def self.eager_load_flavors!
425
+ return if @flavors_loaded
426
+
427
+ constants.each do |c|
428
+ next unless c.to_s.match?(/\A[A-Z][a-zA-Z0-9]+\z/)
429
+
430
+ begin
431
+ const_get(c)
432
+ rescue StandardError
433
+ nil
434
+ end
435
+ end
436
+ @flavors_loaded = true
437
+ end
438
+
439
+ # Static leading prefix tokens for a single flavor.
440
+ #
441
+ # @param flavor [Symbol, String] a registered flavor name (e.g. +:iso+)
442
+ # @return [Array<String>] the flavor's prefixes (see {PrefixesSupport})
443
+ # @raise [ArgumentError] if the flavor is not registered
444
+ def self.prefixes(flavor)
445
+ mod = Registry.get(flavor)
446
+ raise ArgumentError, "unknown flavor: #{flavor.inspect}" unless mod
447
+
448
+ mod.prefixes
449
+ end
450
+
451
+ # Reverse index mapping every canonical prefix token to the flavor(s) that
452
+ # own it — the exact routing table relaton needs. Co-published prefixes list
453
+ # every co-publisher (e.g. +"ISO/IEC" => [:iec, :iso]+); see the inclusion /
454
+ # exclusion policy documented on {PrefixesSupport}.
455
+ #
456
+ # The +:cen+ alias of +:cen_cenelec+ is de-duplicated by module identity, so a
457
+ # prefix is attributed to a flavor's canonical
458
+ # {PrefixesSupport#prefix_flavor_key} exactly once.
459
+ #
460
+ # @return [Hash{String => Array<Symbol>}] prefix token => sorted flavor keys,
461
+ # e.g. +{ "ISO" => [:iso], "ISO/IEC" => [:iec, :iso], ... }+
462
+ def self.prefix_flavors
463
+ index = Hash.new { |h, k| h[k] = [] }
464
+ each_prefix_flavor_module do |mod|
465
+ key = mod.prefix_flavor_key
466
+ mod.prefixes.each { |prefix| index[prefix] |= [key] }
467
+ end
468
+ index.transform_values(&:sort).sort.to_h
469
+ end
470
+
471
+ # Yields each unique flavor module that exposes +prefixes+ exactly once,
472
+ # collapsing alias registrations (e.g. +:cen+ and +:cen_cenelec+ both point to
473
+ # +Pubid::CenCenelec+) by module identity.
474
+ # @yieldparam mod [Module] a flavor module
475
+ def self.each_prefix_flavor_module
476
+ eager_load_flavors!
477
+ seen = {}
478
+ Registry.flavor_names.each do |flavor_name|
479
+ mod = Registry.get(flavor_name)
480
+ next if seen.key?(mod) || !mod.respond_to?(:prefixes)
481
+
482
+ seen[mod] = true
483
+ yield mod
484
+ end
485
+ end
486
+
487
+ # Typed-stage lookup by abbreviation, across flavors.
488
+ #
489
+ # Each flavor module memoises +all_typed_stages+ over its own +Identifiers+
490
+ # namespace, so an abbreviation only one flavor uses is invisible from any
491
+ # other: +Pubid::Iso.locate_stage("ADTS")+ is nil while
492
+ # +Pubid::Iec.locate_stage("ADTS")+ finds it. A consumer that holds an
493
+ # abbreviation but not the owning flavor had nowhere to ask.
494
+ #
495
+ # @param abbr [String, Symbol] the stage abbreviation (case-insensitive)
496
+ # @param flavor [Symbol, String, nil] search this flavor only; nil searches
497
+ # every registered flavor and returns the first match
498
+ # @return [Object, nil] the flavor's typed-stage object, or nil. The class is
499
+ # flavor-specific: most return {Pubid::Components::TypedStage}, but IEEE
500
+ # has its own +Ieee::Components::TypedStage+, which is not a subclass.
501
+ # @raise [ArgumentError] if +flavor+ names a flavor that is not registered
502
+ def self.locate_stage(abbr, flavor: nil)
503
+ return locate_stage_in(Registry.get(flavor), abbr, flavor) if flavor
504
+
505
+ each_stage_flavor_module do |mod|
506
+ stage = mod.locate_stage(abbr)
507
+ return stage if stage
508
+ end
509
+ nil
510
+ end
511
+
512
+ # Every flavor that knows +abbr+ — the diagnostic companion to
513
+ # {locate_stage}, for telling a consumer which module owns a stage.
514
+ #
515
+ # @param abbr [String, Symbol] the stage abbreviation (case-insensitive)
516
+ # @return [Array<Symbol>] registered flavor keys, sorted
517
+ def self.locate_stage_flavors(abbr)
518
+ found = []
519
+ each_stage_flavor_module do |mod, flavor_name|
520
+ found << flavor_name.to_sym if mod.locate_stage(abbr)
521
+ end
522
+ found.sort
523
+ end
524
+
525
+ # Yields each unique flavor module that implements +locate_stage+, exactly
526
+ # once. Three registered flavors (adobe, easc, gost) define no typed stages
527
+ # at all, so a cross-flavor sweep must skip them rather than raise on the
528
+ # first one it reaches; alias registrations are collapsed by module identity,
529
+ # as in {each_prefix_flavor_module}.
530
+ #
531
+ # @yieldparam mod [Module] a flavor module
532
+ # @yieldparam flavor_name [String] the registry key it was reached under
533
+ def self.each_stage_flavor_module
534
+ eager_load_flavors!
535
+ seen = {}
536
+ Registry.flavor_names.each do |flavor_name|
537
+ mod = Registry.get(flavor_name)
538
+ next if seen.key?(mod) || !mod.respond_to?(:locate_stage)
539
+
540
+ seen[mod] = true
541
+ yield mod, flavor_name
542
+ end
543
+ end
544
+
545
+ # @api private
546
+ def self.locate_stage_in(mod, abbr, flavor)
547
+ raise ArgumentError, "unknown flavor: #{flavor.inspect}" unless mod
548
+ return nil unless mod.respond_to?(:locate_stage)
549
+
550
+ mod.locate_stage(abbr)
551
+ end
552
+ private_class_method :locate_stage_in
553
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal
2
+
3
+ require_relative "../../lib/pubid/core/pattern_doc_generator"
4
+
5
+ namespace :docs do
6
+ desc "Generate identifier pattern reference docs"
7
+ task :patterns do
8
+ output_dir = File.join(__dir__, "..", "..", "docs", "identifier-patterns")
9
+ FileUtils.mkdir_p(output_dir)
10
+
11
+ flavors = Dir[File.join(__dir__, "..", "..", "lib", "pubid",
12
+ "*")].select do |d|
13
+ File.directory?(d)
14
+ end
15
+ .map do |d|
16
+ File.basename(d)
17
+ end
18
+ .reject do |f|
19
+ %w[core components rendering
20
+ parser serializable utils].include?(f)
21
+ end
22
+
23
+ flavors.each do |flavor|
24
+ puts "Generating docs for #{flavor}..."
25
+ generator = Pubid::Core::PatternDocGenerator.new(flavor)
26
+ content = generator.generate
27
+ File.write(File.join(output_dir, "#{flavor}.md"), content)
28
+ end
29
+
30
+ # Generate cross-flavor comparison table
31
+ puts "Generating cross-flavor comparison..."
32
+ table = Pubid::Core::PatternDocGenerator.generate_cross_flavor_table(flavors)
33
+ File.write(File.join(output_dir, "README.md"), table)
34
+
35
+ puts "Done. Generated docs for #{flavors.length} flavors in #{output_dir}/"
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ namespace :export do
6
+ desc "Export library metadata as JSON for the PubID website"
7
+ task :website_data do
8
+ require "pubid/export"
9
+ data = Pubid::Export::Exporter.export_all
10
+ output_path = File.expand_path("website-data.json", __dir__)
11
+ File.write(output_path, JSON.pretty_generate(data))
12
+ puts "Exported #{data.keys.size} flavors to #{output_path}"
13
+ data.each do |flavor, fd|
14
+ count = fd[:identifier_types]&.size || 0
15
+ puts " #{flavor}: #{count} identifier types"
16
+ end
17
+ end
18
+
19
+ desc "Audit library data against website publishers"
20
+ task :audit do
21
+ require "pubid/export"
22
+
23
+ # Auditor compares string-keyed, JSON-shaped data (see Auditor.from_file and
24
+ # auditor_spec.rb), so roundtrip the export through JSON to convert the
25
+ # symbol keys (:identifier_types) into the string keys it expects.
26
+ data = JSON.parse(JSON.generate(Pubid::Export::Exporter.export_all))
27
+ auditor = Pubid::Export::Auditor.new(data)
28
+
29
+ # Build a minimal website representation from the generated data itself
30
+ # (in production, this would parse the website's publishers.ts)
31
+ summary = data.transform_values do |fd|
32
+ keys = fd["identifier_types"].map { |t| { "key" => t["key"] } }
33
+ { "doc_types" => keys }
34
+ end
35
+
36
+ results = auditor.audit(summary)
37
+ puts auditor.summary(results)
38
+ end
39
+ end