pubid 2.0.0.pre.alpha.7 → 2.0.0.pre.alpha.9

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 (485) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +9 -50
  3. data/data/bipm/update_codes.yaml +9 -0
  4. data/data/iec/update_codes.yaml +3 -0
  5. data/data/ieee/update_codes.yaml +107 -1
  6. data/data/nist/series.yaml +155 -0
  7. data/data/nist/update_codes.yaml +8 -0
  8. data/lib/pubid/adobe/builder.rb +52 -0
  9. data/lib/pubid/adobe/identifier.rb +49 -0
  10. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  11. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  12. data/lib/pubid/adobe/identifiers.rb +10 -0
  13. data/lib/pubid/adobe/parser.rb +128 -0
  14. data/lib/pubid/adobe/renderer.rb +39 -0
  15. data/lib/pubid/adobe/urn_generator.rb +42 -0
  16. data/lib/pubid/adobe/urn_parser.rb +69 -0
  17. data/lib/pubid/adobe.rb +60 -0
  18. data/lib/pubid/amca/builder.rb +2 -2
  19. data/lib/pubid/amca/identifier.rb +1 -3
  20. data/lib/pubid/amca/identifiers/base.rb +1 -6
  21. data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
  22. data/lib/pubid/amca/identifiers/publication.rb +1 -1
  23. data/lib/pubid/amca/identifiers/standard.rb +1 -1
  24. data/lib/pubid/amca/identifiers.rb +0 -1
  25. data/lib/pubid/amca/single_identifier.rb +1 -1
  26. data/lib/pubid/amca.rb +3 -3
  27. data/lib/pubid/ashrae/builder.rb +22 -22
  28. data/lib/pubid/ashrae/identifier.rb +3 -4
  29. data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
  30. data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
  31. data/lib/pubid/ashrae/identifiers/base.rb +14 -8
  32. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
  33. data/lib/pubid/ashrae/identifiers.rb +0 -1
  34. data/lib/pubid/ashrae/parser.rb +14 -9
  35. data/lib/pubid/ashrae/renderer.rb +19 -19
  36. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  37. data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
  38. data/lib/pubid/ashrae.rb +3 -3
  39. data/lib/pubid/bipm/builder.rb +107 -0
  40. data/lib/pubid/bipm/identifier.rb +160 -0
  41. data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
  42. data/lib/pubid/bipm/identifiers/guide.rb +24 -0
  43. data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
  44. data/lib/pubid/bipm/identifiers/mep.rb +21 -0
  45. data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
  46. data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
  47. data/lib/pubid/bipm/identifiers.rb +15 -0
  48. data/lib/pubid/bipm/parser.rb +184 -0
  49. data/lib/pubid/bipm/renderer.rb +110 -0
  50. data/lib/pubid/bipm/urn_generator.rb +58 -0
  51. data/lib/pubid/bipm/urn_parser.rb +52 -0
  52. data/lib/pubid/bipm.rb +86 -0
  53. data/lib/pubid/bsi/builder.rb +14 -14
  54. data/lib/pubid/bsi/identifier.rb +0 -1
  55. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  56. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  57. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  58. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  59. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  60. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  61. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  62. data/lib/pubid/bsi/renderer.rb +8 -8
  63. data/lib/pubid/bsi/single_identifier.rb +48 -0
  64. data/lib/pubid/builder/base.rb +5 -3
  65. data/lib/pubid/bundled_identifier.rb +3 -3
  66. data/lib/pubid/calconnect/builder.rb +38 -0
  67. data/lib/pubid/calconnect/identifier.rb +117 -0
  68. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  69. data/lib/pubid/calconnect/identifiers.rb +9 -0
  70. data/lib/pubid/calconnect/parser.rb +54 -0
  71. data/lib/pubid/calconnect/renderer.rb +36 -0
  72. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  73. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  74. data/lib/pubid/calconnect.rb +77 -0
  75. data/lib/pubid/ccsds/builder.rb +1 -1
  76. data/lib/pubid/ccsds/identifier.rb +1 -1
  77. data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
  78. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  79. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  80. data/lib/pubid/cen_cenelec/builder.rb +46 -12
  81. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
  82. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
  83. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
  84. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  85. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  86. data/lib/pubid/cen_cenelec/renderer.rb +5 -5
  87. data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
  88. data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
  89. data/lib/pubid/cen_cenelec.rb +76 -72
  90. data/lib/pubid/cie/builder.rb +139 -24
  91. data/lib/pubid/cie/identifier.rb +7 -3
  92. data/lib/pubid/cie/identifiers/bundle.rb +32 -4
  93. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  94. data/lib/pubid/cie/identifiers/conference.rb +9 -4
  95. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  96. data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
  97. data/lib/pubid/cie/identifiers/identical.rb +7 -7
  98. data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
  99. data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
  100. data/lib/pubid/cie/identifiers/standard.rb +33 -7
  101. data/lib/pubid/cie/identifiers/supplement.rb +24 -22
  102. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
  103. data/lib/pubid/cie/identifiers.rb +2 -0
  104. data/lib/pubid/cie/parser.rb +54 -5
  105. data/lib/pubid/cie/single_identifier.rb +40 -1
  106. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  107. data/lib/pubid/cie/urn_generator.rb +11 -8
  108. data/lib/pubid/cie.rb +0 -1
  109. data/lib/pubid/components/date.rb +21 -5
  110. data/lib/pubid/csa/builder.rb +1 -1
  111. data/lib/pubid/csa/composite_identifier.rb +17 -1
  112. data/lib/pubid/csa/identifier.rb +48 -3
  113. data/lib/pubid/csa/identifiers/bundled.rb +6 -0
  114. data/lib/pubid/csa/identifiers/combined.rb +6 -0
  115. data/lib/pubid/csa/identifiers/package.rb +2 -2
  116. data/lib/pubid/csa/parser.rb +6 -6
  117. data/lib/pubid/csa/wrapper_identifier.rb +17 -0
  118. data/lib/pubid/doi/builder.rb +18 -0
  119. data/lib/pubid/doi/identifier.rb +46 -0
  120. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  121. data/lib/pubid/doi/identifiers.rb +9 -0
  122. data/lib/pubid/doi/parser.rb +52 -0
  123. data/lib/pubid/doi/renderer.rb +13 -0
  124. data/lib/pubid/doi.rb +55 -0
  125. data/lib/pubid/easc/builder.rb +55 -0
  126. data/lib/pubid/easc/identifier.rb +61 -0
  127. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  128. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  129. data/lib/pubid/easc/identifiers.rb +10 -0
  130. data/lib/pubid/easc/parser.rb +80 -0
  131. data/lib/pubid/easc/renderer.rb +48 -0
  132. data/lib/pubid/easc/urn_generator.rb +46 -0
  133. data/lib/pubid/easc/urn_parser.rb +57 -0
  134. data/lib/pubid/easc.rb +52 -0
  135. data/lib/pubid/ecma/builder.rb +31 -0
  136. data/lib/pubid/ecma/identifier.rb +76 -0
  137. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  138. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  139. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  140. data/lib/pubid/ecma/identifiers.rb +11 -0
  141. data/lib/pubid/ecma/parser.rb +41 -0
  142. data/lib/pubid/ecma/renderer.rb +46 -0
  143. data/lib/pubid/ecma/urn_generator.rb +25 -0
  144. data/lib/pubid/ecma/urn_parser.rb +35 -0
  145. data/lib/pubid/ecma.rb +67 -0
  146. data/lib/pubid/etsi/builder.rb +7 -3
  147. data/lib/pubid/etsi/identifier.rb +1 -3
  148. data/lib/pubid/etsi/identifiers/base.rb +28 -10
  149. data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
  150. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
  151. data/lib/pubid/etsi/identifiers.rb +0 -1
  152. data/lib/pubid/etsi/parser.rb +8 -2
  153. data/lib/pubid/etsi/renderer.rb +8 -2
  154. data/lib/pubid/etsi.rb +5 -5
  155. data/lib/pubid/export/exporter.rb +2 -1
  156. data/lib/pubid/export/flavor_exporter.rb +18 -3
  157. data/lib/pubid/gb/builder.rb +45 -0
  158. data/lib/pubid/gb/identifier.rb +64 -0
  159. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  160. data/lib/pubid/gb/identifiers.rb +9 -0
  161. data/lib/pubid/gb/parser.rb +63 -0
  162. data/lib/pubid/gb/renderer.rb +35 -0
  163. data/lib/pubid/gb.rb +87 -0
  164. data/lib/pubid/gost/builder.rb +148 -0
  165. data/lib/pubid/gost/identifier.rb +49 -0
  166. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  167. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  168. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  169. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  170. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  171. data/lib/pubid/gost/identifiers.rb +13 -0
  172. data/lib/pubid/gost/parser.rb +97 -0
  173. data/lib/pubid/gost/renderer.rb +48 -0
  174. data/lib/pubid/gost/urn_generator.rb +46 -0
  175. data/lib/pubid/gost/urn_parser.rb +52 -0
  176. data/lib/pubid/gost.rb +49 -0
  177. data/lib/pubid/iala/builder.rb +22 -27
  178. data/lib/pubid/iala/identifier.rb +27 -2
  179. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  180. data/lib/pubid/iala/identifiers/annex.rb +14 -12
  181. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  182. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  183. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  184. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  185. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  186. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  187. data/lib/pubid/iala/identifiers/report.rb +1 -1
  188. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  189. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  190. data/lib/pubid/iala/identifiers.rb +0 -1
  191. data/lib/pubid/iala/renderer.rb +1 -1
  192. data/lib/pubid/iala/urn_generator.rb +1 -1
  193. data/lib/pubid/iala/urn_parser.rb +19 -2
  194. data/lib/pubid/iala.rb +4 -4
  195. data/lib/pubid/iana/builder.rb +20 -0
  196. data/lib/pubid/iana/identifier.rb +72 -0
  197. data/lib/pubid/iana/identifiers/registry.rb +33 -0
  198. data/lib/pubid/iana/identifiers.rb +9 -0
  199. data/lib/pubid/iana/parser.rb +38 -0
  200. data/lib/pubid/iana/renderer.rb +29 -0
  201. data/lib/pubid/iana/urn_generator.rb +15 -0
  202. data/lib/pubid/iana/urn_parser.rb +24 -0
  203. data/lib/pubid/iana.rb +69 -0
  204. data/lib/pubid/identifier.rb +210 -23
  205. data/lib/pubid/idf/builder.rb +1 -1
  206. data/lib/pubid/idf/parser.rb +2 -2
  207. data/lib/pubid/idf/renderer.rb +1 -1
  208. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  209. data/lib/pubid/iec/builder.rb +35 -25
  210. data/lib/pubid/iec/identifier.rb +47 -2
  211. data/lib/pubid/iec/identifiers/base.rb +2 -2
  212. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  213. data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
  214. data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
  215. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  216. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  217. data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
  218. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
  219. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  220. data/lib/pubid/iec/identifiers.rb +1 -0
  221. data/lib/pubid/iec/parser.rb +51 -10
  222. data/lib/pubid/iec/renderer.rb +18 -8
  223. data/lib/pubid/iec/single_identifier.rb +1 -1
  224. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  225. data/lib/pubid/iec.rb +1 -6
  226. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  227. data/lib/pubid/ieee/aiee/identifier.rb +45 -61
  228. data/lib/pubid/ieee/builder.rb +341 -68
  229. data/lib/pubid/ieee/compaction.rb +121 -0
  230. data/lib/pubid/ieee/components/draft.rb +47 -7
  231. data/lib/pubid/ieee/identifier.rb +1 -3
  232. data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
  233. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  234. data/lib/pubid/ieee/identifiers/base.rb +106 -13
  235. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  236. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  237. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  238. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
  239. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  240. data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
  241. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  242. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
  243. data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
  244. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
  245. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  246. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  247. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  248. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  249. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  250. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  251. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  252. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  253. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  254. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  255. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  256. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  257. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  258. data/lib/pubid/ieee/identifiers.rb +2 -1
  259. data/lib/pubid/ieee/ire/builder.rb +7 -6
  260. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  261. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  262. data/lib/pubid/ieee/nesc/parser.rb +15 -14
  263. data/lib/pubid/ieee/parser.rb +461 -43
  264. data/lib/pubid/ieee/pre_parser.rb +1 -1
  265. data/lib/pubid/ieee/renderer.rb +154 -57
  266. data/lib/pubid/ieee/typed_stages.rb +12 -1
  267. data/lib/pubid/ieee/urn_generator.rb +3 -5
  268. data/lib/pubid/ieee.rb +56 -3
  269. data/lib/pubid/ietf/builder.rb +62 -0
  270. data/lib/pubid/ietf/identifier.rb +5 -0
  271. data/lib/pubid/ietf/identifiers/base.rb +75 -0
  272. data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
  273. data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
  274. data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
  275. data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
  276. data/lib/pubid/ietf/identifiers/std.rb +25 -0
  277. data/lib/pubid/ietf/identifiers.rb +13 -0
  278. data/lib/pubid/ietf/parser.rb +43 -0
  279. data/lib/pubid/ietf/renderer.rb +26 -0
  280. data/lib/pubid/ietf/urn_generator.rb +23 -0
  281. data/lib/pubid/ietf/urn_parser.rb +35 -0
  282. data/lib/pubid/ietf.rb +76 -0
  283. data/lib/pubid/iho/identifier.rb +1 -3
  284. data/lib/pubid/iho/identifiers/base.rb +1 -7
  285. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  286. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  287. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  288. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  289. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  290. data/lib/pubid/iho/identifiers.rb +0 -1
  291. data/lib/pubid/iho.rb +7 -7
  292. data/lib/pubid/isbn/builder.rb +44 -0
  293. data/lib/pubid/isbn/check_digit.rb +53 -0
  294. data/lib/pubid/isbn/identifier.rb +63 -0
  295. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  296. data/lib/pubid/isbn/identifiers.rb +9 -0
  297. data/lib/pubid/isbn/parser.rb +45 -0
  298. data/lib/pubid/isbn/renderer.rb +16 -0
  299. data/lib/pubid/isbn.rb +52 -0
  300. data/lib/pubid/iso/builder.rb +9 -4
  301. data/lib/pubid/iso/combined_identifier.rb +2 -2
  302. data/lib/pubid/iso/identifier.rb +17 -1
  303. data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
  304. data/lib/pubid/iso/normalizer.rb +2 -2
  305. data/lib/pubid/iso/parser.rb +16 -12
  306. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  307. data/lib/pubid/iso/urn_generator.rb +4 -1
  308. data/lib/pubid/iso/urn_parser.rb +1 -1
  309. data/lib/pubid/itu/builder.rb +230 -29
  310. data/lib/pubid/itu/components/code.rb +48 -5
  311. data/lib/pubid/itu/components/designation.rb +35 -0
  312. data/lib/pubid/itu/components.rb +1 -0
  313. data/lib/pubid/itu/identifier.rb +1 -3
  314. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  315. data/lib/pubid/itu/identifiers/amendment.rb +6 -28
  316. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  317. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  318. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  319. data/lib/pubid/itu/identifiers/base.rb +341 -23
  320. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  321. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  322. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  323. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  324. data/lib/pubid/itu/identifiers/question.rb +63 -0
  325. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  326. data/lib/pubid/itu/identifiers/report.rb +39 -0
  327. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  328. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  329. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  330. data/lib/pubid/itu/identifiers.rb +10 -1
  331. data/lib/pubid/itu/model.rb +1 -1
  332. data/lib/pubid/itu/parser.rb +480 -26
  333. data/lib/pubid/itu/urn_generator.rb +36 -6
  334. data/lib/pubid/itu/urn_parser.rb +8 -0
  335. data/lib/pubid/itu.rb +11 -3
  336. data/lib/pubid/jcgm/builder.rb +23 -13
  337. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  338. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  339. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  340. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  341. data/lib/pubid/jcgm/identifiers.rb +2 -0
  342. data/lib/pubid/jcgm/parser.rb +66 -6
  343. data/lib/pubid/jcgm/renderer.rb +26 -12
  344. data/lib/pubid/jcgm/single_identifier.rb +74 -5
  345. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  346. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  347. data/lib/pubid/jcgm/urn_parser.rb +15 -3
  348. data/lib/pubid/jis/identifier.rb +52 -0
  349. data/lib/pubid/nist/builder.rb +29 -9
  350. data/lib/pubid/nist/caster.rb +7 -45
  351. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  352. data/lib/pubid/nist/components/supplement.rb +5 -2
  353. data/lib/pubid/nist/configuration.rb +7 -1
  354. data/lib/pubid/nist/identifier.rb +1 -3
  355. data/lib/pubid/nist/identifiers/base.rb +121 -37
  356. data/lib/pubid/nist/identifiers/circular.rb +1 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  358. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  359. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
  360. data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
  361. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  362. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  363. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  364. data/lib/pubid/nist/identifiers/handbook.rb +1 -1
  365. data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
  366. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  367. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
  368. data/lib/pubid/nist/identifiers/monograph.rb +1 -1
  369. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  370. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  371. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  372. data/lib/pubid/nist/identifiers/report.rb +1 -1
  373. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  374. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  375. data/lib/pubid/nist/identifiers.rb +0 -1
  376. data/lib/pubid/nist/parser.rb +29 -4
  377. data/lib/pubid/nist/preprocessor.rb +15 -0
  378. data/lib/pubid/nist/router.rb +3 -2
  379. data/lib/pubid/nist/series/ir.rb +0 -3
  380. data/lib/pubid/nist/supplement_identifier.rb +9 -9
  381. data/lib/pubid/nist.rb +13 -12
  382. data/lib/pubid/oasis/builder.rb +77 -0
  383. data/lib/pubid/oasis/identifier.rb +82 -0
  384. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  385. data/lib/pubid/oasis/identifiers.rb +9 -0
  386. data/lib/pubid/oasis/parser.rb +34 -0
  387. data/lib/pubid/oasis/renderer.rb +29 -0
  388. data/lib/pubid/oasis/urn_generator.rb +25 -0
  389. data/lib/pubid/oasis/urn_parser.rb +22 -0
  390. data/lib/pubid/oasis.rb +74 -0
  391. data/lib/pubid/ogc/builder.rb +33 -0
  392. data/lib/pubid/ogc/identifier.rb +77 -0
  393. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  394. data/lib/pubid/ogc/identifiers.rb +10 -0
  395. data/lib/pubid/ogc/parser.rb +40 -0
  396. data/lib/pubid/ogc/renderer.rb +33 -0
  397. data/lib/pubid/ogc/urn_generator.rb +14 -0
  398. data/lib/pubid/ogc/urn_parser.rb +22 -0
  399. data/lib/pubid/ogc.rb +71 -0
  400. data/lib/pubid/oiml/builder.rb +31 -7
  401. data/lib/pubid/oiml/identifier.rb +9 -1
  402. data/lib/pubid/oiml/parser.rb +11 -12
  403. data/lib/pubid/oiml/renderer.rb +13 -13
  404. data/lib/pubid/oiml/single_identifier.rb +20 -0
  405. data/lib/pubid/oiml/supplement_identifier.rb +9 -9
  406. data/lib/pubid/oiml/urn_parser.rb +23 -6
  407. data/lib/pubid/oiml.rb +4 -0
  408. data/lib/pubid/omg/builder.rb +19 -0
  409. data/lib/pubid/omg/identifier.rb +44 -0
  410. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  411. data/lib/pubid/omg/identifiers.rb +9 -0
  412. data/lib/pubid/omg/parser.rb +40 -0
  413. data/lib/pubid/omg/renderer.rb +19 -0
  414. data/lib/pubid/omg.rb +51 -0
  415. data/lib/pubid/parsers/mr_string.rb +101 -7
  416. data/lib/pubid/plateau/builder.rb +8 -4
  417. data/lib/pubid/plateau/identifier.rb +1 -3
  418. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  419. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  420. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  421. data/lib/pubid/plateau/identifiers.rb +0 -1
  422. data/lib/pubid/plateau/parser.rb +15 -5
  423. data/lib/pubid/plateau/renderer.rb +1 -1
  424. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  425. data/lib/pubid/plateau.rb +4 -4
  426. data/lib/pubid/renderers/human_readable.rb +3 -1
  427. data/lib/pubid/renderers/mr_string.rb +46 -4
  428. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  429. data/lib/pubid/rendering/supplement.rb +4 -4
  430. data/lib/pubid/sae/builder.rb +1 -1
  431. data/lib/pubid/sae/identifier.rb +1 -3
  432. data/lib/pubid/sae/identifiers/base.rb +10 -7
  433. data/lib/pubid/sae/identifiers.rb +0 -1
  434. data/lib/pubid/sae.rb +3 -3
  435. data/lib/pubid/tgpp/builder.rb +41 -0
  436. data/lib/pubid/tgpp/identifier.rb +91 -0
  437. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  438. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  439. data/lib/pubid/tgpp/identifiers.rb +11 -0
  440. data/lib/pubid/tgpp/parser.rb +62 -0
  441. data/lib/pubid/tgpp/renderer.rb +36 -0
  442. data/lib/pubid/tgpp/urn_generator.rb +20 -0
  443. data/lib/pubid/tgpp/urn_parser.rb +28 -0
  444. data/lib/pubid/tgpp.rb +78 -0
  445. data/lib/pubid/type_resolver.rb +59 -0
  446. data/lib/pubid/un/builder.rb +42 -0
  447. data/lib/pubid/un/identifier.rb +37 -0
  448. data/lib/pubid/un/identifiers/document.rb +24 -0
  449. data/lib/pubid/un/identifiers.rb +9 -0
  450. data/lib/pubid/un/parser.rb +25 -0
  451. data/lib/pubid/un/renderer.rb +11 -0
  452. data/lib/pubid/un.rb +46 -0
  453. data/lib/pubid/version.rb +1 -1
  454. data/lib/pubid/w3c/builder.rb +55 -0
  455. data/lib/pubid/w3c/identifier.rb +101 -0
  456. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  457. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  458. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  459. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  460. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  461. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  462. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  463. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  464. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  465. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  466. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  467. data/lib/pubid/w3c/identifiers.rb +25 -0
  468. data/lib/pubid/w3c/parser.rb +43 -0
  469. data/lib/pubid/w3c/renderer.rb +35 -0
  470. data/lib/pubid/w3c/urn_generator.rb +18 -0
  471. data/lib/pubid/w3c/urn_parser.rb +36 -0
  472. data/lib/pubid/w3c.rb +67 -0
  473. data/lib/pubid/xsf/builder.rb +17 -0
  474. data/lib/pubid/xsf/identifier.rb +62 -0
  475. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  476. data/lib/pubid/xsf/identifiers.rb +9 -0
  477. data/lib/pubid/xsf/parser.rb +25 -0
  478. data/lib/pubid/xsf/renderer.rb +23 -0
  479. data/lib/pubid/xsf/urn_generator.rb +13 -0
  480. data/lib/pubid/xsf/urn_parser.rb +18 -0
  481. data/lib/pubid/xsf.rb +76 -0
  482. data/lib/pubid.rb +25 -1
  483. metadata +205 -4
  484. data/lib/pubid/cie/components/code.rb +0 -80
  485. data/lib/pubid/iala/identifiers/base.rb +0 -14
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ module Identifiers
6
+ # The SI Brochure — a single bespoke record. The English form drops the
7
+ # "sur le SI" phrase the French form carries.
8
+ #
9
+ # Printed forms (both round-trip):
10
+ # "BIPM SI Brochure 9e v3.01 (2019/2024, E)"
11
+ # "BIPM SI Brochure sur le SI 9e v3.01 (2019/2024, F)"
12
+ class SiBrochure < Identifier
13
+ def self.type
14
+ { key: :si_brochure, web: :si_brochure,
15
+ title: "SI Brochure", short: "si-brochure" }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ # Namespace for concrete BIPM identifier types.
6
+ module Identifiers
7
+ autoload :CommitteeDocument, "#{__dir__}/identifiers/committee_document"
8
+ autoload :Guide, "#{__dir__}/identifiers/guide"
9
+ autoload :Meeting, "#{__dir__}/identifiers/meeting"
10
+ autoload :Mep, "#{__dir__}/identifiers/mep"
11
+ autoload :MetrologiaArticle, "#{__dir__}/identifiers/metrologia_article"
12
+ autoload :SiBrochure, "#{__dir__}/identifiers/si_brochure"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Bipm
7
+ # Parslet grammar for the four BIPM identifier families. The root branches
8
+ # by leading token / shape; each alternative is wrapped in a distinct key
9
+ # (:committee_short, :meeting_en, …) so the Builder can dispatch on the
10
+ # matched branch without re-inspecting the string.
11
+ #
12
+ # Group and type-word alternations are built from the shared vocabularies on
13
+ # {Identifier} (sorted longest-first so e.g. "CCTF" is tried before "CCT").
14
+ class Parser < Parslet::Parser
15
+ # --- primitives ---
16
+ rule(:space) { str(" ") }
17
+ rule(:digits) { match["0-9"].repeat(1) }
18
+ rule(:alnum) { match["0-9A-Za-z"].repeat(1) }
19
+ # Number, preserved as a string: digits with optional hyphenated parts.
20
+ rule(:number) do
21
+ (digits >> (str("-") >> digits).repeat).as(:number)
22
+ end
23
+ rule(:year) { match["0-9"].repeat(4, 4).as(:year) }
24
+ rule(:lang) { match["EF"].as(:language) }
25
+ # "(YYYY)" or "(YYYY, E)"
26
+ rule(:year_paren) do
27
+ str("(") >> year >> (str(", ") >> lang).maybe >> str(")")
28
+ end
29
+ rule(:year_paren_nolang) { str("(") >> year >> str(")") }
30
+
31
+ # Longest-first alternation over a list of literal tokens, so a token that
32
+ # is a prefix of another (e.g. "CCT" of "CCTF") never shadows it.
33
+ def alternation(tokens)
34
+ tokens.sort_by { |t| -t.length }.map { |t| str(t) }.reduce(:|)
35
+ end
36
+
37
+ rule(:group) { alternation(Identifier::GROUPS).as(:group) }
38
+
39
+ rule(:type_abbrev) do
40
+ alternation(Identifier::TYPE_CODES).as(:type_word)
41
+ end
42
+ rule(:type_name_en) do
43
+ names = Identifier::TYPE_NAME_EN.values.uniq + ["Declaration"]
44
+ alternation(names).as(:type_word)
45
+ end
46
+ rule(:type_name_fr) do
47
+ names = Identifier::TYPE_NAME_FR.values.uniq + ["Déclaration"]
48
+ alternation(names).as(:type_word)
49
+ end
50
+ rule(:connective) { str("de la") | str("du") }
51
+ rule(:ordinal) { str("st") | str("nd") | str("rd") | str("th") }
52
+
53
+ # --- committee documents ---
54
+ # The trailing "(YYYY)" date is optional (`.maybe`) so a partial reference
55
+ # that omits it — e.g. "CCTF REC 2" — still parses, leaving :year absent.
56
+ rule(:committee_short) do
57
+ (group >> space >> type_abbrev >>
58
+ (space >> number).maybe >> (space >> year_paren).maybe)
59
+ .as(:committee_short)
60
+ end
61
+ rule(:committee_long_en) do
62
+ (group >> space >> type_name_en >>
63
+ (space >> number).maybe >> (space >> year_paren_nolang).maybe)
64
+ .as(:committee_long_en)
65
+ end
66
+ rule(:committee_long_fr) do
67
+ (type_name_fr >> (space >> number).maybe >> space >>
68
+ connective >> space >> group >> (space >> year_paren_nolang).maybe)
69
+ .as(:committee_long_fr)
70
+ end
71
+ # Bare MRA-interpretation form: a group directly followed by a document
72
+ # number with no type word (e.g. "CIPM 2005-06"). Tried last, so typed
73
+ # committee documents and meetings always win; only fires when a digit
74
+ # follows the group and the string is fully consumed.
75
+ rule(:committee_bare) do
76
+ (group >> space >> number >> (space >> year_paren).maybe)
77
+ .as(:committee_bare)
78
+ end
79
+
80
+ # --- meetings ---
81
+ rule(:meeting_en) do
82
+ (group >> space >> number >> ordinal >> space >>
83
+ str("Meeting") >> (space >> year_paren).maybe).as(:meeting_en)
84
+ end
85
+ rule(:meeting_fr) do
86
+ (group >> space >> number >> str("<sup>e</sup>") >> space >>
87
+ str("réunion") >> (space >> year_paren).maybe).as(:meeting_fr)
88
+ end
89
+
90
+ # --- Metrologia journal ---
91
+ rule(:metrologia) do
92
+ (str("Metrologia") >>
93
+ (space >> digits.as(:volume) >>
94
+ (space >> alnum.as(:issue) >>
95
+ (space >> alnum.as(:article)).maybe).maybe).maybe).as(:metrologia)
96
+ end
97
+
98
+ # --- SI Brochure ---
99
+ rule(:edition) { (digits >> str("e")).as(:edition) }
100
+ rule(:version) { (str("v") >> match["0-9."].repeat(1)).as(:version) }
101
+ rule(:years) { (digits >> (str("/") >> digits).maybe).as(:years) }
102
+ rule(:si_brochure) do
103
+ (str("BIPM SI Brochure") >> space >>
104
+ (str("sur le SI") >> space).maybe >>
105
+ edition >> space >> version >> space >>
106
+ str("(") >> years >> str(", ") >> lang >> str(")")).as(:si_brochure)
107
+ end
108
+
109
+ # --- SI Brochure appendices / derived products ---
110
+ # The full primary-docidentifier content the relaton crawler indexes by,
111
+ # e.g. "BIPM SI Brochure Appendix 3" / "…Concise" / "…FAQ". The bare
112
+ # "SI Brochure Appendix 3" docnumber form is accepted too (rendered back
113
+ # with the "BIPM " prefix, matching the base SI Brochure record).
114
+ rule(:brochure_variant) do
115
+ ((str("Appendix") >> space >> digits) | str("Concise") | str("FAQ"))
116
+ .as(:variant)
117
+ end
118
+ rule(:si_brochure_variant) do
119
+ ((str("BIPM SI Brochure") | str("SI Brochure")) >> space >>
120
+ brochure_variant).as(:si_brochure_variant)
121
+ end
122
+
123
+ # Shared "Appendix N [Annex N] Part N[.M]" tail carried by the full
124
+ # docidentifier content of MEPs and CC guides (the "Appendix 2 Part 1.1"
125
+ # or "Appendix 2 Annex 2 Part 1" suffix on "BIPM SI MEP …" etc.).
126
+ rule(:appendix_part) do
127
+ str("Appendix") >> space >> digits.as(:appendix) >>
128
+ (space >> str("Annex") >> space >> digits.as(:annex)).maybe >>
129
+ space >> str("Part") >> space >>
130
+ (digits >> (str(".") >> digits).maybe).as(:part)
131
+ end
132
+
133
+ # --- Mises en pratique (MEP) ---
134
+ # Two index-relevant spellings: the short docnumber ("SI MEP S1",
135
+ # "Rapport BIPM-2019/05") and the full "BIPM …" primary-docidentifier
136
+ # content the crawler actually keys on ("BIPM SI MEP S1 Appendix 2 Part
137
+ # 1.1"). The renderer reproduces whichever the identifier carries.
138
+ rule(:mep_code) { match["0-9A-Za-z"].repeat(1).as(:mep_code) }
139
+ rule(:report_code) do
140
+ (str("BIPM-") >> digits >> str("/") >> digits).as(:report_code)
141
+ end
142
+ rule(:mep_body) do
143
+ (str("SI MEP") >> space >> mep_code) |
144
+ (str("Rapport") >> space >> report_code)
145
+ end
146
+ rule(:mep) do
147
+ ((str("BIPM") >> space >> mep_body >> space >> appendix_part) |
148
+ mep_body).as(:mep)
149
+ end
150
+
151
+ # --- Consultative-Committee guides ---
152
+ # "<committee>-GD-<kind>-<number>" (e.g. "CCL-GD-MeP-1"), and its full
153
+ # "BIPM … Appendix 2 Part 2.2" content form. <kind> is "MeP" (mise en
154
+ # pratique) or "RSI" (réalisation du SI). Reuses the shared `group`
155
+ # (committee) and `number` (trailing sequence).
156
+ rule(:guide_kind) { (str("MeP") | str("RSI")).as(:guide_kind) }
157
+ rule(:guide_body) do
158
+ group >> str("-GD-") >> guide_kind >> str("-") >> digits.as(:number)
159
+ end
160
+ rule(:guide) do
161
+ ((str("BIPM") >> space >> guide_body >> space >> appendix_part) |
162
+ guide_body).as(:guide)
163
+ end
164
+
165
+ # After a leading group token, the shape after the first space decides:
166
+ # a digit → meeting; a type word → committee.
167
+ rule(:group_leading) do
168
+ meeting_en | meeting_fr | committee_short | committee_long_en |
169
+ committee_bare
170
+ end
171
+
172
+ rule(:identifier) do
173
+ metrologia | si_brochure | si_brochure_variant | mep | guide |
174
+ committee_long_fr | group_leading
175
+ end
176
+
177
+ root(:identifier)
178
+
179
+ def self.parse(input)
180
+ new.parse(input)
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ # Human-readable renderer for the four BIPM identifier families. Registered
6
+ # as the `:human` format and invoked via `render(format: :human)`.
7
+ class Renderer < ::Pubid::Renderers::Base
8
+ def render(context: nil, **_opts)
9
+ case @id
10
+ when Identifiers::CommitteeDocument then render_committee(@id)
11
+ when Identifiers::Meeting then render_meeting(@id)
12
+ when Identifiers::MetrologiaArticle then render_metrologia(@id)
13
+ when Identifiers::SiBrochure then render_si_brochure(@id)
14
+ when Identifiers::Mep then render_mep(@id)
15
+ when Identifiers::Guide then render_guide(@id)
16
+ else
17
+ raise "Cannot render BIPM identifier: #{@id.class}"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Optional " <number>" segment (with a leading space), or "" when absent.
24
+ def number_segment(id)
25
+ id.number ? " #{id.number}" : ""
26
+ end
27
+
28
+ # Optional " (<year>[, <lang>])" segment (with a leading space), or ""
29
+ # when the year is absent (a partial reference). `lang` is the trailing
30
+ # ", E"/", F" suffix carried only by the short committee form.
31
+ def year_segment(id, lang: "")
32
+ id.year ? " (#{id.year}#{lang})" : ""
33
+ end
34
+
35
+ def render_committee(id)
36
+ return render_committee_long(id) if id.long?
37
+
38
+ # short abbreviated key form. The type word is optional — the bare MRA
39
+ # form (e.g. "CIPM 2005-06") has no type_code, so omit it (and its
40
+ # leading space) rather than emit a double space.
41
+ lang = id.language ? ", #{id.language}" : ""
42
+ type = id.type_code ? " #{id.type_code}" : ""
43
+ "#{id.group}#{type}#{number_segment(id)}" \
44
+ "#{year_segment(id, lang: lang)}"
45
+ end
46
+
47
+ def render_committee_long(id)
48
+ if id.language == "F"
49
+ name = Identifier::TYPE_NAME_FR[id.type_code]
50
+ conn = Identifier.french_connective(id.group)
51
+ "#{name}#{number_segment(id)} #{conn} #{id.group}#{year_segment(id)}"
52
+ else
53
+ name = Identifier::TYPE_NAME_EN[id.type_code]
54
+ "#{id.group} #{name}#{number_segment(id)}#{year_segment(id)}"
55
+ end
56
+ end
57
+
58
+ def render_meeting(id)
59
+ if id.language == "F"
60
+ "#{id.group} #{id.number}<sup>e</sup> réunion#{year_segment(id)}"
61
+ else
62
+ "#{id.group} #{id.ordinal_en} Meeting#{year_segment(id)}"
63
+ end
64
+ end
65
+
66
+ def render_metrologia(id)
67
+ result = +"Metrologia"
68
+ result << " #{id.volume}" if id.volume
69
+ result << " #{id.issue}" if id.issue
70
+ result << " #{id.article}" if id.article
71
+ result
72
+ end
73
+
74
+ def render_si_brochure(id)
75
+ # Appendix / derived-product form indexed by relaton, keyed on the full
76
+ # "BIPM SI Brochure …" primary docidentifier content.
77
+ return "BIPM SI Brochure #{id.variant}" if id.variant
78
+
79
+ phrase = id.language == "F" ? "sur le SI " : ""
80
+ lang = id.language ? ", #{id.language}" : ""
81
+ "BIPM SI Brochure #{phrase}#{id.edition} #{id.version} " \
82
+ "(#{id.years}#{lang})"
83
+ end
84
+
85
+ # MEP: short docnumber ("SI MEP <code>" / "Rapport BIPM-YYYY/NN"), or the
86
+ # full "BIPM … Appendix N [Annex N] Part N.M" content the crawler keys on.
87
+ def render_mep(id)
88
+ body = id.report_code ? "Rapport #{id.report_code}" : "SI MEP #{id.mep_code}"
89
+ render_full_content(id, body)
90
+ end
91
+
92
+ # CC guide: short "<committee>-GD-<kind>-<number>", or its full
93
+ # "BIPM … Appendix N Part N.M" content form.
94
+ def render_guide(id)
95
+ body = "#{id.group}-GD-#{id.guide_kind}-#{id.number}"
96
+ render_full_content(id, body)
97
+ end
98
+
99
+ # Wrap a short body in the "BIPM … Appendix N [Annex N] Part N.M" content
100
+ # form when the identifier carries the appendix/part tail; otherwise emit
101
+ # the bare short body. `part` presence is what distinguishes the two.
102
+ def render_full_content(id, body)
103
+ return body unless id.part
104
+
105
+ annex = id.annex ? " Annex #{id.annex}" : ""
106
+ "BIPM #{body} Appendix #{id.appendix}#{annex} Part #{id.part}"
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ # Emits a URN carrying the canonical (language/form-neutral) document
6
+ # identity for each family:
7
+ # committee: urn:bipm:<group>:<type>:<number>:<year> (empty number seg
8
+ # when number-less)
9
+ # meeting: urn:bipm:<group>:meeting:<number>:<year>
10
+ # metrologia: urn:bipm:metrologia:<vol>[:<issue>[:<article>]]
11
+ # brochure: urn:bipm:si-brochure:<lang>:<edition>:<version>:<years>
12
+ class UrnGenerator < Pubid::UrnGenerator::Base
13
+ def generate
14
+ case identifier
15
+ when Identifiers::CommitteeDocument then committee
16
+ when Identifiers::Meeting then meeting
17
+ when Identifiers::MetrologiaArticle then metrologia
18
+ when Identifiers::SiBrochure then si_brochure
19
+ else
20
+ raise "Cannot build URN for BIPM identifier: #{identifier.class}"
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def committee
27
+ id = identifier
28
+ # type_code is nil for the bare MRA form → empty type segment, mirroring
29
+ # the empty-number-segment convention for number-less documents.
30
+ parts = ["urn", "bipm", id.group.downcase,
31
+ id.type_code.to_s.downcase, id.number.to_s]
32
+ # A partial (date-less) reference drops the trailing year segment; a
33
+ # number-less-but-dated doc keeps its empty number segment.
34
+ parts << id.year if id.year
35
+ parts.join(":")
36
+ end
37
+
38
+ def meeting
39
+ id = identifier
40
+ parts = ["urn", "bipm", id.group.downcase, "meeting", id.number.to_s]
41
+ parts << id.year if id.year
42
+ parts.join(":")
43
+ end
44
+
45
+ def metrologia
46
+ parts = ["urn", "bipm", "metrologia", identifier.volume]
47
+ parts << identifier.issue if identifier.issue
48
+ parts << identifier.article if identifier.article
49
+ parts.join(":")
50
+ end
51
+
52
+ def si_brochure
53
+ ["urn", "bipm", "si-brochure", identifier.language.to_s.downcase,
54
+ identifier.edition, identifier.version, identifier.years].join(":")
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ # Inverts {UrnGenerator}, rebuilding the identifier directly from the URN
6
+ # fields (rather than reconstructing a printed string) because the printed
7
+ # forms carry surface detail — meeting ordinals, French wording — that the
8
+ # canonical URN intentionally omits.
9
+ class UrnParser < Pubid::UrnParser::Base
10
+ def parse_urn(urn)
11
+ body = strip_namespace(urn)
12
+ parts = body.split(":", -1)
13
+
14
+ case parts.first
15
+ when "metrologia" then build_metrologia(parts)
16
+ when "si-brochure" then build_si_brochure(parts)
17
+ else build_group_leading(parts)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def build_group_leading(parts)
24
+ group = parts[0].upcase
25
+ if parts[1] == "meeting"
26
+ Identifiers::Meeting.new(
27
+ group: group, number: parts[2].to_s, year: parts[3]&.to_i,
28
+ )
29
+ else
30
+ Identifiers::CommitteeDocument.new(
31
+ group: group,
32
+ type_code: (parts[1].empty? ? nil : parts[1].upcase),
33
+ number: (parts[2].empty? ? nil : parts[2]), year: parts[3]&.to_i
34
+ )
35
+ end
36
+ end
37
+
38
+ def build_metrologia(parts)
39
+ Identifiers::MetrologiaArticle.new(
40
+ volume: parts[1]&.to_i, issue: parts[2], article: parts[3],
41
+ )
42
+ end
43
+
44
+ def build_si_brochure(parts)
45
+ Identifiers::SiBrochure.new(
46
+ language: parts[1].to_s.upcase, edition: parts[2],
47
+ version: parts[3], years: parts[4]
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/pubid/bipm.rb ADDED
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Bipm
5
+ extend Pubid::PrefixesSupport
6
+
7
+ # Leading tokens a printed BIPM identifier can start with: the 13 committee
8
+ # acronyms, "Metrologia" (journal), and "BIPM" (the SI Brochure). JCGM is
9
+ # deliberately excluded — it is owned by the separate Pubid::Jcgm flavor,
10
+ # so BIPM never emits pubid:jcgm:* rows. French full-name forms that lead
11
+ # with a type word ("Recommandation 1 du CCL …") are omitted per the
12
+ # "exclude ambiguous tokens" policy.
13
+ PREFIXES = %w[
14
+ BIPM Metrologia
15
+ CIPM CGPM JCRB CCTF CCQM CCT CCL CCAUV CCU CCM CCEM CCPR CCRI
16
+ ].freeze
17
+
18
+ autoload :Builder, "#{__dir__}/bipm/builder"
19
+ autoload :Identifier, "#{__dir__}/bipm/identifier"
20
+ autoload :Identifiers, "#{__dir__}/bipm/identifiers"
21
+ autoload :Parser, "#{__dir__}/bipm/parser"
22
+ autoload :Renderer, "#{__dir__}/bipm/renderer"
23
+ autoload :UrnGenerator, "#{__dir__}/bipm/urn_generator"
24
+ autoload :UrnParser, "#{__dir__}/bipm/urn_parser"
25
+
26
+ # Parse a BIPM identifier string into an identifier object.
27
+ # @param identifier [String] the printed identifier
28
+ # @return [Identifier] the parsed identifier
29
+ def self.parse(identifier)
30
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
31
+ raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
32
+ end
33
+
34
+ Identifier.parse(identifier)
35
+ end
36
+
37
+ # Per-flavor format registry: inherits global formats, overrides :human
38
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
39
+ Identifier.format_registry.register(:human, renderer: Bipm::Renderer)
40
+
41
+ # Auto-discover all identifier types from the Identifiers namespace
42
+ # @return [Array<Class>] identifier classes that define a self.type Hash
43
+ def self.identifier_types
44
+ @identifier_types ||= Identifiers.constants.filter_map do |const|
45
+ klass = Identifiers.const_get(const)
46
+ klass if klass.is_a?(Class) &&
47
+ klass.singleton_methods(false).include?(:type) &&
48
+ klass.type.is_a?(Hash)
49
+ rescue NameError
50
+ nil
51
+ end
52
+ end
53
+
54
+ # Build typed stage index from identifier types
55
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
56
+ def self.all_typed_stages
57
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
58
+ if klass.const_defined?(:TYPED_STAGES)
59
+ klass.const_get(:TYPED_STAGES)
60
+ else
61
+ []
62
+ end
63
+ end
64
+ end
65
+
66
+ # Lookup: type code -> identifier class
67
+ # @param code [String, Symbol] the type key to find
68
+ # @return [Class, nil] the matching identifier class
69
+ def self.locate_type(code)
70
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
71
+ end
72
+
73
+ # Lookup: abbreviation -> typed stage
74
+ # @param abbr [String, Symbol] the abbreviation to find
75
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
76
+ def self.locate_stage(abbr)
77
+ abbr_str = abbr.to_s.upcase
78
+ all_typed_stages.find do |s|
79
+ s.abbr.any? { |a| a.to_s.upcase == abbr_str }
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ # Register BIPM flavor with the registry
86
+ Pubid::Registry.register(:bipm, Pubid::Bipm)
@@ -674,7 +674,7 @@ module Pubid
674
674
  topic = @original_data[:expert_commentary_topic]&.to_s
675
675
 
676
676
  Identifiers::ExpertCommentary.new(
677
- base_identifier: base_id,
677
+ base: base_id,
678
678
  format: format,
679
679
  topic: topic,
680
680
  )
@@ -724,7 +724,7 @@ module Pubid
724
724
  end
725
725
 
726
726
  Identifiers::SupplementDocument.new(
727
- base_identifier: base_id,
727
+ base: base_id,
728
728
  supplement_number: data[:supplement_number].to_s,
729
729
  supplement_year: data[:supplement_year].to_i,
730
730
  supplement_type: supplement_type,
@@ -771,7 +771,7 @@ module Pubid
771
771
  end
772
772
 
773
773
  Identifiers::AddendumDocument.new(
774
- base_identifier: base_id,
774
+ base: base_id,
775
775
  addendum_number: data[:addendum_number].to_s,
776
776
  addendum_year: data[:addendum_year].to_i,
777
777
  addendum_type: addendum_type,
@@ -837,7 +837,7 @@ module Pubid
837
837
  base_id = build(base_data)
838
838
 
839
839
  Identifiers::ValueAddedPublication.new(
840
- base_identifier: base_id,
840
+ base: base_id,
841
841
  format: format,
842
842
  )
843
843
  end
@@ -882,14 +882,14 @@ module Pubid
882
882
 
883
883
  if supp[:type] == :amendment
884
884
  Identifiers::Amendment.new(
885
- base_identifier: nil, # NA supplements don't wrap base
885
+ base: nil, # NA supplements don't wrap base
886
886
  amendment_number: supp[:number],
887
887
  amendment_year: year_val&.to_i,
888
888
  separator: supp[:separator] || "+",
889
889
  )
890
890
  else
891
891
  Identifiers::Corrigendum.new(
892
- base_identifier: nil,
892
+ base: nil,
893
893
  corrigendum_number: supp[:number],
894
894
  corrigendum_year: year_val&.to_i,
895
895
  separator: supp[:separator] || "+",
@@ -1411,17 +1411,17 @@ module Pubid
1411
1411
  end
1412
1412
  end
1413
1413
 
1414
- def wrap_with_consolidated(base_identifier, supplements_data,
1414
+ def wrap_with_consolidated(base, supplements_data,
1415
1415
  expert_commentary: nil, expert_commentary_topic: nil)
1416
- # If expert_commentary data is provided, set it on the base_identifier
1416
+ # If expert_commentary data is provided, set it on the base
1417
1417
  # This allows ConsolidatedIdentifier to render the ExComm suffix correctly
1418
1418
  if expert_commentary
1419
- base_attrs = base_identifier.class.attributes
1419
+ base_attrs = base.class.attributes
1420
1420
  if base_attrs.key?(:expert_commentary)
1421
- base_identifier.expert_commentary = expert_commentary
1421
+ base.expert_commentary = expert_commentary
1422
1422
  end
1423
1423
  if expert_commentary_topic && base_attrs.key?(:expert_commentary_topic)
1424
- base_identifier.expert_commentary_topic = expert_commentary_topic
1424
+ base.expert_commentary_topic = expert_commentary_topic
1425
1425
  end
1426
1426
  end
1427
1427
 
@@ -1436,7 +1436,7 @@ expert_commentary: nil, expert_commentary_topic: nil)
1436
1436
 
1437
1437
  if supp[:type] == :amendment
1438
1438
  Identifiers::Amendment.new(
1439
- base_identifier: base_identifier,
1439
+ base: base,
1440
1440
  amendment_number: supp[:number],
1441
1441
  amendment_year: year_val&.to_i,
1442
1442
  separator: supp[:separator] || "+",
@@ -1444,7 +1444,7 @@ expert_commentary: nil, expert_commentary_topic: nil)
1444
1444
  )
1445
1445
  else
1446
1446
  Identifiers::Corrigendum.new(
1447
- base_identifier: base_identifier,
1447
+ base: base,
1448
1448
  corrigendum_number: supp[:number],
1449
1449
  corrigendum_year: year_val&.to_i,
1450
1450
  separator: supp[:separator] || "+",
@@ -1453,7 +1453,7 @@ expert_commentary: nil, expert_commentary_topic: nil)
1453
1453
  end
1454
1454
 
1455
1455
  Identifiers::ConsolidatedIdentifier.new(
1456
- identifiers: [base_identifier] + supplement_ids,
1456
+ identifiers: [base] + supplement_ids,
1457
1457
  )
1458
1458
  end
1459
1459
 
@@ -4,4 +4,3 @@
4
4
  # subclass); its body, `.parse` (including the IEC-delegation logic), and the
5
5
  # SingleIdentifier back-compat alias live in single_identifier.rb. This file
6
6
  # just ensures it is loaded when a consumer references Pubid::Bsi::Identifier.
7
- require_relative "single_identifier"
@@ -11,7 +11,7 @@ module Pubid
11
11
  # "BS 2000-0:Addendum 1:1983"
12
12
  # "BS 6034:1981:Addendum No. 1:1986"
13
13
  class AddendumDocument < SingleIdentifier
14
- attribute :base_identifier, ::Pubid::Identifier, polymorphic: true
14
+ attribute :base, ::Pubid::Identifier, polymorphic: true
15
15
  attribute :addendum_number, :string
16
16
  attribute :addendum_year, :integer
17
17
  attribute :addendum_type, :string, default: -> {
@@ -22,7 +22,7 @@ module Pubid
22
22
  } # Separator before Addendum (":" or " ")
23
23
 
24
24
  def publisher
25
- base_identifier&.publisher
25
+ base&.publisher
26
26
  end
27
27
  end
28
28
  end