pubid 2.0.0.pre.alpha.8 → 2.0.0.pre.alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. checksums.yaml +4 -4
  2. data/data/bipm/update_codes.yaml +9 -0
  3. data/data/iec/update_codes.yaml +3 -0
  4. data/data/ieee/update_codes.yaml +107 -1
  5. data/data/nist/series.yaml +155 -0
  6. data/data/nist/update_codes.yaml +8 -0
  7. data/lib/pubid/adobe/builder.rb +52 -0
  8. data/lib/pubid/adobe/identifier.rb +49 -0
  9. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  10. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  11. data/lib/pubid/adobe/identifiers.rb +10 -0
  12. data/lib/pubid/adobe/parser.rb +128 -0
  13. data/lib/pubid/adobe/renderer.rb +39 -0
  14. data/lib/pubid/adobe/urn_generator.rb +42 -0
  15. data/lib/pubid/adobe/urn_parser.rb +69 -0
  16. data/lib/pubid/adobe.rb +60 -0
  17. data/lib/pubid/amca/builder.rb +2 -2
  18. data/lib/pubid/amca/identifier.rb +1 -3
  19. data/lib/pubid/amca/identifiers/base.rb +1 -6
  20. data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
  21. data/lib/pubid/amca/identifiers/publication.rb +1 -1
  22. data/lib/pubid/amca/identifiers/standard.rb +1 -1
  23. data/lib/pubid/amca/identifiers.rb +0 -1
  24. data/lib/pubid/amca/single_identifier.rb +1 -1
  25. data/lib/pubid/amca.rb +3 -3
  26. data/lib/pubid/ashrae/builder.rb +22 -22
  27. data/lib/pubid/ashrae/identifier.rb +3 -4
  28. data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
  29. data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
  30. data/lib/pubid/ashrae/identifiers/base.rb +14 -8
  31. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
  32. data/lib/pubid/ashrae/identifiers.rb +0 -1
  33. data/lib/pubid/ashrae/parser.rb +14 -9
  34. data/lib/pubid/ashrae/renderer.rb +19 -19
  35. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  36. data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
  37. data/lib/pubid/ashrae.rb +3 -3
  38. data/lib/pubid/bipm/builder.rb +107 -0
  39. data/lib/pubid/bipm/identifier.rb +160 -0
  40. data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
  41. data/lib/pubid/bipm/identifiers/guide.rb +24 -0
  42. data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
  43. data/lib/pubid/bipm/identifiers/mep.rb +21 -0
  44. data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
  45. data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
  46. data/lib/pubid/bipm/identifiers.rb +15 -0
  47. data/lib/pubid/bipm/parser.rb +184 -0
  48. data/lib/pubid/bipm/renderer.rb +110 -0
  49. data/lib/pubid/bipm/urn_generator.rb +58 -0
  50. data/lib/pubid/bipm/urn_parser.rb +52 -0
  51. data/lib/pubid/bipm.rb +86 -0
  52. data/lib/pubid/bsi/builder.rb +14 -14
  53. data/lib/pubid/bsi/identifier.rb +0 -1
  54. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  55. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  56. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  57. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  58. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  59. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  60. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  61. data/lib/pubid/bsi/renderer.rb +8 -8
  62. data/lib/pubid/bsi/single_identifier.rb +48 -0
  63. data/lib/pubid/builder/base.rb +5 -3
  64. data/lib/pubid/bundled_identifier.rb +3 -3
  65. data/lib/pubid/calconnect/builder.rb +38 -0
  66. data/lib/pubid/calconnect/identifier.rb +117 -0
  67. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  68. data/lib/pubid/calconnect/identifiers.rb +9 -0
  69. data/lib/pubid/calconnect/parser.rb +54 -0
  70. data/lib/pubid/calconnect/renderer.rb +36 -0
  71. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  72. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  73. data/lib/pubid/calconnect.rb +77 -0
  74. data/lib/pubid/ccsds/builder.rb +1 -1
  75. data/lib/pubid/ccsds/identifier.rb +1 -1
  76. data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
  77. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  78. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  79. data/lib/pubid/cen_cenelec/builder.rb +46 -12
  80. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
  81. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
  82. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
  83. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  84. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  85. data/lib/pubid/cen_cenelec/renderer.rb +5 -5
  86. data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
  87. data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
  88. data/lib/pubid/cen_cenelec.rb +76 -72
  89. data/lib/pubid/cie/builder.rb +139 -24
  90. data/lib/pubid/cie/identifier.rb +7 -3
  91. data/lib/pubid/cie/identifiers/bundle.rb +32 -4
  92. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  93. data/lib/pubid/cie/identifiers/conference.rb +9 -4
  94. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  95. data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
  96. data/lib/pubid/cie/identifiers/identical.rb +7 -7
  97. data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
  98. data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
  99. data/lib/pubid/cie/identifiers/standard.rb +33 -7
  100. data/lib/pubid/cie/identifiers/supplement.rb +24 -22
  101. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
  102. data/lib/pubid/cie/identifiers.rb +2 -0
  103. data/lib/pubid/cie/parser.rb +54 -5
  104. data/lib/pubid/cie/single_identifier.rb +40 -1
  105. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  106. data/lib/pubid/cie/urn_generator.rb +11 -8
  107. data/lib/pubid/cie.rb +0 -1
  108. data/lib/pubid/components/date.rb +21 -5
  109. data/lib/pubid/csa/builder.rb +1 -1
  110. data/lib/pubid/csa/composite_identifier.rb +17 -1
  111. data/lib/pubid/csa/identifier.rb +48 -3
  112. data/lib/pubid/csa/identifiers/bundled.rb +6 -0
  113. data/lib/pubid/csa/identifiers/combined.rb +6 -0
  114. data/lib/pubid/csa/identifiers/package.rb +2 -2
  115. data/lib/pubid/csa/parser.rb +6 -6
  116. data/lib/pubid/csa/wrapper_identifier.rb +17 -0
  117. data/lib/pubid/doi/builder.rb +18 -0
  118. data/lib/pubid/doi/identifier.rb +46 -0
  119. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  120. data/lib/pubid/doi/identifiers.rb +9 -0
  121. data/lib/pubid/doi/parser.rb +52 -0
  122. data/lib/pubid/doi/renderer.rb +13 -0
  123. data/lib/pubid/doi.rb +55 -0
  124. data/lib/pubid/easc/builder.rb +55 -0
  125. data/lib/pubid/easc/identifier.rb +61 -0
  126. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  127. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  128. data/lib/pubid/easc/identifiers.rb +10 -0
  129. data/lib/pubid/easc/parser.rb +80 -0
  130. data/lib/pubid/easc/renderer.rb +48 -0
  131. data/lib/pubid/easc/urn_generator.rb +46 -0
  132. data/lib/pubid/easc/urn_parser.rb +57 -0
  133. data/lib/pubid/easc.rb +52 -0
  134. data/lib/pubid/ecma/builder.rb +31 -0
  135. data/lib/pubid/ecma/identifier.rb +76 -0
  136. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  137. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  138. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  139. data/lib/pubid/ecma/identifiers.rb +11 -0
  140. data/lib/pubid/ecma/parser.rb +41 -0
  141. data/lib/pubid/ecma/renderer.rb +46 -0
  142. data/lib/pubid/ecma/urn_generator.rb +25 -0
  143. data/lib/pubid/ecma/urn_parser.rb +35 -0
  144. data/lib/pubid/ecma.rb +67 -0
  145. data/lib/pubid/etsi/builder.rb +7 -3
  146. data/lib/pubid/etsi/identifier.rb +1 -3
  147. data/lib/pubid/etsi/identifiers/base.rb +28 -10
  148. data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
  149. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
  150. data/lib/pubid/etsi/identifiers.rb +0 -1
  151. data/lib/pubid/etsi/parser.rb +8 -2
  152. data/lib/pubid/etsi/renderer.rb +8 -2
  153. data/lib/pubid/etsi.rb +5 -5
  154. data/lib/pubid/export/exporter.rb +2 -1
  155. data/lib/pubid/export/flavor_exporter.rb +18 -3
  156. data/lib/pubid/gb/builder.rb +45 -0
  157. data/lib/pubid/gb/identifier.rb +64 -0
  158. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  159. data/lib/pubid/gb/identifiers.rb +9 -0
  160. data/lib/pubid/gb/parser.rb +63 -0
  161. data/lib/pubid/gb/renderer.rb +35 -0
  162. data/lib/pubid/gb.rb +87 -0
  163. data/lib/pubid/gost/builder.rb +148 -0
  164. data/lib/pubid/gost/identifier.rb +49 -0
  165. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  166. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  167. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  168. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  169. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  170. data/lib/pubid/gost/identifiers.rb +13 -0
  171. data/lib/pubid/gost/parser.rb +97 -0
  172. data/lib/pubid/gost/renderer.rb +48 -0
  173. data/lib/pubid/gost/urn_generator.rb +46 -0
  174. data/lib/pubid/gost/urn_parser.rb +52 -0
  175. data/lib/pubid/gost.rb +49 -0
  176. data/lib/pubid/iala/builder.rb +22 -27
  177. data/lib/pubid/iala/identifier.rb +27 -2
  178. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  179. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  180. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  181. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  182. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  183. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  184. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  185. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  186. data/lib/pubid/iala/identifiers/report.rb +1 -1
  187. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  188. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  189. data/lib/pubid/iala/identifiers.rb +0 -1
  190. data/lib/pubid/iala/renderer.rb +1 -1
  191. data/lib/pubid/iala/urn_generator.rb +1 -1
  192. data/lib/pubid/iala/urn_parser.rb +19 -2
  193. data/lib/pubid/iala.rb +4 -4
  194. data/lib/pubid/iana/builder.rb +20 -0
  195. data/lib/pubid/iana/identifier.rb +72 -0
  196. data/lib/pubid/iana/identifiers/registry.rb +33 -0
  197. data/lib/pubid/iana/identifiers.rb +9 -0
  198. data/lib/pubid/iana/parser.rb +38 -0
  199. data/lib/pubid/iana/renderer.rb +29 -0
  200. data/lib/pubid/iana/urn_generator.rb +15 -0
  201. data/lib/pubid/iana/urn_parser.rb +24 -0
  202. data/lib/pubid/iana.rb +69 -0
  203. data/lib/pubid/identifier.rb +210 -23
  204. data/lib/pubid/idf/builder.rb +1 -1
  205. data/lib/pubid/idf/parser.rb +2 -2
  206. data/lib/pubid/idf/renderer.rb +1 -1
  207. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  208. data/lib/pubid/iec/builder.rb +35 -25
  209. data/lib/pubid/iec/identifier.rb +47 -2
  210. data/lib/pubid/iec/identifiers/base.rb +2 -2
  211. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
  213. data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
  214. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  215. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  216. data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
  217. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
  218. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  219. data/lib/pubid/iec/identifiers.rb +1 -0
  220. data/lib/pubid/iec/parser.rb +51 -10
  221. data/lib/pubid/iec/renderer.rb +18 -8
  222. data/lib/pubid/iec/single_identifier.rb +1 -1
  223. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  224. data/lib/pubid/iec.rb +1 -6
  225. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  226. data/lib/pubid/ieee/aiee/identifier.rb +45 -61
  227. data/lib/pubid/ieee/builder.rb +341 -68
  228. data/lib/pubid/ieee/compaction.rb +121 -0
  229. data/lib/pubid/ieee/components/draft.rb +47 -7
  230. data/lib/pubid/ieee/identifier.rb +1 -3
  231. data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
  232. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  233. data/lib/pubid/ieee/identifiers/base.rb +106 -13
  234. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  235. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  236. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  237. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
  238. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  239. data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
  240. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  241. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
  242. data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
  243. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
  244. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  245. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  246. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  247. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  248. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  249. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  250. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  251. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  252. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  253. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  254. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  255. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  256. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  257. data/lib/pubid/ieee/identifiers.rb +2 -1
  258. data/lib/pubid/ieee/ire/builder.rb +7 -6
  259. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  260. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  261. data/lib/pubid/ieee/nesc/parser.rb +15 -14
  262. data/lib/pubid/ieee/parser.rb +461 -43
  263. data/lib/pubid/ieee/pre_parser.rb +1 -1
  264. data/lib/pubid/ieee/renderer.rb +154 -57
  265. data/lib/pubid/ieee/typed_stages.rb +12 -1
  266. data/lib/pubid/ieee/urn_generator.rb +3 -5
  267. data/lib/pubid/ieee.rb +56 -3
  268. data/lib/pubid/ietf/builder.rb +62 -0
  269. data/lib/pubid/ietf/identifier.rb +5 -0
  270. data/lib/pubid/ietf/identifiers/base.rb +75 -0
  271. data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
  272. data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
  273. data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
  274. data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
  275. data/lib/pubid/ietf/identifiers/std.rb +25 -0
  276. data/lib/pubid/ietf/identifiers.rb +13 -0
  277. data/lib/pubid/ietf/parser.rb +43 -0
  278. data/lib/pubid/ietf/renderer.rb +26 -0
  279. data/lib/pubid/ietf/urn_generator.rb +23 -0
  280. data/lib/pubid/ietf/urn_parser.rb +35 -0
  281. data/lib/pubid/ietf.rb +76 -0
  282. data/lib/pubid/iho/identifier.rb +1 -3
  283. data/lib/pubid/iho/identifiers/base.rb +1 -7
  284. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  285. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  286. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  287. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  288. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  289. data/lib/pubid/iho/identifiers.rb +0 -1
  290. data/lib/pubid/iho.rb +7 -7
  291. data/lib/pubid/isbn/builder.rb +44 -0
  292. data/lib/pubid/isbn/check_digit.rb +53 -0
  293. data/lib/pubid/isbn/identifier.rb +63 -0
  294. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  295. data/lib/pubid/isbn/identifiers.rb +9 -0
  296. data/lib/pubid/isbn/parser.rb +45 -0
  297. data/lib/pubid/isbn/renderer.rb +16 -0
  298. data/lib/pubid/isbn.rb +52 -0
  299. data/lib/pubid/iso/builder.rb +9 -4
  300. data/lib/pubid/iso/combined_identifier.rb +2 -2
  301. data/lib/pubid/iso/identifier.rb +17 -1
  302. data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
  303. data/lib/pubid/iso/normalizer.rb +2 -2
  304. data/lib/pubid/iso/parser.rb +16 -12
  305. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  306. data/lib/pubid/iso/urn_generator.rb +4 -1
  307. data/lib/pubid/iso/urn_parser.rb +1 -1
  308. data/lib/pubid/itu/builder.rb +230 -29
  309. data/lib/pubid/itu/components/code.rb +48 -5
  310. data/lib/pubid/itu/components/designation.rb +35 -0
  311. data/lib/pubid/itu/components.rb +1 -0
  312. data/lib/pubid/itu/identifier.rb +1 -3
  313. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  314. data/lib/pubid/itu/identifiers/amendment.rb +6 -28
  315. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  316. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  317. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  318. data/lib/pubid/itu/identifiers/base.rb +341 -23
  319. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  320. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  321. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  322. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  323. data/lib/pubid/itu/identifiers/question.rb +63 -0
  324. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  325. data/lib/pubid/itu/identifiers/report.rb +39 -0
  326. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  327. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  328. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  329. data/lib/pubid/itu/identifiers.rb +10 -1
  330. data/lib/pubid/itu/model.rb +1 -1
  331. data/lib/pubid/itu/parser.rb +480 -26
  332. data/lib/pubid/itu/urn_generator.rb +36 -6
  333. data/lib/pubid/itu/urn_parser.rb +8 -0
  334. data/lib/pubid/itu.rb +11 -3
  335. data/lib/pubid/jcgm/builder.rb +23 -13
  336. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  337. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  338. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  339. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  340. data/lib/pubid/jcgm/identifiers.rb +2 -0
  341. data/lib/pubid/jcgm/parser.rb +66 -6
  342. data/lib/pubid/jcgm/renderer.rb +26 -12
  343. data/lib/pubid/jcgm/single_identifier.rb +74 -5
  344. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  345. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  346. data/lib/pubid/jcgm/urn_parser.rb +15 -3
  347. data/lib/pubid/jis/identifier.rb +52 -0
  348. data/lib/pubid/nist/builder.rb +29 -9
  349. data/lib/pubid/nist/caster.rb +7 -45
  350. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  351. data/lib/pubid/nist/components/supplement.rb +5 -2
  352. data/lib/pubid/nist/configuration.rb +7 -1
  353. data/lib/pubid/nist/identifier.rb +1 -3
  354. data/lib/pubid/nist/identifiers/base.rb +121 -37
  355. data/lib/pubid/nist/identifiers/circular.rb +1 -1
  356. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  358. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
  359. data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
  360. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  361. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  362. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  363. data/lib/pubid/nist/identifiers/handbook.rb +1 -1
  364. data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
  365. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  366. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
  367. data/lib/pubid/nist/identifiers/monograph.rb +1 -1
  368. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  369. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  370. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  371. data/lib/pubid/nist/identifiers/report.rb +1 -1
  372. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  373. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  374. data/lib/pubid/nist/identifiers.rb +0 -1
  375. data/lib/pubid/nist/parser.rb +26 -3
  376. data/lib/pubid/nist/preprocessor.rb +15 -0
  377. data/lib/pubid/nist/router.rb +2 -2
  378. data/lib/pubid/nist/series/ir.rb +0 -3
  379. data/lib/pubid/nist/supplement_identifier.rb +9 -9
  380. data/lib/pubid/nist.rb +12 -12
  381. data/lib/pubid/oasis/builder.rb +77 -0
  382. data/lib/pubid/oasis/identifier.rb +82 -0
  383. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  384. data/lib/pubid/oasis/identifiers.rb +9 -0
  385. data/lib/pubid/oasis/parser.rb +34 -0
  386. data/lib/pubid/oasis/renderer.rb +29 -0
  387. data/lib/pubid/oasis/urn_generator.rb +25 -0
  388. data/lib/pubid/oasis/urn_parser.rb +22 -0
  389. data/lib/pubid/oasis.rb +74 -0
  390. data/lib/pubid/ogc/builder.rb +33 -0
  391. data/lib/pubid/ogc/identifier.rb +77 -0
  392. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  393. data/lib/pubid/ogc/identifiers.rb +10 -0
  394. data/lib/pubid/ogc/parser.rb +40 -0
  395. data/lib/pubid/ogc/renderer.rb +33 -0
  396. data/lib/pubid/ogc/urn_generator.rb +14 -0
  397. data/lib/pubid/ogc/urn_parser.rb +22 -0
  398. data/lib/pubid/ogc.rb +71 -0
  399. data/lib/pubid/oiml/builder.rb +31 -7
  400. data/lib/pubid/oiml/identifier.rb +9 -1
  401. data/lib/pubid/oiml/parser.rb +11 -12
  402. data/lib/pubid/oiml/renderer.rb +13 -13
  403. data/lib/pubid/oiml/single_identifier.rb +20 -0
  404. data/lib/pubid/oiml/supplement_identifier.rb +9 -9
  405. data/lib/pubid/oiml/urn_parser.rb +23 -6
  406. data/lib/pubid/oiml.rb +4 -0
  407. data/lib/pubid/omg/builder.rb +19 -0
  408. data/lib/pubid/omg/identifier.rb +44 -0
  409. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  410. data/lib/pubid/omg/identifiers.rb +9 -0
  411. data/lib/pubid/omg/parser.rb +40 -0
  412. data/lib/pubid/omg/renderer.rb +19 -0
  413. data/lib/pubid/omg.rb +51 -0
  414. data/lib/pubid/parsers/mr_string.rb +101 -7
  415. data/lib/pubid/plateau/builder.rb +8 -4
  416. data/lib/pubid/plateau/identifier.rb +1 -3
  417. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  418. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  419. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  420. data/lib/pubid/plateau/identifiers.rb +0 -1
  421. data/lib/pubid/plateau/parser.rb +15 -5
  422. data/lib/pubid/plateau/renderer.rb +1 -1
  423. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  424. data/lib/pubid/plateau.rb +4 -4
  425. data/lib/pubid/renderers/human_readable.rb +3 -1
  426. data/lib/pubid/renderers/mr_string.rb +46 -4
  427. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  428. data/lib/pubid/rendering/supplement.rb +4 -4
  429. data/lib/pubid/sae/builder.rb +1 -1
  430. data/lib/pubid/sae/identifier.rb +1 -3
  431. data/lib/pubid/sae/identifiers/base.rb +10 -7
  432. data/lib/pubid/sae/identifiers.rb +0 -1
  433. data/lib/pubid/sae.rb +3 -3
  434. data/lib/pubid/tgpp/builder.rb +41 -0
  435. data/lib/pubid/tgpp/identifier.rb +91 -0
  436. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  437. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  438. data/lib/pubid/tgpp/identifiers.rb +11 -0
  439. data/lib/pubid/tgpp/parser.rb +62 -0
  440. data/lib/pubid/tgpp/renderer.rb +36 -0
  441. data/lib/pubid/tgpp/urn_generator.rb +20 -0
  442. data/lib/pubid/tgpp/urn_parser.rb +28 -0
  443. data/lib/pubid/tgpp.rb +78 -0
  444. data/lib/pubid/type_resolver.rb +59 -0
  445. data/lib/pubid/un/builder.rb +42 -0
  446. data/lib/pubid/un/identifier.rb +37 -0
  447. data/lib/pubid/un/identifiers/document.rb +24 -0
  448. data/lib/pubid/un/identifiers.rb +9 -0
  449. data/lib/pubid/un/parser.rb +25 -0
  450. data/lib/pubid/un/renderer.rb +11 -0
  451. data/lib/pubid/un.rb +46 -0
  452. data/lib/pubid/version.rb +1 -1
  453. data/lib/pubid/w3c/builder.rb +55 -0
  454. data/lib/pubid/w3c/identifier.rb +101 -0
  455. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  456. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  457. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  458. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  459. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  460. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  461. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  462. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  463. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  464. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  465. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  466. data/lib/pubid/w3c/identifiers.rb +25 -0
  467. data/lib/pubid/w3c/parser.rb +43 -0
  468. data/lib/pubid/w3c/renderer.rb +35 -0
  469. data/lib/pubid/w3c/urn_generator.rb +18 -0
  470. data/lib/pubid/w3c/urn_parser.rb +36 -0
  471. data/lib/pubid/w3c.rb +67 -0
  472. data/lib/pubid/xsf/builder.rb +17 -0
  473. data/lib/pubid/xsf/identifier.rb +62 -0
  474. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  475. data/lib/pubid/xsf/identifiers.rb +9 -0
  476. data/lib/pubid/xsf/parser.rb +25 -0
  477. data/lib/pubid/xsf/renderer.rb +23 -0
  478. data/lib/pubid/xsf/urn_generator.rb +13 -0
  479. data/lib/pubid/xsf/urn_parser.rb +18 -0
  480. data/lib/pubid/xsf.rb +76 -0
  481. data/lib/pubid.rb +25 -1
  482. metadata +205 -4
  483. data/lib/pubid/cie/components/code.rb +0 -80
  484. data/lib/pubid/iala/identifiers/base.rb +0 -14
@@ -19,6 +19,7 @@ module Pubid
19
19
  rule(:identifier) do
20
20
  working_programme_with_publisher |
21
21
  working_programme |
22
+ technical_group |
22
23
  working_document |
23
24
  sheet_supplement_identifier |
24
25
  sheet_identifier |
@@ -29,6 +30,42 @@ module Pubid
29
30
  identifier_copublishers
30
31
  end
31
32
 
33
+ # Technical Group identifier — names a committee rather than a document.
34
+ # Examples: "IEC TC 1", "ISO/IEC JTC 1", "ISO/IEC JTC 1/SC 7",
35
+ # "IEC SC 100A", "CISPR", "CIS/A".
36
+ rule(:technical_group) do
37
+ technical_group_with_publisher | technical_group_bare
38
+ end
39
+
40
+ rule(:technical_group_with_publisher) do
41
+ prefix_sole_publisher >> copublishers.maybe >> space >>
42
+ tc_body.as(:technical_committee) >>
43
+ (str("/") >> space? >> sc_body).as(:subcommittee).maybe
44
+ end
45
+
46
+ rule(:technical_group_bare) do
47
+ # CISPR / CIS-letter forms and bare TYPE NUMBER forms both default
48
+ # publisher to "IEC" via the Base class default.
49
+ tc_body.as(:technical_committee) >>
50
+ (str("/") >> space? >> sc_body).as(:subcommittee).maybe
51
+ end
52
+
53
+ # Committee body forms accepted by the parser. Order matters: longer
54
+ # or more specific patterns first so they win the ordered choice.
55
+ rule(:tc_body) do
56
+ str("CISPR") |
57
+ (str("CIS") >> str("/") >> match("[A-Z]")) |
58
+ (tc_type >> space >> digits >> match("[A-Z]").maybe)
59
+ end
60
+
61
+ rule(:sc_body) do
62
+ str("SC") >> space >> digits >> match("[A-Z]").maybe
63
+ end
64
+
65
+ rule(:tc_type) do
66
+ str("JTC") | str("JPC") | str("TC") | str("SC") | str("PC")
67
+ end
68
+
32
69
  # Working Programme format: [PWI|PNW] [TR] number edition
33
70
  # Examples: "PWI TR 100-36 ED1", "PWI 100-44 ED1", "PNW 65-915 ED1"
34
71
  # TC-style names: "PWI TR SYCSMARTENERGY-1", "PWI SyCLVDC-1 ED1"
@@ -158,12 +195,16 @@ module Pubid
158
195
  end
159
196
 
160
197
  rule(:date) do
161
- # :2005-02 or optional for DB without date
198
+ # :2005-02 or :-- (undated reference — ISO/IEC undated-reference form,
199
+ # e.g. IEC 60050:--, also accepted as the em-dash variant IEC 60050:—)
162
200
  (str(":") | dash) >>
163
- (year_digits >>
164
- (dash >> month_digits).maybe >>
165
- (dash >> day_digits).maybe
166
- ).as(:date)
201
+ (
202
+ (str("--") | str("—")).as(:undated_marker) |
203
+ (year_digits >>
204
+ (dash >> month_digits).maybe >>
205
+ (dash >> day_digits).maybe
206
+ ).as(:date)
207
+ )
167
208
  end
168
209
 
169
210
  rule(:part_and_subpart) do
@@ -251,14 +292,14 @@ module Pubid
251
292
  # IEC 60695-2-1/1:1994 (sheet 1 from year 1994)
252
293
  # IEC 60695-2-1/1 (sheet 1 without year)
253
294
  rule(:sheet_identifier) do
254
- identifier_copublishers_no_third.as(:base_identifier) >>
295
+ identifier_copublishers_no_third.as(:base) >>
255
296
  (sheet_notation | sheet_notation_no_year)
256
297
  end
257
298
 
258
299
  # Sheet identifier followed by supplement: base/sheet/supplement
259
300
  # IEC 60695-2-1/1:1994/COR1:1995
260
301
  rule(:sheet_supplement_identifier) do
261
- identifier_copublishers_no_third.as(:base_identifier) >>
302
+ identifier_copublishers_no_third.as(:base) >>
262
303
  sheet_notation >>
263
304
  str("/") >> supplement_type_with_stage >>
264
305
  space? >> second_part >> third_part
@@ -353,7 +394,7 @@ module Pubid
353
394
  # ISO/IEC 17025:2017 handles copublisher in copublishers rule
354
395
  # We handle this in identifier_copublishers already
355
396
  rule(:joint_identifier) do
356
- identifier_copublishers_no_third.as(:base_identifier) >>
397
+ identifier_copublishers_no_third.as(:base) >>
357
398
  space? >> str("|") >> space? >>
358
399
  scope { iso_identifier }.as(:joint_identifier)
359
400
  end
@@ -381,7 +422,7 @@ module Pubid
381
422
 
382
423
  # IEC 60038:2009/Amd 1:2011
383
424
  rule(:supplement_identifier_no_third) do
384
- identifier_copublishers_no_third.as(:base_identifier) >>
425
+ identifier_copublishers_no_third.as(:base) >>
385
426
  str("/") >> supplement_type_with_stage >>
386
427
  space? >> second_part
387
428
  end
@@ -392,7 +433,7 @@ module Pubid
392
433
 
393
434
  # IEC 60038:2009/Amd 1:2011/Cor 1:2012
394
435
  rule(:supplement_supplement_identifier) do
395
- supplement_identifier_no_third.as(:base_identifier) >>
436
+ supplement_identifier_no_third.as(:base) >>
396
437
  str("/") >> supplement_type_with_stage >>
397
438
  space? >> second_part >> third_part
398
439
  end
@@ -37,6 +37,8 @@ module Pubid
37
37
  render_fragment(id, opts, context)
38
38
  when Identifiers::WorkingDocument
39
39
  render_working_document(id, context)
40
+ when Identifiers::TechnicalGroup
41
+ render_technical_group(id, context)
40
42
  when Identifiers::TestReportForm
41
43
  render_test_report_form(id, context)
42
44
  when SupplementIdentifier
@@ -75,11 +77,11 @@ module Pubid
75
77
  end
76
78
 
77
79
  def render_supplement(id, opts, context)
78
- id.ensure_base_identifier
80
+ id.ensure_base
79
81
 
80
82
  if id.synthetic_base?
81
83
  render_supplement_standalone(id, context)
82
- elsif id.base_identifier
84
+ elsif id.base
83
85
  render_supplement_attached(id, opts, context)
84
86
  else
85
87
  render_single(id, opts, context)
@@ -97,7 +99,7 @@ module Pubid
97
99
  end
98
100
 
99
101
  abbr = id.typed_stage.abbr.first
100
- number_str = id.base_identifier.number.to_s
102
+ number_str = id.base.number.to_s
101
103
  number_str += "-#{id.number}" if id.number
102
104
  number_str += "-#{id.subpart}" if id.subpart
103
105
  parts << "#{abbr} #{number_str}"
@@ -110,7 +112,7 @@ module Pubid
110
112
 
111
113
  def render_supplement_attached(id, opts, context)
112
114
  parts = []
113
- parts << id.base_identifier.to_s(**opts)
115
+ parts << id.base.to_s(**opts)
114
116
 
115
117
  abbr = id.typed_stage.abbr.first.upcase
116
118
  supp_part = "/#{abbr}#{id.number}"
@@ -155,7 +157,7 @@ module Pubid
155
157
  def render_vap(id, opts, context)
156
158
  parts = []
157
159
 
158
- parts << id.base_identifier.to_s(**opts.merge(with_edition: false))
160
+ parts << id.base.to_s(**opts.merge(with_edition: false))
159
161
  parts << " #{id.vap.join('-')}" if id.vap&.any?
160
162
  parts << " #{id.edition.render(context:)}" if id.edition&.number
161
163
 
@@ -164,7 +166,7 @@ module Pubid
164
166
 
165
167
  def render_sheet(id, opts, context)
166
168
  parts = []
167
- parts << id.base_identifier.to_s(**opts)
169
+ parts << id.base.to_s(**opts)
168
170
  parts << "/#{id.sheet_number}"
169
171
  parts << ":#{id.year}" if id.year
170
172
  parts.join
@@ -172,9 +174,9 @@ module Pubid
172
174
 
173
175
  def render_fragment(id, opts, context)
174
176
  parts = []
175
- parts << id.base_identifier.to_s(**opts)
177
+ parts << id.base.to_s(**opts)
176
178
 
177
- parts << if id.base_identifier.is_a?(Identifiers::Corrigendum)
179
+ parts << if id.base.is_a?(Identifiers::Corrigendum)
178
180
  "/FRAGC#{id.fragment_number}"
179
181
  else
180
182
  "/FRAG#{id.fragment_number}"
@@ -185,6 +187,14 @@ module Pubid
185
187
  parts.join
186
188
  end
187
189
 
190
+ def render_technical_group(id, _context)
191
+ parts = []
192
+ parts << id.publisher_portion
193
+ parts << " #{id.technical_committee}"
194
+ parts << id.subcommittee if id.subcommittee
195
+ parts.join
196
+ end
197
+
188
198
  def render_working_document(id, context)
189
199
  if id.wp_stage
190
200
  parts = []
@@ -48,7 +48,7 @@ module Pubid
48
48
  (part ? "-#{part}" : ""),
49
49
  (subpart ? "-#{subpart}" : ""),
50
50
  (stage_iteration ? ".#{stage_iteration}" : ""),
51
- (date ? ":#{date.year}" : ""),
51
+ (date ? ":#{date.render}" : ""),
52
52
  ].join
53
53
  end
54
54
 
@@ -4,7 +4,7 @@ module Pubid
4
4
  module Iec
5
5
  # Identifier that represents a supplement to a base identifier.
6
6
  class SupplementIdentifier < SingleIdentifier
7
- attribute :base_identifier, Identifier, polymorphic: true
7
+ attribute :base, Identifier, polymorphic: true
8
8
 
9
9
  # Serialize the supplemented document under "base". The supplement's own
10
10
  # number/date/stage come from the inherited common maps; route the nested
@@ -15,10 +15,10 @@ module Pubid
15
15
  end
16
16
 
17
17
  def base_to_kv(model, doc)
18
- base = model.base_identifier
18
+ base = model.base
19
19
  return unless base
20
20
 
21
- # `base_identifier` synthesises a base for a supplement that has none
21
+ # `base` synthesises a base for a supplement that has none
22
22
  # (e.g. a bare "+AMD1:2008" nested in a consolidation): a fake doc whose
23
23
  # number equals the supplement's own. It renders nothing and the getter
24
24
  # recreates it identically on load, so don't persist it. A standalone
@@ -34,7 +34,7 @@ module Pubid
34
34
  return unless value
35
35
 
36
36
  base = ::Pubid::Iec::Identifier.from_hash(value)
37
- model.base_identifier = base
37
+ model.base = base
38
38
 
39
39
  # A base of the exact SingleIdentifier class is the synthetic self-base
40
40
  # of a standalone supplement ("IEC/FDAM 60038-1"); a real attached base
@@ -55,18 +55,18 @@ module Pubid
55
55
  @supplement_number = @number
56
56
  end
57
57
 
58
- # Override base_identifier getter to ensure it's always created for standalone supplements
59
- def base_identifier
60
- @base_identifier || ensure_base_identifier
58
+ # Override base getter to ensure it's always created for standalone supplements
59
+ def base
60
+ @base || ensure_base
61
61
  end
62
62
 
63
63
  # Override number getter to trigger swap for standalone supplements
64
64
  def number
65
- # Guard against recursion in ensure_base_identifier
65
+ # Guard against recursion in ensure_base
66
66
  return @number if @ensuring_base
67
67
 
68
68
  # For standalone supplements, trigger base creation first
69
- ensure_base_identifier if @synthetic_base.nil? && publisher && part
69
+ ensure_base if @synthetic_base.nil? && publisher && part
70
70
 
71
71
  if @synthetic_base
72
72
  @supplement_number || @number
@@ -85,7 +85,7 @@ module Pubid
85
85
  end
86
86
  end
87
87
 
88
- # Delegate publisher and copublishers to base_identifier whenever there is
88
+ # Delegate publisher and copublishers to base whenever there is
89
89
  # a base (a supplement carries the publisher of the document it
90
90
  # supplements). Checking base first — rather than `@publisher || base` — is
91
91
  # required now that the publisher attribute has an IEC default, which would
@@ -93,20 +93,20 @@ module Pubid
93
93
  def publisher
94
94
  return @publisher if @ensuring_base
95
95
 
96
- base_identifier ? base_identifier.publisher : @publisher
96
+ base ? base.publisher : @publisher
97
97
  end
98
98
 
99
99
  def copublishers
100
100
  return @copublishers if @ensuring_base
101
101
 
102
- base_identifier ? base_identifier.copublishers : @copublishers
102
+ base ? base.copublishers : @copublishers
103
103
  end
104
104
 
105
- # Ensure we have a base_identifier for standalone supplements
105
+ # Ensure we have a base for standalone supplements
106
106
  # Creates a synthetic base identifier from supplement attributes if needed
107
- # Returns the base_identifier
108
- def ensure_base_identifier
109
- return @base_identifier if @base_identifier
107
+ # Returns the base
108
+ def ensure_base
109
+ return @base if @base
110
110
 
111
111
  # Guard flag to prevent recursion in number getter
112
112
  @ensuring_base = true
@@ -140,14 +140,14 @@ module Pubid
140
140
  stage_code: :undated,
141
141
  )
142
142
 
143
- @base_identifier = base
143
+ @base = base
144
144
 
145
145
  # Store the supplement number for getter override
146
- # The original number is the base number (moved to base_identifier)
146
+ # The original number is the base number (moved to base)
147
147
  # The original part is the supplement number (what we want to return)
148
148
  @supplement_number = supplement_number
149
149
 
150
- @base_identifier
150
+ @base
151
151
  ensure
152
152
  @ensuring_base = false
153
153
  end
@@ -160,6 +160,19 @@ module Pubid
160
160
  def to_s(**opts)
161
161
  render(format: :human, **opts)
162
162
  end
163
+
164
+ # MR supplement suffix: `/{type}.{number}.{year}` (e.g. "/amd.1.2016").
165
+ # The MrString renderer recurses into `base` and appends this so the
166
+ # full supplement chain round-trips losslessly (issue #142).
167
+ def mr_supplement_suffix
168
+ segments = []
169
+ segments << mr_type if mr_type
170
+ segments << number&.to_s if number
171
+ segments << date&.year&.to_s if date&.year
172
+ return nil if segments.empty?
173
+
174
+ segments.join(".")
175
+ end
163
176
  end
164
177
  end
165
178
  end
data/lib/pubid/iec.rb CHANGED
@@ -23,12 +23,7 @@ module Pubid
23
23
  autoload :Renderer, "#{__dir__}/iec/renderer"
24
24
 
25
25
  def self.parse(identifier_string)
26
- if identifier_string.length > Pubid::MAX_INPUT_LENGTH
27
- raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
28
- end
29
-
30
- parsed = Parser.new.parse(identifier_string)
31
- Builder.new.build(parsed)
26
+ Identifier.parse(identifier_string)
32
27
  end
33
28
 
34
29
  def self.parse_urn(urn)
@@ -23,7 +23,7 @@ module Pubid
23
23
  end
24
24
 
25
25
  # Extract code
26
- code_str = extract_value(parsed[:number])
26
+ code_str = extract_number(parsed[:number])
27
27
  if code_str
28
28
  attributes[:code] = Components::Code.parse(code_str)
29
29
  end
@@ -36,9 +36,11 @@ module Pubid
36
36
  month_str = extract_value(parsed[:month])
37
37
  attributes[:month] = month_str if month_str
38
38
 
39
- # Extract separator (for rendering distinction)
39
+ # Extract the long-form date separator ("," or ".") for rendering.
40
+ # Named `date_separator` on the identifier to avoid colliding with the
41
+ # CodeNumber code-part `separator`.
40
42
  separator_str = extract_value(parsed[:separator])
41
- attributes[:separator] = separator_str if separator_str
43
+ attributes[:date_separator] = separator_str if separator_str
42
44
 
43
45
  # Set original format based on parsed data
44
46
  attributes[:original_format] = if separator_str || month_str
@@ -53,6 +55,18 @@ module Pubid
53
55
 
54
56
  private
55
57
 
58
+ # Extract the number, flattening a "431 (105)" main-number/parenthetical
59
+ # subtree into a plain string. Without this, a Hash node leaks its raw
60
+ # Parslet inspect form (e.g. `{main_number: "431"@8, ...}`) into `to_s`.
61
+ def extract_number(value)
62
+ return extract_value(value) unless value.is_a?(Hash)
63
+
64
+ main = extract_value(value[:main_number])
65
+ paren = value[:parenthetical]
66
+ alt = paren.is_a?(Hash) ? extract_value(paren[:alt_number]) : nil
67
+ alt ? "#{main} (#{alt})" : main
68
+ end
69
+
56
70
  def extract_value(value)
57
71
  return nil if value.nil?
58
72
  return nil if value.is_a?(Array) && value.empty?
@@ -1,88 +1,73 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
-
5
3
  module Pubid
6
4
  module Ieee
7
5
  module Aiee
8
- # Base class for AIEE identifiers
9
- # AIEE (American Institute of Electrical Engineers): 1884-1963
10
- class Identifier < Lutaml::Model::Serializable
11
- attribute :publisher, :string, default: -> { "AIEE" }
12
- attribute :type, :string # "No.", "No", "Standard", "Trans."
13
- attribute :code, Components::Code
14
- attribute :year, :string
15
- attribute :month, :string
16
- attribute :separator, :string # "," or "." for long form dates
17
- attribute :original_format, :string # "short" or "long" (preserves parsed format)
18
- attribute :relationships, Pubid::Ieee::Components::Relationship,
19
- collection: true
6
+ # AIEE identifiers (American Institute of Electrical Engineers: 1884-1963).
7
+ #
8
+ # Reparented onto Pubid::Ieee::Identifier + the CodeNumber mixin so AIEE
9
+ # shares the flat split-column serialization (number/prefix/parts/
10
+ # separator), a polymorphic `_type`, `#root`, and from_hash routing with
11
+ # every other IEEE type. Previously it descended from bare
12
+ # Lutaml::Model::Serializable and serialized a nested `code` object with no
13
+ # `_type`, so Pubid::Ieee::Identifier.from_hash could not route back to
14
+ # this class and dropped the code entirely — every AIEE row failed the
15
+ # relaton index-v2 round-trip gate and had a nil `root.number`.
16
+ #
17
+ # The date long-form separator is named `date_separator` (not `separator`)
18
+ # to avoid colliding with the CodeNumber code-part `separator`.
19
+ class Identifier < Pubid::Ieee::Identifier
20
+ include Pubid::Ieee::Identifiers::CodeNumber
20
21
 
21
- def initialize(**args)
22
- super()
23
-
24
- # Handle number/code as string or Code object
25
- # Builder passes :code, but also support :number for backward compatibility
26
- code_value = args[:code] || args[:number]
27
- if code_value.is_a?(String)
28
- self.code = Components::Code.parse(code_value)
29
- elsif code_value
30
- self.code = code_value
31
- end
32
-
33
- # Set other attributes
34
- attrs = self.class.attributes
35
- args.each do |key, value|
36
- next if %i[code number].include?(key)
37
-
38
- setter = :"#{key}="
39
- public_send(setter, value) if attrs.key?(key)
40
- end
41
- end
22
+ attribute :publisher, :string, default: -> { "AIEE" }
23
+ # AIEE carries no implicit type keyword, so override the base's "Std"
24
+ # default (else "AIEE 11-1937" would render as "AIEE Std 11-1937").
25
+ attribute :type, :string, default: -> {}
26
+ attribute :date_separator, :string # "," or "." for long-form dates
27
+ attribute :original_format, :string # "short"/"long" (preserves parsed format)
42
28
 
43
- # Provide number accessor for backward compatibility
44
- # Returns the string representation of the code
45
- def number
46
- code&.to_s
29
+ # A distinct polymorphic name so from_hash routes to AIEE. The derived
30
+ # default (last name segment "Identifier") would be
31
+ # "pubid:ieee:identifier", colliding with the base class.
32
+ def self.polymorphic_name
33
+ "pubid:ieee:aiee"
47
34
  end
48
35
 
49
36
  # Parse AIEE identifier string
50
37
  def self.parse(input)
51
38
  parsed = Parser.new.parse(input)
52
- builder = Builder.new
53
- builder.build(parsed)
39
+ Builder.new.build(parsed)
54
40
  end
55
41
 
56
- def to_s(date_format: nil)
42
+ def to_s(date_format: nil, trademark: false)
57
43
  result = [publisher]
58
44
  result << type if type
59
45
  result << code.to_s if code
60
46
 
61
47
  base = result.join(" ")
62
48
 
63
- # Determine which format to use
64
- # Priority: explicit parameter > original_format > default (long if month/separator, short otherwise)
65
- format = date_format&.to_s || original_format
66
-
67
- if !format
68
- # Auto-detect from parsed attributes
69
- format = month || separator ? "long" : "short"
49
+ # IEEE attaches the mark to the number, before the date suffix
50
+ # ("AIEE No 13™-1930").
51
+ if trademark
52
+ base += Pubid::Ieee.trademark_symbol_for(code_obj&.number,
53
+ code_obj&.prefix,
54
+ publishers: [publisher])
70
55
  end
71
56
 
72
- # Date formatting based on format parameter
57
+ # Priority: explicit parameter > original_format > format auto-detect
58
+ format = date_format&.to_s || original_format
59
+ format ||= month || date_separator ? "long" : "short"
60
+
73
61
  if year
74
62
  case format
75
63
  when "short", :short
76
- # Short form: dash + year
77
64
  base += "-#{year}"
78
65
  when "long", :long
79
- # Long form: separator + optional month + year
80
- sep = separator || "," # Default to comma for long form
66
+ sep = date_separator || "," # Default to comma for long form
81
67
  base += "#{sep} #{"#{month} " if month}#{year}"
82
68
  else
83
- # Preserve original format (backward compatibility)
84
- base += if separator
85
- "#{separator} #{"#{month} " if month}#{year}"
69
+ base += if date_separator
70
+ "#{date_separator} #{"#{month} " if month}#{year}"
86
71
  elsif month
87
72
  ", #{month} #{year}"
88
73
  else
@@ -91,11 +76,10 @@ module Pubid
91
76
  end
92
77
  end
93
78
 
94
- # Add relationships if present
95
- if relationships && !relationships.empty?
96
- relationship_str = relationships.join(" / ")
97
- base += " (#{relationship_str})"
98
- end
79
+ # The descriptive relationships narrative is deliberately kept out of
80
+ # to_s (an identifier string must stay bounded — it is used as a
81
+ # document number/filename downstream). It stays reachable on
82
+ # `relationships`.
99
83
 
100
84
  base
101
85
  end