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
@@ -12,8 +12,9 @@ module Pubid
12
12
  # CIE S 014-4/E2007 - part with dash + language
13
13
  # CIE S 008/E:2001 (ISO 8995-1:2002(E)) - language with colon year
14
14
  class Identical < SingleIdentifier
15
+ include CodeAttributes # flat number/part/iteration/part_separator + #code_string
16
+
15
17
  attribute :s_prefix, :boolean, default: -> { false }
16
- attribute :code, Components::Code
17
18
  attribute :language, Components::Language
18
19
  attribute :iso_reference, :string # The ISO identifier in parentheses
19
20
 
@@ -24,12 +25,12 @@ module Pubid
24
25
  parts << "S" if s_prefix
25
26
 
26
27
  # Code
27
- parts << code.to_s if code
28
+ parts << code_string if number
28
29
 
29
30
  result = parts.join(" ")
30
31
 
31
32
  # Language + Year combined for slash formats before ISO reference
32
- if language && (language.format == "slash_colon" || (language.format == "slash" && year && date_separator != "slash"))
33
+ if language && (language.format == "slash_colon" || (language.format == "slash" && year && style != "slash"))
33
34
  # Render /E:YYYY or /EYYYY (language with year, no separate date separator)
34
35
  result += if language.format == "slash_colon"
35
36
  "/#{language.code}:#{year}" # /E:2001
@@ -39,13 +40,12 @@ module Pubid
39
40
  elsif language && language.format == "slash"
40
41
  # Language without year: /E
41
42
  result += "/#{language.code}"
42
- elsif year && date_separator == "slash"
43
+ elsif year && style == "slash"
43
44
  # Legacy slash-year format without language: /1998
44
45
  result += "/#{year}"
45
46
  elsif year
46
- # Standard date with separator (colon or dash)
47
- separator = date_separator == "colon" ? ":" : "-"
48
- result += "#{separator}#{year}"
47
+ # Standard date with separator derived from style
48
+ result += "#{date_sep_char}#{year}"
49
49
  end
50
50
 
51
51
  # Language (parenthetical) after date
@@ -8,8 +8,9 @@ module Pubid
8
8
  # Joint published identifier for CIE
9
9
  # Handles CIE ISO, CIE IEC, CIE ISO/CIE patterns
10
10
  class JointPublished < SingleIdentifier
11
+ include CodeAttributes # flat number/part/iteration/part_separator + #code_string
12
+
11
13
  attribute :copublisher, :string # "ISO", "IEC", or "ISO/CIE"
12
- attribute :code, Components::Code
13
14
  attribute :language, Components::Language
14
15
  attribute :doc_type, :string # "TR" for Technical Report
15
16
  attribute :stage, :string # "DIS" for draft stage
@@ -24,21 +25,20 @@ module Pubid
24
25
  parts << stage if stage
25
26
 
26
27
  # Code (number-part) - special handling for IEC dot separator
27
- if code
28
- code_str = code.to_s
28
+ if number
29
+ code_str = code_string
29
30
  # For IEC copublisher, if code has a part, use dot not slash/dash
30
- if copublisher == "IEC" && code.part
31
- code_str = "#{code.number}.#{code.part}"
31
+ if copublisher == "IEC" && part
32
+ code_str = "#{number}.#{part}"
32
33
  end
33
34
  parts << code_str
34
35
  end
35
36
 
36
37
  result = parts.join(" ")
37
38
 
38
- # Date - use the actual captured separator
39
+ # Date - separator derived from style
39
40
  if year
40
- separator = date_separator == "colon" ? ":" : "-"
41
- result += "#{separator}#{year}"
41
+ result += "#{date_sep_char}#{year}"
42
42
  end
43
43
 
44
44
  # Language (always parenthetical for joint published)
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Pubid
6
+ module Cie
7
+ module Identifiers
8
+ # Proceedings paper identifier for CIE conference papers.
9
+ #
10
+ # Two surface forms share this type:
11
+ # x-prefixed (attached to a conference): "CIE x043-OP01"
12
+ # standalone (with a page range): "CIE OP02 1-5"
13
+ #
14
+ # The paper itself is the document, so its identity (code + running
15
+ # number, e.g. "OP01") is stored flat as +number+ for BOTH forms. This
16
+ # gives every proceedings row a non-empty relaton-index binary-search key
17
+ # (see index_number_spec). The x-form's parent conference lives in
18
+ # +conference+; the standalone form's +page+ range is its locality.
19
+ # No-default values so absent keys drop from to_hash (round-trip).
20
+ class Proceedings < SingleIdentifier
21
+ # The paper identity "OP01" / "P03". :string overrides the base
22
+ # ::Pubid::Identifier Components::Code type.
23
+ attribute :number, :string
24
+ # The parent conference "043" (x-form only; nil for standalone).
25
+ attribute :conference, :string
26
+ # Page range "1-5" (standalone form only).
27
+ attribute :page, :string
28
+
29
+ def to_s
30
+ if conference
31
+ "CIE x#{conference}-#{number}"
32
+ else
33
+ "CIE #{number} #{page}"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -8,8 +8,12 @@ module Pubid
8
8
  # Standard identifier for CIE
9
9
  # Handles both legacy (pre-2001) and current (2001+) styles
10
10
  class Standard < SingleIdentifier
11
+ include CodeAttributes # flat number/part/iteration/part_separator + #code_string
12
+
11
13
  attribute :s_prefix, :boolean, default: -> { false }
12
- attribute :code, Components::Code
14
+ # D-series marker (CIE D001-2006). Boolean default false so it is
15
+ # canonicalized away for every non-D standard (round-trip contract).
16
+ attribute :d_prefix, :boolean, default: -> { false }
13
17
  attribute :language, Components::Language
14
18
  attribute :stage, :string # DIS, DS
15
19
 
@@ -19,11 +23,16 @@ module Pubid
19
23
  # Stage (DIS/DS) before code if present
20
24
  parts << stage if stage
21
25
 
22
- # S prefix
23
- parts << "S" if s_prefix
26
+ if d_prefix
27
+ # D-series: the D is attached to the code (no space): CIE D001
28
+ parts << "D#{code_string}"
29
+ else
30
+ # S prefix
31
+ parts << "S" if s_prefix
24
32
 
25
- # Code
26
- parts << code.to_s if code
33
+ # Code
34
+ parts << code_string if number
35
+ end
27
36
 
28
37
  # Build initial result from parts
29
38
  result = parts.join(" ")
@@ -39,10 +48,15 @@ module Pubid
39
48
  return result # Year already added
40
49
  end
41
50
 
51
+ # Bare slash-year (legacy, no language): CIE S 007/1998
52
+ if year && style == "slash"
53
+ result += "/#{year}"
54
+ return result
55
+ end
56
+
42
57
  # Date with separator (for non-slash-colon formats)
43
58
  if year
44
- separator = date_separator == "colon" ? ":" : "-"
45
- result += "#{separator}#{year}"
59
+ result += "#{date_sep_char}#{year}"
46
60
  end
47
61
 
48
62
  # Language (parenthetical formats) - comes after date
@@ -52,6 +66,18 @@ module Pubid
52
66
 
53
67
  result
54
68
  end
69
+
70
+ # CIE Standard distinguishes S-prefixed standards (`CIE S 017`) from
71
+ # plain (`CIE 015`), D-prefixed (`CIE D001`), and DIS-staged. The
72
+ # generic mr_type looks at typed_stage, which CIE doesn't use, so
73
+ # without this override the `S`/`D`/stage marker would be lost in MR.
74
+ def mr_type
75
+ return stage.downcase if stage
76
+ return "d" if d_prefix
77
+ return "s" if s_prefix
78
+
79
+ nil
80
+ end
55
81
  end
56
82
  end
57
83
  end
@@ -5,38 +5,40 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Cie
7
7
  module Identifiers
8
- # Supplement identifier for CIE
9
- # Handles -SPN and -SPN.P notation with recursive base parsing
8
+ # Supplement identifier for CIE (-SPN / -SPN.P notation).
9
+ # Wraps a nested base (the base Standard); the "-SPN" is
10
+ # inserted after the base number, so to_s renders from the base's parts.
10
11
  # Examples: CIE 121-SP1:2009, CIE 198-SP1.4:2011, CIE DIS 025-SP1/E:2019
11
12
  class Supplement < SupplementIdentifier
12
- attribute :base_number, :string
13
- attribute :supplement_number, :string # "1", "2"
14
- attribute :supplement_part, :string # "1" in "SP1.1", "4" in "SP1.4"
15
- attribute :year, :string
16
- attribute :stage, :string # "DIS", "DS"
17
- attribute :language, Components::Language
13
+ # +number+ (the "-SPN" ordinal) is inherited from SupplementIdentifier.
14
+ attribute :part, :string # "1" in "SP1.1", "4" in "SP1.4"
15
+
16
+ # Uniform supplement interface (shared with Corrigendum).
17
+ def supplement_type
18
+ :supplement
19
+ end
20
+
21
+ def supplement_year
22
+ base&.year
23
+ end
18
24
 
19
25
  def to_s
26
+ b = base
20
27
  parts = ["CIE"]
28
+ parts << b.stage if b.respond_to?(:stage) && b.stage
21
29
 
22
- # Stage if present (DIS/DS)
23
- parts << stage if stage
24
-
25
- # Build base number and supplement
30
+ core = "#{b.number}-SP#{number}"
31
+ core += ".#{part}" if part
32
+ parts << core
26
33
  result = parts.join(" ")
27
- result += " #{base_number}-SP#{supplement_number}"
28
-
29
- # Add part if present (e.g., ".4" in "SP1.4")
30
- result += ".#{supplement_part}" if supplement_part
31
34
 
32
- # Add language with slash if present (before year)
33
- if language && language.format == "slash_colon"
34
- result += "/#{language.code}"
35
+ # Language with slash (before year), e.g. "/E"
36
+ if b.language && b.language.format == "slash_colon"
37
+ result += "/#{b.language.code}"
35
38
  end
36
39
 
37
- # Add year with colon (supplements always use current style)
38
- result += ":#{year}" if year
39
-
40
+ # Supplements always use the current (colon) style.
41
+ result += ":#{b.year}" if b.year
40
42
  result
41
43
  end
42
44
  end
@@ -8,11 +8,15 @@ module Pubid
8
8
  # Tutorial Bundle identifier for CIE
9
9
  # Special text-based identifier
10
10
  # Example: CIE Tutorials Bundle 1
11
+ #
12
+ # The ordinal ("1") is the bundle's own +number+ (also the relaton-index
13
+ # root key); there is no separate document, so no nested base.
11
14
  class TutorialBundle < SingleIdentifier
12
- attribute :bundle_number, :string
15
+ # :string overrides the base ::Pubid::Identifier Components::Code type.
16
+ attribute :number, :string
13
17
 
14
18
  def to_s
15
- "CIE Tutorials Bundle #{bundle_number}"
19
+ "CIE Tutorials Bundle #{number}"
16
20
  end
17
21
  end
18
22
  end
@@ -3,12 +3,14 @@
3
3
  module Pubid
4
4
  module Cie
5
5
  module Identifiers
6
+ autoload :CodeAttributes, "#{__dir__}/identifiers/code_attributes"
6
7
  autoload :Bundle, "#{__dir__}/identifiers/bundle"
7
8
  autoload :Conference, "#{__dir__}/identifiers/conference"
8
9
  autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
9
10
  autoload :DualPublished, "#{__dir__}/identifiers/dual_published"
10
11
  autoload :Identical, "#{__dir__}/identifiers/identical"
11
12
  autoload :JointPublished, "#{__dir__}/identifiers/joint_published"
13
+ autoload :Proceedings, "#{__dir__}/identifiers/proceedings"
12
14
  autoload :Standard, "#{__dir__}/identifiers/standard"
13
15
  autoload :Supplement, "#{__dir__}/identifiers/supplement"
14
16
  autoload :TutorialBundle, "#{__dir__}/identifiers/tutorial_bundle"
@@ -135,9 +135,50 @@ module Pubid
135
135
  (str("FDIS") | str("DIS") | str("DS")) >> space
136
136
  end
137
137
 
138
- # Document type (TR for Technical Report)
138
+ # Document type (TR for Technical Report, TS for Technical Specification)
139
139
  rule(:doc_type) do
140
- str("TR") # Don't consume trailing space
140
+ (str("TR") | str("TS")) # Don't consume trailing space
141
+ end
142
+
143
+ # Proceedings paper code: 1+ uppercase letters (OP, PO, PP, WP, IP, P, ...)
144
+ # Deliberately generic (open set); greedy letters then digits.
145
+ rule(:paper_code) do
146
+ match("[A-Z]").repeat(1).as(:paper_code)
147
+ end
148
+
149
+ # Techstreet opaque conference variant: /<lowercase-alnum slug>
150
+ # Charset kept lowercase-alnum so it can't collide with the uppercase
151
+ # /E, /Cor, /IEC tails or the self.parse language gsub.
152
+ rule(:variant_slug) do
153
+ slash >> match("[0-9a-z]").repeat(1).as(:variant)
154
+ end
155
+
156
+ # Conference proceedings paper (x-prefixed): CIE x043-OP01
157
+ rule(:conf_proceedings) do
158
+ str("CIE") >> space >> str("x") >> digits.as(:conf_number) >>
159
+ dash >> paper_code >> digits.as(:paper_number)
160
+ end
161
+
162
+ # Standalone proceedings paper: CIE OP02 1-5
163
+ rule(:standalone_proceedings) do
164
+ str("CIE") >> space >> paper_code >> digits.as(:paper_number) >>
165
+ space >> (digits >> dash >> digits).as(:page_range)
166
+ end
167
+
168
+ # D-series: CIE D001-2006 / CIE D002:2004
169
+ rule(:d_series_identifier) do
170
+ str("CIE") >> space >> str("D").as(:d_prefix) >> digits.as(:number) >> date
171
+ end
172
+
173
+ # Standard with bare slash-year (no language letter): CIE S 007/1998
174
+ # Uses a narrow number(+iteration) pattern rather than the full code rule
175
+ # so code_with_part_slash doesn't greedily consume the /year.
176
+ rule(:standard_with_slash_year) do
177
+ str("CIE") >> space >>
178
+ stage_code.maybe.as(:stage) >>
179
+ s_prefix.maybe.as(:s_prefix) >>
180
+ (digits.as(:number) >> (dot >> digits.as(:iteration)).maybe) >>
181
+ slash >> year_digits.as(:slash_year)
141
182
  end
142
183
 
143
184
  # DIS stage with supplement pattern (e.g., DIS 025-SP1/E:2019)
@@ -157,12 +198,14 @@ module Pubid
157
198
  stage_code.maybe.as(:stage) >>
158
199
  s_prefix.maybe.as(:s_prefix) >>
159
200
  code >>
160
- # Language can come BEFORE date, AFTER date, or both
201
+ # Language can come BEFORE date, AFTER date, or both.
202
+ # The whole date group is optional so a bare "CIE 015" (no year)
203
+ # parses with year left nil (partial reference for relaton matching).
161
204
  (
162
205
  (language >> date).as(:lang_before) |
163
206
  (date >> language.maybe).as(:date_then_lang) |
164
207
  date
165
- )
208
+ ).maybe
166
209
  end
167
210
 
168
211
  # Standard identifier without ISO reference but with language-year (CIE S 014-4/E:2007)
@@ -181,7 +224,9 @@ module Pubid
181
224
  digits.as(:conf_number) >>
182
225
  date >>
183
226
  # Optional amendment
184
- (space >> str("Amendment") >> space >> digits.as(:amd_number)).maybe
227
+ (space >> str("Amendment") >> space >> digits.as(:amd_number)).maybe >>
228
+ # Optional techstreet opaque /slug variant
229
+ variant_slug.maybe
185
230
  end
186
231
 
187
232
  # Joint published with ISO
@@ -320,6 +365,10 @@ module Pubid
320
365
  corrigendum_identifier |
321
366
  supplement_identifier |
322
367
  standard_with_language_year |
368
+ standard_with_slash_year |
369
+ d_series_identifier |
370
+ conf_proceedings |
371
+ standalone_proceedings |
323
372
  legacy_code_with_year | # Before standard to catch 001-1980 pattern
324
373
  conference_identifier |
325
374
  standard_identifier
@@ -24,7 +24,46 @@ module Pubid
24
24
  attribute :publisher, :string, default: -> { "CIE" }
25
25
 
26
26
  attribute :year, :string
27
- attribute :date_separator, :string # "dash" or "colon"
27
+ # The number<->year separator character, derived from +style+ (the sole
28
+ # separator field; there is no date_separator attribute):
29
+ # current -> ":" legacy -> "-" slash -> "/"
30
+ def date_sep_char
31
+ { "legacy" => "-", "slash" => "/" }.fetch(style, ":")
32
+ end
33
+
34
+ # Partial-reference matching: CIE keeps the publication year in its own
35
+ # `year` string attribute (the separator lives in `style`), not a `Date`
36
+ # component, so the base's `:year`->`:date` remap would nil the unused
37
+ # inherited `date` and leave `year` intact. Call super (preserving the
38
+ # nested-identifier recursion), then nil `year` directly so a year-less
39
+ # CIE ref is a year wildcard under `matches?(ignore: [:year])`.
40
+ #
41
+ # Known limit: `style` (which also encodes the era: current<->colon,
42
+ # legacy<->dash) is intentionally NOT wildcarded, so bare `CIE 015`
43
+ # (always current) matches a colon-dated full but not a legacy dash-dated
44
+ # (pre-2001) one. Partial-ref scope targets modern colon forms.
45
+ def exclude(*args)
46
+ result = super
47
+ result.year = nil if args.include?(:year) || args.include?(:date)
48
+ result
49
+ end
50
+
51
+ # CIE stores its publication year in its own `year` string attribute
52
+ # (not a Components::Date), and uses a single-Language component with
53
+ # multiple formats. Override the lossless MR template so `CIE S 017/E:2011`
54
+ # round-trips as `CIE.S.017.E.2011` rather than losing the type letter,
55
+ # language, and year (issue #142). Subclasses add the `s_prefix` and
56
+ # `language` attributes that this template reads.
57
+ def mr_year
58
+ year&.to_s
59
+ end
60
+
61
+ def mr_languages
62
+ return nil unless respond_to?(:language) && language
63
+
64
+ # Lowercase + filename-safe: drop the leading `/` (path-unsafe).
65
+ language.code.to_s.downcase
66
+ end
28
67
  end
29
68
  end
30
69
  end
@@ -2,25 +2,38 @@
2
2
 
3
3
  module Pubid
4
4
  module Cie
5
- # Base class for CIE supplement identifiers
6
- # Single Responsibility: Provide common attributes for supplement documents
5
+ # Base class for CIE supplement identifiers (Supplement, Corrigendum).
7
6
  #
8
- # Supplement identifiers modify or extend base identifiers.
9
- # Unlike ISO/IEC, CIE supplements store base information as flat
10
- # string attributes rather than recursive Identifier objects.
7
+ # Like ISO/IEC/BSI/JCGM, a CIE supplement wraps its base document as a
8
+ # nested full identifier (+base+, a Pubid::Cie::Identifier),
9
+ # rather than flat base_number/base_year strings. This lets CIE supplements
10
+ # participate in the shared base_document / drop_supplements / matches?
11
+ # vocabulary relaton uses to match a citation to its base standard.
11
12
  #
12
- # Classes inheriting from SupplementIdentifier:
13
- # - Corrigendum (corrigenda with /CorN notation)
14
- # - Supplement (supplements with -SPN notation)
15
- #
16
- # Architecture Note:
17
- # CIE uses a different architectural approach than ISO/IEC:
18
- # - ISO/IEC: Recursive base_identifier objects
19
- # - CIE: Flat string attributes (base_number, base_year, etc.)
13
+ # Concrete subtypes: Supplement (-SPN), Corrigendum (/CorN).
20
14
  class SupplementIdentifier < Identifier
21
- # Common attribute for all CIE identifiers
22
- # Values: "current" (colon date separator) or "legacy" (dash date separator)
23
- attribute :style, :string
15
+ attribute :base, Identifier, polymorphic: true
16
+ # The supplement's/corrigendum's own ordinal ("1" in -SP1 / Cor1).
17
+ # :string overrides the base ::Pubid::Identifier Components::Code type.
18
+ # (Not the index key — relaton keys on #root.number, the base standard's.)
19
+ attribute :number, :string
20
+
21
+ # Uniform, class-agnostic supplement interface (shared by Supplement and
22
+ # Corrigendum) so callers never special-case corrigenda. +supplement_type+
23
+ # and +supplement_year+ are defined per subclass.
24
+ def supplement_number
25
+ number
26
+ end
27
+
28
+ # The underlying standard, with supplement layer(s) peeled recursively.
29
+ def base_document
30
+ base&.base_document || self
31
+ end
32
+
33
+ # Dropping one supplement layer yields the wrapped base identifier.
34
+ def drop_supplements
35
+ base || self
36
+ end
24
37
  end
25
38
  end
26
39
  end
@@ -15,8 +15,8 @@ module Pubid
15
15
 
16
16
  parts << publisher_component
17
17
 
18
- if identifier.code
19
- parts << identifier.code.to_s
18
+ if identifier.respond_to?(:code_string) && identifier.code_string
19
+ parts << identifier.code_string
20
20
  end
21
21
 
22
22
  year = extract_year
@@ -37,8 +37,8 @@ module Pubid
37
37
  stage = maybe(:stage)
38
38
  parts << stage.to_s.downcase if stage
39
39
 
40
- date_separator = maybe(:date_separator)
41
- parts << "sep.#{date_separator}" if date_separator
40
+ # style is the sole separator field; record it for dated identifiers
41
+ parts << "sep.#{maybe(:style)}" if year
42
42
 
43
43
  iec_identifier = maybe(:iec_identifier)
44
44
  parts << "iec.#{iec_identifier}" if iec_identifier
@@ -49,11 +49,14 @@ module Pubid
49
49
  doc_type = maybe(:doc_type)
50
50
  parts << "doctype.#{doc_type}" if doc_type
51
51
 
52
- identifiers_string = maybe(:identifiers_string)
53
- parts << "bundle.#{identifiers_string}" if identifiers_string
52
+ if identifier.respond_to?(:ids) && identifier.ids&.any?
53
+ parts << "bundle.#{identifier}"
54
+ end
54
55
 
55
- bundle_number = maybe(:bundle_number)
56
- parts << "tut-bundle.#{bundle_number}" if bundle_number
56
+ if identifier.is_a?(Cie::Identifiers::TutorialBundle) &&
57
+ identifier.number
58
+ parts << "tut-bundle.#{identifier.number}"
59
+ end
57
60
 
58
61
  languages = maybe(:languages)
59
62
  if languages&.any?
data/lib/pubid/cie.rb CHANGED
@@ -8,7 +8,6 @@ module Pubid
8
8
  PREFIXES = ["CIE"].freeze
9
9
 
10
10
  module Components
11
- autoload :Code, "#{__dir__}/cie/components/code"
12
11
  autoload :Language, "#{__dir__}/cie/components/language"
13
12
  end
14
13
 
@@ -6,19 +6,33 @@ module Pubid
6
6
  module Components
7
7
  # Publication date component
8
8
  #
9
- # Human render: "YYYY" or "YYYY-MM" or "YYYY-MM-DD".
10
- # URN render: year only (RFC 5141-bis URN spec).
9
+ # Human render: "YYYY" or "YYYY-MM" or "YYYY-MM-DD"; or "--" when the
10
+ # date slot is present but explicitly undated (ISO/IEC undated-reference
11
+ # convention, e.g. "ISO 16634:--"). URN render: year only (RFC 5141-bis
12
+ # URN spec); flavors that drop the slot when undated gate that decision
13
+ # at the URN-generator level, not here.
11
14
  class Date < Lutaml::Model::Serializable
12
15
  attribute :year, :string
13
16
  attribute :month, :string
14
17
  attribute :day, :string
18
+ attribute :undated, :boolean, default: false
15
19
 
16
- # True when the year is set to a non-empty value.
20
+ # True when the year is set to a non-empty value, OR the date is
21
+ # explicitly marked undated. An undated date is a meaningful
22
+ # publication-date slot (it is what renders as `:--` in ISO/IEC), so
23
+ # callers that gate rendering on "is there a date at all?" should
24
+ # treat undated as present.
17
25
  def present?
26
+ return true if undated
18
27
  !year.nil? && !year.to_s.empty?
19
28
  end
20
29
 
30
+ def undated?
31
+ !!undated
32
+ end
33
+
21
34
  def render(context: nil)
35
+ return "--" if undated? && (year.nil? || year.to_s.empty?)
22
36
  return nil unless present?
23
37
  return year.to_s if context&.urn?
24
38
  return year.to_s unless month
@@ -29,6 +43,7 @@ module Pubid
29
43
  end
30
44
 
31
45
  def to_s(_context: nil, _include_month: false)
46
+ return "--" if undated? && (year.nil? || year.to_s.empty?)
32
47
  return year.to_s unless month
33
48
 
34
49
  result = "#{year}-#{pad2(month)}"
@@ -43,13 +58,14 @@ module Pubid
43
58
  end
44
59
 
45
60
  def hash
46
- @hash ||= [year, month, day].compact.map(&:hash).hash
61
+ @hash ||= [year, month, day, undated].compact.map(&:hash).hash
47
62
  end
48
63
 
49
64
  def eql?(other)
50
65
  return false unless other.is_a?(self.class)
51
66
 
52
- year == other.year && month == other.month && day == other.day
67
+ year == other.year && month == other.month && day == other.day &&
68
+ undated == other.undated
53
69
  end
54
70
  end
55
71
  end
@@ -53,7 +53,7 @@ module Pubid
53
53
  # Build base identifier (without package_portion)
54
54
  base_data = parsed_hash.dup
55
55
  base_data.delete(:package_portion)
56
- package.base_identifier = build_single(base_data)
56
+ package.base = build_single(base_data)
57
57
 
58
58
  # Set package materials
59
59
  if parsed_hash[:package_portion]
@@ -16,12 +16,28 @@ module Pubid
16
16
  class CompositeIdentifier < Lutaml::Model::Serializable
17
17
  # The primary/base identifier
18
18
  # Use attr_accessor since it can be any identifier object
19
- attr_accessor :base_identifier
19
+ attr_accessor :base
20
20
 
21
21
  # Subclasses MUST implement to_s to define how they render
22
22
  def to_s
23
23
  raise NotImplementedError, "Subclasses must implement to_s method"
24
24
  end
25
+
26
+ # CSA composites serialise through `to_s`, so MR mirrors that with
27
+ # ` ` → `.`, `:` → `.`, `/` → `-`, then lowercased (issue #142).
28
+ def to_mr_string
29
+ to_s.tr(" ", ".").tr(":", ".").tr("/", "-").downcase
30
+ end
31
+
32
+ def to_slug
33
+ to_mr_string
34
+ end
35
+
36
+ # CSA composites are not Pubid::Identifier objects, so they do not inherit
37
+ # #root. They are their own origin for matching purposes.
38
+ def root
39
+ self
40
+ end
25
41
  end
26
42
  end
27
43
  end