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
@@ -21,118 +21,122 @@ module Pubid
21
21
  autoload :UrnParser, "#{__dir__}/cen_cenelec/urn_parser"
22
22
 
23
23
  # TYPED_STAGES_REGISTRY for native CEN types
24
+ # Covers the CEN PROJEX stage-code table per issue #251.
24
25
  TYPED_STAGES_REGISTRY = [
25
- # European Norm (EN)
26
+ # === European Norm (EN) lifecycle ===
27
+ # Preliminary (pWI EN): proposal/WI stages
26
28
  Pubid::Components::TypedStage.new(
27
- code: :puben,
28
- stage_code: :published,
29
- type_code: :en,
30
- abbr: ["EN"],
31
- name: "European Norm",
32
- harmonized_stages: %w[60.00 60.60],
29
+ code: :pwien, stage_code: :preliminary, type_code: :en,
30
+ abbr: ["pWI EN"], name: "Preliminary Work Item EN",
31
+ harmonized_stages: %w[00.60 10.98 10.99 20.60],
33
32
  ),
33
+ # Proposal (prEN): working draft stages
34
34
  Pubid::Components::TypedStage.new(
35
- code: :pren,
36
- stage_code: :proposal,
37
- type_code: :en,
38
- abbr: ["prEN"],
39
- name: "Proposal European Norm",
40
- harmonized_stages: %w[30.00 30.20 30.60 30.92 30.98 30.99],
35
+ code: :pren, stage_code: :proposal, type_code: :en,
36
+ abbr: ["prEN"], name: "Proposal European Norm",
37
+ harmonized_stages: %w[30.00 30.20 30.60 30.92 30.97 30.98 30.99],
38
+ ),
39
+ # Final Proposal (FprEN): enquiry stages
40
+ Pubid::Components::TypedStage.new(
41
+ code: :fpren, stage_code: :final_proposal, type_code: :en,
42
+ abbr: ["FprEN"], name: "Final Proposal European Norm",
43
+ harmonized_stages: %w[40.00 40.20 40.60 40.92 40.97 40.98 40.99],
44
+ ),
45
+ # Formal Vote (FV prEN): COCOR + FV dispatch
46
+ Pubid::Components::TypedStage.new(
47
+ code: :fven, stage_code: :formal_vote, type_code: :en,
48
+ abbr: ["FV prEN"], name: "Formal Vote EN",
49
+ harmonized_stages: %w[43.20 43.60 43.97 43.98 45.97 45.98 45.99],
50
+ ),
51
+ # Vote (vEN): enquiry/vote
52
+ Pubid::Components::TypedStage.new(
53
+ code: :ven, stage_code: :vote, type_code: :en,
54
+ abbr: ["vEN"], name: "Vote EN",
55
+ harmonized_stages: %w[50.20 50.60 50.97 50.98],
56
+ ),
57
+ # Published (EN): ratification + publication milestones
58
+ Pubid::Components::TypedStage.new(
59
+ code: :puben, stage_code: :published, type_code: :en,
60
+ abbr: ["EN"], name: "European Norm",
61
+ harmonized_stages: %w[60.00 60.55 60.60 65.31 65.51 65.62],
62
+ ),
63
+ # Review (rvEN): 2-year review
64
+ Pubid::Components::TypedStage.new(
65
+ code: :rven, stage_code: :review, type_code: :en,
66
+ abbr: ["rvEN"], name: "Review EN",
67
+ harmonized_stages: %w[90.00 90.20 90.60 90.92 90.93 90.98],
68
+ ),
69
+ # Reactivation (racEN)
70
+ Pubid::Components::TypedStage.new(
71
+ code: :racen, stage_code: :reactivation, type_code: :en,
72
+ abbr: ["racEN"], name: "Re-activated EN",
73
+ harmonized_stages: %w[96.60],
41
74
  ),
75
+ # Withdrawn (wdEN)
42
76
  Pubid::Components::TypedStage.new(
43
- code: :fpren,
44
- stage_code: :final_proposal,
45
- type_code: :en,
46
- abbr: ["FprEN"],
47
- name: "Final Proposal European Norm",
48
- harmonized_stages: %w[40.00 40.20 40.60 40.92 40.98 40.99],
77
+ code: :wden, stage_code: :withdrawn, type_code: :en,
78
+ abbr: ["wdEN"], name: "Withdrawn EN",
79
+ harmonized_stages: %w[99.60],
49
80
  ),
50
81
 
51
- # Technical Specification (TS)
82
+ # === Technical Specification (TS) ===
52
83
  Pubid::Components::TypedStage.new(
53
- code: :pubts,
54
- stage_code: :published,
55
- type_code: :ts,
56
- abbr: ["TS"],
57
- name: "Technical Specification",
84
+ code: :pubts, stage_code: :published, type_code: :ts,
85
+ abbr: ["TS"], name: "Technical Specification",
58
86
  harmonized_stages: %w[60.00 60.60],
59
87
  ),
60
88
  Pubid::Components::TypedStage.new(
61
- code: :prts,
62
- stage_code: :proposal,
63
- type_code: :ts,
64
- abbr: ["prTS"],
65
- name: "Proposal Technical Specification",
89
+ code: :prts, stage_code: :proposal, type_code: :ts,
90
+ abbr: ["prTS"], name: "Proposal Technical Specification",
66
91
  harmonized_stages: %w[30.00 30.20 30.60 30.92 30.98 30.99],
67
92
  ),
68
93
 
69
- # Technical Report (TR)
94
+ # === Technical Report (TR) ===
70
95
  Pubid::Components::TypedStage.new(
71
- code: :pubtr,
72
- stage_code: :published,
73
- type_code: :tr,
74
- abbr: ["TR"],
75
- name: "Technical Report",
96
+ code: :pubtr, stage_code: :published, type_code: :tr,
97
+ abbr: ["TR"], name: "Technical Report",
76
98
  harmonized_stages: %w[60.00 60.60],
77
99
  ),
78
100
 
79
- # CEN Workshop Agreement (CWA)
101
+ # === CEN Workshop Agreement (CWA) ===
80
102
  Pubid::Components::TypedStage.new(
81
- code: :pubcwa,
82
- stage_code: :published,
83
- type_code: :cwa,
84
- abbr: ["CWA"],
85
- name: "CEN Workshop Agreement",
103
+ code: :pubcwa, stage_code: :published, type_code: :cwa,
104
+ abbr: ["CWA"], name: "CEN Workshop Agreement",
86
105
  harmonized_stages: %w[60.00 60.60],
87
106
  ),
88
107
 
89
- # Guide
108
+ # === Guide ===
90
109
  Pubid::Components::TypedStage.new(
91
- code: :pubguide,
92
- stage_code: :published,
93
- type_code: :guide,
94
- abbr: ["Guide"],
95
- name: "Guide",
110
+ code: :pubguide, stage_code: :published, type_code: :guide,
111
+ abbr: ["Guide"], name: "Guide",
96
112
  harmonized_stages: %w[60.00 60.60],
97
113
  ),
98
114
 
99
- # Harmonization Document (HD)
115
+ # === Harmonization Document (HD) ===
100
116
  Pubid::Components::TypedStage.new(
101
- code: :pubhd,
102
- stage_code: :published,
103
- type_code: :hd,
104
- abbr: ["HD"],
105
- name: "Harmonization Document",
117
+ code: :pubhd, stage_code: :published, type_code: :hd,
118
+ abbr: ["HD"], name: "Harmonization Document",
106
119
  harmonized_stages: %w[60.00 60.60],
107
120
  ),
108
121
 
109
- # European Specification (ES)
122
+ # === European Specification (ES) ===
110
123
  Pubid::Components::TypedStage.new(
111
- code: :pubes,
112
- stage_code: :published,
113
- type_code: :es,
114
- abbr: ["ES"],
115
- name: "European Specification",
124
+ code: :pubes, stage_code: :published, type_code: :es,
125
+ abbr: ["ES"], name: "European Specification",
116
126
  harmonized_stages: %w[60.00 60.60],
117
127
  ),
118
128
 
119
- # CEN Report (CR)
129
+ # === CEN Report (CR) ===
120
130
  Pubid::Components::TypedStage.new(
121
- code: :pubcr,
122
- stage_code: :published,
123
- type_code: :cr,
124
- abbr: ["CR"],
125
- name: "CEN Report",
131
+ code: :pubcr, stage_code: :published, type_code: :cr,
132
+ abbr: ["CR"], name: "CEN Report",
126
133
  harmonized_stages: %w[60.00 60.60],
127
134
  ),
128
135
 
129
- # European Prestandard (ENV)
136
+ # === European Prestandard (ENV) ===
130
137
  Pubid::Components::TypedStage.new(
131
- code: :pubenv,
132
- stage_code: :published,
133
- type_code: :env,
134
- abbr: ["ENV"],
135
- name: "European Prestandard",
138
+ code: :pubenv, stage_code: :published, type_code: :env,
139
+ abbr: ["ENV"], name: "European Prestandard",
136
140
  harmonized_stages: %w[60.00 60.60],
137
141
  ),
138
142
  ].freeze
@@ -14,12 +14,20 @@ module Pubid
14
14
  # Determine identifier class based on parsed content
15
15
  identifier_class = determine_class(parsed_hash)
16
16
 
17
+ # Supplement / Corrigendum wrap a nested base.
18
+ if identifier_class == Cie::Identifiers::Corrigendum
19
+ return build_corrigendum(parsed_hash)
20
+ end
21
+ if identifier_class == Cie::Identifiers::Supplement
22
+ return build_supplement(parsed_hash)
23
+ end
24
+
17
25
  # Extract attributes with style detection
18
26
  attributes = extract_attributes(parsed_hash)
19
27
 
20
- # For Bundle identifier, store original string
28
+ # For Bundle, parse each comma-separated member and hoist a shared base.
21
29
  if parsed_hash[:bundle_items] && original_string
22
- attributes[:identifiers_string] = original_string
30
+ attributes.merge!(build_bundle(original_string))
23
31
  end
24
32
 
25
33
  # Construct identifier
@@ -28,6 +36,85 @@ module Pubid
28
36
 
29
37
  private
30
38
 
39
+ # Build a Bundle's attributes from its printed form. Parse each member,
40
+ # then — since a CIE bundle is the parts of one supplement of one standard
41
+ # — hoist the shared base and keep only the differing supplement
42
+ # number/part in each doc. If the members don't share a base (not seen in
43
+ # practice, but the grammar allows it), keep each doc's own base instead.
44
+ def build_bundle(original_string)
45
+ members = split_bundle_members(original_string)
46
+ shared = common_base(members)
47
+ return { ids: members } unless shared
48
+
49
+ ids = members.map do |m|
50
+ Cie::Identifiers::Supplement.new(number: m.number, part: m.part)
51
+ end
52
+ { base: shared, ids: ids }
53
+ end
54
+
55
+ # The publisher prefix is written once, so only the first item carries
56
+ # "CIE "; prepend it to the rest before parsing each member.
57
+ def split_bundle_members(original_string)
58
+ original_string.split(",").each_with_index.map do |item, i|
59
+ ref = i.zero? ? item.strip : "CIE #{item.strip}"
60
+ Cie::Identifier.parse(ref)
61
+ end
62
+ end
63
+
64
+ # The base shared by every member, or nil if they differ (or any is
65
+ # base-less). Compared by canonical hash so structural equality holds.
66
+ def common_base(members)
67
+ bases = members.map(&:base)
68
+ return nil if bases.any?(&:nil?)
69
+
70
+ first = bases.first.to_hash
71
+ bases.all? { |b| b.to_hash == first } ? bases.first : nil
72
+ end
73
+
74
+ # Supplement: nest the base Standard (the stage/year/language belong to
75
+ # the base), keep only the -SPN number/part on the wrapper.
76
+ def build_supplement(parsed_hash)
77
+ a = extract_attributes(parsed_hash)
78
+ base = Cie::Identifiers::Standard.new(
79
+ number: a[:base_number],
80
+ stage: a[:stage],
81
+ s_prefix: a.fetch(:s_prefix, false),
82
+ language: a[:language],
83
+ year: a[:year],
84
+ style: "current", # supplements always use the colon style
85
+ )
86
+ Cie::Identifiers::Supplement.new(
87
+ base: base,
88
+ number: a[:supplement_number],
89
+ part: a[:supplement_part],
90
+ )
91
+ end
92
+
93
+ # Corrigendum: nest the base (a Standard, or a Supplement when the base
94
+ # itself carries -SPN), keep only the /CorN number/year on the wrapper.
95
+ def build_corrigendum(parsed_hash)
96
+ a = extract_attributes(parsed_hash)
97
+ base_std = Cie::Identifiers::Standard.new(
98
+ number: a[:base_number],
99
+ year: a[:base_year],
100
+ style: "current",
101
+ )
102
+ base = if a[:base_supplement]
103
+ Cie::Identifiers::Supplement.new(
104
+ base: base_std,
105
+ number: a[:base_supplement],
106
+ part: a[:base_supplement_part],
107
+ )
108
+ else
109
+ base_std
110
+ end
111
+ Cie::Identifiers::Corrigendum.new(
112
+ base: base,
113
+ number: a[:cor_number],
114
+ year: a[:cor_year],
115
+ )
116
+ end
117
+
31
118
  # Determine which identifier class to use
32
119
  def determine_class(parsed_hash)
33
120
  # Tutorial Bundle (special text format)
@@ -50,6 +137,11 @@ module Pubid
50
137
  return Cie::Identifiers::Supplement
51
138
  end
52
139
 
140
+ # Proceedings paper (x-prefixed or standalone)
141
+ if parsed_hash[:paper_code]
142
+ return Cie::Identifiers::Proceedings
143
+ end
144
+
53
145
  # Conference (x-prefix)
54
146
  if parsed_hash[:conference]
55
147
  return Cie::Identifiers::Conference
@@ -179,47 +271,69 @@ module Pubid
179
271
  date_sep = "slash" # Special format for identical identifiers
180
272
  end
181
273
 
182
- # Detect style from date separator
183
- style = if date_sep == "colon"
184
- "current"
185
- else
186
- (date_sep == "dash" ? "legacy" : detect_style_fallback(parsed_hash))
274
+ # Style is the sole separator field (no date_separator):
275
+ # colon -> current (":") dash -> legacy ("-") slash -> slash ("/")
276
+ style = case date_sep
277
+ when "colon" then "current"
278
+ when "dash" then "legacy"
279
+ when "slash" then "slash"
280
+ else detect_style_fallback(parsed_hash)
187
281
  end
188
282
  attributes[:style] = style
189
283
 
190
- # Set year and separator if present
284
+ # Set year if present
191
285
  attributes[:year] = year_value if year_value
192
- attributes[:date_separator] = date_sep if date_sep
193
286
 
194
- # Extract code
287
+ # Extract code (flat number/part/iteration/part_separator on the
288
+ # identifier; the code's style is the identifier's own `style`).
195
289
  if parsed_hash[:number]
196
- code_attrs = { number: extract_value(parsed_hash[:number]),
197
- style: style }
290
+ attributes[:number] = extract_value(parsed_hash[:number])
198
291
  if parsed_hash[:part]
199
- code_attrs[:part] =
200
- extract_value(parsed_hash[:part])
292
+ attributes[:part] = extract_value(parsed_hash[:part])
201
293
  end
202
294
  if parsed_hash[:iteration]
203
- code_attrs[:iteration] =
204
- extract_value(parsed_hash[:iteration])
295
+ attributes[:iteration] = extract_value(parsed_hash[:iteration])
205
296
  end
206
297
 
207
298
  # Detect part separator from parser markers
208
299
  if parsed_hash[:slash_sep]
209
- code_attrs[:part_separator] = "slash"
300
+ attributes[:part_separator] = "slash"
210
301
  elsif parsed_hash[:dash_sep]
211
- code_attrs[:part_separator] = "dash"
302
+ attributes[:part_separator] = "dash"
212
303
  end
213
-
214
- attributes[:code] = Components::Code.new(**code_attrs)
215
304
  end
216
305
 
217
306
  # Conference number (separate from regular code)
218
307
  if parsed_hash[:conf_number]
219
- attributes[:conference_number] =
308
+ attributes[:number] =
220
309
  extract_value(parsed_hash[:conf_number])
221
310
  end
222
311
 
312
+ # Proceedings paper: the paper itself is the document, so its identity
313
+ # (code + running number, e.g. "OP01") is the flat +number+ for both
314
+ # surface forms. The x-form's parent conference goes to
315
+ # +conference+; the standalone form keeps its +page+ range.
316
+ if parsed_hash[:paper_code]
317
+ attributes[:number] =
318
+ "#{extract_value(parsed_hash[:paper_code])}" \
319
+ "#{extract_value(parsed_hash[:paper_number])}"
320
+ if parsed_hash[:conf_number]
321
+ attributes[:conference] =
322
+ extract_value(parsed_hash[:conf_number])
323
+ end
324
+ end
325
+ if parsed_hash[:page_range]
326
+ attributes[:page] = extract_value(parsed_hash[:page_range])
327
+ end
328
+
329
+ # Conference /slug variant (opaque, verbatim)
330
+ if parsed_hash[:variant]
331
+ attributes[:variant] = extract_value(parsed_hash[:variant])
332
+ end
333
+
334
+ # D-series marker
335
+ attributes[:d_prefix] = true if parsed_hash[:d_prefix]
336
+
223
337
  # Extract language (direct lang_code for slash_colon format)
224
338
  lang_code = nil
225
339
  lang_format = nil
@@ -325,10 +439,11 @@ module Pubid
325
439
  extract_value(parsed_hash[:amd_number])
326
440
  end
327
441
 
328
- # Extract bundle data
442
+ # Tutorial bundle: the ordinal is the bundle's own `number` (also its
443
+ # relaton-index key). A comma-list bundle instead keys via its `ids`
444
+ # members through #root, so it needs no stored number.
329
445
  if parsed_hash[:bundle_number]
330
- attributes[:bundle_number] =
331
- extract_value(parsed_hash[:bundle_number])
446
+ attributes[:number] = extract_value(parsed_hash[:bundle_number])
332
447
  end
333
448
 
334
449
  # Extract trailing language from legacy_code_with_year
@@ -5,10 +5,14 @@ module Pubid
5
5
  # Base Identifier class for CIE.
6
6
  #
7
7
  # Inherits the shared Pubid::Identifier contract (format_registry, render,
8
- # to_urn, exclude, hash, eql?) while allowing CIE-specific attributes
9
- # such as +style+ ("legacy" vs "current" date separator).
8
+ # to_urn, exclude, hash, eql?) while allowing CIE-specific attributes.
9
+ #
10
+ # +style+ is the sole number<->year separator field (there is no separate
11
+ # date_separator): "current" -> ":", "legacy" -> "-", "slash" -> "/".
12
+ # It defaults to "current" (the dominant value), so canonicalize_hash drops
13
+ # it from the majority of rows and from_hash restores it.
10
14
  class Identifier < ::Pubid::Identifier
11
- attribute :style, :string # "legacy" or "current"
15
+ attribute :style, :string, default: -> { "current" }
12
16
 
13
17
  def self.parse(input)
14
18
  if input.length > Pubid::MAX_INPUT_LENGTH
@@ -5,14 +5,42 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Cie
7
7
  module Identifiers
8
- # Bundle identifier for CIE
9
- # Handles comma-separated supplement lists
8
+ # Bundle identifier for CIE: a comma-separated list of sibling documents,
9
+ # each a full CIE identifier (typically a Supplement).
10
10
  # Example: CIE 198-SP1.1:2011,198-SP1.2:2011,198-SP1.3:2011,198-SP1.4:2011
11
+ #
12
+ # A CIE bundle is the parts of one supplement of one standard, so its
13
+ # members share a base document. That shared +base+ is hoisted to the
14
+ # bundle and the +ids+ carry only what differs (supplement number/part);
15
+ # #root walks +base+ to the origin standard for the relaton-index key.
16
+ # (Defensive: if members ever don't share a base, each id keeps its own
17
+ # and +base+ is nil — see Builder#build_bundle.)
11
18
  class Bundle < SingleIdentifier
12
- attribute :identifiers_string, :string # Store as string for now
19
+ attribute :base, Identifier, polymorphic: true
20
+ attribute :ids, Identifier, polymorphic: true, collection: true
13
21
 
22
+ # The origin document: the shared base's root, else the first member's.
23
+ def root
24
+ (base || ids&.first)&.root || self
25
+ end
26
+
27
+ # The printed form writes the publisher once: the first member keeps its
28
+ # "CIE " prefix, the rest are bare. A base-less member is re-based onto
29
+ # the bundle's shared base for rendering.
14
30
  def to_s
15
- identifiers_string || ""
31
+ return "" unless ids&.any?
32
+
33
+ ids.each_with_index.map do |id, i|
34
+ member = id.base ? id : rebased(id)
35
+ i.zero? ? member.to_s : member.to_s.delete_prefix("CIE ")
36
+ end.join(",")
37
+ end
38
+
39
+ private
40
+
41
+ # Attach the bundle's shared base to a base-less member for rendering.
42
+ def rebased(id)
43
+ Supplement.new(base: base, number: id.number, part: id.part)
16
44
  end
17
45
  end
18
46
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Cie
5
+ module Identifiers
6
+ # Shared document-code attributes + rendering for the CIE identifier
7
+ # types that carry a code (Standard, Identical, JointPublished,
8
+ # DualPublished).
9
+ #
10
+ # The code fields live *flat* on the identifier (no nested
11
+ # Components::Code), so the serialized hash stays compact:
12
+ # {style:, year:, ..., number: "018", iteration: "2"}
13
+ # rather than nesting them under a code: {number:, iteration:, style:}.
14
+ #
15
+ # +code.style+ is intentionally gone: it always equalled the identifier's
16
+ # own +style+ (the builder set both from one value), so #code_string reads
17
+ # the identifier's +style+ directly for the part-separator fallback.
18
+ module CodeAttributes
19
+ def self.included(base)
20
+ base.class_eval do
21
+ attribute :number, :string # "018", "170", "11664"
22
+ attribute :part, :string # "1", "2", "4"
23
+ attribute :iteration, :string # "2" in "018.2"
24
+ attribute :part_separator, :string # "slash" | "dash" (original sep)
25
+ end
26
+ end
27
+
28
+ # Render the code portion: "018.2", "170-1", "19/2.1", "11664-1".
29
+ # Uses +part_separator+ when set, otherwise falls back to the
30
+ # identifier's +style+ (legacy -> "/", current -> "-").
31
+ def code_string
32
+ return nil unless number
33
+
34
+ result = number.dup
35
+ if part && iteration
36
+ result += "/#{part}.#{iteration}"
37
+ elsif iteration
38
+ result += ".#{iteration}"
39
+ elsif part
40
+ separator = case part_separator
41
+ when "slash" then "/"
42
+ when "dash" then "-"
43
+ else style == "current" ? "-" : "/"
44
+ end
45
+ result += "#{separator}#{part}"
46
+ end
47
+ result
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -9,21 +9,26 @@ module Pubid
9
9
  # Handles x-prefix conference proceedings
10
10
  # Example: CIE x038:2013, CIE x038:2013 Amendment 1
11
11
  class Conference < SingleIdentifier
12
- attribute :conference_number, :string
12
+ # :string overrides the base ::Pubid::Identifier Components::Code type.
13
+ attribute :number, :string
13
14
  attribute :amendment_number, :string
15
+ # Techstreet opaque /slug variant (no default -> round-trips cleanly)
16
+ attribute :variant, :string
14
17
 
15
18
  def to_s
16
- result = "CIE x#{conference_number}"
19
+ result = "CIE x#{number}"
17
20
 
18
21
  # Date with separator
19
22
  if year
20
- separator = date_separator == "colon" ? ":" : "-"
21
- result += "#{separator}#{year}"
23
+ result += "#{date_sep_char}#{year}"
22
24
  end
23
25
 
24
26
  # Amendment if present
25
27
  result += " Amendment #{amendment_number}" if amendment_number
26
28
 
29
+ # Opaque /slug variant if present
30
+ result += "/#{variant}" if variant
31
+
27
32
  result
28
33
  end
29
34
  end
@@ -5,34 +5,28 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Cie
7
7
  module Identifiers
8
- # Corrigendum identifier for CIE
9
- # Handles /CorN notation with recursive base parsing
8
+ # Corrigendum identifier for CIE (/CorN notation).
9
+ # Wraps a nested base a Standard, or a Supplement when the
10
+ # corrigendum applies to a supplement (CIE 198-SP1.4:2011/Cor1:2013).
11
+ # The "/CorN:year" is a clean trailing suffix on the base's rendering.
10
12
  # Examples: CIE 232:2019/Cor1:2020, CIE 198-SP1.4:2011/Cor1:2013
11
13
  class Corrigendum < SupplementIdentifier
12
- attribute :base_number, :string
13
- attribute :base_year, :string
14
- attribute :base_supplement, :string # If base is a supplement
15
- attribute :base_supplement_part, :string # Part of supplement
16
- attribute :cor_number, :string
17
- attribute :cor_year, :string
14
+ # +number+ (the "/CorN" ordinal) is inherited from SupplementIdentifier.
15
+ # The corrigendum's own year — SupplementIdentifier descends from the
16
+ # base Identifier (not SingleIdentifier), so there is no inherited year.
17
+ attribute :year, :string
18
18
 
19
- def to_s
20
- # Build base identifier string
21
- result = "CIE #{base_number}"
22
-
23
- # Add supplement notation if base is a supplement
24
- if base_supplement
25
- result += "-SP#{base_supplement}"
26
- result += ".#{base_supplement_part}" if base_supplement_part
27
- end
28
-
29
- # Add base year with colon
30
- result += ":#{base_year}" if base_year
19
+ # Uniform supplement interface (shared with Supplement).
20
+ def supplement_type
21
+ :corrigendum
22
+ end
31
23
 
32
- # Add corrigendum with slash and colon
33
- result += "/Cor#{cor_number}:#{cor_year}"
24
+ def supplement_year
25
+ year
26
+ end
34
27
 
35
- result
28
+ def to_s
29
+ "#{base}/Cor#{number}:#{year}"
36
30
  end
37
31
  end
38
32
  end
@@ -9,8 +9,9 @@ module Pubid
9
9
  # Represents CIE/IEC dual published standards
10
10
  # Example: CIE S 009:2002/IEC 62471:2006
11
11
  class DualPublished < SingleIdentifier
12
+ include CodeAttributes # flat number/part/iteration/part_separator + #code_string
13
+
12
14
  attribute :s_prefix, :boolean, default: -> { false }
13
- attribute :code, Components::Code
14
15
  attribute :iec_identifier, :string # IEC portion as string
15
16
 
16
17
  def to_s
@@ -20,14 +21,13 @@ module Pubid
20
21
  parts << "S" if s_prefix
21
22
 
22
23
  # Code
23
- parts << code.to_s if code
24
+ parts << code_string if number
24
25
 
25
26
  result = parts.join(" ")
26
27
 
27
28
  # Date
28
29
  if year
29
- separator = date_separator == "colon" ? ":" : "-"
30
- result += "#{separator}#{year}"
30
+ result += "#{date_sep_char}#{year}"
31
31
  end
32
32
 
33
33
  # IEC portion with slash separator