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
@@ -3,15 +3,112 @@
3
3
  module Pubid
4
4
  module Ieee
5
5
  module Identifiers
6
- # IEC/IEEE Copublished Identifier - represents standards copublished by IEC and IEEE
6
+ # IEC/IEEE Copublished Identifier - standards copublished by IEC and IEEE.
7
7
  # Example: "IEC/IEEE 60079-30-2/D5 IEC:2013 (10/07)"
8
- class IecIeeeCopublished < Base
9
- attribute :iec_identifier, Base, polymorphic: true
10
- attribute :ieee_identifier, Base, polymorphic: true
11
- attribute :copublished_number, :string # The shared number like "60079-30-2"
8
+ #
9
+ # The printed IEC/IEEE number is stored as split index columns rather than
10
+ # a verbatim string: `number` (bare-digit narrowing key), `parts` (matched
11
+ # within the bucket), `separators` (per-part `.`/`-`, since a single code
12
+ # mixes them, e.g. `60076.57-1202`), and the trailing publication `year`
13
+ # (inherited from the base; attached with `year_sep`, always `-` in
14
+ # practice). The verbatim `copublished_number` is reconstructed from these
15
+ # for rendering — see #copublished_number — so it is NOT serialized.
16
+ class IecIeeeCopublished < Identifier
17
+ attribute :number, :string
18
+ attribute :parts, :string, collection: true, default: -> { [] }
19
+ attribute :separators, :string, collection: true, default: -> { [] }
20
+ attribute :year_sep, :string, default: -> { "-" }
21
+ # `year` is inherited from the base (:string).
22
+
23
+ attribute :iec_identifier, Identifier, polymorphic: true
24
+ attribute :ieee_identifier, Identifier, polymorphic: true
12
25
  attribute :draft_info, :string # Draft information like "/D5"
13
26
  attribute :iec_year, :string # IEC year like "2013"
14
27
  attribute :date_info, :string # Date information like "(10/07)"
28
+
29
+ # The printed IEC/IEEE number, rebuilt losslessly from the split
30
+ # columns (the renderer/urn read this). Not stored — number/parts/
31
+ # separators/year fully describe it, so the verbatim string never
32
+ # bloats an index row.
33
+ # @param mark [String] IEEE trademark symbol, spliced in after the
34
+ # number and its parts and before the publication year (IEEE prints
35
+ # it there); "" for the ordinary, unmarked rendering.
36
+ def copublished_number(mark = "")
37
+ return nil if number.to_s.empty?
38
+
39
+ code = marked_code(mark)
40
+ code += "#{year_sep}#{year}" if year
41
+ code
42
+ end
43
+
44
+ # The dotted/dashed parts portion, each part with its own separator.
45
+ def parts_suffix
46
+ separators.zip(parts).map { |sep, part| "#{sep}#{part}" }.join
47
+ end
48
+
49
+ # A stage word printed ahead of the number (`FDIS 60079-30-2`,
50
+ # `CD2 P62704-5 ED1`, `TS P61869-105 ED1`). The lookahead — the next
51
+ # token must start like a document number — is what stops this eating a
52
+ # number that merely begins with a letter.
53
+ STAGE_PREFIX = /\A[A-Z]+\d*\s+(?=P?\d)/
54
+
55
+ # Inside the number token, the printed code stops early at:
56
+ #
57
+ # * a colon-attached publication year (`62582-2:2022`);
58
+ # * a dash/dot-attached 19xx/20xx year (`62395.1-2024 Redline`) — only
59
+ # one a descriptive tail stranded inside the code gets here, since
60
+ # #peel_copublished_year moves a genuinely trailing year into the
61
+ # `year` attribute. The 19/20 prefix keeps a part that merely looks
62
+ # like a year (`60076.57-1202`) from matching;
63
+ # * a glued parenthetical (`62704-1(E)`), which is a language marker
64
+ # rather than part of the number.
65
+ CODE_END = /:\d{4}|[-.](?:19|20)\d{2}\z|\(/
66
+
67
+ # `number` + #parts_suffix with the mark spliced at the end of the code
68
+ # proper.
69
+ #
70
+ # Some copublished references carry an edition, a colon year, a stage
71
+ # word or a "- Redline" tail that the parser keeps inside
72
+ # `number`/`parts` rather than in dedicated attributes; appending the
73
+ # mark after all of it would print
74
+ # `IEC/IEEE 60076-16 Edition 2.0 2018-09™` instead of
75
+ # `IEC/IEEE 60076-16™ Edition 2.0 2018-09`. Scanning the whole printed
76
+ # code (not just the suffix) matters because the split point varies —
77
+ # `60802 Edition 1` lands in `number`, `-16 Edition 2` in `parts`.
78
+ #
79
+ # With the flag off `mark` is "" and this returns the code unchanged, so
80
+ # the plain rendering is byte-identical by construction.
81
+ def marked_code(mark)
82
+ code = "#{number}#{parts_suffix}"
83
+ return code if mark.to_s.empty?
84
+
85
+ at = code_end_index(code)
86
+ "#{code[0...at]}#{mark}#{code[at..]}"
87
+ end
88
+
89
+ # Index at which the printed code ends and descriptive text begins.
90
+ #
91
+ # The number is the first whitespace-delimited token after any stage
92
+ # word, so the code can never run past that token's end — which is what
93
+ # keeps the mark off a trailing edition/date phrase even when no
94
+ # CODE_END boundary matches inside the token.
95
+ def code_end_index(code)
96
+ start = code[STAGE_PREFIX]&.length || 0
97
+ token_end = code.index(" ", start) || code.length
98
+ boundary = code[start...token_end].index(CODE_END)
99
+ boundary ? start + boundary : token_end
100
+ end
101
+
102
+ # The base IEEE #exclude already nils year/month/day; also reset the
103
+ # year separator (a format sibling of the scalar year, per the CSA
104
+ # lesson) so a date-less reference matches a `:`-dated form too.
105
+ def exclude(*args)
106
+ result = super
107
+ if args.intersect?(%i[year date]) && result.respond_to?(:year_sep=)
108
+ result.year_sep = "-"
109
+ end
110
+ result
111
+ end
15
112
  end
16
113
  end
17
114
  end
@@ -7,7 +7,8 @@ module Pubid
7
7
  # Represents an interpretation sheet or clarification
8
8
  # Example: IEEE Std 1076/INT-1991, IEEE Std 1003.1-1988/INT
9
9
  class InterpretationIdentifier < SupplementIdentifier
10
- attribute :int_year, :string
10
+ # Uniform `year` (the interpretation year), not `int_year` — inherited
11
+ # from the base, so no attribute is declared here.
11
12
 
12
13
  # TYPED_STAGES for interpretation
13
14
  # Interpretation uses "INT" abbreviation
@@ -29,18 +29,27 @@ module Pubid
29
29
  # - "P" prefix means IEEE project (any stage)
30
30
  # - ISO stages and IEEE drafts can coexist but are not equivalent
31
31
  # - Format conversion preserves semantic meaning within each system
32
- class JointDevelopment < Base
32
+ class JointDevelopment < Identifier
33
+ # Split index columns (number/prefix/parts/separator) instead of a
34
+ # `code` string, like every IEEE leaf — see CodeNumber. Rendering reads
35
+ # `code` (base #code → code_obj), which CodeNumber rebuilds from the
36
+ # split fields, so to_ieee_format / to_iso_format are unaffected.
37
+ include CodeNumber
38
+
33
39
  attribute :publishers, :string, collection: true
34
40
  attribute :lead_party, :string # "IEEE", "ISO", "IEC", etc.
35
- attribute :code, :string
36
41
  attribute :typed_stage, Components::TypedStage
37
42
  attribute :year, :string
38
43
  attribute :iso_stage, :string # For ISO stage if present
39
44
  attribute :ieee_draft, :string # For IEEE P/D notation if present
40
45
 
41
- def initialize(**args)
46
+ # Accepts keyword args or a single positional hash (the base
47
+ # #exclude/matching rebuild passes the latter) — see
48
+ # Identifier#initialize.
49
+ def initialize(args = {}, **kwargs)
50
+ args = args.merge(kwargs) unless kwargs.empty?
42
51
  # Call super FIRST to initialize Lutaml::Model attributes
43
- super
52
+ super(args)
44
53
 
45
54
  # Then handle typed_stage
46
55
  if args[:typed_stage].is_a?(Components::TypedStage)
@@ -82,15 +91,25 @@ module Pubid
82
91
  # JointDevelopment has its own dual-format logic (IEEE vs ISO)
83
92
  # that doesn't go through the format registry renderer.
84
93
  # @param format [Symbol] :ieee or :iso (defaults to canonical_format)
94
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
85
95
  # @return [String] formatted identifier
86
- def to_s(format: canonical_format)
96
+ def to_s(format: canonical_format, trademark: false)
97
+ # The mark goes after the code number, before the draft and the year
98
+ # ("ISO/IEC/IEEE P26511™/D8-2018"), so it is threaded into the
99
+ # format builders rather than appended to the finished string.
100
+ mark = if trademark
101
+ Pubid::Ieee.trademark_symbol_for(code&.number,
102
+ code&.prefix,
103
+ publishers: publishers)
104
+ else
105
+ ""
106
+ end
107
+
87
108
  case format
88
109
  when :iso
89
- to_iso_format
90
- when :ieee
91
- to_ieee_format
110
+ to_iso_format(mark)
92
111
  else
93
- to_ieee_format
112
+ to_ieee_format(mark)
94
113
  end
95
114
  end
96
115
 
@@ -99,7 +118,7 @@ module Pubid
99
118
  # Convert to ISO format representation
100
119
  # ISO/IEC/IEEE FDIS 26511:2018
101
120
  # @return [String] ISO format string
102
- def to_iso_format
121
+ def to_iso_format(mark = "")
103
122
  parts = []
104
123
 
105
124
  # Publishers (slash-separated)
@@ -117,6 +136,7 @@ module Pubid
117
136
 
118
137
  # Code (NO P prefix in ISO format, NO draft notation)
119
138
  code_str = code.to_s.gsub(/^P/, "")
139
+ code_str += mark unless code_str.empty?
120
140
  parts << code_str if code_str && !code_str.empty?
121
141
 
122
142
  # Join with space and add year with colon
@@ -129,7 +149,7 @@ module Pubid
129
149
  # Convert to IEEE format representation
130
150
  # ISO/IEC/IEEE P26511/D8-2018
131
151
  # @return [String] IEEE format string
132
- def to_ieee_format
152
+ def to_ieee_format(mark = "")
133
153
  parts = []
134
154
 
135
155
  # Publishers (slash-separated)
@@ -143,6 +163,9 @@ module Pubid
143
163
  code_str = "P#{code_str}"
144
164
  end
145
165
 
166
+ # Mark after the number, before the draft and the year
167
+ code_str += mark unless code_str.empty?
168
+
146
169
  # Add IEEE draft notation if available (e.g., /D8)
147
170
  if ieee_draft
148
171
  code_str += "/#{ieee_draft}"
@@ -159,6 +182,12 @@ module Pubid
159
182
  result
160
183
  end
161
184
 
185
+ # Public again: these override base accessors and MUST be public — lutaml
186
+ # serialization calls `public_send(:publisher)`, so leaving them under the
187
+ # `private` above made JointDevelopment#to_hash raise (it could not be
188
+ # serialized or round-tripped / indexed at all).
189
+ public
190
+
162
191
  # Override to ensure proper publisher handling
163
192
  def publisher
164
193
  publishers&.first || super
@@ -168,6 +197,22 @@ module Pubid
168
197
  def copublisher
169
198
  publishers&.drop(1) || super
170
199
  end
200
+
201
+ # `publisher`/`copublisher` are *derived* from `publishers` (the source
202
+ # of truth, which IS serialized). Emitting them too breaks the canonical
203
+ # round-trip: the derived `publisher` is default-omitted on the parse
204
+ # path but re-emitted after from_hash (the override returns
205
+ # publishers.first, not the default). Drop both — publishers rebuilds
206
+ # them. (JointDevelopment is a top-level root, never nested, so a
207
+ # to_hash-level drop is sufficient.)
208
+ def to_hash(*args)
209
+ hash = super
210
+ if hash.is_a?(::Hash)
211
+ hash.delete("publisher")
212
+ hash.delete("copublisher")
213
+ end
214
+ hash
215
+ end
171
216
  end
172
217
  end
173
218
  end
@@ -8,7 +8,7 @@ module Pubid
8
8
  # Examples:
9
9
  # - "IEEE Std 1299/C62.22.1-1996" (same document, two numbers)
10
10
  # - "IEEE Std 960-1989, Std 1177-1989" (same document, two numbers)
11
- class MultiNumberedIdentifier < Base
11
+ class MultiNumberedIdentifier < Identifier
12
12
  # Primary identifier (main IEEE standard number)
13
13
  # Stored as-is (Lutaml model type checking doesn't work with polymorphic identifiers)
14
14
  attr_accessor :primary_identifier
@@ -13,21 +13,58 @@ module Pubid
13
13
  #
14
14
  # @example Standard format
15
15
  # nesc = Pubid::Ieee.parse("C2-1997 National Electric Safety Code")
16
- # nesc.code.value # => "C2"
17
- # nesc.year.year # => 1997
16
+ # nesc.code.number # => "2" (prefix "C")
17
+ # nesc.year # => "1997"
18
18
  #
19
19
  # @example Handbook format
20
20
  # nesc = Pubid::Ieee.parse("2017 NESC Handbook, Premier Edition")
21
- # nesc.year.year # => 2017
21
+ # nesc.year # => "2017"
22
22
  # nesc.variant # => "Handbook"
23
23
  # nesc.edition # => "Premier Edition"
24
- class Base < Lutaml::Model::Serializable
25
- attribute :code, Pubid::Ieee::Components::Code # "C2" code designation
26
- attribute :year, Pubid::Components::Date # Publication year
27
- attribute :variant, :string # Handbook, Redline, etc.
28
- attribute :edition, :string # Edition notation
29
- attribute :draft, :boolean # Draft flag
30
- attribute :month, :string # For draft identifiers
24
+ #
25
+ # Reparented onto Pubid::Ieee::Identifier (it used to descend from bare
26
+ # Lutaml::Model::Serializable) so NESC shares `#root`, a polymorphic
27
+ # `_type` and from_hash routing with every other IEEE type — see
28
+ # Pubid::Ieee::Aiee::Identifier for the same migration. Three
29
+ # attributes were reconciled against the base to avoid type collisions:
30
+ #
31
+ # `code` -> travels as the runtime `code_obj` (base #code returns
32
+ # it); the concrete leaves serialize the flat split
33
+ # columns via the CodeNumber mixin.
34
+ # `year` -> the base's plain `:string` year (was a
35
+ # Pubid::Components::Date), matching IEEE's scalar-date
36
+ # convention. `nesc.year` is now "2017", not a component.
37
+ # `draft` -> dropped; the base declares a `:string` `draft` (the draft
38
+ # *designator*), so a boolean here would corrupt it. Test
39
+ # draft-ness with `#draft?` / the Nesc::Draft class.
40
+ #
41
+ # This class is abstract and enforces it in #initialize: the builder
42
+ # always instantiates a concrete leaf (Nesc::Edition for the plain
43
+ # year-first form), because only leaves may redefine `number` as a
44
+ # :string (see the CodeNumber mixin) and only leaves declare the
45
+ # NESC-specific `polymorphic_name` that from_hash routes on.
46
+ class Base < Pubid::Ieee::Identifier
47
+ attribute :variant, :string # Handbook, Redline, etc.
48
+ # Registered-trademark "(R)" after the full name or abbreviation
49
+ attribute :registered, :boolean
50
+ # Whether the "(NESC)"/"(NESC(R))" abbreviation suffix was present
51
+ attribute :abbr_suffix, :boolean
52
+ # Registered-trademark "(R)" inside the "(NESC(R))" suffix
53
+ attribute :abbr_suffix_registered, :boolean
54
+
55
+ # Guards the abstract contract — see the class docs. Ruby has no
56
+ # `abstract`, and an instantiated Base would carry the derived
57
+ # `_type` "pubid:ieee:base" (which from_hash cannot resolve back to
58
+ # NESC) and a nil `number` (the empty relaton index key).
59
+ def initialize(args = {}, **kwargs)
60
+ if instance_of?(Base)
61
+ raise NotImplementedError,
62
+ "#{self.class} is abstract; instantiate a concrete NESC " \
63
+ "type (Standard, Edition, Handbook, Redline, Draft)"
64
+ end
65
+
66
+ super
67
+ end
31
68
 
32
69
  # Publisher portion for NESC identifiers
33
70
  #
@@ -36,18 +73,52 @@ module Pubid
36
73
  "NESC"
37
74
  end
38
75
 
39
- # Base rendering - override in subclasses
76
+ # Whether this is a draft of the code. NESC has no `draft` attribute
77
+ # of its own (the base's `draft` is the draft designator string), so
78
+ # draft-ness lives in the class.
79
+ #
80
+ # @return [Boolean]
81
+ def draft?
82
+ is_a?(Nesc::Draft)
83
+ end
84
+
85
+ # Rendering for year-first NESC identifiers (the C2-code standard form
86
+ # overrides this in Nesc::Standard). IEEE catalogues the year-first
87
+ # editions with the "IEEE Std" prefix, so it is prepended here.
40
88
  #
89
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
41
90
  # @return [String] String representation
42
- def to_s
43
- parts = []
44
- if code && year
45
- parts << "#{code}-#{year.year}"
46
- elsif year
47
- parts << year.year.to_s
91
+ def to_s(trademark: false)
92
+ result = ["IEEE Std", year, name_portion].compact.join(" ")
93
+ result += trademark_symbol if trademark
94
+ result
95
+ end
96
+
97
+ # Trademark symbol for this document's own code. A NESC string starts
98
+ # with the publication *year*, so the string-scanning
99
+ # Pubid::Ieee.trademark_symbol would pick the wrong field — an
100
+ # edition year of 2030 would silently render ®.
101
+ #
102
+ # @return [String] "®" or "™"
103
+ def trademark_symbol
104
+ Pubid::Ieee.trademark_symbol_for(code_obj&.number,
105
+ code_obj&.prefix,
106
+ publishers: [publisher])
107
+ end
108
+
109
+ # The document-name portion, including the registered marks and the
110
+ # optional "(NESC(R))" abbreviation suffix.
111
+ #
112
+ # @return [String] e.g. "National Electrical Safety Code(R) (NESC(R))"
113
+ def name_portion
114
+ name = "National Electrical Safety Code"
115
+ name += "(R)" if registered
116
+ if abbr_suffix
117
+ suffix = "NESC"
118
+ suffix += "(R)" if abbr_suffix_registered
119
+ name += " (#{suffix})"
48
120
  end
49
- parts << "National Electrical Safety Code"
50
- parts.join(" ")
121
+ name
51
122
  end
52
123
  end
53
124
  end
@@ -10,16 +10,31 @@ module Pubid
10
10
  # that are under development or review.
11
11
  #
12
12
  # @example
13
- # nesc = Pubid::Ieee.parse("Draft National Electrical Safety Code, January 2016")
14
- # nesc.to_s # => "Draft National Electrical Safety Code, January 2016"
13
+ # nesc = Pubid::Ieee.parse("Draft NESC, June 2011")
14
+ # nesc.to_s
15
+ # # => "Draft National Electrical Safety Code, June 2011"
16
+ #
17
+ # NOTE: the spelled-out "Draft National Electrical Safety Code, …" form
18
+ # is claimed by the generic IEEE grammar before it reaches the NESC
19
+ # sub-parser, so it does not currently build this class. Pre-existing
20
+ # dispatcher gap, pinned in spec/pubid/ieee/ire_nesc_roundtrip_spec.rb.
15
21
  class Draft < Base
22
+ include Pubid::Ieee::Identifiers::CodeNumber
23
+
24
+ def self.polymorphic_name
25
+ "pubid:ieee:nesc-draft"
26
+ end
27
+
16
28
  # Render draft identifier
17
29
  #
30
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
18
31
  # @return [String] Draft format with optional month and year
19
- def to_s
32
+ def to_s(trademark: false)
20
33
  parts = ["Draft National Electrical Safety Code"]
21
- parts << ", #{month} #{year.year}" if month && year
22
- parts.join
34
+ parts << ", #{month} #{year}" if month && year
35
+ result = parts.join
36
+ result += trademark_symbol if trademark
37
+ result
23
38
  end
24
39
  end
25
40
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ieee
5
+ module Identifiers
6
+ module Nesc
7
+ # A plain year-first NESC edition — the National Electrical Safety Code
8
+ # itself, referenced by publication year rather than by its C2 code.
9
+ #
10
+ # @example
11
+ # nesc = Pubid::Ieee.parse(
12
+ # "2017 National Electrical Safety Code(R) (NESC(R))",
13
+ # )
14
+ # nesc.to_s
15
+ # # => "IEEE Std 2017 National Electrical Safety Code(R) (NESC(R))"
16
+ #
17
+ # Rendering is Nesc::Base's; this class exists so that the builder never
18
+ # instantiates the abstract Base. Only concrete leaves may carry the
19
+ # CodeNumber mixin's `:string` `number` (see the mixin's notes on the
20
+ # multi-flavor attribute-resolution landmine), and every identifier that
21
+ # can be a `#root` needs a non-empty `number` for the relaton index.
22
+ class Edition < Base
23
+ include Pubid::Ieee::Identifiers::CodeNumber
24
+
25
+ def self.polymorphic_name
26
+ "pubid:ieee:nesc-edition"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -11,19 +11,30 @@ module Pubid
11
11
  #
12
12
  # @example Basic handbook
13
13
  # nesc = Pubid::Ieee.parse("2012 NESC Handbook")
14
- # nesc.to_s # => "2012 NESC Handbook"
14
+ # nesc.to_s # => "IEEE Std 2012 NESC Handbook"
15
15
  #
16
16
  # @example With edition
17
17
  # nesc = Pubid::Ieee.parse("2017 NESC Handbook, Premier Edition")
18
- # nesc.to_s # => "2017 NESC Handbook, Premier Edition"
18
+ # nesc.to_s # => "IEEE Std 2017 NESC Handbook, Premier Edition"
19
19
  class Handbook < Base
20
+ include Pubid::Ieee::Identifiers::CodeNumber
21
+
22
+ def self.polymorphic_name
23
+ "pubid:ieee:nesc-handbook"
24
+ end
25
+
20
26
  # Render handbook identifier
21
27
  #
28
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
22
29
  # @return [String] YYYY NESC Handbook format with optional edition
23
- def to_s
24
- parts = ["#{year.year} NESC Handbook"]
30
+ def to_s(trademark: false)
31
+ abbr = "NESC"
32
+ abbr += "(R)" if registered
33
+ parts = [["IEEE Std", year, "#{abbr} Handbook"].compact.join(" ")]
25
34
  parts << ", #{edition}" if edition
26
- parts.join
35
+ result = parts.join
36
+ result += trademark_symbol if trademark
37
+ result
27
38
  end
28
39
  end
29
40
  end
@@ -13,11 +13,20 @@ module Pubid
13
13
  # nesc = Pubid::Ieee.parse("2017 NESC Redline")
14
14
  # nesc.to_s # => "2017 NESC Redline"
15
15
  class Redline < Base
16
+ include Pubid::Ieee::Identifiers::CodeNumber
17
+
18
+ def self.polymorphic_name
19
+ "pubid:ieee:nesc-redline"
20
+ end
21
+
16
22
  # Render redline identifier
17
23
  #
24
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
18
25
  # @return [String] YYYY NESC Redline format
19
- def to_s
20
- "#{year.year} NESC Redline"
26
+ def to_s(trademark: false)
27
+ result = [year, "NESC Redline"].compact.join(" ")
28
+ result += trademark_symbol if trademark
29
+ result
21
30
  end
22
31
  end
23
32
  end
@@ -13,11 +13,26 @@ module Pubid
13
13
  # nesc = Pubid::Ieee.parse("C2-1997 National Electric Safety Code")
14
14
  # nesc.to_s # => "C2-1997 National Electrical Safety Code"
15
15
  class Standard < Base
16
+ include Pubid::Ieee::Identifiers::CodeNumber
17
+
18
+ # Distinct from Identifiers::Standard, whose derived polymorphic name
19
+ # is also "pubid:ieee:standard".
20
+ def self.polymorphic_name
21
+ "pubid:ieee:nesc-standard"
22
+ end
23
+
16
24
  # Render standard NESC identifier
17
25
  #
18
- # @return [String] C2-YYYY format
19
- def to_s
20
- "C2-#{year.year} National Electrical Safety Code"
26
+ # @param trademark [Boolean] append the IEEE trademark symbol (™/®)
27
+ # @return [String] C2-YYYY format (bare "C2" when the year is absent,
28
+ # e.g. a partial reference produced by `#exclude(:year)`)
29
+ def to_s(trademark: false)
30
+ # Unlike the year-first NESC editions, this form renders a code, so
31
+ # the mark goes after it and before the year — as everywhere else.
32
+ code_part = "C2"
33
+ code_part += trademark_symbol if trademark
34
+ code_part += "-#{year}" if year
35
+ "#{code_part} National Electrical Safety Code"
21
36
  end
22
37
  end
23
38
  end
@@ -6,6 +6,7 @@ module Pubid
6
6
  module Nesc
7
7
  autoload :Base, "#{__dir__}/nesc/base"
8
8
  autoload :Draft, "#{__dir__}/nesc/draft"
9
+ autoload :Edition, "#{__dir__}/nesc/edition"
9
10
  autoload :Handbook, "#{__dir__}/nesc/handbook"
10
11
  autoload :Redline, "#{__dir__}/nesc/redline"
11
12
  autoload :Standard, "#{__dir__}/nesc/standard"
@@ -5,9 +5,9 @@ module Pubid
5
5
  module Identifiers
6
6
  # Parenthetical Identifier - wraps identifier with parenthetical annotation
7
7
  # Example: "IEEE Standard No 18-1968 (ANSI C55.1-1968)"
8
- class ParentheticalIdentifier < Base
9
- attribute :base_identifier, Base, polymorphic: true
10
- attribute :parenthetical_identifier, Base, polymorphic: true
8
+ class ParentheticalIdentifier < Identifier
9
+ attribute :base, Identifier, polymorphic: true
10
+ attribute :parenthetical_identifier, Identifier, polymorphic: true
11
11
  end
12
12
  end
13
13
  end
@@ -8,7 +8,12 @@ module Pubid
8
8
  # where P1234 is the project number and D5 is the draft version
9
9
  # This is distinct from a StandardIdentifier - the "P" indicates project status,
10
10
  # not a code prefix like "C" in "C57.12"
11
- class ProjectDraftIdentifier < Base
11
+ class ProjectDraftIdentifier < Identifier
12
+ # Reliable string `number` for relaton's index key (see CodeNumber).
13
+ # Its #initialize `super` chains through CodeNumber, which sets `number`
14
+ # from the (P-stripped) code after the parent builds code_obj.
15
+ include CodeNumber
16
+
12
17
  TYPED_STAGES = [
13
18
  Components::TypedStage.new(
14
19
  abbr: ["P"],
@@ -24,16 +29,19 @@ module Pubid
24
29
  { key: :P, title: "Project Draft", short: "P" }
25
30
  end
26
31
 
27
- # Override initialize to strip "P" prefix from code before creating Code object
28
- # The "P" is reflected in the typed_stage, not in the Code component itself
29
- def initialize(**args)
32
+ # Override initialize to strip "P" prefix from code before creating Code
33
+ # object. The "P" is reflected in the typed_stage, not in the Code
34
+ # component itself. Accepts keyword args or a single positional hash (the
35
+ # base #exclude/matching rebuild passes the latter).
36
+ def initialize(args = {}, **kwargs)
37
+ args = kwargs.empty? ? args.dup : args.merge(kwargs)
30
38
  # If code is provided with "P" prefix (e.g., "P1234"), strip it
31
39
  if args[:code].is_a?(String) && args[:code].start_with?("P")
32
40
  args[:code] = args[:code][1..] # Strip leading "P"
33
41
  end
34
42
 
35
- # Call parent initialize with modified code
36
- super
43
+ # Call parent initialize with modified code (positional hash)
44
+ super(args)
37
45
  end
38
46
  end
39
47
  end
@@ -7,18 +7,18 @@ module Pubid
7
7
  # IEEE standard with optional revision note, marked as redline
8
8
  # Example: "IEEE Std 1018-2013 (Revison of IEEE Std 1018-2004) - Redline"
9
9
  # Contains: base standard + optional revision standard + redline flag
10
- class RedlinedStandard < Base
10
+ class RedlinedStandard < Identifier
11
11
  # The current standard identifier
12
- attribute :base_identifier, Base, polymorphic: true
12
+ attribute :base, Identifier, polymorphic: true
13
13
 
14
14
  # Optional: the standard this revises
15
- attribute :revision_of, Base, polymorphic: true
15
+ attribute :revision_of, Identifier, polymorphic: true
16
16
 
17
17
  # Redline flag (always true for this class)
18
18
  attribute :redline, :boolean, default: -> { true }
19
19
 
20
20
  def publisher
21
- base_identifier&.publisher || "IEEE"
21
+ base&.publisher || "IEEE"
22
22
  end
23
23
  end
24
24
  end