pubid 2.0.0.pre.alpha.8 → 2.0.0.pre.alpha.11

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 (672) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +33 -11
  3. data/conformance/pending.yaml +4 -0
  4. data/data/bipm/update_codes.yaml +9 -0
  5. data/data/iec/update_codes.yaml +3 -0
  6. data/data/ieee/update_codes.yaml +107 -1
  7. data/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
  8. data/data/nist/update_codes.yaml +8 -0
  9. data/lib/pubid/adobe/builder.rb +52 -0
  10. data/lib/pubid/adobe/identifier.rb +47 -0
  11. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  12. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  13. data/lib/pubid/adobe/identifiers.rb +10 -0
  14. data/lib/pubid/adobe/parser.rb +136 -0
  15. data/lib/pubid/adobe/renderer.rb +39 -0
  16. data/lib/pubid/adobe/urn_generator.rb +42 -0
  17. data/lib/pubid/adobe/urn_parser.rb +69 -0
  18. data/lib/pubid/adobe.rb +61 -0
  19. data/lib/pubid/amca/builder.rb +4 -4
  20. data/lib/pubid/amca/identifier.rb +1 -3
  21. data/lib/pubid/amca/identifiers/base.rb +50 -33
  22. data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
  23. data/lib/pubid/amca/identifiers/publication.rb +14 -10
  24. data/lib/pubid/amca/identifiers/standard.rb +3 -1
  25. data/lib/pubid/amca/identifiers.rb +0 -1
  26. data/lib/pubid/amca/parser.rb +1 -1
  27. data/lib/pubid/amca/renderer.rb +4 -4
  28. data/lib/pubid/amca/single_identifier.rb +1 -1
  29. data/lib/pubid/amca/urn_generator.rb +2 -2
  30. data/lib/pubid/amca.rb +5 -4
  31. data/lib/pubid/ansi/builder.rb +2 -2
  32. data/lib/pubid/ansi/identifier.rb +18 -0
  33. data/lib/pubid/ansi/parser.rb +1 -1
  34. data/lib/pubid/ansi/renderer.rb +2 -2
  35. data/lib/pubid/ansi.rb +5 -5
  36. data/lib/pubid/api/builder.rb +16 -2
  37. data/lib/pubid/api/identifier.rb +25 -4
  38. data/lib/pubid/api/identifiers/mpms.rb +10 -8
  39. data/lib/pubid/api/parser.rb +1 -1
  40. data/lib/pubid/api/renderer.rb +16 -7
  41. data/lib/pubid/api/single_identifier.rb +5 -12
  42. data/lib/pubid/api.rb +1 -0
  43. data/lib/pubid/ashrae/builder.rb +53 -32
  44. data/lib/pubid/ashrae/identifier.rb +3 -4
  45. data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
  46. data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
  47. data/lib/pubid/ashrae/identifiers/base.rb +94 -12
  48. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
  49. data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
  50. data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
  51. data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
  52. data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
  53. data/lib/pubid/ashrae/identifiers.rb +0 -1
  54. data/lib/pubid/ashrae/parser.rb +37 -17
  55. data/lib/pubid/ashrae/renderer.rb +20 -20
  56. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  57. data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
  58. data/lib/pubid/ashrae/urn_generator.rb +8 -2
  59. data/lib/pubid/ashrae.rb +10 -4
  60. data/lib/pubid/asme/builder.rb +11 -2
  61. data/lib/pubid/asme/identifier.rb +9 -0
  62. data/lib/pubid/asme/identifiers/standard.rb +86 -2
  63. data/lib/pubid/asme/parser.rb +1 -1
  64. data/lib/pubid/asme/renderer.rb +3 -3
  65. data/lib/pubid/asme/single_identifier.rb +8 -1
  66. data/lib/pubid/asme/urn_generator.rb +2 -2
  67. data/lib/pubid/asme.rb +1 -0
  68. data/lib/pubid/astm/builder.rb +10 -3
  69. data/lib/pubid/astm/identifier.rb +9 -0
  70. data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
  71. data/lib/pubid/astm/identifiers/code_number.rb +81 -0
  72. data/lib/pubid/astm/identifiers/data_series.rb +2 -0
  73. data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
  74. data/lib/pubid/astm/identifiers/manual.rb +10 -0
  75. data/lib/pubid/astm/identifiers/monograph.rb +2 -0
  76. data/lib/pubid/astm/identifiers/research_report.rb +10 -0
  77. data/lib/pubid/astm/identifiers/standard.rb +10 -0
  78. data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
  79. data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
  80. data/lib/pubid/astm/identifiers.rb +1 -0
  81. data/lib/pubid/astm/parser.rb +1 -1
  82. data/lib/pubid/astm/renderer.rb +1 -1
  83. data/lib/pubid/astm/single_identifier.rb +31 -1
  84. data/lib/pubid/astm/urn_generator.rb +7 -5
  85. data/lib/pubid/astm.rb +1 -0
  86. data/lib/pubid/bipm/builder.rb +163 -0
  87. data/lib/pubid/bipm/identifier.rb +285 -0
  88. data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
  89. data/lib/pubid/bipm/identifiers/guide.rb +35 -0
  90. data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
  91. data/lib/pubid/bipm/identifiers/mep.rb +33 -0
  92. data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
  93. data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
  94. data/lib/pubid/bipm/identifiers.rb +15 -0
  95. data/lib/pubid/bipm/parser.rb +237 -0
  96. data/lib/pubid/bipm/renderer.rb +118 -0
  97. data/lib/pubid/bipm/urn_generator.rb +58 -0
  98. data/lib/pubid/bipm/urn_parser.rb +60 -0
  99. data/lib/pubid/bipm.rb +92 -0
  100. data/lib/pubid/bsi/builder.rb +62 -52
  101. data/lib/pubid/bsi/identifier.rb +0 -1
  102. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  103. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
  104. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
  105. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  106. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
  107. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
  108. data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
  109. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  110. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  111. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  112. data/lib/pubid/bsi/identifiers/handbook.rb +0 -2
  113. data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
  114. data/lib/pubid/bsi/identifiers/set.rb +11 -0
  115. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
  116. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  117. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  118. data/lib/pubid/bsi/parser.rb +1 -1
  119. data/lib/pubid/bsi/renderer.rb +71 -59
  120. data/lib/pubid/bsi/single_identifier.rb +64 -7
  121. data/lib/pubid/bsi/urn_generator.rb +11 -2
  122. data/lib/pubid/bsi.rb +7 -1
  123. data/lib/pubid/builder/base.rb +23 -11
  124. data/lib/pubid/bundled_identifier.rb +19 -9
  125. data/lib/pubid/calconnect/builder.rb +38 -0
  126. data/lib/pubid/calconnect/identifier.rb +121 -0
  127. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  128. data/lib/pubid/calconnect/identifiers.rb +9 -0
  129. data/lib/pubid/calconnect/parser.rb +54 -0
  130. data/lib/pubid/calconnect/renderer.rb +36 -0
  131. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  132. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  133. data/lib/pubid/calconnect.rb +83 -0
  134. data/lib/pubid/ccsds/builder.rb +1 -1
  135. data/lib/pubid/ccsds/identifier.rb +10 -3
  136. data/lib/pubid/ccsds/identifiers/base.rb +4 -2
  137. data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
  138. data/lib/pubid/ccsds/parser.rb +1 -1
  139. data/lib/pubid/ccsds/single_identifier.rb +2 -2
  140. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  141. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  142. data/lib/pubid/ccsds.rb +1 -0
  143. data/lib/pubid/cen_cenelec/builder.rb +131 -72
  144. data/lib/pubid/cen_cenelec/identifier.rb +115 -3
  145. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
  146. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
  147. data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
  148. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
  149. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
  150. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
  151. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -14
  152. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
  153. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  154. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
  155. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
  156. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
  157. data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
  158. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
  159. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
  160. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
  161. data/lib/pubid/cen_cenelec/parser.rb +1 -1
  162. data/lib/pubid/cen_cenelec/renderer.rb +55 -60
  163. data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
  164. data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
  165. data/lib/pubid/cen_cenelec.rb +104 -82
  166. data/lib/pubid/cie/builder.rb +149 -24
  167. data/lib/pubid/cie/identifier.rb +13 -4
  168. data/lib/pubid/cie/identifiers/bundle.rb +35 -5
  169. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  170. data/lib/pubid/cie/identifiers/conference.rb +11 -6
  171. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  172. data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
  173. data/lib/pubid/cie/identifiers/identical.rb +9 -9
  174. data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
  175. data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
  176. data/lib/pubid/cie/identifiers/standard.rb +43 -8
  177. data/lib/pubid/cie/identifiers/supplement.rb +27 -25
  178. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
  179. data/lib/pubid/cie/identifiers.rb +2 -0
  180. data/lib/pubid/cie/parser.rb +55 -6
  181. data/lib/pubid/cie/single_identifier.rb +40 -1
  182. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  183. data/lib/pubid/cie/urn_generator.rb +11 -8
  184. data/lib/pubid/cie.rb +7 -2
  185. data/lib/pubid/components/date.rb +21 -5
  186. data/lib/pubid/conformance/checks.rb +72 -0
  187. data/lib/pubid/conformance/corpus/case.rb +55 -0
  188. data/lib/pubid/conformance/corpus.rb +36 -0
  189. data/lib/pubid/conformance/generator.rb +212 -0
  190. data/lib/pubid/conformance/pending.rb +63 -0
  191. data/lib/pubid/conformance/runner.rb +153 -0
  192. data/lib/pubid/conformance.rb +55 -0
  193. data/lib/pubid/core.rb +2 -0
  194. data/lib/pubid/csa/builder.rb +48 -48
  195. data/lib/pubid/csa/composite_identifier.rb +18 -7
  196. data/lib/pubid/csa/identifier.rb +187 -80
  197. data/lib/pubid/csa/identifiers/bundled.rb +25 -9
  198. data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
  199. data/lib/pubid/csa/identifiers/cec.rb +44 -4
  200. data/lib/pubid/csa/identifiers/combined.rb +97 -69
  201. data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
  202. data/lib/pubid/csa/identifiers/package.rb +4 -4
  203. data/lib/pubid/csa/parser.rb +12 -8
  204. data/lib/pubid/csa/renderer.rb +13 -5
  205. data/lib/pubid/csa/single_identifier.rb +93 -4
  206. data/lib/pubid/csa/urn_generator.rb +9 -2
  207. data/lib/pubid/csa/wrapper_identifier.rb +43 -10
  208. data/lib/pubid/csa.rb +7 -1
  209. data/lib/pubid/doi/builder.rb +18 -0
  210. data/lib/pubid/doi/identifier.rb +49 -0
  211. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  212. data/lib/pubid/doi/identifiers.rb +9 -0
  213. data/lib/pubid/doi/parser.rb +52 -0
  214. data/lib/pubid/doi/renderer.rb +13 -0
  215. data/lib/pubid/doi.rb +56 -0
  216. data/lib/pubid/easc/builder.rb +55 -0
  217. data/lib/pubid/easc/identifier.rb +59 -0
  218. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  219. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  220. data/lib/pubid/easc/identifiers.rb +10 -0
  221. data/lib/pubid/easc/parser.rb +88 -0
  222. data/lib/pubid/easc/renderer.rb +48 -0
  223. data/lib/pubid/easc/urn_generator.rb +46 -0
  224. data/lib/pubid/easc/urn_parser.rb +57 -0
  225. data/lib/pubid/easc.rb +53 -0
  226. data/lib/pubid/ecma/builder.rb +45 -0
  227. data/lib/pubid/ecma/identifier.rb +147 -0
  228. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  229. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  230. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  231. data/lib/pubid/ecma/identifiers.rb +11 -0
  232. data/lib/pubid/ecma/parser.rb +76 -0
  233. data/lib/pubid/ecma/renderer.rb +67 -0
  234. data/lib/pubid/ecma/urn_generator.rb +46 -0
  235. data/lib/pubid/ecma/urn_parser.rb +51 -0
  236. data/lib/pubid/ecma.rb +68 -0
  237. data/lib/pubid/errors.rb +80 -0
  238. data/lib/pubid/etsi/builder.rb +13 -4
  239. data/lib/pubid/etsi/identifier.rb +1 -3
  240. data/lib/pubid/etsi/identifiers/base.rb +43 -11
  241. data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
  242. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
  243. data/lib/pubid/etsi/identifiers.rb +0 -1
  244. data/lib/pubid/etsi/parser.rb +9 -3
  245. data/lib/pubid/etsi/renderer.rb +8 -2
  246. data/lib/pubid/etsi.rb +6 -5
  247. data/lib/pubid/evs/builder.rb +26 -0
  248. data/lib/pubid/evs/identifier.rb +37 -0
  249. data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
  250. data/lib/pubid/evs/identifiers.rb +9 -0
  251. data/lib/pubid/evs/parser.rb +27 -0
  252. data/lib/pubid/evs/renderer.rb +30 -0
  253. data/lib/pubid/evs/urn_generator.rb +30 -0
  254. data/lib/pubid/evs/urn_parser.rb +80 -0
  255. data/lib/pubid/evs.rb +90 -0
  256. data/lib/pubid/export/exporter.rb +2 -1
  257. data/lib/pubid/export/flavor_exporter.rb +18 -3
  258. data/lib/pubid/export.rb +1 -0
  259. data/lib/pubid/format_detector.rb +1 -0
  260. data/lib/pubid/gb/builder.rb +45 -0
  261. data/lib/pubid/gb/identifier.rb +67 -0
  262. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  263. data/lib/pubid/gb/identifiers.rb +9 -0
  264. data/lib/pubid/gb/parser.rb +63 -0
  265. data/lib/pubid/gb/renderer.rb +35 -0
  266. data/lib/pubid/gb.rb +88 -0
  267. data/lib/pubid/gost/builder.rb +185 -0
  268. data/lib/pubid/gost/identifier.rb +47 -0
  269. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  270. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  271. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  272. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  273. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  274. data/lib/pubid/gost/identifiers.rb +13 -0
  275. data/lib/pubid/gost/parser.rb +105 -0
  276. data/lib/pubid/gost/renderer.rb +48 -0
  277. data/lib/pubid/gost/urn_generator.rb +46 -0
  278. data/lib/pubid/gost/urn_parser.rb +52 -0
  279. data/lib/pubid/gost.rb +50 -0
  280. data/lib/pubid/iala/builder.rb +22 -27
  281. data/lib/pubid/iala/identifier.rb +36 -8
  282. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  283. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  284. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  285. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  286. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  287. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  288. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  289. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  290. data/lib/pubid/iala/identifiers/report.rb +1 -1
  291. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  292. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  293. data/lib/pubid/iala/identifiers.rb +0 -1
  294. data/lib/pubid/iala/parser.rb +10 -2
  295. data/lib/pubid/iala/renderer.rb +1 -1
  296. data/lib/pubid/iala/urn_generator.rb +1 -1
  297. data/lib/pubid/iala/urn_parser.rb +24 -3
  298. data/lib/pubid/iala.rb +5 -4
  299. data/lib/pubid/iana/builder.rb +22 -0
  300. data/lib/pubid/iana/identifier.rb +140 -0
  301. data/lib/pubid/iana/identifiers/registry.rb +69 -0
  302. data/lib/pubid/iana/identifiers.rb +9 -0
  303. data/lib/pubid/iana/parser.rb +38 -0
  304. data/lib/pubid/iana/renderer.rb +32 -0
  305. data/lib/pubid/iana/urn_generator.rb +19 -0
  306. data/lib/pubid/iana/urn_parser.rb +24 -0
  307. data/lib/pubid/iana.rb +70 -0
  308. data/lib/pubid/identifier.rb +797 -26
  309. data/lib/pubid/identifier_metadata.rb +1 -0
  310. data/lib/pubid/idf/builder.rb +4 -4
  311. data/lib/pubid/idf/identifier.rb +18 -9
  312. data/lib/pubid/idf/parser.rb +3 -3
  313. data/lib/pubid/idf/renderer.rb +5 -5
  314. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  315. data/lib/pubid/idf/urn_generator.rb +1 -1
  316. data/lib/pubid/idf.rb +7 -1
  317. data/lib/pubid/iec/builder.rb +49 -32
  318. data/lib/pubid/iec/components.rb +0 -1
  319. data/lib/pubid/iec/identifier.rb +112 -77
  320. data/lib/pubid/iec/identifiers/amendment.rb +6 -2
  321. data/lib/pubid/iec/identifiers/base.rb +2 -2
  322. data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
  323. data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
  324. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  325. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
  326. data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
  327. data/lib/pubid/iec/identifiers/guide.rb +0 -16
  328. data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
  329. data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
  330. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
  331. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  332. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
  333. data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
  334. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  335. data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
  336. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
  337. data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
  338. data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
  339. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  340. data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
  341. data/lib/pubid/iec/identifiers/working_document.rb +24 -10
  342. data/lib/pubid/iec/identifiers.rb +1 -0
  343. data/lib/pubid/iec/parser.rb +53 -28
  344. data/lib/pubid/iec/renderer.rb +31 -18
  345. data/lib/pubid/iec/single_identifier.rb +34 -11
  346. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  347. data/lib/pubid/iec/urn_generator.rb +227 -61
  348. data/lib/pubid/iec/urn_parser.rb +42 -4
  349. data/lib/pubid/iec.rb +2 -6
  350. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  351. data/lib/pubid/ieee/aiee/identifier.rb +46 -62
  352. data/lib/pubid/ieee/aiee/parser.rb +1 -1
  353. data/lib/pubid/ieee/builder.rb +386 -69
  354. data/lib/pubid/ieee/compaction.rb +121 -0
  355. data/lib/pubid/ieee/components/draft.rb +47 -7
  356. data/lib/pubid/ieee/identifier.rb +1 -3
  357. data/lib/pubid/ieee/identifiers/adopted_standard.rb +62 -5
  358. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  359. data/lib/pubid/ieee/identifiers/base.rb +148 -18
  360. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  361. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  362. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  363. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +24 -3
  364. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  365. data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
  366. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  367. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
  368. data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
  369. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
  370. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  371. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  372. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  373. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  374. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  375. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  376. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  377. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  378. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  379. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  380. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  381. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  382. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  383. data/lib/pubid/ieee/identifiers.rb +2 -1
  384. data/lib/pubid/ieee/ire/builder.rb +7 -6
  385. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  386. data/lib/pubid/ieee/ire/parser.rb +1 -1
  387. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  388. data/lib/pubid/ieee/nesc/parser.rb +16 -15
  389. data/lib/pubid/ieee/parser.rb +462 -44
  390. data/lib/pubid/ieee/pre_parser.rb +1 -1
  391. data/lib/pubid/ieee/renderer.rb +158 -57
  392. data/lib/pubid/ieee/typed_stages.rb +12 -1
  393. data/lib/pubid/ieee/urn_generator.rb +35 -8
  394. data/lib/pubid/ieee.rb +63 -4
  395. data/lib/pubid/ieee_debug.rb +1 -0
  396. data/lib/pubid/ietf/builder.rb +78 -0
  397. data/lib/pubid/ietf/identifier.rb +5 -0
  398. data/lib/pubid/ietf/identifiers/base.rb +72 -0
  399. data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
  400. data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
  401. data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
  402. data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
  403. data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
  404. data/lib/pubid/ietf/identifiers/std.rb +36 -0
  405. data/lib/pubid/ietf/identifiers.rb +14 -0
  406. data/lib/pubid/ietf/parser.rb +61 -0
  407. data/lib/pubid/ietf/renderer.rb +64 -0
  408. data/lib/pubid/ietf/urn_generator.rb +37 -0
  409. data/lib/pubid/ietf/urn_parser.rb +43 -0
  410. data/lib/pubid/ietf.rb +86 -0
  411. data/lib/pubid/iho/identifier.rb +1 -3
  412. data/lib/pubid/iho/identifiers/base.rb +11 -10
  413. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  414. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  415. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  416. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  417. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  418. data/lib/pubid/iho/identifiers.rb +0 -1
  419. data/lib/pubid/iho/parser.rb +1 -1
  420. data/lib/pubid/iho.rb +8 -7
  421. data/lib/pubid/isbn/builder.rb +44 -0
  422. data/lib/pubid/isbn/check_digit.rb +53 -0
  423. data/lib/pubid/isbn/identifier.rb +81 -0
  424. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  425. data/lib/pubid/isbn/identifiers.rb +9 -0
  426. data/lib/pubid/isbn/parser.rb +45 -0
  427. data/lib/pubid/isbn/renderer.rb +16 -0
  428. data/lib/pubid/isbn.rb +53 -0
  429. data/lib/pubid/iso/builder.rb +9 -4
  430. data/lib/pubid/iso/bundled_identifier.rb +5 -3
  431. data/lib/pubid/iso/combined_identifier.rb +6 -4
  432. data/lib/pubid/iso/identifier.rb +29 -8
  433. data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
  434. data/lib/pubid/iso/normalizer.rb +2 -2
  435. data/lib/pubid/iso/parser.rb +17 -13
  436. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  437. data/lib/pubid/iso/urn_generator.rb +4 -1
  438. data/lib/pubid/iso/urn_parser.rb +1 -1
  439. data/lib/pubid/iso.rb +7 -1
  440. data/lib/pubid/itu/builder.rb +230 -29
  441. data/lib/pubid/itu/components/code.rb +48 -5
  442. data/lib/pubid/itu/components/designation.rb +35 -0
  443. data/lib/pubid/itu/components.rb +1 -0
  444. data/lib/pubid/itu/identifier.rb +1 -3
  445. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  446. data/lib/pubid/itu/identifiers/amendment.rb +7 -29
  447. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  448. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  449. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  450. data/lib/pubid/itu/identifiers/base.rb +357 -25
  451. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  452. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  453. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  454. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  455. data/lib/pubid/itu/identifiers/question.rb +63 -0
  456. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  457. data/lib/pubid/itu/identifiers/report.rb +39 -0
  458. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  459. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  460. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  461. data/lib/pubid/itu/identifiers.rb +10 -1
  462. data/lib/pubid/itu/model.rb +1 -1
  463. data/lib/pubid/itu/parser.rb +481 -27
  464. data/lib/pubid/itu/urn_generator.rb +36 -6
  465. data/lib/pubid/itu/urn_parser.rb +8 -0
  466. data/lib/pubid/itu.rb +12 -3
  467. data/lib/pubid/jcgm/builder.rb +24 -14
  468. data/lib/pubid/jcgm/identifier.rb +10 -0
  469. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  470. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  471. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  472. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  473. data/lib/pubid/jcgm/identifiers.rb +2 -0
  474. data/lib/pubid/jcgm/parser.rb +74 -7
  475. data/lib/pubid/jcgm/renderer.rb +33 -12
  476. data/lib/pubid/jcgm/single_identifier.rb +84 -6
  477. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  478. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  479. data/lib/pubid/jcgm/urn_parser.rb +164 -10
  480. data/lib/pubid/jcgm.rb +10 -0
  481. data/lib/pubid/jis/identifier.rb +62 -3
  482. data/lib/pubid/jis/parser.rb +1 -1
  483. data/lib/pubid/jis.rb +1 -0
  484. data/lib/pubid/nist/builder.rb +29 -9
  485. data/lib/pubid/nist/caster.rb +7 -45
  486. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  487. data/lib/pubid/nist/components/stage.rb +2 -2
  488. data/lib/pubid/nist/components/supplement.rb +5 -2
  489. data/lib/pubid/nist/configuration.rb +6 -2
  490. data/lib/pubid/nist/identifier.rb +1 -3
  491. data/lib/pubid/nist/identifiers/base.rb +133 -39
  492. data/lib/pubid/nist/identifiers/circular.rb +10 -3
  493. data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
  494. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  495. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  496. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +8 -2
  497. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
  498. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  499. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  500. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  501. data/lib/pubid/nist/identifiers/handbook.rb +10 -3
  502. data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
  503. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  504. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
  505. data/lib/pubid/nist/identifiers/monograph.rb +15 -8
  506. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  507. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  508. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  509. data/lib/pubid/nist/identifiers/report.rb +15 -7
  510. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  511. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  512. data/lib/pubid/nist/identifiers.rb +0 -1
  513. data/lib/pubid/nist/parser.rb +27 -4
  514. data/lib/pubid/nist/preprocessor.rb +15 -0
  515. data/lib/pubid/nist/router.rb +2 -2
  516. data/lib/pubid/nist/series/ir.rb +0 -3
  517. data/lib/pubid/nist/supplement_identifier.rb +24 -9
  518. data/lib/pubid/nist.rb +19 -13
  519. data/lib/pubid/oasis/builder.rb +79 -0
  520. data/lib/pubid/oasis/identifier.rb +160 -0
  521. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  522. data/lib/pubid/oasis/identifiers.rb +9 -0
  523. data/lib/pubid/oasis/parser.rb +34 -0
  524. data/lib/pubid/oasis/renderer.rb +29 -0
  525. data/lib/pubid/oasis/urn_generator.rb +25 -0
  526. data/lib/pubid/oasis/urn_parser.rb +22 -0
  527. data/lib/pubid/oasis.rb +80 -0
  528. data/lib/pubid/ogc/builder.rb +33 -0
  529. data/lib/pubid/ogc/identifier.rb +81 -0
  530. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  531. data/lib/pubid/ogc/identifiers.rb +10 -0
  532. data/lib/pubid/ogc/parser.rb +40 -0
  533. data/lib/pubid/ogc/renderer.rb +33 -0
  534. data/lib/pubid/ogc/urn_generator.rb +14 -0
  535. data/lib/pubid/ogc/urn_parser.rb +22 -0
  536. data/lib/pubid/ogc.rb +72 -0
  537. data/lib/pubid/oiml/builder.rb +36 -8
  538. data/lib/pubid/oiml/identifier.rb +9 -1
  539. data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
  540. data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
  541. data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
  542. data/lib/pubid/oiml/identifiers/document.rb +2 -0
  543. data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
  544. data/lib/pubid/oiml/identifiers/guide.rb +2 -0
  545. data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
  546. data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
  547. data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
  548. data/lib/pubid/oiml/identifiers.rb +1 -0
  549. data/lib/pubid/oiml/parser.rb +12 -13
  550. data/lib/pubid/oiml/renderer.rb +13 -13
  551. data/lib/pubid/oiml/single_identifier.rb +41 -37
  552. data/lib/pubid/oiml/supplement_identifier.rb +36 -9
  553. data/lib/pubid/oiml/urn_parser.rb +23 -6
  554. data/lib/pubid/oiml.rb +10 -0
  555. data/lib/pubid/omg/builder.rb +20 -0
  556. data/lib/pubid/omg/identifier.rb +61 -0
  557. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  558. data/lib/pubid/omg/identifiers.rb +9 -0
  559. data/lib/pubid/omg/parser.rb +93 -0
  560. data/lib/pubid/omg/renderer.rb +31 -0
  561. data/lib/pubid/omg.rb +52 -0
  562. data/lib/pubid/parser/grammar.rb +74 -0
  563. data/lib/pubid/parser.rb +2 -0
  564. data/lib/pubid/parsers/mr_string.rb +120 -7
  565. data/lib/pubid/plateau/builder.rb +8 -4
  566. data/lib/pubid/plateau/identifier.rb +1 -3
  567. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  568. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  569. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  570. data/lib/pubid/plateau/identifiers.rb +0 -1
  571. data/lib/pubid/plateau/parser.rb +16 -6
  572. data/lib/pubid/plateau/renderer.rb +1 -1
  573. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  574. data/lib/pubid/plateau.rb +14 -4
  575. data/lib/pubid/prefixes_support.rb +1 -0
  576. data/lib/pubid/renderers/annotator.rb +233 -0
  577. data/lib/pubid/renderers/base.rb +13 -0
  578. data/lib/pubid/renderers/directives_renderer.rb +3 -3
  579. data/lib/pubid/renderers/human_readable.rb +6 -4
  580. data/lib/pubid/renderers/mr_string.rb +54 -6
  581. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  582. data/lib/pubid/renderers.rb +1 -0
  583. data/lib/pubid/rendering/numbering.rb +25 -7
  584. data/lib/pubid/rendering/supplement.rb +4 -4
  585. data/lib/pubid/rendering.rb +1 -0
  586. data/lib/pubid/sae/builder.rb +1 -1
  587. data/lib/pubid/sae/identifier.rb +1 -3
  588. data/lib/pubid/sae/identifiers/base.rb +19 -9
  589. data/lib/pubid/sae/identifiers.rb +0 -1
  590. data/lib/pubid/sae/parser.rb +1 -1
  591. data/lib/pubid/sae.rb +4 -3
  592. data/lib/pubid/schema/declaration.rb +33 -0
  593. data/lib/pubid/schema/error.rb +14 -0
  594. data/lib/pubid/schema/identifier_type.rb +23 -0
  595. data/lib/pubid/schema/loader.rb +117 -0
  596. data/lib/pubid/schema/typed_stage.rb +24 -0
  597. data/lib/pubid/schema.rb +25 -0
  598. data/lib/pubid/tgpp/builder.rb +41 -0
  599. data/lib/pubid/tgpp/identifier.rb +107 -0
  600. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  601. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  602. data/lib/pubid/tgpp/identifiers.rb +11 -0
  603. data/lib/pubid/tgpp/parser.rb +78 -0
  604. data/lib/pubid/tgpp/renderer.rb +52 -0
  605. data/lib/pubid/tgpp/urn_generator.rb +39 -0
  606. data/lib/pubid/tgpp/urn_parser.rb +30 -0
  607. data/lib/pubid/tgpp.rb +84 -0
  608. data/lib/pubid/type_resolver.rb +74 -0
  609. data/lib/pubid/un/builder.rb +42 -0
  610. data/lib/pubid/un/identifier.rb +40 -0
  611. data/lib/pubid/un/identifiers/document.rb +24 -0
  612. data/lib/pubid/un/identifiers.rb +9 -0
  613. data/lib/pubid/un/parser.rb +25 -0
  614. data/lib/pubid/un/renderer.rb +11 -0
  615. data/lib/pubid/un.rb +47 -0
  616. data/lib/pubid/urn_parser/errors.rb +8 -1
  617. data/lib/pubid/urn_parser.rb +1 -0
  618. data/lib/pubid/utils.rb +1 -0
  619. data/lib/pubid/version.rb +1 -1
  620. data/lib/pubid/w3c/builder.rb +55 -0
  621. data/lib/pubid/w3c/identifier.rb +130 -0
  622. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  623. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  624. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  625. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  626. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  627. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  628. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  629. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  630. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  631. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  632. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  633. data/lib/pubid/w3c/identifiers.rb +25 -0
  634. data/lib/pubid/w3c/parser.rb +43 -0
  635. data/lib/pubid/w3c/renderer.rb +35 -0
  636. data/lib/pubid/w3c/urn_generator.rb +18 -0
  637. data/lib/pubid/w3c/urn_parser.rb +36 -0
  638. data/lib/pubid/w3c.rb +68 -0
  639. data/lib/pubid/xsf/builder.rb +17 -0
  640. data/lib/pubid/xsf/identifier.rb +66 -0
  641. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  642. data/lib/pubid/xsf/identifiers.rb +9 -0
  643. data/lib/pubid/xsf/parser.rb +38 -0
  644. data/lib/pubid/xsf/renderer.rb +23 -0
  645. data/lib/pubid/xsf/urn_generator.rb +13 -0
  646. data/lib/pubid/xsf/urn_parser.rb +18 -0
  647. data/lib/pubid/xsf.rb +82 -0
  648. data/lib/pubid.rb +424 -22
  649. data/lib/tasks/conformance.rake +34 -0
  650. data/lib/tasks/docs.rake +3 -3
  651. data/lib/tasks/schema.rake +88 -0
  652. data/schema/core/joint_prefixes.yaml +24 -0
  653. data/schema/iec.yaml +1017 -0
  654. data/schema/iso.yaml +1586 -0
  655. data/schema/schema.schema.yaml +96 -0
  656. metadata +241 -19
  657. data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
  658. data/archived-gems/pubid-iec/stages.yaml +0 -129
  659. data/archived-gems/pubid-iec/update_codes.yaml +0 -67
  660. data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
  661. data/archived-gems/pubid-iso/stages.yaml +0 -106
  662. data/archived-gems/pubid-iso/update_codes.yaml +0 -4
  663. data/archived-gems/pubid-itu/i18n.yaml +0 -13
  664. data/archived-gems/pubid-itu/series.yaml +0 -42
  665. data/archived-gems/pubid-nist/publishers.yaml +0 -6
  666. data/archived-gems/pubid-nist/update_codes.yaml +0 -93
  667. data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
  668. data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
  669. data/lib/pubid/cie/components/code.rb +0 -80
  670. data/lib/pubid/iala/identifiers/base.rb +0 -14
  671. data/lib/pubid/iec/components/code.rb +0 -36
  672. /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
@@ -4,28 +4,28 @@ module Pubid
4
4
  module Ccsds
5
5
  # Base class for CCSDS supplements (corrigenda, amendments, etc.).
6
6
  # Descends from the abstract root (not the concrete Base) and points
7
- # `base_identifier` at the root, so the polymorphic attribute never
7
+ # `base` at the root, so the polymorphic attribute never
8
8
  # resolves to its own superclass — which is what prevents lutaml from
9
9
  # recursing forever while building a supplement from a hash.
10
10
  class SupplementIdentifier < Identifier
11
- attribute :base_identifier, Identifier, polymorphic: true
11
+ attribute :base, Identifier, polymorphic: true
12
12
 
13
13
  # Serialize the supplemented identifier under "base" (matches ISO/JIS).
14
- # The key stays `base_identifier` for the attribute/getter, which
14
+ # The key stays `base` for the attribute/getter, which
15
15
  # relaton-index's get_id_number relies on. A supplement's own code
16
16
  # attributes (number/part/edition/...) stay nil — they live inside
17
17
  # `base` — so the merged root key_value omits them here, keeping the
18
18
  # serialization lean and non-duplicated.
19
19
  key_value do
20
- map "base", to: :base_identifier
20
+ map "base", to: :base
21
21
  end
22
22
 
23
23
  def <=>(other)
24
24
  return nil unless other.is_a?(SupplementIdentifier)
25
25
 
26
26
  # Compare base identifiers first
27
- if base_identifier && other.base_identifier
28
- base_cmp = base_identifier <=> other.base_identifier
27
+ if base && other.base
28
+ base_cmp = base <=> other.base
29
29
  return base_cmp unless base_cmp.zero?
30
30
  end
31
31
 
@@ -91,14 +91,14 @@ module Pubid
91
91
 
92
92
  while current.is_a?(SupplementIdentifier)
93
93
  supplement_chain.unshift(current)
94
- current = current.base_identifier
94
+ current = current.base
95
95
  end
96
96
 
97
97
  base_gen = self.class.new(current)
98
98
  base_urn = base_gen.generate_base_urn
99
99
 
100
- base_identifier_part = base_urn.sub(/^urn:ccsds:/, "")
101
- parts << base_identifier_part
100
+ base_part = base_urn.sub(/^urn:ccsds:/, "")
101
+ parts << base_part
102
102
 
103
103
  supplement_chain.each do |supp|
104
104
  if supp.number && !supp.number.to_s.empty?
data/lib/pubid/ccsds.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Ccsds
5
6
  extend Pubid::PrefixesSupport
@@ -18,6 +18,28 @@ module Pubid
18
18
  return build_fragment_identifier(data)
19
19
  end
20
20
 
21
+ # Every base document (an adopted norm, an ENV adoption, a plain
22
+ # identifier) goes through the same supplement wrapping. The adopted
23
+ # branches used to return early, so "CEN ISO/TS 21003-7:2008/A1:2010"
24
+ # lost its "/A1:2010".
25
+ base = build_base_document(data)
26
+
27
+ # A slash separator makes a standalone amendment/corrigendum; a plus
28
+ # separator makes a consolidated (bundled) identifier.
29
+ if has_slash_supplements?(data)
30
+ build_standalone_supplement(base, data)
31
+ elsif (supplements_data = extract_supplements(data)).any?
32
+ wrap_with_consolidated(base, supplements_data)
33
+ else
34
+ base
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ # The document that the supplements of +data+ apply to, or the whole
41
+ # identifier when there are no supplements.
42
+ def build_base_document(data)
21
43
  # Check if this is an adopted identifier (EN ISO, EN IEC, etc.)
22
44
  if data[:adopted_string]
23
45
  # Special case: ENV can adopt ISO/IEC standards
@@ -28,27 +50,41 @@ module Pubid
28
50
  return build_adopted_identifier(data)
29
51
  end
30
52
 
31
- # Check if this is a standalone amendment/corrigendum (slash separator)
32
- if has_slash_supplements?(data)
33
- return build_standalone_supplement(data)
53
+ # Implicit adoption: when an EN has no explicit "IEC" prefix but
54
+ # the number falls in the IEC range (60000-79999), treat it as an
55
+ # adoption of the corresponding IEC standard. The lower ISO-only
56
+ # range (1-59999) is intentionally NOT mapped here — too many
57
+ # existing CEN publications (EN Guide N, EN N as a real CEN-assigned
58
+ # number) would change type. Callers who want explicit adoption
59
+ # can still write "EN ISO 12345".
60
+ # (https://github.com/pubid/pubid/issues/249)
61
+ # Skip when parts are present — they would be lost when we rebuild
62
+ # the identifier from just the base number — and when supplements
63
+ # are present, which the adoption used to drop the same way.
64
+ if data[:publisher]&.to_s == "EN" && data[:parts].to_a.empty? &&
65
+ !supplements?(data) &&
66
+ (adopted = build_implicit_adoption(data))
67
+ return adopted
34
68
  end
35
69
 
36
- # Extract supplements before building base identifier (only plus/bundled)
37
- supplements_data = extract_supplements(data)
38
-
39
70
  # Determine identifier class using the module's lookup helpers
40
- identifier = locate_identifier_klass(data).new
41
- assign_attributes(identifier, data)
71
+ base_data = data.except(:supplements)
72
+ identifier = locate_identifier_klass(base_data).new
73
+ assign_attributes(identifier, base_data)
74
+ identifier
75
+ end
42
76
 
43
- # Wrap with consolidated if supplements present (plus/bundled only)
44
- if supplements_data.any?
45
- wrap_with_consolidated(identifier, supplements_data)
46
- else
47
- identifier
48
- end
77
+ def supplements?(data)
78
+ has_slash_supplements?(data) || extract_supplements(data).any?
49
79
  end
50
80
 
51
- private
81
+ # A number or month the grammar captured as an empty string is stored
82
+ # as nil: `to_hash` drops an empty string, so from_hash would give nil
83
+ # and the two identifiers would not be `==`.
84
+ def present_string(value)
85
+ str = value&.to_s
86
+ str unless str.nil? || str.empty?
87
+ end
52
88
 
53
89
  def build_fragment_identifier(data)
54
90
  # Build base identifier first (without amendment/fragment)
@@ -56,19 +92,19 @@ module Pubid
56
92
  base_data.delete(:amendment_number)
57
93
  base_data.delete(:fragment_number)
58
94
 
59
- base_identifier = locate_identifier_klass(base_data).new
60
- assign_attributes(base_identifier, base_data)
95
+ base = locate_identifier_klass(base_data).new
96
+ assign_attributes(base, base_data)
61
97
 
62
98
  # Build Amendment identifier wrapping the base
63
99
  amendment = Identifiers::Amendment.new(
64
- base_identifier: base_identifier,
65
- amendment_number: data[:amendment_number].to_s,
100
+ base: base,
101
+ number: data[:amendment_number].to_s,
66
102
  )
67
103
 
68
104
  # Build Fragment wrapping the amendment
69
105
  Identifiers::Fragment.new(
70
- base_identifier: amendment,
71
- fragment_number: data[:fragment_number].to_s,
106
+ base: amendment,
107
+ number: data[:fragment_number].to_s,
72
108
  )
73
109
  end
74
110
 
@@ -78,7 +114,7 @@ module Pubid
78
114
 
79
115
  # Check if publisher is actually a type code (CWA, HD, ES, CR, ENV act as publisher)
80
116
  publisher_str = parsed_hash[:publisher].to_s
81
- if %w[CWA HD ES CR ENV].include?(publisher_str)
117
+ if CenCenelec::PUBLISHER_TYPES.include?(publisher_str)
82
118
  typed_stage = CenCenelec.locate_stage(publisher_str)
83
119
  if (klass = CenCenelec.locate_type(typed_stage.type_code))
84
120
  return klass
@@ -116,7 +152,7 @@ module Pubid
116
152
  end
117
153
 
118
154
  when :number
119
- Components::Code.new(value: value.to_s)
155
+ value.to_s
120
156
 
121
157
  when :parts
122
158
  # Extract first part, preserve full multi-level part string
@@ -126,11 +162,11 @@ module Pubid
126
162
  part_str = parts_array.first[:part].to_s
127
163
 
128
164
  # Store the full part value for multi-level parts
129
- { part: Components::Code.new(value: part_str) }
165
+ { part: part_str }
130
166
  end
131
167
 
132
168
  when :part
133
- Components::Code.new(value: value[:part].to_s) if value.is_a?(Hash)
169
+ value[:part].to_s if value.is_a?(Hash)
134
170
 
135
171
  when :year, :date
136
172
  # Check if month is present in the data and include it
@@ -186,24 +222,55 @@ module Pubid
186
222
  nil
187
223
  end
188
224
 
189
- # Build publishers array (EN is default for adoptions)
190
- publishers = []
191
- publishers << data[:publisher].to_s if data[:publisher]
192
-
193
- # Handle copublishers array
194
- if data[:copublishers]
195
- Array(data[:copublishers]).each do |copub|
196
- publishers << copub[:copublisher].to_s
225
+ # The publisher is a Components::Publisher (EN is the default for
226
+ # adoptions); a second publisher ("CEN/CLC") is a copublisher.
227
+ copublishers = if data[:copublishers]
228
+ Array(data[:copublishers]).map do |copub|
229
+ copub[:copublisher].to_s
230
+ end
231
+ elsif data[:copublisher]
232
+ [data[:copublisher].to_s]
233
+ else
234
+ []
235
+ end
236
+
237
+ attrs = { adopted: adopted_id }
238
+ # "prEN ISO 1234:2020": the draft stage is on the CEN adoption. The
239
+ # parser captures it as type_with_stage and not as a publisher, and
240
+ # it used to be dropped here, so the identifier rendered as "EN ISO".
241
+ if data[:type_with_stage]
242
+ attrs.merge!(cast(:type_with_stage, data[:type_with_stage]))
243
+ end
244
+ if data[:publisher]
245
+ attrs[:publisher] =
246
+ Components::Publisher.new(body: data[:publisher].to_s)
247
+ end
248
+ # Only when present: an empty collection would not survive to_hash,
249
+ # and from_hash would then give nil where the parse gave [].
250
+ unless copublishers.empty?
251
+ attrs[:copublishers] = copublishers.map do |body|
252
+ Components::Publisher.new(body: body)
197
253
  end
198
- elsif data[:copublisher]
199
- publishers << data[:copublisher].to_s
200
254
  end
201
255
 
202
- publishers = ["EN"] if publishers.empty?
256
+ Identifiers::AdoptedEuropeanNorm.new(**attrs)
257
+ end
258
+
259
+ # Implicit adoption by number range. Returns an AdoptedEuropeanNorm
260
+ # wrapping the IEC identifier that the EN number implies, or nil if the
261
+ # number does not fall in the IEC range. Limited to IEC range only —
262
+ # see the call site comment for why the ISO range is excluded.
263
+ def build_implicit_adoption(data)
264
+ number = data[:number].to_s
265
+ num_str = number.to_s.strip
266
+ return nil unless num_str.match?(/\A\d{1,6}\z/)
267
+
268
+ num = num_str.to_i
269
+ return nil unless (60_000..79_999).cover?(num)
203
270
 
271
+ # The publisher is the "EN" default.
204
272
  Identifiers::AdoptedEuropeanNorm.new(
205
- publisher: publishers,
206
- adopted_identifier: adopted_id,
273
+ adopted: Pubid::Iec.parse("IEC #{num_str}"),
207
274
  )
208
275
  end
209
276
 
@@ -220,32 +287,35 @@ module Pubid
220
287
  Pubid::Iec.parse(adopted_str)
221
288
  end
222
289
 
290
+ # The publisher is ENV, as for a plain "ENV 1613:1995"; the
291
+ # SingleIdentifier default is EN.
223
292
  Identifiers::EuropeanPrestandard.new(
224
- adopted_identifier: adopted_id,
293
+ publisher: Components::Publisher.new(body: "ENV"),
294
+ adopted: adopted_id,
225
295
  )
226
296
  end
227
297
 
228
- def wrap_with_consolidated(base_identifier, supplements_data)
298
+ # The members after the first carry no `base`: the consolidated
299
+ # identifier holds the base document once, as its first member. With a
300
+ # `base` in each member, `to_hash` wrote the base again for every "+".
301
+ def wrap_with_consolidated(base, supplements_data)
229
302
  supplement_ids = supplements_data.map do |supp|
230
303
  if supp[:type] == :amendment
231
304
  Identifiers::Amendment.new(
232
- base_identifier: base_identifier,
233
- amendment_number: supp[:number],
234
- amendment_year: supp[:year]&.to_i,
305
+ number: present_string(supp[:number]),
306
+ year: present_string(supp[:year]),
235
307
  )
236
308
  else
237
- corr_attrs = {
238
- base_identifier: base_identifier,
239
- corrigendum_number: supp[:number],
240
- corrigendum_year: supp[:year]&.to_i,
241
- }
242
- corr_attrs[:corrigendum_month] = supp[:month] if supp[:month]
243
- Identifiers::Corrigendum.new(**corr_attrs)
309
+ Identifiers::Corrigendum.new(
310
+ number: present_string(supp[:number]),
311
+ year: present_string(supp[:year]),
312
+ month: present_string(supp[:month]),
313
+ )
244
314
  end
245
315
  end
246
316
 
247
317
  Identifiers::ConsolidatedIdentifier.new(
248
- identifiers: [base_identifier] + supplement_ids,
318
+ identifiers: [base] + supplement_ids,
249
319
  )
250
320
  end
251
321
 
@@ -290,13 +360,7 @@ module Pubid
290
360
  end
291
361
  end
292
362
 
293
- def build_standalone_supplement(data)
294
- # Build base identifier first (without supplements)
295
- base_data = data.dup
296
- base_data.delete(:supplements)
297
- base_identifier = locate_identifier_klass(base_data).new
298
- assign_attributes(base_identifier, base_data)
299
-
363
+ def build_standalone_supplement(base, data)
300
364
  # Get the first supplement (slash means only one supplement)
301
365
  supp_array = data[:supplements]
302
366
  supp_data = supp_array.first
@@ -305,22 +369,17 @@ module Pubid
305
369
  # Build appropriate supplement identifier
306
370
  if supp_data[:amd_number]
307
371
  Identifiers::Amendment.new(
308
- base_identifier: base_identifier,
309
- amendment_number: supp_data[:amd_number].to_s,
310
- amendment_year: supp_data[:amd_year]&.to_i,
372
+ base: base,
373
+ number: supp_data[:amd_number].to_s,
374
+ year: present_string(supp_data[:amd_year]),
311
375
  )
312
376
  else
313
- corr_attrs = {
314
- base_identifier: base_identifier,
315
- corrigendum_number: supp_data[:cor_number]&.to_s,
316
- corrigendum_year: (supp_data[:cor_year] || supp_data[:year])&.to_i,
317
- }
318
- month_val = supp_data[:month]&.to_s
319
- if month_val && !month_val.empty?
320
- corr_attrs[:corrigendum_month] =
321
- month_val
322
- end
323
- Identifiers::Corrigendum.new(**corr_attrs)
377
+ Identifiers::Corrigendum.new(
378
+ base: base,
379
+ number: present_string(supp_data[:cor_number]),
380
+ year: present_string(supp_data[:year]),
381
+ month: present_string(supp_data[:month]),
382
+ )
324
383
  end
325
384
  end
326
385
  end
@@ -8,15 +8,127 @@ module Pubid
8
8
  # CEN/CENELEC identifier `is_a?(Pubid::CenCenelec::Identifier)` natively (and
9
9
  # giving them the shared polymorphic `from_hash`). No facade needed.
10
10
  class Identifier < ::Pubid::Identifier
11
+ # `number`/`part`/`subpart` are declared here rather than inherited as a
12
+ # Components::Code: CEN/CENELEC stores a bare string in every one of them.
13
+ # This class is the shared parent of BOTH branches, so one declaration
14
+ # here replaces the three that used to disagree (Identifiers::Base said
15
+ # :string, SingleIdentifier inherited Code, SupplementIdentifier declared
16
+ # Code again). Declaring here is safe because this body lives in one file
17
+ # and is never reopened, so every subclass body opens after it has run
18
+ # (lutaml deep-dups the parent attribute table at class-definition time).
19
+ attribute :number, :string
20
+ attribute :part, :string
21
+ attribute :subpart, :string
22
+
23
+ # The publisher serializes as a bare string ("publisher" => "CEN"), and
24
+ # the copublishers as a list of strings. The shared table does not do
25
+ # this for every flavor, because IEEE has a published index whose rows
26
+ # hold the nested {"body" => …} form.
27
+ def self.flat_scalar_components
28
+ super.merge(publisher: "publisher", copublishers: "copublishers")
29
+ end
30
+
31
+ def self.flat_scalar_fields
32
+ super.merge(publisher: :body, copublishers: :body)
33
+ end
34
+
35
+ # A draft stage serializes as its typed-stage code ("stage" => "pren"),
36
+ # as ISO ("dis") and IEC ("cd") do. The `type`, `stage` and
37
+ # `typed_stage` components all repeat one entry of the stage registry,
38
+ # so the code is enough, and #inflate_scalar_components rebuilds the
39
+ # three from it. The short form is written only when the three are
40
+ # exactly what the registry entry gives; any other combination keeps
41
+ # the nested components, so the round trip stays exact.
42
+ def self.compact_hash(model, hash)
43
+ stage = model.typed_stage
44
+ return unless stage && hash.key?("typed_stage")
45
+ return unless model.type == stage.to_type &&
46
+ model.stage == stage.to_stage
47
+
48
+ hash.delete("type")
49
+ hash.delete("typed_stage")
50
+ hash["stage"] = stage.code.to_s
51
+ end
52
+
53
+ # Reads the short stage form back; see #compact_hash. The nested form
54
+ # still reads as before.
55
+ def self.inflate_scalar_components(data)
56
+ data = super
57
+ return data unless data.is_a?(::Hash) && component_attribute?(:stage)
58
+
59
+ key = data.key?("stage") ? "stage" : :stage
60
+ value = data[key]
61
+ return data unless value.is_a?(::String) || value.is_a?(::Symbol)
62
+
63
+ stage = CenCenelec.locate_stage_by_code(value)
64
+ return data unless stage
65
+
66
+ data = data.dup
67
+ data.delete(key)
68
+ data["type"] = stage.to_type.to_hash
69
+ data["stage"] = stage.to_stage.to_hash
70
+ data["typed_stage"] = stage.to_hash
71
+ data
72
+ end
73
+
74
+ # The slug names a draft stage by its code ("en.pren.1234.2020"), so a
75
+ # prEN, an FprEN and an EN with one number and year get three slugs.
76
+ # The shared hook gave the type code "en" for all of them.
77
+ def mr_type
78
+ stage = typed_stage
79
+ return super unless stage && stage.stage_code.to_s != "published"
80
+
81
+ stage.code.to_s.downcase
82
+ end
83
+
84
+ # The attributes that hold a supplement's own date: `year`, and `month`
85
+ # on a corrigendum. Empty for a document. See #exclude.
86
+ def self.supplement_date_attributes
87
+ []
88
+ end
89
+
90
+ # The CEN year rule, as in BSI: `:year` removes only the base
91
+ # document's year ("EN 13250:2000/A1:2005" -> "EN 13250/A1:2005"), and
92
+ # the CEN key `:supplement_year` removes the supplement's own date
93
+ # ("EN 13250:2000/A1"). A supplement declares its date as a `year`
94
+ # attribute, which the base #exclude resets for `:year`, so the value is
95
+ # put back here. The month goes with the year, or a "/AC:2016-11" would
96
+ # keep a month with no year. The base #exclude passes every key on to
97
+ # the nested identifiers, so the members of a consolidated identifier
98
+ # follow the same rule.
99
+ def exclude(*args)
100
+ result = super
101
+ attrs = self.class.supplement_date_attributes
102
+ # `exclude(:amendment)` returns the base document, not a copy of self.
103
+ return result if attrs.empty? || !result.instance_of?(self.class)
104
+
105
+ drop = args.include?(:supplement_year)
106
+ attrs.each do |attr|
107
+ result.public_send(:"#{attr}=", drop ? nil : public_send(attr))
108
+ end
109
+ result
110
+ end
111
+
11
112
  def self.parse(identifier)
113
+ unless identifier.is_a?(String)
114
+ raise Pubid::Errors::InvalidInputError,
115
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
116
+ end
117
+
12
118
  if identifier.length > Pubid::MAX_INPUT_LENGTH
13
- raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
119
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
14
120
  end
15
121
 
16
122
  parsed = Parser.parse(identifier)
17
123
  Builder.new.build(parsed)
18
- rescue Parslet::ParseFailed => e
19
- raise "Failed to parse CEN identifier '#{identifier}': #{e.message}"
124
+ end
125
+
126
+ private
127
+
128
+ # "amd.1.2005" from ("amd", "1", 2005). A nil or blank segment is left
129
+ # out, so an unnumbered "/AC:2003" gives "cor.2003", not "cor..2003".
130
+ def mr_join_segments(*segments)
131
+ segments.map(&:to_s).reject(&:empty?).join(".").downcase
20
132
  end
21
133
  end
22
134
  end
@@ -5,8 +5,15 @@ module Pubid
5
5
  module Identifiers
6
6
  # AdoptedEuropeanNorm wraps ISO/IEC identifiers
7
7
  # Example: "EN ISO 8601:2019" where ISO 8601:2019 is an ISO identifier object
8
+ #
9
+ # `publisher` is the inherited Components::Publisher ("EN", "CEN",
10
+ # "CR", "HD"); a second publisher goes in `copublishers`. It used to be
11
+ # an Array of Strings in that Components::Publisher attribute, so
12
+ # `to_hash` raised on every adopted norm.
8
13
  class AdoptedEuropeanNorm < EuropeanNorm
9
- attribute :adopted_identifier, Base, polymorphic: true # ISO/IEC/IEEE object
14
+ # Typed to the root class: the adopted document is an ISO or IEC
15
+ # identifier, never a CEN one.
16
+ attribute :adopted, ::Pubid::Identifier, polymorphic: true
10
17
 
11
18
  # Override self.type to return nil so that AdoptedEuropeanNorm is NOT
12
19
  # registered as a type in CenCenelec.identifier_types. The class is a
@@ -19,25 +26,29 @@ module Pubid
19
26
  nil
20
27
  end
21
28
 
22
- # Delegate common methods to adopted identifier
23
- def number
24
- adopted_identifier&.number
29
+ # Walk to the adopted document for the relaton-index key.
30
+ #
31
+ # This replaces reader methods named number, year, date, parts and
32
+ # part that delegated to the adopted document. `number`, `date` and
33
+ # `part` are lutaml attributes, so the serializer read the ISO values
34
+ # through them and wrote them again at the top level of the hash.
35
+ # `#root` is the documented wrapper shape (EuropeanPrestandard,
36
+ # ConsolidatedIdentifier).
37
+ def root
38
+ adopted ? adopted.root : self
25
39
  end
26
40
 
27
- def year
28
- adopted_identifier&.year if adopted_identifier&.methods&.include?(:year)
41
+ # MR "cen.iso.ts.21003-7.2019": the CEN publisher ("cen" or
42
+ # "cen-clc"), then the adopted document's own MR string in place of a
43
+ # number. These are hooks and not a `to_mr_string` override, so the
44
+ # MR of an amendment on this norm renders its base the same way.
45
+ def mr_publisher
46
+ mr_join(*([publisher] + Array(copublishers)).compact
47
+ .map { |p| p.to_s.downcase })
29
48
  end
30
49
 
31
- def date
32
- adopted_identifier&.date if adopted_identifier&.methods&.include?(:date)
33
- end
34
-
35
- def parts
36
- adopted_identifier&.parts if adopted_identifier&.methods&.include?(:parts)
37
- end
38
-
39
- def part
40
- adopted_identifier&.part if adopted_identifier&.methods&.include?(:part)
50
+ def mr_number_with_part
51
+ adopted&.to_mr_string
41
52
  end
42
53
  end
43
54
  end
@@ -5,13 +5,53 @@ module Pubid
5
5
  module Identifiers
6
6
  # Amendment Identifier
7
7
  # Contains a base identifier plus amendment parameters
8
- class Amendment < Base
9
- attribute :base_identifier, Base, polymorphic: true
10
- attribute :amendment_number, :string
11
- attribute :amendment_year, :integer
8
+ #
9
+ # It descends from the shared Pubid::CenCenelec::Identifier, not from
10
+ # the legacy Identifiers::Base. That class declares publisher, year and
11
+ # parts attributes that an amendment does not have, and its `==` compared
12
+ # only those, so any two amendments were equal.
13
+ #
14
+ # The amendment number is the inherited `number`, and its year is a
15
+ # `year` string, so the hash uses the same keys as a document:
16
+ # {"base" => {…}, "number" => "1", "year" => "2005"}. The member of a
17
+ # consolidated identifier has no `base`; the consolidated identifier
18
+ # holds the base document once.
19
+ class Amendment < Pubid::CenCenelec::Identifier
20
+ # Typed to the shared parent: the base of an amendment is a
21
+ # SingleIdentifier ("EN 13250:2000"), an adopted norm
22
+ # ("CEN ISO/TS 21003-7:2008") or another supplement.
23
+ attribute :base, Pubid::CenCenelec::Identifier, polymorphic: true
24
+ attribute :year, :string
12
25
 
13
- def publisher
14
- base_identifier&.publisher
26
+ def self.supplement_date_attributes
27
+ %i[year]
28
+ end
29
+
30
+ def base_document
31
+ base&.base_document || self
32
+ end
33
+
34
+ # Dropping the supplement layer yields the base standard.
35
+ def drop_supplements
36
+ base || self
37
+ end
38
+
39
+ # Uniform supplement interface (shared with Corrigendum and with BSI)
40
+ # so callers need not special-case the class.
41
+ def supplement_type
42
+ :amendment
43
+ end
44
+
45
+ def supplement_number
46
+ number
47
+ end
48
+
49
+ def supplement_year
50
+ year
51
+ end
52
+
53
+ def mr_supplement_suffix
54
+ mr_join_segments("amd", number, year)
15
55
  end
16
56
  end
17
57
  end
@@ -12,20 +12,19 @@ module Pubid
12
12
 
13
13
  attribute :publisher, :string, collection: true # EN, CEN, CLC, etc.
14
14
  attribute :type, :string # TR, TS, Guide
15
- attribute :number, :string
15
+ # `number` is inherited as a :string from Pubid::CenCenelec::Identifier;
16
+ # a same-type redeclaration here is the determinism landmine in
17
+ # miniature, and it moves the generated accessor onto this class.
16
18
  attribute :parts, :string, collection: true
17
19
  attribute :year, :integer
18
20
  attribute :stage, :string # prEN, FprEN
19
21
  attribute :supplements, :string, collection: true # Amendments and corrigenda
20
- attribute :adopted_identifier, Base, polymorphic: true # Nested identifier object (ISO, IEC, etc.)
22
+ # Nested identifier object (ISO, IEC, etc.)
23
+ attribute :adopted, Base, polymorphic: true
21
24
  attribute :edition, :string # Edition number
22
-
23
- def ==(other)
24
- return false unless other.is_a?(Base)
25
-
26
- publisher == other.publisher && number == other.number &&
27
- parts == other.parts && year == other.year
28
- end
25
+ # No custom `==`: the one that was here compared only publisher,
26
+ # number, parts and year, so every amendment equalled every other.
27
+ # lutaml's attribute-wise `==` compares the whole identifier.
29
28
  end
30
29
  end
31
30
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  module CenCenelec
7
7
  module Identifiers
8
8
  class CenReport < SingleIdentifier
9
- attribute :type, Components::Type, default: -> { self.class.type[:key] }
9
+ attribute :type, Components::Type, default: -> { self.class.default_type }
10
10
 
11
11
  TYPED_STAGES = [
12
12
  Components::TypedStage.new(
@@ -5,7 +5,7 @@ module Pubid
5
5
  module CenCenelec
6
6
  module Identifiers
7
7
  class CenWorkshopAgreement < SingleIdentifier
8
- attribute :type, Components::Type, default: -> { self.class.type[:key] }
8
+ attribute :type, Components::Type, default: -> { self.class.default_type }
9
9
 
10
10
  TYPED_STAGES = [
11
11
  Components::TypedStage.new(