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
@@ -5,16 +5,23 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Csa
7
7
  module Identifiers
8
- # CombinedIdentifier represents CSA identifiers combined with "/" separator
8
+ # Combined represents CSA identifiers joined with "/" or ", "
9
9
  # Examples:
10
10
  # CSA A23.1:24/CSA A23.2:24
11
11
  # CSA N285.0:23/CSA N285.6 SERIES:23
12
12
  # CSA A123.1-05/A123.5-05 (R2015)
13
13
  # CSA B44:19/B44.1:19/B44.2:19 (triple combined)
14
- class Combined < Lutaml::Model::Serializable
15
- attribute :first, Standard
16
- attribute :second, Standard
17
- attribute :third, Standard
14
+ class Combined < Identifier
15
+ # The co-equal designations, in printed order.
16
+ #
17
+ # One polymorphic collection, the IEC ConsolidatedIdentifier shape —
18
+ # not the historical first/second/third triple, which hard-capped the
19
+ # form at three and froze a non-standard hash shape. The first member
20
+ # is the primary designation, which is what #root walks so the index
21
+ # key is non-empty. Typed cross-flavor for the same reason as
22
+ # WrapperIdentifier#base.
23
+ attribute :identifiers, ::Pubid::Identifier, polymorphic: true,
24
+ collection: true
18
25
  attribute :reaffirmation, :string
19
26
  attribute :original_reaffirmation_4digit, :boolean, default: -> {
20
27
  false
@@ -23,61 +30,74 @@ module Pubid
23
30
  attribute :year_format, :string # Dummy for compatibility
24
31
  attribute :separator, :string, default: -> { "/" } # "/" or ", "
25
32
 
26
- def to_s
27
- # For comma separator, render both parts with full prefix
28
- # For slash separator, second/third parts without prefix
29
- if separator == ", "
30
- # Comma: Both with full CSA prefix
31
- parts = [first.to_s, second.to_s]
32
- parts << third.to_s if third
33
- else
34
- # Slash: Second and third without CSA prefix (continuation)
35
- parts = [first.to_s]
36
- parts << render_continuation(second)
37
- parts << render_continuation(third) if third
38
- end
33
+ # A combined id stores its members in `identifiers`, not `base`, so
34
+ # walk the primary designation to the origin document
35
+ # (Iec::Identifiers::ConsolidatedIdentifier does the same).
36
+ def root
37
+ identifiers&.first&.root || self
38
+ end
39
39
 
40
- result = parts.join(separator || "/")
40
+ # Co-equal designations, so both matching primitives reduce to the
41
+ # primary one — the Iec::Identifiers::ConsolidatedIdentifier shape.
42
+ def base_document
43
+ identifiers&.first&.base_document || self
44
+ end
41
45
 
42
- # Reaffirmation - preserve original format and determine spacing
43
- if reaffirmation
44
- # For combined identifiers, check year format from first identifier
45
- # to determine spacing
46
- year_was_2digit = first.class.attributes.key?(:original_year_4digit) && !first.original_year_4digit
47
-
48
- # Check if reaffirmation was originally 4-digit
49
- # Note: We need to track this at the Combined level, but for now
50
- # assume 4-digit if the value is 4 digits and starts with 19/20
51
- reaffirmation_was_4digit = reaffirmation.to_s.length == 4 &&
52
- reaffirmation.to_s.start_with?("19", "20")
53
-
54
- # Determine spacing based on original formats
55
- # Space needed if year is 2-digit and reaffirmation is 4-digit
56
- result += if year_was_2digit && reaffirmation_was_4digit
57
- " (R#{reaffirmation})"
58
- else
59
- "(R#{reaffirmation})"
60
- end
61
- end
46
+ def drop_supplements
47
+ identifiers&.first || self
48
+ end
62
49
 
50
+ def to_s(**opts)
51
+ parts = render_parts
52
+ result = parts.join(separator || "/")
53
+ result += render_reaffirmation if reaffirmation
63
54
  result += package if package
64
- result
55
+ annotate_plain_render(result, **opts)
65
56
  end
66
57
 
67
58
  private
68
59
 
60
+ # With a comma separator every designation carries its full prefix;
61
+ # with a slash the trailing ones are continuations printed bare.
62
+ def render_parts
63
+ return identifiers.map(&:to_s) if separator == ", "
64
+
65
+ identifiers.each_with_index.map do |identifier, index|
66
+ index.zero? ? identifier.to_s : render_continuation(identifier)
67
+ end
68
+ end
69
+
70
+ # Reaffirmation - preserve original format and determine spacing.
71
+ # A space is needed when the year was printed 2-digit and the
72
+ # reaffirmation 4-digit; the year format comes from the primary
73
+ # designation.
74
+ def render_reaffirmation
75
+ primary = identifiers&.first
76
+ year_was_2digit =
77
+ primary &&
78
+ primary.class.attributes.key?(:original_year_4digit) &&
79
+ !primary.original_year_4digit
80
+
81
+ reaffirmation_was_4digit = reaffirmation.to_s.length == 4 &&
82
+ reaffirmation.to_s.start_with?("19", "20")
83
+
84
+ if year_was_2digit && reaffirmation_was_4digit
85
+ " (R#{reaffirmation})"
86
+ else
87
+ "(R#{reaffirmation})"
88
+ end
89
+ end
90
+
69
91
  # Render identifier without CSA prefix (unless has_publisher is true)
70
92
  def render_continuation(identifier)
71
93
  parts = []
72
94
 
73
95
  # Add CSA prefix if present in original
74
96
  if identifier.has_publisher
75
- prefix = identifier.publisher_prefix || "CSA"
76
- !prefix.end_with?("-")
77
- parts << prefix
97
+ parts << (identifier.publisher_prefix || "CSA")
78
98
  end
79
99
 
80
- code_part = identifier.code.to_s if identifier.code
100
+ code_part = identifier.number.to_s if identifier.number
81
101
 
82
102
  # NO. keyword
83
103
  if identifier.no_number
@@ -92,34 +112,42 @@ module Pubid
92
112
  code_part += " SERIES"
93
113
  end
94
114
 
95
- # Year with proper format (colon or dash)
96
- if identifier.year
97
- separator = identifier.year_format == "dash" ? "-" : ":"
98
- year_part = separator
99
- year_part += identifier.year_prefix if identifier.year_prefix # Add M or F prefix
100
- year_part += "F" if identifier.french && identifier.year_format != "dash" && !identifier.year_prefix # Only add F if no prefix
101
- # Convert 4-digit year back to 2-digit
102
- year_str = identifier.year.to_s
103
- year_part += if year_str.length == 4 && year_str.start_with?("20")
104
- year_str[2..3]
105
- else
106
- year_str
107
- end
108
- code_part += year_part
109
- end
115
+ code_part += render_continuation_year(identifier) if identifier.year
110
116
 
111
117
  parts << code_part if code_part
112
118
 
113
- # Join with proper spacing based on prefix
114
- if identifier.has_publisher && parts.length > 1
115
- prefix = parts[0]
116
- needs_space = !prefix.end_with?("-")
117
- if needs_space
118
- parts.join(" ")
119
- else
120
- # No space after dash-ending prefix
121
- parts[0] + parts[1..].join(" ")
122
- end
119
+ join_continuation(identifier, parts)
120
+ end
121
+
122
+ # Year with proper format (colon or dash)
123
+ def render_continuation_year(identifier)
124
+ separator = identifier.year_format == "dash" ? "-" : ":"
125
+ year_part = separator
126
+ # Add M or F prefix
127
+ year_part += identifier.year_prefix if identifier.year_prefix
128
+ # Only add F if no prefix
129
+ if identifier.french && identifier.year_format != "dash" &&
130
+ !identifier.year_prefix
131
+ year_part += "F"
132
+ end
133
+ # Convert 4-digit year back to 2-digit
134
+ year_str = identifier.year.to_s
135
+ year_part + if year_str.length == 4 && year_str.start_with?("20")
136
+ year_str[2..3]
137
+ else
138
+ year_str
139
+ end
140
+ end
141
+
142
+ # Join with proper spacing based on prefix
143
+ def join_continuation(identifier, parts)
144
+ return parts.join(" ") unless identifier.has_publisher &&
145
+ parts.length > 1
146
+
147
+ prefix = parts[0]
148
+ if prefix.end_with?("-")
149
+ # No space after dash-ending prefix
150
+ prefix + parts[1..].join(" ")
123
151
  else
124
152
  parts.join(" ")
125
153
  end
@@ -18,16 +18,16 @@ module Pubid
18
18
  #
19
19
  # This is a wrapper pattern where:
20
20
  # - CSA prefix indicates adoption
21
- # - The wrapped_identifier is the external standard (ISO/IEC/CISPR)
21
+ # - The base is the external standard (ISO/IEC/CISPR)
22
22
  # - Wrapped identifier is recursively parsed using external flavor parsers
23
23
  class CsaAdopted < WrapperIdentifier
24
24
  # Publisher prefix (e.g., "CSA-", "CAN3-") for rendering
25
25
  # When set, uses dash format without space (e.g., "CSA-ISO" not "CSA ISO")
26
26
  attribute :publisher_prefix, :string
27
27
 
28
- def to_s
28
+ def to_s(**opts)
29
29
  # Get string representation from wrapped identifier
30
- base_str = wrapped_identifier.to_s
30
+ base_str = base.to_s
31
31
 
32
32
  # Convert 4-digit years to 2-digit for CSA adoption format
33
33
  # ISO/IEC TR 12785-3:2015 → ISO/IEC TR 12785-3:15
@@ -70,7 +70,7 @@ module Pubid
70
70
  # Append reaffirmation if present
71
71
  result += " (R#{reaffirmation})" if reaffirmation
72
72
 
73
- result
73
+ annotate_plain_render(result, **opts)
74
74
  end
75
75
  end
76
76
  end
@@ -12,7 +12,7 @@ module Pubid
12
12
  # CSA C22.2 NO. 60601-1:15 PACKAGE WITH ADDENDUM
13
13
  #
14
14
  # This is a composite pattern where:
15
- # - base_identifier is the core CSA standard (recursively parsed)
15
+ # - base is the core CSA standard (recursively parsed)
16
16
  # - package_materials describes what's included in the package
17
17
  # - Package portion is metadata, not a parseable identifier
18
18
  #
@@ -33,8 +33,8 @@ module Pubid
33
33
  # false = materials BEFORE: "CSA B149.1:25 Code, Handbook & Training Package"
34
34
  attribute :materials_after_keyword, :boolean, default: -> { true }
35
35
 
36
- def to_s
37
- result = base_identifier.to_s
36
+ def to_s(**opts)
37
+ result = base.to_s
38
38
 
39
39
  # Add package materials if present
40
40
  if package_materials && !package_materials.empty?
@@ -57,7 +57,7 @@ module Pubid
57
57
  result += " PACKAGE"
58
58
  end
59
59
 
60
- result
60
+ annotate_plain_render(result, **opts)
61
61
  end
62
62
  end
63
63
  end
@@ -4,7 +4,7 @@ require "parslet"
4
4
 
5
5
  module Pubid
6
6
  module Csa
7
- class Parser < Parslet::Parser
7
+ class Parser < ::Pubid::Parser::Grammar
8
8
  # Basic building blocks
9
9
  rule(:space) { str(" ") }
10
10
  rule(:dash) { str("-") }
@@ -179,7 +179,7 @@ module Pubid
179
179
  # Optional series prefix (MH, RV, etc.) before SERIES keyword
180
180
  (series_prefix >> space).maybe >>
181
181
  series_keyword.as(:series_type) >>
182
- (colon_year | dash_year) >>
182
+ (colon_year | dash_year).maybe >>
183
183
  reaffirmation.maybe
184
184
  end
185
185
 
@@ -194,7 +194,7 @@ module Pubid
194
194
  ).as(:cec_part) >>
195
195
  no_notation >>
196
196
  no_number >>
197
- (colon_year | dash_year) >>
197
+ (colon_year | dash_year).maybe >>
198
198
  reaffirmation.maybe
199
199
  end
200
200
 
@@ -257,7 +257,7 @@ module Pubid
257
257
  (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
258
258
  # Option 4: just year (no series, no NO.)
259
259
  (colon_year | dash_year)
260
- ) >>
260
+ ).maybe >> # trailing year optional (partial reference)
261
261
  amendment_slash.maybe # Add amendment support here
262
262
  end
263
263
 
@@ -274,7 +274,7 @@ module Pubid
274
274
  (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
275
275
  # Option 4: just year
276
276
  (colon_year | dash_year)
277
- )
277
+ ).maybe # trailing year optional (partial reference)
278
278
  end
279
279
 
280
280
  # Continuation code (optional CSA publisher prefix, for combined identifiers)
@@ -290,7 +290,7 @@ module Pubid
290
290
  (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
291
291
  # Option 4: just year
292
292
  (colon_year | dash_year)
293
- ) >>
293
+ ).maybe >> # trailing year optional (partial reference)
294
294
  amendment_slash.maybe
295
295
  end
296
296
 
@@ -353,7 +353,7 @@ module Pubid
353
353
  (space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
354
354
  # Option 3: just year
355
355
  (colon_year | dash_year)
356
- ) >>
356
+ ).maybe >> # trailing year optional (partial reference)
357
357
  (space >> str("PACKAGE")).as(:package_portion).maybe
358
358
  end
359
359
 
@@ -367,7 +367,11 @@ module Pubid
367
367
  # Preprocessing to normalize input
368
368
  def parse(input)
369
369
  # Skip comment lines
370
- raise Parslet::ParseFailed.new("Comment line") if input.strip.start_with?("#")
370
+ if input.strip.start_with?("#")
371
+ raise Pubid::Errors::ParseError.new(
372
+ "Comment line", input: input, flavor: "csa"
373
+ )
374
+ end
371
375
 
372
376
  # Remove CONSOLIDATED notation FIRST (before other processing)
373
377
  normalized = input.gsub(/\s*\(\s*CONSOLIDATED\s*\)\s*/, " ")
@@ -35,7 +35,7 @@ module Pubid
35
35
 
36
36
  # Base rendering: "CSA B149.1:20", "CAN/CSA-C22.2-05"
37
37
  def render_base(id)
38
- prefix = id.publisher_prefix || "CSA"
38
+ prefix = publisher_prefix_for(id)
39
39
 
40
40
  # Handle code_only identifiers (empty string means no prefix)
41
41
  if prefix == ""
@@ -51,7 +51,7 @@ module Pubid
51
51
  end
52
52
 
53
53
  # Code and year together
54
- code_part = id.code.to_s if id.code
54
+ code_part = id.number.to_s if id.number
55
55
 
56
56
  # NO. keyword
57
57
  if id.no_number
@@ -131,7 +131,7 @@ module Pubid
131
131
  parts = []
132
132
 
133
133
  # Publisher prefix (CSA, CAN/CSA-, CAN3-)
134
- prefix = id.publisher_prefix || "CSA"
134
+ prefix = publisher_prefix_for(id)
135
135
 
136
136
  # Determine if we need space after prefix
137
137
  # CAN/CSA- and CAN3- end with dash, so no space needed
@@ -203,7 +203,7 @@ module Pubid
203
203
  result = series_publisher_prefix_portion(id)
204
204
 
205
205
  # Add code FIRST (before SERIES keyword)
206
- result += id.code.to_s
206
+ result += id.number.to_s
207
207
 
208
208
  # Add space before series prefix/SERIES keyword
209
209
  result += " "
@@ -255,8 +255,16 @@ module Pubid
255
255
  end
256
256
  end
257
257
 
258
+ # The publisher prefix to print. A code_only identifier printed none, so
259
+ # it must not gain the default "CSA" — see SingleIdentifier#code_only.
260
+ def publisher_prefix_for(id)
261
+ return "" if id.respond_to?(:code_only) && id.code_only
262
+
263
+ id.publisher_prefix || "CSA"
264
+ end
265
+
258
266
  def series_publisher_prefix_portion(id)
259
- prefix = id.publisher_prefix || "CSA"
267
+ prefix = publisher_prefix_for(id)
260
268
 
261
269
  # Handle code_only identifiers (empty string means no prefix)
262
270
  return "" if prefix == ""
@@ -3,11 +3,18 @@
3
3
  module Pubid
4
4
  module Csa
5
5
  class SingleIdentifier < Identifier
6
- # Generate URN for this identifier
6
+ # The document code — "B149.1", "Z240", "C22.2" — and the relaton index
7
+ # key: Relaton::Index sorts and bsearches every row on
8
+ # `id.root.number.to_s`, so it must never be empty.
7
9
  #
8
- # @return [String] URN representation
9
-
10
- attribute :code, Components::Code
10
+ # It is the `number` INHERITED from ::Pubid::Identifier, not a
11
+ # redeclaration: Pubid::Csa::Components::Code is a bare alias of
12
+ # Pubid::Components::Code, which is exactly the parent's declared type.
13
+ # That matters. CSA's base is split across two files (csa/identifier.rb +
14
+ # csa/single_identifier.rb) — the IEEE shape in which a leaf can snapshot
15
+ # a half-built parent attribute table (CLAUDE.md, the `number`
16
+ # determinism landmine). Declaring nothing here keeps CSA clear of it.
17
+ # The attribute was named `code` before; there is no alias.
11
18
  attribute :no_number, :string
12
19
  attribute :year, :string
13
20
  attribute :year_format, :string # "colon" or "dash"
@@ -25,6 +32,88 @@ module Pubid
25
32
  attribute :series, :boolean # Track if SERIES keyword present
26
33
  attribute :package, :string # Package portion (Code, Handbook, etc.)
27
34
  attribute :publisher_prefix, :string # Original prefix: "CAN/CSA-", "CSA", "CAN3-"
35
+
36
+ # True when the reference printed no publisher at all ("C22.1-15"), so
37
+ # rendering must not supply the default "CSA".
38
+ #
39
+ # This used to be an empty-string `publisher_prefix` sentinel, which the
40
+ # canonical `to_hash` drops (it strips empty and default-valued
41
+ # attributes by design) — so a code-only identifier came back
42
+ # from `from_hash` with a nil prefix and re-rendered as
43
+ # "CSA C22.1-15". Named for the RARE case with a `false` default,
44
+ # per CLAUDE.md, so it is dropped from every ordinary row.
45
+ attribute :code_only, :boolean, default: -> { false }
46
+
47
+ # A flat, index-friendly serialized shape: the `Components::Code`
48
+ # attributes collapse to bare scalars (`number: C22.2-286`, not
49
+ # `number: {value: C22.2-286}`), the ISO/ETSI/ITU `key_value` pattern.
50
+ #
51
+ # This is deliberately a serialization mapping rather than an
52
+ # `attribute :number, :string` redeclaration. CSA's base is split across
53
+ # two files (csa/identifier.rb + csa/single_identifier.rb) — the IEEE
54
+ # shape in which a leaf can snapshot a half-built parent attribute table
55
+ # — so a retype here would reintroduce the `number` determinism landmine
56
+ # recorded in CLAUDE.md. The runtime attribute stays a Components::Code;
57
+ # only the hash is flat.
58
+ #
59
+ # A lutaml key_value block is EXHAUSTIVE — an unmapped attribute is
60
+ # dropped, `_type` included — so every attribute above appears here. It
61
+ # lives on SingleIdentifier, which only the single-document types
62
+ # inherit; the container types descend from Csa::Identifier directly and
63
+ # keep the default shape for their nested `base`/`identifiers`.
64
+ key_value do
65
+ map "_type", to: :_type
66
+ map "number", with: { to: :number_to_kv, from: :number_from_kv }
67
+ map "no_number",
68
+ with: { to: :no_number_to_kv, from: :no_number_from_kv }
69
+ map "year", to: :year
70
+ map "year_format", to: :year_format
71
+ map "year_prefix", to: :year_prefix
72
+ map "original_year_4digit", to: :original_year_4digit
73
+ map "french", to: :french
74
+ map "reaffirmation", to: :reaffirmation
75
+ map "original_reaffirmation_4digit", to: :original_reaffirmation_4digit
76
+ map "has_publisher", to: :has_publisher
77
+ map "series_prefix", to: :series_prefix
78
+ map "series", to: :series
79
+ map "package", to: :package
80
+ map "publisher_prefix", to: :publisher_prefix
81
+ map "code_only", to: :code_only
82
+ end
83
+
84
+ def number_to_kv(model, doc)
85
+ emit_kv(doc, "number", model.number)
86
+ end
87
+
88
+ def number_from_kv(model, value)
89
+ model.number = Components::Code.new(value: value.to_s)
90
+ end
91
+
92
+ # `no_number` is a plain :string here but a Components::Code on Cec, so
93
+ # the converter reads through whichever it is given.
94
+ def no_number_to_kv(model, doc)
95
+ emit_kv(doc, "no_number", model.no_number)
96
+ end
97
+
98
+ def no_number_from_kv(model, value)
99
+ model.no_number =
100
+ if model.class.attributes[:no_number].type == Components::Code
101
+ Components::Code.new(value: value.to_s)
102
+ else
103
+ value.to_s
104
+ end
105
+ end
106
+
107
+ # Emit a scalar, skipping a nil or empty value so the canonical
108
+ # no-defaults hash never gains an empty key.
109
+ def emit_kv(doc, key, value)
110
+ text = value.respond_to?(:value) ? value.value : value
111
+ return if text.nil? || text.to_s.empty?
112
+
113
+ doc.add_child(
114
+ Lutaml::KeyValue::DataModel::Element.new(key, text.to_s),
115
+ )
116
+ end
28
117
  end
29
118
  end
30
119
  end
@@ -3,16 +3,23 @@
3
3
  module Pubid
4
4
  module Csa
5
5
  class UrnGenerator < Pubid::UrnGenerator::Base
6
+ # A code_only identifier printed no publisher, so it keeps an empty
7
+ # publisher segment rather than falling back to "csa" in #generate.
6
8
  def urn_publisher_prefix
9
+ return "" if code_only?
7
10
  return nil unless identifier.publisher_prefix
8
11
 
9
12
  identifier.publisher_prefix.to_s.downcase
10
13
  end
11
14
 
15
+ def code_only?
16
+ identifier.respond_to?(:code_only) && identifier.code_only
17
+ end
18
+
12
19
  def urn_number
13
- return nil unless identifier.code
20
+ return nil unless identifier.number
14
21
 
15
- identifier.code.render(context: URN_CONTEXT)
22
+ identifier.number.render(context: URN_CONTEXT)
16
23
  end
17
24
 
18
25
  def urn_no_number
@@ -4,28 +4,61 @@ require "lutaml/model"
4
4
 
5
5
  module Pubid
6
6
  module Csa
7
- # WrapperIdentifier is the base class for all CSA identifiers that wrap other identifiers
7
+ # WrapperIdentifier is the base class for all CSA identifiers that wrap
8
+ # other identifiers.
8
9
  # Examples:
9
- # - CanadianAdoptedIdentifier: CAN/{wrapped_identifier}
10
- # - CsaAdoptedIdentifier: CSA {ISO/IEC/CISPR identifier}
10
+ # - CanadianAdopted: CAN/{base}
11
+ # - CsaAdopted: CSA {ISO/IEC/CISPR identifier}
11
12
  #
12
- # The wrapper pattern allows proper MODEL-DRIVEN architecture where adoptions
13
- # are objects that contain other identifier objects, not string prefixes.
14
- class WrapperIdentifier < Lutaml::Model::Serializable
15
- # The wrapped identifier (recursively parsed)
16
- # Use attr_accessor since it can be any identifier object (CSA, ISO, IEC, etc.)
17
- attr_accessor :wrapped_identifier
13
+ # The wrapper pattern allows proper MODEL-DRIVEN architecture where
14
+ # adoptions are objects that contain other identifier objects, not string
15
+ # prefixes.
16
+ class WrapperIdentifier < Identifier
17
+ # The wrapped identifier (recursively parsed).
18
+ #
19
+ # A real lutaml attribute, not an attr_accessor: the accessor was
20
+ # invisible to `to_hash`, `from_hash` AND `#exclude` (which iterates
21
+ # `self.class.attributes`), so a wrapper serialized to a hash with no
22
+ # identifier in it at all. It is named `base` — the uniform parent
23
+ # accessor every flavor uses — so the inherited `#root` walks it to the
24
+ # origin document and `exclude_from_nested` reaches inside. There is no
25
+ # `wrapped_identifier` alias.
26
+ #
27
+ # Typed as the cross-flavor `::Pubid::Identifier`, not the CSA one:
28
+ # CsaAdopted wraps ISO/IEC/CISPR ids, and lutaml enforces the declared
29
+ # type — `polymorphic: true` widens it only to SUBCLASSES, so a narrower
30
+ # type raises Lutaml::Model::IncorrectModelError on `to_hash`. The
31
+ # Ieee::Identifiers::AdoptedStandard precedent. The nested child carries
32
+ # its own `_type`, so `from_hash` routes it back via TypeResolver.
33
+ attribute :base, ::Pubid::Identifier, polymorphic: true
18
34
 
19
35
  # Reaffirmation year (common across wrappers)
20
36
  attribute :reaffirmation, :string
21
37
 
38
+ # Whether the reaffirmation was printed 4-digit ("(R2004)") rather than
39
+ # 2-digit ("(R04)"). CanadianAdopted#to_s reads it to choose the spacing
40
+ # and to render the year back in its original width.
41
+ attribute :original_reaffirmation_4digit, :boolean, default: -> { false }
42
+
22
43
  # Year format tracking (for compatibility)
23
44
  attribute :year_format, :string
24
45
 
25
46
  # Subclasses MUST implement to_s
26
- def to_s
47
+ def to_s(**_opts)
27
48
  raise NotImplementedError, "Subclasses must implement to_s method"
28
49
  end
50
+
51
+ # The matching primitives relaton uses to normalise a reference before
52
+ # comparing it. An adoption wrapper peels to the document it adopts;
53
+ # without these the inherited defaults return the WRAPPER, which is a
54
+ # silently wrong answer rather than a loud one.
55
+ def base_document
56
+ base ? base.base_document : self
57
+ end
58
+
59
+ def drop_supplements
60
+ base || self
61
+ end
29
62
  end
30
63
  end
31
64
  end
data/lib/pubid/csa.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Csa
5
6
  extend Pubid::PrefixesSupport
@@ -20,8 +21,13 @@ module Pubid
20
21
  autoload :Components, "#{__dir__}/csa/components"
21
22
 
22
23
  def self.parse(identifier_string)
24
+ unless identifier_string.is_a?(String)
25
+ raise Pubid::Errors::InvalidInputError,
26
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
27
+ end
28
+
23
29
  if identifier_string.length > Pubid::MAX_INPUT_LENGTH
24
- raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
30
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
25
31
  end
26
32
 
27
33
  Identifier.parse(identifier_string)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Doi
5
+ class Builder
6
+ def self.build(parsed_data)
7
+ new.build(parsed_data)
8
+ end
9
+
10
+ def build(data)
11
+ Identifiers::Resource.new(
12
+ prefix: "10.#{data[:prefix]}",
13
+ suffix: data[:suffix].to_s,
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end