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
@@ -35,11 +35,11 @@ module Pubid
35
35
 
36
36
  # Delegate base identifier attributes for easier access
37
37
  def copublishers
38
- base_identifier&.copublishers
38
+ base&.copublishers
39
39
  end
40
40
 
41
41
  def publisher
42
- base_identifier&.publisher
42
+ base&.publisher
43
43
  end
44
44
 
45
45
  TYPED_STAGES = [
@@ -61,19 +61,19 @@ module Pubid
61
61
  # def render_directives_supplement_identifier(identifier)
62
62
  # raise "Not a directives supplement identifier" unless identifier.is_a?(Identifiers::DirectivesSupplement)
63
63
 
64
- # render(identifier.base_identifier) +
64
+ # render(identifier.base) +
65
65
  # " #{identifier.publisher.body}" +
66
66
  # " #{identifier.stage.abbr}" +
67
67
  # (identifier.date ? ":#{identifier.date.year}" : "")
68
68
  # end
69
69
 
70
70
  def to_s(lang: :en, lang_single: false, with_edition: false,
71
- format: nil, stage_format_long: nil, with_date: nil)
72
- if base_identifier
71
+ format: nil, stage_format_long: nil, with_date: nil, **opts)
72
+ if base
73
73
  # Full rendering with base identifier
74
74
  [
75
- base_identifier.to_s(lang: lang, lang_single: lang_single,
76
- with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date),
75
+ base.to_s(lang: lang, lang_single: lang_single,
76
+ with_edition: with_edition, format: format, stage_format_long: stage_format_long, with_date: with_date, **opts),
77
77
  " #{supplement_publisher.render}",
78
78
  " SUP", # Always render as "SUP" even though typed_stage.abbreviation is "DIR SUP"
79
79
  (date ? ":#{date.render}" : ""),
@@ -81,13 +81,13 @@ format: nil, stage_format_long: nil, with_date: nil)
81
81
  ].join
82
82
  else
83
83
  # Simplified rendering for bundled identifiers (just the supplement part)
84
- to_supplement_s(lang: lang, lang_single: lang_single)
84
+ to_supplement_s(lang: lang, lang_single: lang_single, **opts)
85
85
  end
86
86
  end
87
87
 
88
88
  # Render just the supplement part (for use in bundled identifiers)
89
89
  def to_supplement_s(lang: :en, lang_single: false, with_edition: false,
90
- format: nil, stage_format_long: nil, with_date: nil)
90
+ format: nil, stage_format_long: nil, with_date: nil, **_opts)
91
91
  date_str = if date
92
92
  month_part = date.month ? "-#{date.month}" : ""
93
93
  ":#{date.render}#{month_part}"
@@ -107,8 +107,8 @@ format: nil, stage_format_long: nil, with_date: nil)
107
107
  def to_urn
108
108
  urn_ctx = Rendering::RenderingContext.urn
109
109
 
110
- # If this is a standalone supplement (no base_identifier), build URN directly
111
- unless base_identifier
110
+ # If this is a standalone supplement (no base), build URN directly
111
+ unless base
112
112
  parts = ["urn", "iso", "doc"]
113
113
  parts << supplement_publisher.render(context: urn_ctx) if supplement_publisher
114
114
  parts << "sup"
@@ -118,7 +118,7 @@ format: nil, stage_format_long: nil, with_date: nil)
118
118
  end
119
119
 
120
120
  # Start with base identifier's URN parts (it will use urn:iso:doc scheme)
121
- base_urn = base_identifier.to_urn
121
+ base_urn = base.to_urn
122
122
 
123
123
  # Handle JTC pattern specially
124
124
  if supplement_publisher&.body&.match?(/^JTC\s+(\d+)$/i)
@@ -69,10 +69,10 @@ module Pubid
69
69
  supplement_year = match[4] # "1987" or nil
70
70
 
71
71
  base_parsed = Pubid::Iso.parser.parse(base_str)
72
- base_identifier = Pubid::Iso.builder.build(base_parsed)
72
+ base = Pubid::Iso.builder.build(base_parsed)
73
73
 
74
74
  addendum = Identifiers::Addendum.new
75
- addendum.base_identifier = base_identifier
75
+ addendum.base = base
76
76
  addendum.number = Iso::Components::Code.new(value: supplement_number)
77
77
  addendum.date = Pubid::Components::Date.new(year: supplement_year) if supplement_year
78
78
 
@@ -3,7 +3,7 @@ require "parslet"
3
3
 
4
4
  module Pubid
5
5
  module Iso
6
- class Parser < Parslet::Parser
6
+ class Parser < ::Pubid::Parser::Grammar
7
7
  include ::Pubid::Parser::CommonParseRules
8
8
  include ::Pubid::Parser::CommonParseMethods
9
9
 
@@ -99,7 +99,7 @@ module Pubid
99
99
  rule(:iso_r_supplement_identifier) do
100
100
  (
101
101
  str("ISO/R").as(:iso_r_prefix) >> space >> iso_r_second_part
102
- ).as(:base_identifier) >>
102
+ ).as(:base) >>
103
103
  iso_r_supplement_separator >>
104
104
  supplement_type_with_stage >>
105
105
  space? >> second_part >> third_part
@@ -148,12 +148,16 @@ module Pubid
148
148
  end
149
149
 
150
150
  rule(:date) do
151
- # :2005-02
151
+ # :2005-02 or :-- (undated reference — ISO/IEC undated-reference form,
152
+ # e.g. ISO 16634:--, also accepted as the em-dash variant ISO 16634:—)
152
153
  (str(":") | dash) >>
153
- (year_digits >>
154
- (dash >> month_digits).maybe >>
155
- (dash >> day_digits).maybe
156
- ).as(:date).maybe
154
+ (
155
+ (str("--") | str("—")).as(:undated_marker) |
156
+ (year_digits >>
157
+ (dash >> month_digits).maybe >>
158
+ (dash >> day_digits).maybe
159
+ ).as(:date)
160
+ ).maybe
157
161
  end
158
162
 
159
163
  rule(:part_and_subpart) do
@@ -270,14 +274,14 @@ module Pubid
270
274
  end
271
275
 
272
276
  # For joint identifiers, we do not treat it as a supplementary identifier
273
- # (hence not a base_identifier)
277
+ # (hence not a base)
274
278
  # ISO only supports IDF in joint identifiers
275
279
  # ISO 5537|IDF 26
276
280
  # ISO 17678|IDF 202:2010
277
281
  # ISO/TS 4985:2023 | IDF/RM 255
278
282
  # ISO 4214:2022 | IDF 254:2022
279
283
  rule(:joint_identifier) do
280
- identifier_copublishers_no_third.as(:base_identifier) >>
284
+ identifier_copublishers_no_third.as(:base) >>
281
285
  space? >> str("|") >> space? >>
282
286
  scope { idf_identifier }.as(:joint_identifier)
283
287
  end
@@ -336,7 +340,7 @@ module Pubid
336
340
  # ISO 8601-1:2019/Amd 2:2024
337
341
  # ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
338
342
  rule(:supplement_identifier_no_third) do
339
- identifier_copublishers_no_third.as(:base_identifier) >>
343
+ identifier_copublishers_no_third.as(:base) >>
340
344
  str("/") >> supplement_type_with_stage >>
341
345
  # The trailing number/date is optional: some draft supplements have no
342
346
  # number yet, e.g. "ISO/IEC 9579/WD Amd".
@@ -351,14 +355,14 @@ module Pubid
351
355
  # ISO/IEC 19794-7:2014/Amd 1:2015/CD Cor 1
352
356
  # ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
353
357
  rule(:supplement_supplement_identifier) do
354
- supplement_identifier_no_third.as(:base_identifier) >>
358
+ supplement_identifier_no_third.as(:base) >>
355
359
  str("/") >> supplement_type_with_stage >>
356
360
  ((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
357
361
  end
358
362
 
359
363
  # ISO 12345:2020/Amd 1:2021/Cor 1:2022/Amd 2:2023 (three-level supplement)
360
364
  rule(:supplement_supplement_supplement_identifier) do
361
- supplement_supplement_identifier.as(:base_identifier) >>
365
+ supplement_supplement_identifier.as(:base) >>
362
366
  str("/") >> supplement_type_with_stage >>
363
367
  ((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
364
368
  end
@@ -408,7 +412,7 @@ module Pubid
408
412
  end
409
413
 
410
414
  rule(:directives_supplement_identifier) do
411
- directives_identifier_no_third.as(:base_identifier) >> space? >> directives_supplement_part
415
+ directives_identifier_no_third.as(:base) >> space? >> directives_supplement_part
412
416
  end
413
417
 
414
418
  DIRECTIVES_SUPPLEMENTS_TYPED_STAGES = Identifiers::DirectivesSupplement::TYPED_STAGES.map(&:abbr).flatten.sort_by(&:length).reverse
@@ -3,13 +3,13 @@
3
3
  module Pubid
4
4
  module Iso
5
5
  class SupplementIdentifier < SingleIdentifier
6
- attribute :base_identifier, Identifier,
6
+ attribute :base, Identifier,
7
7
  polymorphic: true
8
8
 
9
9
  key_value do
10
10
  # Serialized key is "base" (matches JIS); the attribute/method stays
11
- # `base_identifier`, which relaton-index's get_id_number depends on.
12
- map "base", to: :base_identifier, polymorphic: {
11
+ # `base`, which relaton-index's get_id_number depends on.
12
+ map "base", to: :base, polymorphic: {
13
13
  attribute: "_type",
14
14
  class_map: Identifier::ISO_TYPE_MAP,
15
15
  }
@@ -20,14 +20,14 @@ module Pubid
20
20
  # nested supplement (e.g. ".../Amd 1/Cor 1") reads identity from the
21
21
  # underlying standard in one hop, regardless of chain depth. This keeps a
22
22
  # parsed supplement and a from_hash-deserialized one in agreement (== and
23
- # index matching compare both). Guard on base_identifier: `root` returns
23
+ # index matching compare both). Guard on base: `root` returns
24
24
  # self when there is no base, which would otherwise recurse forever.
25
25
  def publisher
26
- root.publisher if base_identifier
26
+ root.publisher if base
27
27
  end
28
28
 
29
29
  def copublishers
30
- root.copublishers if base_identifier
30
+ root.copublishers if base
31
31
  end
32
32
 
33
33
  def to_s(**opts)
@@ -35,6 +35,19 @@ module Pubid
35
35
  Pubid::Renderers::SupplementRenderer.new(self).render(context:,
36
36
  **opts.slice(:with_edition))
37
37
  end
38
+
39
+ # MR supplement suffix: `/{type}.{number}.{year}` (e.g. "/amd.1.2020").
40
+ # The MrString renderer recurses into `base` and appends this so the
41
+ # full supplement chain round-trips losslessly (issue #142).
42
+ def mr_supplement_suffix
43
+ segments = []
44
+ segments << mr_type if mr_type
45
+ segments << number&.to_s if number
46
+ segments << date&.year&.to_s if date&.year
47
+ return nil if segments.empty?
48
+
49
+ segments.join(".")
50
+ end
38
51
  end
39
52
  end
40
53
  end
@@ -84,7 +84,7 @@ module Pubid
84
84
 
85
85
  while current.is_a?(SupplementIdentifier)
86
86
  supplement_chain.unshift(current)
87
- current = current.base_identifier
87
+ current = current.base
88
88
  end
89
89
 
90
90
  base_id = current
@@ -258,6 +258,9 @@ module Pubid
258
258
 
259
259
  def year_component
260
260
  return nil unless identifier.date&.present?
261
+ # Undated references (e.g. ISO 16634:--) drop the year slot in the URN,
262
+ # matching the date-less identifier's URN form (per issue #138).
263
+ return nil if identifier.date&.undated?
261
264
  return nil if identifier.is_a?(Pubid::Iso::SingleIdentifier)
262
265
 
263
266
  identifier.date.render(context: URN_CONTEXT)
@@ -425,7 +425,7 @@ typed_stage
425
425
 
426
426
  # Wrap current identifier with supplement
427
427
  base_hash = {
428
- base_identifier: base_hash,
428
+ base: base_hash,
429
429
  **supp_hash,
430
430
  }
431
431
  end
data/lib/pubid/iso.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  require "lutaml/model"
4
5
 
5
6
  module Pubid
@@ -31,8 +32,13 @@ module Pubid
31
32
  # @param format [Symbol] :auto, :human, :mr_string, or :urn
32
33
  # @return [Identifier] the parsed identifier
33
34
  def self.parse(identifier, format: :auto)
35
+ unless identifier.is_a?(String)
36
+ raise Pubid::Errors::InvalidInputError,
37
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
38
+ end
39
+
34
40
  if identifier.length > Pubid::MAX_INPUT_LENGTH
35
- raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
41
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
36
42
  end
37
43
 
38
44
  format = Pubid::FormatDetector.detect(identifier) if format == :auto
@@ -13,15 +13,59 @@ module Pubid
13
13
  return build_annex(data[:annex_to])
14
14
  end
15
15
 
16
+ # Common-text twin ("| ISO/IEC ..." suffix) — extract before building
17
+ # the base ITU identifier, then attach to whichever class the base
18
+ # resolves to.
19
+ twin = parse_common_text_twin(data.delete(:common_text_twin))
20
+
21
+ # Labelled annex of a Recommendation — "ITU-T A.23 Annex A (06/2014)".
22
+ # The annexed document is the :base subtree; :year/:month at this level
23
+ # are the annex's own date, not the base's.
24
+ if data[:annex_number]
25
+ annex = build_annex_of_recommendation(data)
26
+ annex.common_text_twin = twin if twin
27
+ return annex
28
+ end
29
+
30
+ # Labelled appendix of a Recommendation — "ITU-T G.101 App. I
31
+ # (05/2000)". Same shape as the annex above.
32
+ if data[:appendix_number]
33
+ appendix = build_appendix_of_recommendation(data)
34
+ appendix.common_text_twin = twin if twin
35
+ return appendix
36
+ end
37
+
16
38
  # Operational Bulletin (Special Publication) — series == "OB" or
17
39
  # legacy long form ("Operational Bulletin No. ...").
18
- if data[:series].to_s == "OB" || data[:_op_bull]
19
- return build_special_publication(data)
40
+ # The series_dash guard keeps a series-code "ITU-T OB-1" out of this
41
+ # branch, which would drop the dash and render it "ITU OB No. 1".
42
+ # Belt-and-braces: `series_code_body` already refuses "OB" + dash, so
43
+ # nothing reaches here with both set — the guard documents that coupling
44
+ # so removing the parser's `absent?` fails loudly rather than silently
45
+ # rerouting.
46
+ if (data[:series].to_s == "OB" && data[:series_dash].nil?) ||
47
+ data[:_op_bull]
48
+ sp = build_special_publication(data)
49
+ sp.common_text_twin = twin if twin && sp
50
+ return sp
20
51
  end
21
52
 
22
53
  # Check if this is a supplement identifier
23
54
  if data[:supplement_type]
24
- return build_supplement(data)
55
+ supp = build_supplement(data)
56
+ supp.common_text_twin = twin if twin && supp
57
+ return supp
58
+ end
59
+
60
+ # Handbook — "ITU-R 42.HDB"
61
+ if data[:handbook_marker]
62
+ return build_handbook(data)
63
+ end
64
+
65
+ # Question — numeric ("ITU-R 234-1/7:") or letter-series
66
+ # ("ITU-R P.3/BL/7"). Both carry a :study_group marker.
67
+ if data[:study_group]
68
+ return build_question(data)
25
69
  end
26
70
 
27
71
  # Build basic recommendation or combined identifier
@@ -30,44 +74,77 @@ module Pubid
30
74
  code = build_code(data) if data[:number]
31
75
  date = build_date(data) if data[:year]
32
76
 
33
- # Check if this is a combined identifier (has combined_series and combined_number)
34
- if data[:combined_series] || data[:combined_number]
35
- if data[:combined_series]
36
- combined_series = Components::Series.new(
37
- series: data[:combined_series][:series].to_s,
38
- )
39
- end
40
-
41
- if data[:combined_number]
42
- combined_code = Components::Code.new(
43
- number: data[:combined_number].to_s,
44
- subseries: data[:combined_subseries]&.to_s,
45
- parts: extract_parts(data[:combined_parts]),
46
- )
47
- end
48
-
77
+ # Combined (joint) recommendation — one or more additional
78
+ # "/SERIES.CODE" designations after the primary (e.g. "G.780/Y.1351",
79
+ # "G.780/Y.1351/Z.1362"). The primary stays on the base series/code.
80
+ if data[:combined]
49
81
  return Identifiers::CombinedIdentifier.new(
50
82
  sector: sector,
51
83
  series: series,
52
84
  code: code,
53
- combined_series: combined_series,
54
- combined_code: combined_code,
85
+ combined: build_designations(data[:combined]),
55
86
  date: date,
87
+ version: data[:version]&.to_s,
88
+ # with_series offers these slots on either side of
89
+ # combined_suffixes, so a joint id can carry them too; not
90
+ # forwarding them let "ITU-T H.350/X.1 attachment" compare equal to
91
+ # the un-attached document.
92
+ series_word: !data[:series_word].nil?,
93
+ series_dash: !data[:series_dash].nil?,
94
+ attachment: !data[:attachment].nil?,
95
+ range_end: data[:range_end]&.to_s,
56
96
  language: data[:language]&.to_s,
97
+ common_text_twin: twin,
57
98
  )
58
99
  end
59
100
 
60
- Identifiers::Recommendation.new(
101
+ # A Report ("Report ITU-R BT.2020-1") is shaped exactly like a
102
+ # Recommendation — only the leading word, captured as :report_marker,
103
+ # tells the two apart, and it has to, because the two series number
104
+ # independently and the same series/number is two real documents.
105
+ klass = data[:report_marker] ? Identifiers::Report : Identifiers::Recommendation
106
+
107
+ klass.new(
61
108
  sector: sector,
62
109
  series: series,
63
110
  code: code,
64
111
  date: date,
112
+ version: data[:version]&.to_s,
113
+ series_word: !data[:series_word].nil?,
114
+ series_dash: !data[:series_dash].nil?,
115
+ attachment: !data[:attachment].nil?,
116
+ range_end: data[:range_end]&.to_s,
65
117
  language: data[:language]&.to_s,
118
+ common_text_twin: twin,
66
119
  )
67
120
  end
68
121
 
122
+ # Parse the common-text twin string ("| ISO/IEC 13818-1:2022") into
123
+ # the appropriate flavor's identifier object. Returns nil if the twin
124
+ # is empty or unparseable.
125
+ def parse_common_text_twin(twin_raw)
126
+ return nil if twin_raw.nil?
127
+
128
+ twin_str = twin_raw.to_s.strip
129
+ # Strip a leading pipe if the parser captured it
130
+ twin_str = twin_str.sub(/\A\s*\|\s*/, "")
131
+ return nil if twin_str.empty?
132
+
133
+ case twin_str
134
+ when /\AISO\/IEC\b/, /\AISO\b/
135
+ Pubid::Iso.parse(twin_str)
136
+ when /\AIEC\b/
137
+ Pubid::Iec.parse(twin_str)
138
+ end
139
+ rescue StandardError
140
+ # If the twin doesn't parse as a known flavor, leave it as nil
141
+ # rather than blowing up the whole parse — the ITU half is still
142
+ # usable on its own.
143
+ nil
144
+ end
145
+
69
146
  # Build Special Publication (OB). Sector is silently dropped — OB is a
70
- # cross-bureau publication and `Identifiers::Base` rejects sector+OB
147
+ # cross-bureau publication and `Identifier` rejects sector+OB
71
148
  # in its constructor.
72
149
  def build_special_publication(data)
73
150
  Identifiers::SpecialPublication.new(
@@ -88,6 +165,59 @@ module Pubid
88
165
  )
89
166
  end
90
167
 
168
+ # Build a labelled annex of a Recommendation. sector/series/code are
169
+ # deliberately NOT copied from the base: they are not serialized on the
170
+ # wrapper, so copies would make a from_hash-rebuilt annex differ from the
171
+ # parsed one.
172
+ def build_annex_of_recommendation(data)
173
+ Identifiers::AnnexOfRecommendation.new(
174
+ base: build(data[:base]),
175
+ number: data[:annex_number].to_s,
176
+ date: data[:year] ? build_date(data) : nil,
177
+ language: data[:language]&.to_s,
178
+ )
179
+ end
180
+
181
+ # Build a labelled appendix of a Recommendation. Like the annex above,
182
+ # sector/series/code are deliberately NOT copied from the base — they are
183
+ # not serialized on the wrapper, so copies would make a from_hash-rebuilt
184
+ # appendix differ from the parsed one.
185
+ def build_appendix_of_recommendation(data)
186
+ Identifiers::AppendixOfRecommendation.new(
187
+ base: build(data[:base]),
188
+ number: data[:appendix_number].to_s,
189
+ material: data[:appendix_material]&.to_s,
190
+ date: data[:year] ? build_date(data) : nil,
191
+ language: data[:language]&.to_s,
192
+ )
193
+ end
194
+
195
+ # Build Handbook ("ITU-R 42.HDB").
196
+ def build_handbook(data)
197
+ Identifiers::Handbook.new(
198
+ sector: Components::Sector.new(sector: data[:sector].to_s),
199
+ code: build_code(data),
200
+ date: data[:year] ? build_date(data) : nil,
201
+ )
202
+ end
203
+
204
+ # Build Question (numeric or letter-series).
205
+ def build_question(data)
206
+ series = if data[:series]
207
+ Components::Series.new(series: data[:series].to_s)
208
+ end
209
+
210
+ Identifiers::Question.new(
211
+ sector: Components::Sector.new(sector: data[:sector].to_s),
212
+ series: series,
213
+ code: build_code(data),
214
+ study_group: data[:study_group].to_s,
215
+ has_bl: !data[:has_bl].nil?,
216
+ bracketed: !data[:bracketed].nil?,
217
+ has_colon: !data[:question_colon].nil?,
218
+ )
219
+ end
220
+
91
221
  def build_supplement(data)
92
222
  # Build the base identifier first
93
223
  base = build(data[:base]) if data[:base]
@@ -97,10 +227,22 @@ module Pubid
97
227
  klass = case supplement_type
98
228
  when "Amd"
99
229
  Identifiers::Amendment
230
+ when "Add"
231
+ Identifiers::Addendum
100
232
  when "Cor"
101
233
  Identifiers::Corrigendum
234
+ when "Err"
235
+ Identifiers::Errata
102
236
  when "Suppl"
103
237
  Identifiers::Supplement
238
+ else
239
+ # Previously fell through to a nil class and died with
240
+ # "undefined method 'new' for nil" one frame later. Any token
241
+ # added to Parser#supplement_type without a class here should
242
+ # say so.
243
+ raise ArgumentError,
244
+ "Unknown ITU supplement type: " \
245
+ "#{data[:supplement_type].inspect}"
104
246
  end
105
247
 
106
248
  # Build supplement date (separate from base date)
@@ -111,25 +253,84 @@ module Pubid
111
253
  )
112
254
  end
113
255
 
114
- # Build supplement with extracted components
115
- klass.new(
116
- sector: base&.sector || Components::Sector.new(sector: data[:sector].to_s),
117
- series: base&.series || (data[:series] ? Components::Series.new(series: data[:series].to_s) : nil),
118
- code: base&.code,
256
+ # Sector/series are copied from the base when it has them; the fallback
257
+ # to this level's own tokens is guarded because an annex base keeps
258
+ # sector/series/code on *its* base, leaving all three nil here while the
259
+ # supplement level carries no sector token of its own.
260
+ # An annex base keeps sector/series/code on *its* base, so reach through
261
+ # it via #root; otherwise a supplement of an annex would carry none of
262
+ # them and its MR string would collapse to a bare "itu.<date>".
263
+ base_identity = base&.sector ? base : base&.root
264
+ sector = base_identity&.sector ||
265
+ (Components::Sector.new(sector: data[:sector].to_s) if data[:sector])
266
+ series = base_identity&.series ||
267
+ (Components::Series.new(series: data[:series].to_s) if data[:series])
268
+
269
+ attrs = {
270
+ sector: sector,
271
+ series: series,
272
+ code: base_identity&.code,
119
273
  base: base,
120
274
  number: data[:supplement_number].to_s,
275
+ # The marker is the captured space, so its ABSENCE is the flag.
276
+ number_glued: data[:supplement_space].nil?,
277
+ slash_joined: !data[:supplement_slash].nil?,
121
278
  date: supplement_date,
122
279
  language: data[:language]&.to_s,
123
- )
280
+ }
281
+ # The "series" word rides on the supplement for the base-less,
282
+ # series-only form; with a base it is the base's, and renders from
283
+ # there. It is copied up anyway (like sector/series/code above) so the
284
+ # supplement's own MR slug stays distinct — `render_supplement` and the
285
+ # base-nil-guarded key_value/== only consult it when base is nil, so
286
+ # the copy is render- and serialization-neutral.
287
+ attrs[:series_word] = if base
288
+ !!base_identity&.series_word
289
+ else
290
+ !data[:series_word].nil?
291
+ end
292
+ attrs[:technical] = true if data[:technical] &&
293
+ klass == Identifiers::Corrigendum
294
+
295
+ klass.new(**attrs)
124
296
  end
125
297
 
126
298
  private
127
299
 
300
+ # Build the additional designations of a combined recommendation from the
301
+ # repeated parse subtrees (each `{ designation: { series:, number:, … } }`).
302
+ def build_designations(combined_data)
303
+ Array(combined_data).map do |element|
304
+ d = element[:designation] || element
305
+ Components::Designation.new(
306
+ series: Components::Series.new(series: d[:series].to_s),
307
+ code: Components::Code.new(
308
+ number: d[:number].to_s,
309
+ series_suffix: d[:series_suffix]&.to_s,
310
+ series_suffix_spaced: !d[:series_suffix_spaced].nil?,
311
+ subseries: d[:subseries]&.to_s,
312
+ parts: extract_parts(d[:parts]),
313
+ qualifier: d[:qualifier]&.to_s,
314
+ qualifier_glued: !d[:qualifier].nil? && d[:qualifier_spaced].nil?,
315
+ ),
316
+ )
317
+ end
318
+ end
319
+
128
320
  def build_code(data)
129
321
  Components::Code.new(
322
+ imp_marker: data[:imp_marker]&.to_s,
130
323
  number: data[:number].to_s,
324
+ series_suffix: data[:series_suffix]&.to_s,
325
+ # The marker is the captured separating space, so its presence is
326
+ # the flag for the edition word and its ABSENCE is the flag for the
327
+ # qualifier letter (whose majority spelling is spaced).
328
+ series_suffix_spaced: !data[:series_suffix_spaced].nil?,
131
329
  subseries: data[:subseries]&.to_s,
132
330
  parts: extract_parts(data[:parts]),
331
+ qualifier: data[:qualifier]&.to_s,
332
+ qualifier_glued: !data[:qualifier].nil? &&
333
+ data[:qualifier_spaced].nil?,
133
334
  )
134
335
  end
135
336