pubid 2.0.0.pre.alpha.8 → 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 (484) hide show
  1. checksums.yaml +4 -4
  2. data/data/bipm/update_codes.yaml +9 -0
  3. data/data/iec/update_codes.yaml +3 -0
  4. data/data/ieee/update_codes.yaml +107 -1
  5. data/data/nist/series.yaml +155 -0
  6. data/data/nist/update_codes.yaml +8 -0
  7. data/lib/pubid/adobe/builder.rb +52 -0
  8. data/lib/pubid/adobe/identifier.rb +49 -0
  9. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  10. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  11. data/lib/pubid/adobe/identifiers.rb +10 -0
  12. data/lib/pubid/adobe/parser.rb +128 -0
  13. data/lib/pubid/adobe/renderer.rb +39 -0
  14. data/lib/pubid/adobe/urn_generator.rb +42 -0
  15. data/lib/pubid/adobe/urn_parser.rb +69 -0
  16. data/lib/pubid/adobe.rb +60 -0
  17. data/lib/pubid/amca/builder.rb +2 -2
  18. data/lib/pubid/amca/identifier.rb +1 -3
  19. data/lib/pubid/amca/identifiers/base.rb +1 -6
  20. data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
  21. data/lib/pubid/amca/identifiers/publication.rb +1 -1
  22. data/lib/pubid/amca/identifiers/standard.rb +1 -1
  23. data/lib/pubid/amca/identifiers.rb +0 -1
  24. data/lib/pubid/amca/single_identifier.rb +1 -1
  25. data/lib/pubid/amca.rb +3 -3
  26. data/lib/pubid/ashrae/builder.rb +22 -22
  27. data/lib/pubid/ashrae/identifier.rb +3 -4
  28. data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
  29. data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
  30. data/lib/pubid/ashrae/identifiers/base.rb +14 -8
  31. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
  32. data/lib/pubid/ashrae/identifiers.rb +0 -1
  33. data/lib/pubid/ashrae/parser.rb +14 -9
  34. data/lib/pubid/ashrae/renderer.rb +19 -19
  35. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  36. data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
  37. data/lib/pubid/ashrae.rb +3 -3
  38. data/lib/pubid/bipm/builder.rb +107 -0
  39. data/lib/pubid/bipm/identifier.rb +160 -0
  40. data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
  41. data/lib/pubid/bipm/identifiers/guide.rb +24 -0
  42. data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
  43. data/lib/pubid/bipm/identifiers/mep.rb +21 -0
  44. data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
  45. data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
  46. data/lib/pubid/bipm/identifiers.rb +15 -0
  47. data/lib/pubid/bipm/parser.rb +184 -0
  48. data/lib/pubid/bipm/renderer.rb +110 -0
  49. data/lib/pubid/bipm/urn_generator.rb +58 -0
  50. data/lib/pubid/bipm/urn_parser.rb +52 -0
  51. data/lib/pubid/bipm.rb +86 -0
  52. data/lib/pubid/bsi/builder.rb +14 -14
  53. data/lib/pubid/bsi/identifier.rb +0 -1
  54. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  55. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  56. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  57. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  58. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  59. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  60. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  61. data/lib/pubid/bsi/renderer.rb +8 -8
  62. data/lib/pubid/bsi/single_identifier.rb +48 -0
  63. data/lib/pubid/builder/base.rb +5 -3
  64. data/lib/pubid/bundled_identifier.rb +3 -3
  65. data/lib/pubid/calconnect/builder.rb +38 -0
  66. data/lib/pubid/calconnect/identifier.rb +117 -0
  67. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  68. data/lib/pubid/calconnect/identifiers.rb +9 -0
  69. data/lib/pubid/calconnect/parser.rb +54 -0
  70. data/lib/pubid/calconnect/renderer.rb +36 -0
  71. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  72. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  73. data/lib/pubid/calconnect.rb +77 -0
  74. data/lib/pubid/ccsds/builder.rb +1 -1
  75. data/lib/pubid/ccsds/identifier.rb +1 -1
  76. data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
  77. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  78. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  79. data/lib/pubid/cen_cenelec/builder.rb +46 -12
  80. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
  81. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
  82. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
  83. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  84. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  85. data/lib/pubid/cen_cenelec/renderer.rb +5 -5
  86. data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
  87. data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
  88. data/lib/pubid/cen_cenelec.rb +76 -72
  89. data/lib/pubid/cie/builder.rb +139 -24
  90. data/lib/pubid/cie/identifier.rb +7 -3
  91. data/lib/pubid/cie/identifiers/bundle.rb +32 -4
  92. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  93. data/lib/pubid/cie/identifiers/conference.rb +9 -4
  94. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  95. data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
  96. data/lib/pubid/cie/identifiers/identical.rb +7 -7
  97. data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
  98. data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
  99. data/lib/pubid/cie/identifiers/standard.rb +33 -7
  100. data/lib/pubid/cie/identifiers/supplement.rb +24 -22
  101. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
  102. data/lib/pubid/cie/identifiers.rb +2 -0
  103. data/lib/pubid/cie/parser.rb +54 -5
  104. data/lib/pubid/cie/single_identifier.rb +40 -1
  105. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  106. data/lib/pubid/cie/urn_generator.rb +11 -8
  107. data/lib/pubid/cie.rb +0 -1
  108. data/lib/pubid/components/date.rb +21 -5
  109. data/lib/pubid/csa/builder.rb +1 -1
  110. data/lib/pubid/csa/composite_identifier.rb +17 -1
  111. data/lib/pubid/csa/identifier.rb +48 -3
  112. data/lib/pubid/csa/identifiers/bundled.rb +6 -0
  113. data/lib/pubid/csa/identifiers/combined.rb +6 -0
  114. data/lib/pubid/csa/identifiers/package.rb +2 -2
  115. data/lib/pubid/csa/parser.rb +6 -6
  116. data/lib/pubid/csa/wrapper_identifier.rb +17 -0
  117. data/lib/pubid/doi/builder.rb +18 -0
  118. data/lib/pubid/doi/identifier.rb +46 -0
  119. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  120. data/lib/pubid/doi/identifiers.rb +9 -0
  121. data/lib/pubid/doi/parser.rb +52 -0
  122. data/lib/pubid/doi/renderer.rb +13 -0
  123. data/lib/pubid/doi.rb +55 -0
  124. data/lib/pubid/easc/builder.rb +55 -0
  125. data/lib/pubid/easc/identifier.rb +61 -0
  126. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  127. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  128. data/lib/pubid/easc/identifiers.rb +10 -0
  129. data/lib/pubid/easc/parser.rb +80 -0
  130. data/lib/pubid/easc/renderer.rb +48 -0
  131. data/lib/pubid/easc/urn_generator.rb +46 -0
  132. data/lib/pubid/easc/urn_parser.rb +57 -0
  133. data/lib/pubid/easc.rb +52 -0
  134. data/lib/pubid/ecma/builder.rb +31 -0
  135. data/lib/pubid/ecma/identifier.rb +76 -0
  136. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  137. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  138. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  139. data/lib/pubid/ecma/identifiers.rb +11 -0
  140. data/lib/pubid/ecma/parser.rb +41 -0
  141. data/lib/pubid/ecma/renderer.rb +46 -0
  142. data/lib/pubid/ecma/urn_generator.rb +25 -0
  143. data/lib/pubid/ecma/urn_parser.rb +35 -0
  144. data/lib/pubid/ecma.rb +67 -0
  145. data/lib/pubid/etsi/builder.rb +7 -3
  146. data/lib/pubid/etsi/identifier.rb +1 -3
  147. data/lib/pubid/etsi/identifiers/base.rb +28 -10
  148. data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
  149. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
  150. data/lib/pubid/etsi/identifiers.rb +0 -1
  151. data/lib/pubid/etsi/parser.rb +8 -2
  152. data/lib/pubid/etsi/renderer.rb +8 -2
  153. data/lib/pubid/etsi.rb +5 -5
  154. data/lib/pubid/export/exporter.rb +2 -1
  155. data/lib/pubid/export/flavor_exporter.rb +18 -3
  156. data/lib/pubid/gb/builder.rb +45 -0
  157. data/lib/pubid/gb/identifier.rb +64 -0
  158. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  159. data/lib/pubid/gb/identifiers.rb +9 -0
  160. data/lib/pubid/gb/parser.rb +63 -0
  161. data/lib/pubid/gb/renderer.rb +35 -0
  162. data/lib/pubid/gb.rb +87 -0
  163. data/lib/pubid/gost/builder.rb +148 -0
  164. data/lib/pubid/gost/identifier.rb +49 -0
  165. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  166. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  167. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  168. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  169. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  170. data/lib/pubid/gost/identifiers.rb +13 -0
  171. data/lib/pubid/gost/parser.rb +97 -0
  172. data/lib/pubid/gost/renderer.rb +48 -0
  173. data/lib/pubid/gost/urn_generator.rb +46 -0
  174. data/lib/pubid/gost/urn_parser.rb +52 -0
  175. data/lib/pubid/gost.rb +49 -0
  176. data/lib/pubid/iala/builder.rb +22 -27
  177. data/lib/pubid/iala/identifier.rb +27 -2
  178. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  179. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  180. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  181. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  182. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  183. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  184. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  185. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  186. data/lib/pubid/iala/identifiers/report.rb +1 -1
  187. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  188. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  189. data/lib/pubid/iala/identifiers.rb +0 -1
  190. data/lib/pubid/iala/renderer.rb +1 -1
  191. data/lib/pubid/iala/urn_generator.rb +1 -1
  192. data/lib/pubid/iala/urn_parser.rb +19 -2
  193. data/lib/pubid/iala.rb +4 -4
  194. data/lib/pubid/iana/builder.rb +20 -0
  195. data/lib/pubid/iana/identifier.rb +72 -0
  196. data/lib/pubid/iana/identifiers/registry.rb +33 -0
  197. data/lib/pubid/iana/identifiers.rb +9 -0
  198. data/lib/pubid/iana/parser.rb +38 -0
  199. data/lib/pubid/iana/renderer.rb +29 -0
  200. data/lib/pubid/iana/urn_generator.rb +15 -0
  201. data/lib/pubid/iana/urn_parser.rb +24 -0
  202. data/lib/pubid/iana.rb +69 -0
  203. data/lib/pubid/identifier.rb +210 -23
  204. data/lib/pubid/idf/builder.rb +1 -1
  205. data/lib/pubid/idf/parser.rb +2 -2
  206. data/lib/pubid/idf/renderer.rb +1 -1
  207. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  208. data/lib/pubid/iec/builder.rb +35 -25
  209. data/lib/pubid/iec/identifier.rb +47 -2
  210. data/lib/pubid/iec/identifiers/base.rb +2 -2
  211. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
  213. data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
  214. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  215. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  216. data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
  217. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
  218. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  219. data/lib/pubid/iec/identifiers.rb +1 -0
  220. data/lib/pubid/iec/parser.rb +51 -10
  221. data/lib/pubid/iec/renderer.rb +18 -8
  222. data/lib/pubid/iec/single_identifier.rb +1 -1
  223. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  224. data/lib/pubid/iec.rb +1 -6
  225. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  226. data/lib/pubid/ieee/aiee/identifier.rb +45 -61
  227. data/lib/pubid/ieee/builder.rb +341 -68
  228. data/lib/pubid/ieee/compaction.rb +121 -0
  229. data/lib/pubid/ieee/components/draft.rb +47 -7
  230. data/lib/pubid/ieee/identifier.rb +1 -3
  231. data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
  232. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  233. data/lib/pubid/ieee/identifiers/base.rb +106 -13
  234. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  235. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  236. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  237. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
  238. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  239. data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
  240. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  241. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
  242. data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
  243. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
  244. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  245. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  246. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  247. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  248. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  249. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  250. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  251. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  252. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  253. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  254. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  255. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  256. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  257. data/lib/pubid/ieee/identifiers.rb +2 -1
  258. data/lib/pubid/ieee/ire/builder.rb +7 -6
  259. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  260. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  261. data/lib/pubid/ieee/nesc/parser.rb +15 -14
  262. data/lib/pubid/ieee/parser.rb +461 -43
  263. data/lib/pubid/ieee/pre_parser.rb +1 -1
  264. data/lib/pubid/ieee/renderer.rb +154 -57
  265. data/lib/pubid/ieee/typed_stages.rb +12 -1
  266. data/lib/pubid/ieee/urn_generator.rb +3 -5
  267. data/lib/pubid/ieee.rb +56 -3
  268. data/lib/pubid/ietf/builder.rb +62 -0
  269. data/lib/pubid/ietf/identifier.rb +5 -0
  270. data/lib/pubid/ietf/identifiers/base.rb +75 -0
  271. data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
  272. data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
  273. data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
  274. data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
  275. data/lib/pubid/ietf/identifiers/std.rb +25 -0
  276. data/lib/pubid/ietf/identifiers.rb +13 -0
  277. data/lib/pubid/ietf/parser.rb +43 -0
  278. data/lib/pubid/ietf/renderer.rb +26 -0
  279. data/lib/pubid/ietf/urn_generator.rb +23 -0
  280. data/lib/pubid/ietf/urn_parser.rb +35 -0
  281. data/lib/pubid/ietf.rb +76 -0
  282. data/lib/pubid/iho/identifier.rb +1 -3
  283. data/lib/pubid/iho/identifiers/base.rb +1 -7
  284. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  285. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  286. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  287. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  288. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  289. data/lib/pubid/iho/identifiers.rb +0 -1
  290. data/lib/pubid/iho.rb +7 -7
  291. data/lib/pubid/isbn/builder.rb +44 -0
  292. data/lib/pubid/isbn/check_digit.rb +53 -0
  293. data/lib/pubid/isbn/identifier.rb +63 -0
  294. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  295. data/lib/pubid/isbn/identifiers.rb +9 -0
  296. data/lib/pubid/isbn/parser.rb +45 -0
  297. data/lib/pubid/isbn/renderer.rb +16 -0
  298. data/lib/pubid/isbn.rb +52 -0
  299. data/lib/pubid/iso/builder.rb +9 -4
  300. data/lib/pubid/iso/combined_identifier.rb +2 -2
  301. data/lib/pubid/iso/identifier.rb +17 -1
  302. data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
  303. data/lib/pubid/iso/normalizer.rb +2 -2
  304. data/lib/pubid/iso/parser.rb +16 -12
  305. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  306. data/lib/pubid/iso/urn_generator.rb +4 -1
  307. data/lib/pubid/iso/urn_parser.rb +1 -1
  308. data/lib/pubid/itu/builder.rb +230 -29
  309. data/lib/pubid/itu/components/code.rb +48 -5
  310. data/lib/pubid/itu/components/designation.rb +35 -0
  311. data/lib/pubid/itu/components.rb +1 -0
  312. data/lib/pubid/itu/identifier.rb +1 -3
  313. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  314. data/lib/pubid/itu/identifiers/amendment.rb +6 -28
  315. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  316. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  317. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  318. data/lib/pubid/itu/identifiers/base.rb +341 -23
  319. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  320. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  321. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  322. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  323. data/lib/pubid/itu/identifiers/question.rb +63 -0
  324. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  325. data/lib/pubid/itu/identifiers/report.rb +39 -0
  326. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  327. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  328. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  329. data/lib/pubid/itu/identifiers.rb +10 -1
  330. data/lib/pubid/itu/model.rb +1 -1
  331. data/lib/pubid/itu/parser.rb +480 -26
  332. data/lib/pubid/itu/urn_generator.rb +36 -6
  333. data/lib/pubid/itu/urn_parser.rb +8 -0
  334. data/lib/pubid/itu.rb +11 -3
  335. data/lib/pubid/jcgm/builder.rb +23 -13
  336. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  337. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  338. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  339. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  340. data/lib/pubid/jcgm/identifiers.rb +2 -0
  341. data/lib/pubid/jcgm/parser.rb +66 -6
  342. data/lib/pubid/jcgm/renderer.rb +26 -12
  343. data/lib/pubid/jcgm/single_identifier.rb +74 -5
  344. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  345. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  346. data/lib/pubid/jcgm/urn_parser.rb +15 -3
  347. data/lib/pubid/jis/identifier.rb +52 -0
  348. data/lib/pubid/nist/builder.rb +29 -9
  349. data/lib/pubid/nist/caster.rb +7 -45
  350. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  351. data/lib/pubid/nist/components/supplement.rb +5 -2
  352. data/lib/pubid/nist/configuration.rb +7 -1
  353. data/lib/pubid/nist/identifier.rb +1 -3
  354. data/lib/pubid/nist/identifiers/base.rb +121 -37
  355. data/lib/pubid/nist/identifiers/circular.rb +1 -1
  356. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  358. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
  359. data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
  360. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  361. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  362. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  363. data/lib/pubid/nist/identifiers/handbook.rb +1 -1
  364. data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
  365. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  366. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
  367. data/lib/pubid/nist/identifiers/monograph.rb +1 -1
  368. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  369. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  370. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  371. data/lib/pubid/nist/identifiers/report.rb +1 -1
  372. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  373. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  374. data/lib/pubid/nist/identifiers.rb +0 -1
  375. data/lib/pubid/nist/parser.rb +26 -3
  376. data/lib/pubid/nist/preprocessor.rb +15 -0
  377. data/lib/pubid/nist/router.rb +2 -2
  378. data/lib/pubid/nist/series/ir.rb +0 -3
  379. data/lib/pubid/nist/supplement_identifier.rb +9 -9
  380. data/lib/pubid/nist.rb +12 -12
  381. data/lib/pubid/oasis/builder.rb +77 -0
  382. data/lib/pubid/oasis/identifier.rb +82 -0
  383. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  384. data/lib/pubid/oasis/identifiers.rb +9 -0
  385. data/lib/pubid/oasis/parser.rb +34 -0
  386. data/lib/pubid/oasis/renderer.rb +29 -0
  387. data/lib/pubid/oasis/urn_generator.rb +25 -0
  388. data/lib/pubid/oasis/urn_parser.rb +22 -0
  389. data/lib/pubid/oasis.rb +74 -0
  390. data/lib/pubid/ogc/builder.rb +33 -0
  391. data/lib/pubid/ogc/identifier.rb +77 -0
  392. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  393. data/lib/pubid/ogc/identifiers.rb +10 -0
  394. data/lib/pubid/ogc/parser.rb +40 -0
  395. data/lib/pubid/ogc/renderer.rb +33 -0
  396. data/lib/pubid/ogc/urn_generator.rb +14 -0
  397. data/lib/pubid/ogc/urn_parser.rb +22 -0
  398. data/lib/pubid/ogc.rb +71 -0
  399. data/lib/pubid/oiml/builder.rb +31 -7
  400. data/lib/pubid/oiml/identifier.rb +9 -1
  401. data/lib/pubid/oiml/parser.rb +11 -12
  402. data/lib/pubid/oiml/renderer.rb +13 -13
  403. data/lib/pubid/oiml/single_identifier.rb +20 -0
  404. data/lib/pubid/oiml/supplement_identifier.rb +9 -9
  405. data/lib/pubid/oiml/urn_parser.rb +23 -6
  406. data/lib/pubid/oiml.rb +4 -0
  407. data/lib/pubid/omg/builder.rb +19 -0
  408. data/lib/pubid/omg/identifier.rb +44 -0
  409. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  410. data/lib/pubid/omg/identifiers.rb +9 -0
  411. data/lib/pubid/omg/parser.rb +40 -0
  412. data/lib/pubid/omg/renderer.rb +19 -0
  413. data/lib/pubid/omg.rb +51 -0
  414. data/lib/pubid/parsers/mr_string.rb +101 -7
  415. data/lib/pubid/plateau/builder.rb +8 -4
  416. data/lib/pubid/plateau/identifier.rb +1 -3
  417. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  418. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  419. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  420. data/lib/pubid/plateau/identifiers.rb +0 -1
  421. data/lib/pubid/plateau/parser.rb +15 -5
  422. data/lib/pubid/plateau/renderer.rb +1 -1
  423. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  424. data/lib/pubid/plateau.rb +4 -4
  425. data/lib/pubid/renderers/human_readable.rb +3 -1
  426. data/lib/pubid/renderers/mr_string.rb +46 -4
  427. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  428. data/lib/pubid/rendering/supplement.rb +4 -4
  429. data/lib/pubid/sae/builder.rb +1 -1
  430. data/lib/pubid/sae/identifier.rb +1 -3
  431. data/lib/pubid/sae/identifiers/base.rb +10 -7
  432. data/lib/pubid/sae/identifiers.rb +0 -1
  433. data/lib/pubid/sae.rb +3 -3
  434. data/lib/pubid/tgpp/builder.rb +41 -0
  435. data/lib/pubid/tgpp/identifier.rb +91 -0
  436. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  437. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  438. data/lib/pubid/tgpp/identifiers.rb +11 -0
  439. data/lib/pubid/tgpp/parser.rb +62 -0
  440. data/lib/pubid/tgpp/renderer.rb +36 -0
  441. data/lib/pubid/tgpp/urn_generator.rb +20 -0
  442. data/lib/pubid/tgpp/urn_parser.rb +28 -0
  443. data/lib/pubid/tgpp.rb +78 -0
  444. data/lib/pubid/type_resolver.rb +59 -0
  445. data/lib/pubid/un/builder.rb +42 -0
  446. data/lib/pubid/un/identifier.rb +37 -0
  447. data/lib/pubid/un/identifiers/document.rb +24 -0
  448. data/lib/pubid/un/identifiers.rb +9 -0
  449. data/lib/pubid/un/parser.rb +25 -0
  450. data/lib/pubid/un/renderer.rb +11 -0
  451. data/lib/pubid/un.rb +46 -0
  452. data/lib/pubid/version.rb +1 -1
  453. data/lib/pubid/w3c/builder.rb +55 -0
  454. data/lib/pubid/w3c/identifier.rb +101 -0
  455. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  456. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  457. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  458. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  459. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  460. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  461. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  462. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  463. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  464. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  465. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  466. data/lib/pubid/w3c/identifiers.rb +25 -0
  467. data/lib/pubid/w3c/parser.rb +43 -0
  468. data/lib/pubid/w3c/renderer.rb +35 -0
  469. data/lib/pubid/w3c/urn_generator.rb +18 -0
  470. data/lib/pubid/w3c/urn_parser.rb +36 -0
  471. data/lib/pubid/w3c.rb +67 -0
  472. data/lib/pubid/xsf/builder.rb +17 -0
  473. data/lib/pubid/xsf/identifier.rb +62 -0
  474. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  475. data/lib/pubid/xsf/identifiers.rb +9 -0
  476. data/lib/pubid/xsf/parser.rb +25 -0
  477. data/lib/pubid/xsf/renderer.rb +23 -0
  478. data/lib/pubid/xsf/urn_generator.rb +13 -0
  479. data/lib/pubid/xsf/urn_parser.rb +18 -0
  480. data/lib/pubid/xsf.rb +76 -0
  481. data/lib/pubid.rb +25 -1
  482. metadata +205 -4
  483. data/lib/pubid/cie/components/code.rb +0 -80
  484. data/lib/pubid/iala/identifiers/base.rb +0 -14
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Isbn
7
+ # Parslet grammar for ISBN identifiers per ISO 2108.
8
+ #
9
+ # Accepts:
10
+ # [ISBN[ |:]] {10 or 13 digits with optional hyphens}
11
+ #
12
+ # ISBN-10 final digit may be "X" (check digit value 10). Hyphens are
13
+ # optional and may appear in any group position; they are preserved
14
+ # for round-trip rendering.
15
+ class Parser < Parslet::Parser
16
+ rule(:space) { str(" ") }
17
+ rule(:colon) { str(":") }
18
+ rule(:hyphen) { str("-") }
19
+ rule(:digit) { match("[0-9]") }
20
+ rule(:x_digit) { digit | str("X") }
21
+
22
+ rule(:isbn_prefix) do
23
+ (str("ISBN") >> (space | (space.maybe >> colon >> space.maybe))).maybe
24
+ end
25
+
26
+ rule(:digit_group) { digit.repeat(1) }
27
+ rule(:x_group) { x_digit.repeat(1) }
28
+
29
+ # Loose "ISBN-ish" token: digits or final X, separated by hyphens.
30
+ rule(:isbn_body) do
31
+ (digit_group >> (hyphen >> digit_group).repeat >>
32
+ (hyphen >> x_digit).maybe).as(:body) |
33
+ (digit.repeat(9, 12) >> x_digit.maybe).as(:body)
34
+ end
35
+
36
+ rule(:identifier) { isbn_prefix >> isbn_body }
37
+
38
+ rule(:root) { identifier }
39
+
40
+ def self.parse(input)
41
+ new.parse(input)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Isbn
5
+ # Human-readable renderer for ISBN identifiers.
6
+ #
7
+ # Preserves the original hyphenation when present; otherwise emits the
8
+ # bare digits. Always emits the "ISBN " prefix.
9
+ class Renderer < ::Pubid::Renderers::Base
10
+ def render(**_opts)
11
+ body = @id.hyphenated || @id.raw
12
+ "ISBN #{body}"
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/pubid/isbn.rb ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ # ISBN flavor — bibliographic book identifier per ISO 2108.
5
+ #
6
+ # Parses both 10-digit (ISBN-10) and 13-digit (ISBN-13) forms with
7
+ # optional hyphenation. The check digit is validated; an invalid check
8
+ # digit raises on parse.
9
+ module Isbn
10
+ extend Pubid::PrefixesSupport
11
+
12
+ PREFIXES = ["ISBN"].freeze
13
+
14
+ autoload :CheckDigit, "#{__dir__}/isbn/check_digit"
15
+ autoload :Builder, "#{__dir__}/isbn/builder"
16
+ autoload :Identifier, "#{__dir__}/isbn/identifier"
17
+ autoload :Identifiers, "#{__dir__}/isbn/identifiers"
18
+ autoload :Parser, "#{__dir__}/isbn/parser"
19
+ autoload :Renderer, "#{__dir__}/isbn/renderer"
20
+
21
+ def self.parse(identifier)
22
+ Identifier.parse(identifier)
23
+ end
24
+
25
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
26
+ Identifier.format_registry.register(:human, renderer: Isbn::Renderer)
27
+
28
+ def self.identifier_types
29
+ @identifier_types ||= Identifiers.constants
30
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
31
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
32
+ .select { |c| c.type.is_a?(Hash) }
33
+ end
34
+
35
+ def self.all_typed_stages
36
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
37
+ klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
38
+ end
39
+ end
40
+
41
+ def self.locate_type(code)
42
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
43
+ end
44
+
45
+ def self.locate_stage(abbr)
46
+ abbr_str = abbr.to_s.upcase
47
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
48
+ end
49
+ end
50
+ end
51
+
52
+ Pubid::Registry.register(:isbn, Pubid::Isbn)
@@ -16,7 +16,7 @@ module Pubid
16
16
 
17
17
  def locate_identifier_klass(parsed_hash)
18
18
  # If there is a joint_identifier, we need to use a CombinedIdentifier
19
- # which takes `base_identifier` and `additional_identifiers`
19
+ # which takes `base` and `additional_identifiers`
20
20
  if parsed_hash[:joint_identifier]
21
21
  return CombinedIdentifier
22
22
  end
@@ -47,7 +47,7 @@ module Pubid
47
47
  # a) It is an IS.
48
48
  # b) It is a Directive Supplements. The "SUP" keyword may be entirely missing, and hence nil. If the base type_with_stage is a directive, then if the type_with_stage is blank, it is a directive supplement.
49
49
 
50
- if parsed_hash[:type_with_stage].nil? && parsed_hash[:base_identifier] && parsed_hash[:base_identifier][:type_with_stage] == "DIR"
50
+ if parsed_hash[:type_with_stage].nil? && parsed_hash[:base] && parsed_hash[:base][:type_with_stage] == "DIR"
51
51
  # Directive Supplement without "SUP" keyword
52
52
  parsed_hash[:type_with_stage] = "SUP"
53
53
  end
@@ -150,12 +150,12 @@ module Pubid
150
150
 
151
151
  def cast(type, value)
152
152
  case type
153
- when :base_identifier
153
+ when :base
154
154
  # If it has a base identifier, we need to build a supplement
155
155
  # We assume that the base identifier is already a valid Identifier object
156
156
  build(value)
157
157
 
158
- # If there is a base_identifier, and it has a joint_identifier, we need to use a CombinedIdentifier.
158
+ # If there is a base, and it has a joint_identifier, we need to use a CombinedIdentifier.
159
159
 
160
160
  when :publisher, :directives_supplement_body, :supplement_publisher
161
161
  # value can be either a string OR a hash with publisher + copublisher
@@ -230,6 +230,11 @@ module Pubid
230
230
  when :date
231
231
  parse_date(value)
232
232
 
233
+ when :undated_marker
234
+ # ISO/IEC undated reference (e.g. "ISO 16634:--") — explicit
235
+ # publication-date slot with no year; round-trips via date.render.
236
+ { date: Pubid::Components::Date.new(undated: true) }
237
+
233
238
  when :edition
234
239
  # value can be "Ed.2", "Ed 2", "ED1", "Edition 13", or just "Ed"
235
240
  original_text = value.to_s
@@ -4,14 +4,14 @@ module Pubid
4
4
  module Iso
5
5
  # Identifier that represents a supplement to a base identifier.
6
6
  class CombinedIdentifier < Identifier
7
- attribute :base_identifier, Identifier, polymorphic: true
7
+ attribute :base, Identifier, polymorphic: true
8
8
  attribute :additional_identifiers, ::Pubid::Identifier,
9
9
  polymorphic: true, collection: true
10
10
  attribute :type, :string, default: -> { "combined_identifier" }
11
11
 
12
12
  def to_s(lang: :en, lang_single: false)
13
13
  [
14
- base_identifier.to_s(lang: lang, lang_single: lang_single),
14
+ base.to_s(lang: lang, lang_single: lang_single),
15
15
  additional_identifiers.map do |id|
16
16
  id.to_s(lang: lang, lang_single: lang_single)
17
17
  end,
@@ -103,7 +103,7 @@ module Pubid
103
103
  # The base Pubid::Identifier no longer auto-maps attributes, so each
104
104
  # flavor's top class must declare its own key_value mapping. Subclasses
105
105
  # merge their own blocks on top of this one (e.g. SupplementIdentifier
106
- # adds base_identifier; Directives adds subgroup), so list every base
106
+ # adds base; Directives adds subgroup), so list every base
107
107
  # attribute ISO serializes here once.
108
108
  key_value do
109
109
  map "_type", to: :_type, polymorphic_map: ISO_TYPE_MAP
@@ -117,6 +117,9 @@ module Pubid
117
117
  map "year", with: { to: :year_to_kv, from: :year_from_kv }
118
118
  map "month", with: { to: :month_to_kv, from: :month_from_kv }
119
119
  map "day", with: { to: :day_to_kv, from: :day_from_kv }
120
+ # ISO/IEC undated reference (e.g. ISO 16634:--). The `false` default
121
+ # is omitted; only the meaningful `true` round-trips via to_hash.
122
+ map "undated", with: { to: :undated_to_kv, from: :undated_from_kv }
120
123
  map "edition", to: :edition
121
124
  map "languages", to: :languages
122
125
  # publisher emitted only when the primary isn't the type default;
@@ -217,6 +220,19 @@ module Pubid
217
220
  def day_to_kv(model, doc) = emit_date_part(doc, "day", model.date&.day)
218
221
  def day_from_kv(model, value) = date_for(model).day = value.to_s
219
222
 
223
+ # --- date undated flag (ISO/IEC undated reference, e.g. ISO 16634:--) ---
224
+ # The `false` default is omitted; only the meaningful `true` round-trips
225
+ # via to_hash / from_hash.
226
+ def undated_to_kv(model, doc)
227
+ return unless model.date&.undated?
228
+
229
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("undated", true))
230
+ end
231
+
232
+ def undated_from_kv(model, value)
233
+ date_for(model).undated = value.to_s == "true"
234
+ end
235
+
220
236
  def emit_date_part(doc, key, val)
221
237
  return if val.nil? || val.to_s.empty?
222
238
 
@@ -35,11 +35,11 @@ module Pubid
35
35
 
36
36
  # Delegate base identifier attributes for easier access
37
37
  def copublishers
38
- base_identifier&.copublishers
38
+ base&.copublishers
39
39
  end
40
40
 
41
41
  def publisher
42
- base_identifier&.publisher
42
+ base&.publisher
43
43
  end
44
44
 
45
45
  TYPED_STAGES = [
@@ -61,7 +61,7 @@ module Pubid
61
61
  # def render_directives_supplement_identifier(identifier)
62
62
  # raise "Not a directives supplement identifier" unless identifier.is_a?(Identifiers::DirectivesSupplement)
63
63
 
64
- # render(identifier.base_identifier) +
64
+ # render(identifier.base) +
65
65
  # " #{identifier.publisher.body}" +
66
66
  # " #{identifier.stage.abbr}" +
67
67
  # (identifier.date ? ":#{identifier.date.year}" : "")
@@ -69,10 +69,10 @@ module Pubid
69
69
 
70
70
  def to_s(lang: :en, lang_single: false, with_edition: false,
71
71
  format: nil, stage_format_long: nil, with_date: nil)
72
- if base_identifier
72
+ if base
73
73
  # Full rendering with base identifier
74
74
  [
75
- base_identifier.to_s(lang: lang, lang_single: lang_single,
75
+ base.to_s(lang: lang, lang_single: lang_single,
76
76
  with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date),
77
77
  " #{supplement_publisher.render}",
78
78
  " SUP", # Always render as "SUP" even though typed_stage.abbreviation is "DIR SUP"
@@ -107,8 +107,8 @@ format: nil, stage_format_long: nil, with_date: nil)
107
107
  def to_urn
108
108
  urn_ctx = Rendering::RenderingContext.urn
109
109
 
110
- # If this is a standalone supplement (no base_identifier), build URN directly
111
- unless base_identifier
110
+ # If this is a standalone supplement (no base), build URN directly
111
+ unless base
112
112
  parts = ["urn", "iso", "doc"]
113
113
  parts << supplement_publisher.render(context: urn_ctx) if supplement_publisher
114
114
  parts << "sup"
@@ -118,7 +118,7 @@ format: nil, stage_format_long: nil, with_date: nil)
118
118
  end
119
119
 
120
120
  # Start with base identifier's URN parts (it will use urn:iso:doc scheme)
121
- base_urn = base_identifier.to_urn
121
+ base_urn = base.to_urn
122
122
 
123
123
  # Handle JTC pattern specially
124
124
  if supplement_publisher&.body&.match?(/^JTC\s+(\d+)$/i)
@@ -69,10 +69,10 @@ module Pubid
69
69
  supplement_year = match[4] # "1987" or nil
70
70
 
71
71
  base_parsed = Pubid::Iso.parser.parse(base_str)
72
- base_identifier = Pubid::Iso.builder.build(base_parsed)
72
+ base = Pubid::Iso.builder.build(base_parsed)
73
73
 
74
74
  addendum = Identifiers::Addendum.new
75
- addendum.base_identifier = base_identifier
75
+ addendum.base = base
76
76
  addendum.number = Iso::Components::Code.new(value: supplement_number)
77
77
  addendum.date = Pubid::Components::Date.new(year: supplement_year) if supplement_year
78
78
 
@@ -99,7 +99,7 @@ module Pubid
99
99
  rule(:iso_r_supplement_identifier) do
100
100
  (
101
101
  str("ISO/R").as(:iso_r_prefix) >> space >> iso_r_second_part
102
- ).as(:base_identifier) >>
102
+ ).as(:base) >>
103
103
  iso_r_supplement_separator >>
104
104
  supplement_type_with_stage >>
105
105
  space? >> second_part >> third_part
@@ -148,12 +148,16 @@ module Pubid
148
148
  end
149
149
 
150
150
  rule(:date) do
151
- # :2005-02
151
+ # :2005-02 or :-- (undated reference — ISO/IEC undated-reference form,
152
+ # e.g. ISO 16634:--, also accepted as the em-dash variant ISO 16634:—)
152
153
  (str(":") | dash) >>
153
- (year_digits >>
154
- (dash >> month_digits).maybe >>
155
- (dash >> day_digits).maybe
156
- ).as(:date).maybe
154
+ (
155
+ (str("--") | str("—")).as(:undated_marker) |
156
+ (year_digits >>
157
+ (dash >> month_digits).maybe >>
158
+ (dash >> day_digits).maybe
159
+ ).as(:date)
160
+ ).maybe
157
161
  end
158
162
 
159
163
  rule(:part_and_subpart) do
@@ -270,14 +274,14 @@ module Pubid
270
274
  end
271
275
 
272
276
  # For joint identifiers, we do not treat it as a supplementary identifier
273
- # (hence not a base_identifier)
277
+ # (hence not a base)
274
278
  # ISO only supports IDF in joint identifiers
275
279
  # ISO 5537|IDF 26
276
280
  # ISO 17678|IDF 202:2010
277
281
  # ISO/TS 4985:2023 | IDF/RM 255
278
282
  # ISO 4214:2022 | IDF 254:2022
279
283
  rule(:joint_identifier) do
280
- identifier_copublishers_no_third.as(:base_identifier) >>
284
+ identifier_copublishers_no_third.as(:base) >>
281
285
  space? >> str("|") >> space? >>
282
286
  scope { idf_identifier }.as(:joint_identifier)
283
287
  end
@@ -336,7 +340,7 @@ module Pubid
336
340
  # ISO 8601-1:2019/Amd 2:2024
337
341
  # ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
338
342
  rule(:supplement_identifier_no_third) do
339
- identifier_copublishers_no_third.as(:base_identifier) >>
343
+ identifier_copublishers_no_third.as(:base) >>
340
344
  str("/") >> supplement_type_with_stage >>
341
345
  # The trailing number/date is optional: some draft supplements have no
342
346
  # number yet, e.g. "ISO/IEC 9579/WD Amd".
@@ -351,14 +355,14 @@ module Pubid
351
355
  # ISO/IEC 19794-7:2014/Amd 1:2015/CD Cor 1
352
356
  # ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
353
357
  rule(:supplement_supplement_identifier) do
354
- supplement_identifier_no_third.as(:base_identifier) >>
358
+ supplement_identifier_no_third.as(:base) >>
355
359
  str("/") >> supplement_type_with_stage >>
356
360
  ((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
357
361
  end
358
362
 
359
363
  # ISO 12345:2020/Amd 1:2021/Cor 1:2022/Amd 2:2023 (three-level supplement)
360
364
  rule(:supplement_supplement_supplement_identifier) do
361
- supplement_supplement_identifier.as(:base_identifier) >>
365
+ supplement_supplement_identifier.as(:base) >>
362
366
  str("/") >> supplement_type_with_stage >>
363
367
  ((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
364
368
  end
@@ -408,7 +412,7 @@ module Pubid
408
412
  end
409
413
 
410
414
  rule(:directives_supplement_identifier) do
411
- directives_identifier_no_third.as(:base_identifier) >> space? >> directives_supplement_part
415
+ directives_identifier_no_third.as(:base) >> space? >> directives_supplement_part
412
416
  end
413
417
 
414
418
  DIRECTIVES_SUPPLEMENTS_TYPED_STAGES = Identifiers::DirectivesSupplement::TYPED_STAGES.map(&:abbr).flatten.sort_by(&:length).reverse
@@ -3,13 +3,13 @@
3
3
  module Pubid
4
4
  module Iso
5
5
  class SupplementIdentifier < SingleIdentifier
6
- attribute :base_identifier, Identifier,
6
+ attribute :base, Identifier,
7
7
  polymorphic: true
8
8
 
9
9
  key_value do
10
10
  # Serialized key is "base" (matches JIS); the attribute/method stays
11
- # `base_identifier`, which relaton-index's get_id_number depends on.
12
- map "base", to: :base_identifier, polymorphic: {
11
+ # `base`, which relaton-index's get_id_number depends on.
12
+ map "base", to: :base, polymorphic: {
13
13
  attribute: "_type",
14
14
  class_map: Identifier::ISO_TYPE_MAP,
15
15
  }
@@ -20,14 +20,14 @@ module Pubid
20
20
  # nested supplement (e.g. ".../Amd 1/Cor 1") reads identity from the
21
21
  # underlying standard in one hop, regardless of chain depth. This keeps a
22
22
  # parsed supplement and a from_hash-deserialized one in agreement (== and
23
- # index matching compare both). Guard on base_identifier: `root` returns
23
+ # index matching compare both). Guard on base: `root` returns
24
24
  # self when there is no base, which would otherwise recurse forever.
25
25
  def publisher
26
- root.publisher if base_identifier
26
+ root.publisher if base
27
27
  end
28
28
 
29
29
  def copublishers
30
- root.copublishers if base_identifier
30
+ root.copublishers if base
31
31
  end
32
32
 
33
33
  def to_s(**opts)
@@ -35,6 +35,19 @@ module Pubid
35
35
  Pubid::Renderers::SupplementRenderer.new(self).render(context:,
36
36
  **opts.slice(:with_edition))
37
37
  end
38
+
39
+ # MR supplement suffix: `/{type}.{number}.{year}` (e.g. "/amd.1.2020").
40
+ # The MrString renderer recurses into `base` and appends this so the
41
+ # full supplement chain round-trips losslessly (issue #142).
42
+ def mr_supplement_suffix
43
+ segments = []
44
+ segments << mr_type if mr_type
45
+ segments << number&.to_s if number
46
+ segments << date&.year&.to_s if date&.year
47
+ return nil if segments.empty?
48
+
49
+ segments.join(".")
50
+ end
38
51
  end
39
52
  end
40
53
  end
@@ -84,7 +84,7 @@ module Pubid
84
84
 
85
85
  while current.is_a?(SupplementIdentifier)
86
86
  supplement_chain.unshift(current)
87
- current = current.base_identifier
87
+ current = current.base
88
88
  end
89
89
 
90
90
  base_id = current
@@ -258,6 +258,9 @@ module Pubid
258
258
 
259
259
  def year_component
260
260
  return nil unless identifier.date&.present?
261
+ # Undated references (e.g. ISO 16634:--) drop the year slot in the URN,
262
+ # matching the date-less identifier's URN form (per issue #138).
263
+ return nil if identifier.date&.undated?
261
264
  return nil if identifier.is_a?(Pubid::Iso::SingleIdentifier)
262
265
 
263
266
  identifier.date.render(context: URN_CONTEXT)
@@ -425,7 +425,7 @@ typed_stage
425
425
 
426
426
  # Wrap current identifier with supplement
427
427
  base_hash = {
428
- base_identifier: base_hash,
428
+ base: base_hash,
429
429
  **supp_hash,
430
430
  }
431
431
  end