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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (672) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +33 -11
  3. data/conformance/pending.yaml +4 -0
  4. data/data/bipm/update_codes.yaml +9 -0
  5. data/data/iec/update_codes.yaml +3 -0
  6. data/data/ieee/update_codes.yaml +107 -1
  7. data/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
  8. data/data/nist/update_codes.yaml +8 -0
  9. data/lib/pubid/adobe/builder.rb +52 -0
  10. data/lib/pubid/adobe/identifier.rb +47 -0
  11. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  12. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  13. data/lib/pubid/adobe/identifiers.rb +10 -0
  14. data/lib/pubid/adobe/parser.rb +136 -0
  15. data/lib/pubid/adobe/renderer.rb +39 -0
  16. data/lib/pubid/adobe/urn_generator.rb +42 -0
  17. data/lib/pubid/adobe/urn_parser.rb +69 -0
  18. data/lib/pubid/adobe.rb +61 -0
  19. data/lib/pubid/amca/builder.rb +4 -4
  20. data/lib/pubid/amca/identifier.rb +1 -3
  21. data/lib/pubid/amca/identifiers/base.rb +50 -33
  22. data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
  23. data/lib/pubid/amca/identifiers/publication.rb +14 -10
  24. data/lib/pubid/amca/identifiers/standard.rb +3 -1
  25. data/lib/pubid/amca/identifiers.rb +0 -1
  26. data/lib/pubid/amca/parser.rb +1 -1
  27. data/lib/pubid/amca/renderer.rb +4 -4
  28. data/lib/pubid/amca/single_identifier.rb +1 -1
  29. data/lib/pubid/amca/urn_generator.rb +2 -2
  30. data/lib/pubid/amca.rb +5 -4
  31. data/lib/pubid/ansi/builder.rb +2 -2
  32. data/lib/pubid/ansi/identifier.rb +18 -0
  33. data/lib/pubid/ansi/parser.rb +1 -1
  34. data/lib/pubid/ansi/renderer.rb +2 -2
  35. data/lib/pubid/ansi.rb +5 -5
  36. data/lib/pubid/api/builder.rb +16 -2
  37. data/lib/pubid/api/identifier.rb +25 -4
  38. data/lib/pubid/api/identifiers/mpms.rb +10 -8
  39. data/lib/pubid/api/parser.rb +1 -1
  40. data/lib/pubid/api/renderer.rb +16 -7
  41. data/lib/pubid/api/single_identifier.rb +5 -12
  42. data/lib/pubid/api.rb +1 -0
  43. data/lib/pubid/ashrae/builder.rb +53 -32
  44. data/lib/pubid/ashrae/identifier.rb +3 -4
  45. data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
  46. data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
  47. data/lib/pubid/ashrae/identifiers/base.rb +94 -12
  48. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
  49. data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
  50. data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
  51. data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
  52. data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
  53. data/lib/pubid/ashrae/identifiers.rb +0 -1
  54. data/lib/pubid/ashrae/parser.rb +37 -17
  55. data/lib/pubid/ashrae/renderer.rb +20 -20
  56. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  57. data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
  58. data/lib/pubid/ashrae/urn_generator.rb +8 -2
  59. data/lib/pubid/ashrae.rb +10 -4
  60. data/lib/pubid/asme/builder.rb +11 -2
  61. data/lib/pubid/asme/identifier.rb +9 -0
  62. data/lib/pubid/asme/identifiers/standard.rb +86 -2
  63. data/lib/pubid/asme/parser.rb +1 -1
  64. data/lib/pubid/asme/renderer.rb +3 -3
  65. data/lib/pubid/asme/single_identifier.rb +8 -1
  66. data/lib/pubid/asme/urn_generator.rb +2 -2
  67. data/lib/pubid/asme.rb +1 -0
  68. data/lib/pubid/astm/builder.rb +10 -3
  69. data/lib/pubid/astm/identifier.rb +9 -0
  70. data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
  71. data/lib/pubid/astm/identifiers/code_number.rb +81 -0
  72. data/lib/pubid/astm/identifiers/data_series.rb +2 -0
  73. data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
  74. data/lib/pubid/astm/identifiers/manual.rb +10 -0
  75. data/lib/pubid/astm/identifiers/monograph.rb +2 -0
  76. data/lib/pubid/astm/identifiers/research_report.rb +10 -0
  77. data/lib/pubid/astm/identifiers/standard.rb +10 -0
  78. data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
  79. data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
  80. data/lib/pubid/astm/identifiers.rb +1 -0
  81. data/lib/pubid/astm/parser.rb +1 -1
  82. data/lib/pubid/astm/renderer.rb +1 -1
  83. data/lib/pubid/astm/single_identifier.rb +31 -1
  84. data/lib/pubid/astm/urn_generator.rb +7 -5
  85. data/lib/pubid/astm.rb +1 -0
  86. data/lib/pubid/bipm/builder.rb +163 -0
  87. data/lib/pubid/bipm/identifier.rb +285 -0
  88. data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
  89. data/lib/pubid/bipm/identifiers/guide.rb +35 -0
  90. data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
  91. data/lib/pubid/bipm/identifiers/mep.rb +33 -0
  92. data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
  93. data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
  94. data/lib/pubid/bipm/identifiers.rb +15 -0
  95. data/lib/pubid/bipm/parser.rb +237 -0
  96. data/lib/pubid/bipm/renderer.rb +118 -0
  97. data/lib/pubid/bipm/urn_generator.rb +58 -0
  98. data/lib/pubid/bipm/urn_parser.rb +60 -0
  99. data/lib/pubid/bipm.rb +92 -0
  100. data/lib/pubid/bsi/builder.rb +62 -52
  101. data/lib/pubid/bsi/identifier.rb +0 -1
  102. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  103. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
  104. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
  105. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  106. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
  107. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
  108. data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
  109. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  110. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  111. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  112. data/lib/pubid/bsi/identifiers/handbook.rb +0 -2
  113. data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
  114. data/lib/pubid/bsi/identifiers/set.rb +11 -0
  115. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
  116. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  117. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  118. data/lib/pubid/bsi/parser.rb +1 -1
  119. data/lib/pubid/bsi/renderer.rb +71 -59
  120. data/lib/pubid/bsi/single_identifier.rb +64 -7
  121. data/lib/pubid/bsi/urn_generator.rb +11 -2
  122. data/lib/pubid/bsi.rb +7 -1
  123. data/lib/pubid/builder/base.rb +23 -11
  124. data/lib/pubid/bundled_identifier.rb +19 -9
  125. data/lib/pubid/calconnect/builder.rb +38 -0
  126. data/lib/pubid/calconnect/identifier.rb +121 -0
  127. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  128. data/lib/pubid/calconnect/identifiers.rb +9 -0
  129. data/lib/pubid/calconnect/parser.rb +54 -0
  130. data/lib/pubid/calconnect/renderer.rb +36 -0
  131. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  132. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  133. data/lib/pubid/calconnect.rb +83 -0
  134. data/lib/pubid/ccsds/builder.rb +1 -1
  135. data/lib/pubid/ccsds/identifier.rb +10 -3
  136. data/lib/pubid/ccsds/identifiers/base.rb +4 -2
  137. data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
  138. data/lib/pubid/ccsds/parser.rb +1 -1
  139. data/lib/pubid/ccsds/single_identifier.rb +2 -2
  140. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  141. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  142. data/lib/pubid/ccsds.rb +1 -0
  143. data/lib/pubid/cen_cenelec/builder.rb +131 -72
  144. data/lib/pubid/cen_cenelec/identifier.rb +115 -3
  145. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
  146. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
  147. data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
  148. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
  149. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
  150. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
  151. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -14
  152. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
  153. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  154. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
  155. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
  156. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
  157. data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
  158. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
  159. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
  160. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
  161. data/lib/pubid/cen_cenelec/parser.rb +1 -1
  162. data/lib/pubid/cen_cenelec/renderer.rb +55 -60
  163. data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
  164. data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
  165. data/lib/pubid/cen_cenelec.rb +104 -82
  166. data/lib/pubid/cie/builder.rb +149 -24
  167. data/lib/pubid/cie/identifier.rb +13 -4
  168. data/lib/pubid/cie/identifiers/bundle.rb +35 -5
  169. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  170. data/lib/pubid/cie/identifiers/conference.rb +11 -6
  171. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  172. data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
  173. data/lib/pubid/cie/identifiers/identical.rb +9 -9
  174. data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
  175. data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
  176. data/lib/pubid/cie/identifiers/standard.rb +43 -8
  177. data/lib/pubid/cie/identifiers/supplement.rb +27 -25
  178. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
  179. data/lib/pubid/cie/identifiers.rb +2 -0
  180. data/lib/pubid/cie/parser.rb +55 -6
  181. data/lib/pubid/cie/single_identifier.rb +40 -1
  182. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  183. data/lib/pubid/cie/urn_generator.rb +11 -8
  184. data/lib/pubid/cie.rb +7 -2
  185. data/lib/pubid/components/date.rb +21 -5
  186. data/lib/pubid/conformance/checks.rb +72 -0
  187. data/lib/pubid/conformance/corpus/case.rb +55 -0
  188. data/lib/pubid/conformance/corpus.rb +36 -0
  189. data/lib/pubid/conformance/generator.rb +212 -0
  190. data/lib/pubid/conformance/pending.rb +63 -0
  191. data/lib/pubid/conformance/runner.rb +153 -0
  192. data/lib/pubid/conformance.rb +55 -0
  193. data/lib/pubid/core.rb +2 -0
  194. data/lib/pubid/csa/builder.rb +48 -48
  195. data/lib/pubid/csa/composite_identifier.rb +18 -7
  196. data/lib/pubid/csa/identifier.rb +187 -80
  197. data/lib/pubid/csa/identifiers/bundled.rb +25 -9
  198. data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
  199. data/lib/pubid/csa/identifiers/cec.rb +44 -4
  200. data/lib/pubid/csa/identifiers/combined.rb +97 -69
  201. data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
  202. data/lib/pubid/csa/identifiers/package.rb +4 -4
  203. data/lib/pubid/csa/parser.rb +12 -8
  204. data/lib/pubid/csa/renderer.rb +13 -5
  205. data/lib/pubid/csa/single_identifier.rb +93 -4
  206. data/lib/pubid/csa/urn_generator.rb +9 -2
  207. data/lib/pubid/csa/wrapper_identifier.rb +43 -10
  208. data/lib/pubid/csa.rb +7 -1
  209. data/lib/pubid/doi/builder.rb +18 -0
  210. data/lib/pubid/doi/identifier.rb +49 -0
  211. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  212. data/lib/pubid/doi/identifiers.rb +9 -0
  213. data/lib/pubid/doi/parser.rb +52 -0
  214. data/lib/pubid/doi/renderer.rb +13 -0
  215. data/lib/pubid/doi.rb +56 -0
  216. data/lib/pubid/easc/builder.rb +55 -0
  217. data/lib/pubid/easc/identifier.rb +59 -0
  218. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  219. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  220. data/lib/pubid/easc/identifiers.rb +10 -0
  221. data/lib/pubid/easc/parser.rb +88 -0
  222. data/lib/pubid/easc/renderer.rb +48 -0
  223. data/lib/pubid/easc/urn_generator.rb +46 -0
  224. data/lib/pubid/easc/urn_parser.rb +57 -0
  225. data/lib/pubid/easc.rb +53 -0
  226. data/lib/pubid/ecma/builder.rb +45 -0
  227. data/lib/pubid/ecma/identifier.rb +147 -0
  228. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  229. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  230. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  231. data/lib/pubid/ecma/identifiers.rb +11 -0
  232. data/lib/pubid/ecma/parser.rb +76 -0
  233. data/lib/pubid/ecma/renderer.rb +67 -0
  234. data/lib/pubid/ecma/urn_generator.rb +46 -0
  235. data/lib/pubid/ecma/urn_parser.rb +51 -0
  236. data/lib/pubid/ecma.rb +68 -0
  237. data/lib/pubid/errors.rb +80 -0
  238. data/lib/pubid/etsi/builder.rb +13 -4
  239. data/lib/pubid/etsi/identifier.rb +1 -3
  240. data/lib/pubid/etsi/identifiers/base.rb +43 -11
  241. data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
  242. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
  243. data/lib/pubid/etsi/identifiers.rb +0 -1
  244. data/lib/pubid/etsi/parser.rb +9 -3
  245. data/lib/pubid/etsi/renderer.rb +8 -2
  246. data/lib/pubid/etsi.rb +6 -5
  247. data/lib/pubid/evs/builder.rb +26 -0
  248. data/lib/pubid/evs/identifier.rb +37 -0
  249. data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
  250. data/lib/pubid/evs/identifiers.rb +9 -0
  251. data/lib/pubid/evs/parser.rb +27 -0
  252. data/lib/pubid/evs/renderer.rb +30 -0
  253. data/lib/pubid/evs/urn_generator.rb +30 -0
  254. data/lib/pubid/evs/urn_parser.rb +80 -0
  255. data/lib/pubid/evs.rb +90 -0
  256. data/lib/pubid/export/exporter.rb +2 -1
  257. data/lib/pubid/export/flavor_exporter.rb +18 -3
  258. data/lib/pubid/export.rb +1 -0
  259. data/lib/pubid/format_detector.rb +1 -0
  260. data/lib/pubid/gb/builder.rb +45 -0
  261. data/lib/pubid/gb/identifier.rb +67 -0
  262. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  263. data/lib/pubid/gb/identifiers.rb +9 -0
  264. data/lib/pubid/gb/parser.rb +63 -0
  265. data/lib/pubid/gb/renderer.rb +35 -0
  266. data/lib/pubid/gb.rb +88 -0
  267. data/lib/pubid/gost/builder.rb +185 -0
  268. data/lib/pubid/gost/identifier.rb +47 -0
  269. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  270. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  271. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  272. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  273. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  274. data/lib/pubid/gost/identifiers.rb +13 -0
  275. data/lib/pubid/gost/parser.rb +105 -0
  276. data/lib/pubid/gost/renderer.rb +48 -0
  277. data/lib/pubid/gost/urn_generator.rb +46 -0
  278. data/lib/pubid/gost/urn_parser.rb +52 -0
  279. data/lib/pubid/gost.rb +50 -0
  280. data/lib/pubid/iala/builder.rb +22 -27
  281. data/lib/pubid/iala/identifier.rb +36 -8
  282. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  283. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  284. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  285. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  286. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  287. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  288. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  289. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  290. data/lib/pubid/iala/identifiers/report.rb +1 -1
  291. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  292. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  293. data/lib/pubid/iala/identifiers.rb +0 -1
  294. data/lib/pubid/iala/parser.rb +10 -2
  295. data/lib/pubid/iala/renderer.rb +1 -1
  296. data/lib/pubid/iala/urn_generator.rb +1 -1
  297. data/lib/pubid/iala/urn_parser.rb +24 -3
  298. data/lib/pubid/iala.rb +5 -4
  299. data/lib/pubid/iana/builder.rb +22 -0
  300. data/lib/pubid/iana/identifier.rb +140 -0
  301. data/lib/pubid/iana/identifiers/registry.rb +69 -0
  302. data/lib/pubid/iana/identifiers.rb +9 -0
  303. data/lib/pubid/iana/parser.rb +38 -0
  304. data/lib/pubid/iana/renderer.rb +32 -0
  305. data/lib/pubid/iana/urn_generator.rb +19 -0
  306. data/lib/pubid/iana/urn_parser.rb +24 -0
  307. data/lib/pubid/iana.rb +70 -0
  308. data/lib/pubid/identifier.rb +797 -26
  309. data/lib/pubid/identifier_metadata.rb +1 -0
  310. data/lib/pubid/idf/builder.rb +4 -4
  311. data/lib/pubid/idf/identifier.rb +18 -9
  312. data/lib/pubid/idf/parser.rb +3 -3
  313. data/lib/pubid/idf/renderer.rb +5 -5
  314. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  315. data/lib/pubid/idf/urn_generator.rb +1 -1
  316. data/lib/pubid/idf.rb +7 -1
  317. data/lib/pubid/iec/builder.rb +49 -32
  318. data/lib/pubid/iec/components.rb +0 -1
  319. data/lib/pubid/iec/identifier.rb +112 -77
  320. data/lib/pubid/iec/identifiers/amendment.rb +6 -2
  321. data/lib/pubid/iec/identifiers/base.rb +2 -2
  322. data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
  323. data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
  324. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  325. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
  326. data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
  327. data/lib/pubid/iec/identifiers/guide.rb +0 -16
  328. data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
  329. data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
  330. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
  331. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  332. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
  333. data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
  334. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  335. data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
  336. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
  337. data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
  338. data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
  339. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  340. data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
  341. data/lib/pubid/iec/identifiers/working_document.rb +24 -10
  342. data/lib/pubid/iec/identifiers.rb +1 -0
  343. data/lib/pubid/iec/parser.rb +53 -28
  344. data/lib/pubid/iec/renderer.rb +31 -18
  345. data/lib/pubid/iec/single_identifier.rb +34 -11
  346. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  347. data/lib/pubid/iec/urn_generator.rb +227 -61
  348. data/lib/pubid/iec/urn_parser.rb +42 -4
  349. data/lib/pubid/iec.rb +2 -6
  350. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  351. data/lib/pubid/ieee/aiee/identifier.rb +46 -62
  352. data/lib/pubid/ieee/aiee/parser.rb +1 -1
  353. data/lib/pubid/ieee/builder.rb +386 -69
  354. data/lib/pubid/ieee/compaction.rb +121 -0
  355. data/lib/pubid/ieee/components/draft.rb +47 -7
  356. data/lib/pubid/ieee/identifier.rb +1 -3
  357. data/lib/pubid/ieee/identifiers/adopted_standard.rb +62 -5
  358. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  359. data/lib/pubid/ieee/identifiers/base.rb +148 -18
  360. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  361. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  362. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  363. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +24 -3
  364. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  365. data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
  366. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  367. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
  368. data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
  369. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
  370. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  371. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  372. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  373. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  374. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  375. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  376. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  377. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  378. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  379. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  380. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  381. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  382. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  383. data/lib/pubid/ieee/identifiers.rb +2 -1
  384. data/lib/pubid/ieee/ire/builder.rb +7 -6
  385. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  386. data/lib/pubid/ieee/ire/parser.rb +1 -1
  387. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  388. data/lib/pubid/ieee/nesc/parser.rb +16 -15
  389. data/lib/pubid/ieee/parser.rb +462 -44
  390. data/lib/pubid/ieee/pre_parser.rb +1 -1
  391. data/lib/pubid/ieee/renderer.rb +158 -57
  392. data/lib/pubid/ieee/typed_stages.rb +12 -1
  393. data/lib/pubid/ieee/urn_generator.rb +35 -8
  394. data/lib/pubid/ieee.rb +63 -4
  395. data/lib/pubid/ieee_debug.rb +1 -0
  396. data/lib/pubid/ietf/builder.rb +78 -0
  397. data/lib/pubid/ietf/identifier.rb +5 -0
  398. data/lib/pubid/ietf/identifiers/base.rb +72 -0
  399. data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
  400. data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
  401. data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
  402. data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
  403. data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
  404. data/lib/pubid/ietf/identifiers/std.rb +36 -0
  405. data/lib/pubid/ietf/identifiers.rb +14 -0
  406. data/lib/pubid/ietf/parser.rb +61 -0
  407. data/lib/pubid/ietf/renderer.rb +64 -0
  408. data/lib/pubid/ietf/urn_generator.rb +37 -0
  409. data/lib/pubid/ietf/urn_parser.rb +43 -0
  410. data/lib/pubid/ietf.rb +86 -0
  411. data/lib/pubid/iho/identifier.rb +1 -3
  412. data/lib/pubid/iho/identifiers/base.rb +11 -10
  413. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  414. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  415. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  416. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  417. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  418. data/lib/pubid/iho/identifiers.rb +0 -1
  419. data/lib/pubid/iho/parser.rb +1 -1
  420. data/lib/pubid/iho.rb +8 -7
  421. data/lib/pubid/isbn/builder.rb +44 -0
  422. data/lib/pubid/isbn/check_digit.rb +53 -0
  423. data/lib/pubid/isbn/identifier.rb +81 -0
  424. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  425. data/lib/pubid/isbn/identifiers.rb +9 -0
  426. data/lib/pubid/isbn/parser.rb +45 -0
  427. data/lib/pubid/isbn/renderer.rb +16 -0
  428. data/lib/pubid/isbn.rb +53 -0
  429. data/lib/pubid/iso/builder.rb +9 -4
  430. data/lib/pubid/iso/bundled_identifier.rb +5 -3
  431. data/lib/pubid/iso/combined_identifier.rb +6 -4
  432. data/lib/pubid/iso/identifier.rb +29 -8
  433. data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
  434. data/lib/pubid/iso/normalizer.rb +2 -2
  435. data/lib/pubid/iso/parser.rb +17 -13
  436. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  437. data/lib/pubid/iso/urn_generator.rb +4 -1
  438. data/lib/pubid/iso/urn_parser.rb +1 -1
  439. data/lib/pubid/iso.rb +7 -1
  440. data/lib/pubid/itu/builder.rb +230 -29
  441. data/lib/pubid/itu/components/code.rb +48 -5
  442. data/lib/pubid/itu/components/designation.rb +35 -0
  443. data/lib/pubid/itu/components.rb +1 -0
  444. data/lib/pubid/itu/identifier.rb +1 -3
  445. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  446. data/lib/pubid/itu/identifiers/amendment.rb +7 -29
  447. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  448. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  449. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  450. data/lib/pubid/itu/identifiers/base.rb +357 -25
  451. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  452. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  453. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  454. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  455. data/lib/pubid/itu/identifiers/question.rb +63 -0
  456. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  457. data/lib/pubid/itu/identifiers/report.rb +39 -0
  458. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  459. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  460. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  461. data/lib/pubid/itu/identifiers.rb +10 -1
  462. data/lib/pubid/itu/model.rb +1 -1
  463. data/lib/pubid/itu/parser.rb +481 -27
  464. data/lib/pubid/itu/urn_generator.rb +36 -6
  465. data/lib/pubid/itu/urn_parser.rb +8 -0
  466. data/lib/pubid/itu.rb +12 -3
  467. data/lib/pubid/jcgm/builder.rb +24 -14
  468. data/lib/pubid/jcgm/identifier.rb +10 -0
  469. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  470. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  471. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  472. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  473. data/lib/pubid/jcgm/identifiers.rb +2 -0
  474. data/lib/pubid/jcgm/parser.rb +74 -7
  475. data/lib/pubid/jcgm/renderer.rb +33 -12
  476. data/lib/pubid/jcgm/single_identifier.rb +84 -6
  477. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  478. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  479. data/lib/pubid/jcgm/urn_parser.rb +164 -10
  480. data/lib/pubid/jcgm.rb +10 -0
  481. data/lib/pubid/jis/identifier.rb +62 -3
  482. data/lib/pubid/jis/parser.rb +1 -1
  483. data/lib/pubid/jis.rb +1 -0
  484. data/lib/pubid/nist/builder.rb +29 -9
  485. data/lib/pubid/nist/caster.rb +7 -45
  486. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  487. data/lib/pubid/nist/components/stage.rb +2 -2
  488. data/lib/pubid/nist/components/supplement.rb +5 -2
  489. data/lib/pubid/nist/configuration.rb +6 -2
  490. data/lib/pubid/nist/identifier.rb +1 -3
  491. data/lib/pubid/nist/identifiers/base.rb +133 -39
  492. data/lib/pubid/nist/identifiers/circular.rb +10 -3
  493. data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
  494. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  495. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  496. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +8 -2
  497. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
  498. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  499. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  500. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  501. data/lib/pubid/nist/identifiers/handbook.rb +10 -3
  502. data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
  503. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  504. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
  505. data/lib/pubid/nist/identifiers/monograph.rb +15 -8
  506. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  507. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  508. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  509. data/lib/pubid/nist/identifiers/report.rb +15 -7
  510. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  511. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  512. data/lib/pubid/nist/identifiers.rb +0 -1
  513. data/lib/pubid/nist/parser.rb +27 -4
  514. data/lib/pubid/nist/preprocessor.rb +15 -0
  515. data/lib/pubid/nist/router.rb +2 -2
  516. data/lib/pubid/nist/series/ir.rb +0 -3
  517. data/lib/pubid/nist/supplement_identifier.rb +24 -9
  518. data/lib/pubid/nist.rb +19 -13
  519. data/lib/pubid/oasis/builder.rb +79 -0
  520. data/lib/pubid/oasis/identifier.rb +160 -0
  521. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  522. data/lib/pubid/oasis/identifiers.rb +9 -0
  523. data/lib/pubid/oasis/parser.rb +34 -0
  524. data/lib/pubid/oasis/renderer.rb +29 -0
  525. data/lib/pubid/oasis/urn_generator.rb +25 -0
  526. data/lib/pubid/oasis/urn_parser.rb +22 -0
  527. data/lib/pubid/oasis.rb +80 -0
  528. data/lib/pubid/ogc/builder.rb +33 -0
  529. data/lib/pubid/ogc/identifier.rb +81 -0
  530. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  531. data/lib/pubid/ogc/identifiers.rb +10 -0
  532. data/lib/pubid/ogc/parser.rb +40 -0
  533. data/lib/pubid/ogc/renderer.rb +33 -0
  534. data/lib/pubid/ogc/urn_generator.rb +14 -0
  535. data/lib/pubid/ogc/urn_parser.rb +22 -0
  536. data/lib/pubid/ogc.rb +72 -0
  537. data/lib/pubid/oiml/builder.rb +36 -8
  538. data/lib/pubid/oiml/identifier.rb +9 -1
  539. data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
  540. data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
  541. data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
  542. data/lib/pubid/oiml/identifiers/document.rb +2 -0
  543. data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
  544. data/lib/pubid/oiml/identifiers/guide.rb +2 -0
  545. data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
  546. data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
  547. data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
  548. data/lib/pubid/oiml/identifiers.rb +1 -0
  549. data/lib/pubid/oiml/parser.rb +12 -13
  550. data/lib/pubid/oiml/renderer.rb +13 -13
  551. data/lib/pubid/oiml/single_identifier.rb +41 -37
  552. data/lib/pubid/oiml/supplement_identifier.rb +36 -9
  553. data/lib/pubid/oiml/urn_parser.rb +23 -6
  554. data/lib/pubid/oiml.rb +10 -0
  555. data/lib/pubid/omg/builder.rb +20 -0
  556. data/lib/pubid/omg/identifier.rb +61 -0
  557. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  558. data/lib/pubid/omg/identifiers.rb +9 -0
  559. data/lib/pubid/omg/parser.rb +93 -0
  560. data/lib/pubid/omg/renderer.rb +31 -0
  561. data/lib/pubid/omg.rb +52 -0
  562. data/lib/pubid/parser/grammar.rb +74 -0
  563. data/lib/pubid/parser.rb +2 -0
  564. data/lib/pubid/parsers/mr_string.rb +120 -7
  565. data/lib/pubid/plateau/builder.rb +8 -4
  566. data/lib/pubid/plateau/identifier.rb +1 -3
  567. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  568. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  569. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  570. data/lib/pubid/plateau/identifiers.rb +0 -1
  571. data/lib/pubid/plateau/parser.rb +16 -6
  572. data/lib/pubid/plateau/renderer.rb +1 -1
  573. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  574. data/lib/pubid/plateau.rb +14 -4
  575. data/lib/pubid/prefixes_support.rb +1 -0
  576. data/lib/pubid/renderers/annotator.rb +233 -0
  577. data/lib/pubid/renderers/base.rb +13 -0
  578. data/lib/pubid/renderers/directives_renderer.rb +3 -3
  579. data/lib/pubid/renderers/human_readable.rb +6 -4
  580. data/lib/pubid/renderers/mr_string.rb +54 -6
  581. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  582. data/lib/pubid/renderers.rb +1 -0
  583. data/lib/pubid/rendering/numbering.rb +25 -7
  584. data/lib/pubid/rendering/supplement.rb +4 -4
  585. data/lib/pubid/rendering.rb +1 -0
  586. data/lib/pubid/sae/builder.rb +1 -1
  587. data/lib/pubid/sae/identifier.rb +1 -3
  588. data/lib/pubid/sae/identifiers/base.rb +19 -9
  589. data/lib/pubid/sae/identifiers.rb +0 -1
  590. data/lib/pubid/sae/parser.rb +1 -1
  591. data/lib/pubid/sae.rb +4 -3
  592. data/lib/pubid/schema/declaration.rb +33 -0
  593. data/lib/pubid/schema/error.rb +14 -0
  594. data/lib/pubid/schema/identifier_type.rb +23 -0
  595. data/lib/pubid/schema/loader.rb +117 -0
  596. data/lib/pubid/schema/typed_stage.rb +24 -0
  597. data/lib/pubid/schema.rb +25 -0
  598. data/lib/pubid/tgpp/builder.rb +41 -0
  599. data/lib/pubid/tgpp/identifier.rb +107 -0
  600. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  601. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  602. data/lib/pubid/tgpp/identifiers.rb +11 -0
  603. data/lib/pubid/tgpp/parser.rb +78 -0
  604. data/lib/pubid/tgpp/renderer.rb +52 -0
  605. data/lib/pubid/tgpp/urn_generator.rb +39 -0
  606. data/lib/pubid/tgpp/urn_parser.rb +30 -0
  607. data/lib/pubid/tgpp.rb +84 -0
  608. data/lib/pubid/type_resolver.rb +74 -0
  609. data/lib/pubid/un/builder.rb +42 -0
  610. data/lib/pubid/un/identifier.rb +40 -0
  611. data/lib/pubid/un/identifiers/document.rb +24 -0
  612. data/lib/pubid/un/identifiers.rb +9 -0
  613. data/lib/pubid/un/parser.rb +25 -0
  614. data/lib/pubid/un/renderer.rb +11 -0
  615. data/lib/pubid/un.rb +47 -0
  616. data/lib/pubid/urn_parser/errors.rb +8 -1
  617. data/lib/pubid/urn_parser.rb +1 -0
  618. data/lib/pubid/utils.rb +1 -0
  619. data/lib/pubid/version.rb +1 -1
  620. data/lib/pubid/w3c/builder.rb +55 -0
  621. data/lib/pubid/w3c/identifier.rb +130 -0
  622. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  623. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  624. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  625. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  626. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  627. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  628. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  629. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  630. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  631. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  632. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  633. data/lib/pubid/w3c/identifiers.rb +25 -0
  634. data/lib/pubid/w3c/parser.rb +43 -0
  635. data/lib/pubid/w3c/renderer.rb +35 -0
  636. data/lib/pubid/w3c/urn_generator.rb +18 -0
  637. data/lib/pubid/w3c/urn_parser.rb +36 -0
  638. data/lib/pubid/w3c.rb +68 -0
  639. data/lib/pubid/xsf/builder.rb +17 -0
  640. data/lib/pubid/xsf/identifier.rb +66 -0
  641. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  642. data/lib/pubid/xsf/identifiers.rb +9 -0
  643. data/lib/pubid/xsf/parser.rb +38 -0
  644. data/lib/pubid/xsf/renderer.rb +23 -0
  645. data/lib/pubid/xsf/urn_generator.rb +13 -0
  646. data/lib/pubid/xsf/urn_parser.rb +18 -0
  647. data/lib/pubid/xsf.rb +82 -0
  648. data/lib/pubid.rb +424 -22
  649. data/lib/tasks/conformance.rake +34 -0
  650. data/lib/tasks/docs.rake +3 -3
  651. data/lib/tasks/schema.rake +88 -0
  652. data/schema/core/joint_prefixes.yaml +24 -0
  653. data/schema/iec.yaml +1017 -0
  654. data/schema/iso.yaml +1586 -0
  655. data/schema/schema.schema.yaml +96 -0
  656. metadata +241 -19
  657. data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
  658. data/archived-gems/pubid-iec/stages.yaml +0 -129
  659. data/archived-gems/pubid-iec/update_codes.yaml +0 -67
  660. data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
  661. data/archived-gems/pubid-iso/stages.yaml +0 -106
  662. data/archived-gems/pubid-iso/update_codes.yaml +0 -4
  663. data/archived-gems/pubid-itu/i18n.yaml +0 -13
  664. data/archived-gems/pubid-itu/series.yaml +0 -42
  665. data/archived-gems/pubid-nist/publishers.yaml +0 -6
  666. data/archived-gems/pubid-nist/update_codes.yaml +0 -93
  667. data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
  668. data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
  669. data/lib/pubid/cie/components/code.rb +0 -80
  670. data/lib/pubid/iala/identifiers/base.rb +0 -14
  671. data/lib/pubid/iec/components/code.rb +0 -36
  672. /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
@@ -4,7 +4,7 @@ module Pubid
4
4
  module Ieee
5
5
  # Pre-parser for IEEE identifiers.
6
6
  #
7
- # Owns all regex/scan/dispatch logic that used to live on Identifiers::Base.parse.
7
+ # Owns all regex/scan/dispatch logic that used to live on Identifier.parse.
8
8
  # Base.parse becomes a thin orchestrator that asks PreParser for a decision
9
9
  # and then routes to the right builder.
10
10
  module PreParser
@@ -17,8 +17,52 @@ module Pubid
17
17
  # identifier's own publisher/code/relationship helpers.
18
18
  class Renderer < ::Pubid::Renderers::Base
19
19
  def render(context: nil, **opts)
20
- id = @id
20
+ # IEEE attaches the trademark mark to the document number, before the
21
+ # year and every suffix ("IEEE Std 802.3®-2018"), so the mark is
22
+ # emitted by whichever method renders the number rather than appended
23
+ # to the finished string. A renderer instance is built per render call
24
+ # (Pubid::Identifier#render), so the flag is safe as instance state.
25
+ @trademark = opts[:trademark]
26
+
27
+ render_id(@id)
28
+ end
29
+
30
+ private
31
+
32
+ # Trademark mark for a document number, or "" when the flag is off.
33
+ # @param number [String, nil] bare document number
34
+ # @param prefix [String, nil] letter series of the code
35
+ # @param publishers [Array<String>] printed publisher tokens — the ®
36
+ # series belongs to IEEE, not to another body numbering a document 802
37
+ def mark(number, prefix = nil, publishers: nil)
38
+ return "" unless @trademark
21
39
 
40
+ Pubid::Ieee.trademark_symbol_for(number, prefix, publishers: publishers)
41
+ end
42
+
43
+ # The publisher tokens an identifier prints, for the ® decision.
44
+ def publishers_of(id)
45
+ return id.publishers if id.respond_to?(:publishers) && id.publishers
46
+
47
+ copublishers = id.copublisher if id.respond_to?(:copublisher)
48
+ [id.publisher, *copublishers].compact
49
+ end
50
+
51
+ # Compose a child identifier, propagating the trademark flag only when it
52
+ # is safe. A foreign (non-IEEE) leaf may not accept the `trademark:`
53
+ # keyword at all — Pubid::Nist's `to_s(format = :short)` would silently
54
+ # swallow it as a positional Hash, and Pubid::Iso's would raise — and an
55
+ # adopted or parenthetical child is not the IEEE document being marked.
56
+ def child_to_s(child, **opts)
57
+ return child.to_s(**opts) unless @trademark &&
58
+ child.is_a?(Pubid::Ieee::Identifier)
59
+
60
+ child.to_s(**opts, trademark: true)
61
+ end
62
+
63
+ # Dispatch to the type-specific renderer, returning the composed string
64
+ # (each branch inserts the trademark mark at its own number boundary).
65
+ def render_id(id)
22
66
  case id
23
67
  when Identifiers::DualPublished
24
68
  render_dual_published(id)
@@ -28,6 +72,8 @@ module Pubid
28
72
  render_adopted_standard(id)
29
73
  when Identifiers::RedlinedStandard
30
74
  render_redlined_standard(id)
75
+ when Identifiers::Amendment
76
+ render_amendment(id)
31
77
  when Identifiers::Corrigendum
32
78
  render_corrigendum(id)
33
79
  when Identifiers::InterpretationIdentifier
@@ -45,14 +91,12 @@ module Pubid
45
91
  when Identifiers::SiStandard
46
92
  render_si_standard(id)
47
93
  when Identifiers::JointDevelopment
48
- id.to_s
94
+ child_to_s(id)
49
95
  else
50
96
  render_base(id)
51
97
  end
52
98
  end
53
99
 
54
- private
55
-
56
100
  # ------------------------------------------------------------------
57
101
  # Base IEEE identifier rendering
58
102
  # ------------------------------------------------------------------
@@ -70,12 +114,18 @@ module Pubid
70
114
  # Draft status
71
115
  parts << id.draft_status if id.draft_status
72
116
 
73
- # Type - only render for IEEE/AIEE publishers, and only for non-projects
117
+ # Type - only render for IEEE/AIEE publishers, and only for non-projects.
118
+ # An unapproved draft is not yet a standard, so per IEEE guidance the
119
+ # "Std" token is dropped from the type when draft_status is "Unapproved"
120
+ # (e.g. "Draft Std" -> "Draft", "Std" -> "").
74
121
  should_render_type = id.publisher&.match?(/^(IEEE|AIEE)/)
75
122
 
76
123
  if should_render_type && !id.typed_stage&.project_status && id.type && !id.type.to_s.strip.empty? && id.type != "P"
77
124
  type_str = id.type.dup
78
125
  type_str = type_str.sub(/^P/, "") if type_str.start_with?("P")
126
+ if id.draft_status.to_s.match?(/unapproved/i)
127
+ type_str = type_str.gsub(/\bStd\b/i, "").squeeze(" ").strip
128
+ end
79
129
  parts << type_str unless type_str.strip.empty?
80
130
  end
81
131
 
@@ -88,9 +138,19 @@ module Pubid
88
138
  result = "P#{result}"
89
139
  end
90
140
 
141
+ # Trademark mark — right after the number and its parts, before the
142
+ # year, the revision, the draft and every other suffix.
143
+ result += mark(id.code_obj.number, id.code_obj.prefix,
144
+ publishers: publishers_of(id))
145
+
91
146
  # Only attach year to code if there's no edition, no month, and no draft
92
147
  result += "-#{id.year}" if id.year && !id.draft_obj && !id.edition && !id.month
93
148
 
149
+ # Append the numbered/lettered revision inline, in IEEE's native
150
+ # position — right after the code number and before the draft
151
+ # ("P802.16Rev2/D3"). Keeps a revision distinct from its base standard.
152
+ result += "Rev#{id.revision}" if id.revision
153
+
94
154
  # Append draft to code - with or without space based on original format
95
155
  if id.draft_obj
96
156
  result += id.space_before_draft ? " #{id.draft_obj}" : id.draft_obj.to_s
@@ -99,11 +159,9 @@ module Pubid
99
159
  # Append interpretation notation (/INT)
100
160
  result += "/INT" if id.interpretation
101
161
 
102
- # Append conformance notation (/ConformanceNN-YYYY)
103
- if id.conf_number
104
- result += "/Conformance#{id.conf_number}"
105
- result += "-#{id.conf_year}" if id.conf_year
106
- end
162
+ # Conformance is always built as a ConformanceIdentifier wrapper
163
+ # (render_conformance), never inline on a base standard — the base no
164
+ # longer carries a conf_number attribute.
107
165
 
108
166
  # Append ASHRAE joint publication (/ASHRAE Guideline NN-YYYY)
109
167
  if id.ashrae_number
@@ -138,31 +196,30 @@ module Pubid
138
196
  result += ", #{id.month}"
139
197
  result += " #{id.day}" if id.day
140
198
  if id.year && !id.edition
141
- result += ", #{id.year}"
199
+ result += " #{id.year}"
142
200
  end
143
201
  end
144
202
 
145
- # Add parenthetical content if present
203
+ # Bounded parenthetical markers only. The unbounded relationship/
204
+ # amendment narrative (relationships, revision_of, amendment_to,
205
+ # adoption, note) is deliberately NOT rendered here: an
206
+ # "as amended by …" list can run 300+ chars, and an identifier's to_s
207
+ # is used by consumers (relaton) as a document number and filename. The
208
+ # narrative is preserved on the runtime accessors (id.relationships
209
+ # etc.), just not embedded in the identifier string.
146
210
  parentheticals = []
147
211
 
212
+ # Reaffirmation year — a bounded status marker.
148
213
  reaff = id.reaffirmed
149
- if reaff && !reaff.to_s.strip.empty?
150
- parentheticals << "(R#{reaff})"
151
- end
214
+ parentheticals << "(R#{reaff})" if reaff && !reaff.to_s.strip.empty?
152
215
 
216
+ # The catch-all parenthetical is a bounded, printed identity token, not
217
+ # relationship prose (e.g. the "S-135 (IPCEA P46-426)" co-designation).
218
+ # Long amendment narratives match the structural relationship grammar
219
+ # and land in `relationships`, never in this catch-all, so it stays
220
+ # bounded.
153
221
  if id.parenthetical_content
154
222
  parentheticals << "(#{id.parenthetical_content})"
155
- elsif id.relationships && !id.relationships.empty?
156
- relationship_str = id.relationships.join(" / ")
157
- parentheticals << "(#{relationship_str})"
158
- elsif id.revision_of
159
- parentheticals << "(Revision of IEEE Std #{id.revision_of})"
160
- elsif id.amendment_to
161
- parentheticals << "(Amendment to IEEE Std #{id.amendment_to})"
162
- elsif id.adoption
163
- parentheticals << "(Adoption of #{id.adoption})"
164
- elsif id.note && !id.note.to_s.strip.empty?
165
- parentheticals << "(#{id.note})"
166
223
  end
167
224
 
168
225
  result += " #{parentheticals.join(' ')}" unless parentheticals.empty?
@@ -181,15 +238,19 @@ module Pubid
181
238
  # ------------------------------------------------------------------
182
239
 
183
240
  def render_dual_published(id)
184
- "#{id.first_identifier} and #{id.second_identifier}"
241
+ "#{child_to_s(id.first_identifier)} and " \
242
+ "#{child_to_s(id.second_identifier)}"
185
243
  end
186
244
 
187
245
  def render_dual_identifier(id)
188
- "#{id.first_identifier} and #{id.second_identifier}"
246
+ "#{child_to_s(id.first_identifier)} and " \
247
+ "#{child_to_s(id.second_identifier)}"
189
248
  end
190
249
 
191
250
  def render_adopted_standard(id)
192
- result = id.ieee_identifier.to_s
251
+ # Only the IEEE designation is marked; the adopted identifiers are
252
+ # other bodies' documents (and may be foreign pubid objects).
253
+ result = child_to_s(id.ieee_identifier)
193
254
  if id.adopted_identifiers && !id.adopted_identifiers.empty?
194
255
  adopted_strs = id.adopted_identifiers.map(&:to_s)
195
256
  result += " (#{adopted_strs.join(' and ')})"
@@ -198,68 +259,101 @@ module Pubid
198
259
  end
199
260
 
200
261
  def render_redlined_standard(id)
201
- result = id.base_identifier.to_s
262
+ result = child_to_s(id.base)
263
+ # NOTE: currently unreachable — a redline is built as a flat
264
+ # `redline: true` on a plain Standard (see the redline invariant in
265
+ # CLAUDE.md), so determine_identifier_class never routes here. Kept for
266
+ # completeness; if this path is ever revived, note `revision_of` is a
267
+ # bounded single-id reference, unlike the unbounded relationship
268
+ # narrative that render_base deliberately drops.
202
269
  result += " (Revision of #{id.revision_of})" if id.revision_of
203
270
  result += " - Redline" if id.redline
204
271
  result
205
272
  end
206
273
 
207
274
  def render_corrigendum(id)
208
- return render_base(id) unless id.base_identifier
275
+ return render_base(id) unless id.base
209
276
 
210
- result = id.base_identifier.to_s
277
+ result = child_to_s(id.base)
211
278
  result += "/Cor"
212
- result += ". " if id.cor_number # Add period and space for formal format
213
- result += id.cor_number if id.cor_number
214
- result += "-#{id.cor_year}" if id.cor_year
279
+ result += ". " if id.number # Add period and space for formal format
280
+ result += id.number if id.number
281
+ result += "-#{id.year}" if id.year
282
+ result
283
+ end
284
+
285
+ def render_amendment(id)
286
+ return render_base(id) unless id.base
287
+
288
+ result = child_to_s(id.base)
289
+ result += "/Amd"
290
+ result += " #{id.number}" if id.number # canonical "/Amd 4-2020"
291
+ result += "-#{id.year}" if id.year
215
292
  result
216
293
  end
217
294
 
218
295
  def render_interpretation(id)
219
- return render_base(id) unless id.base_identifier
296
+ return render_base(id) unless id.base
220
297
 
221
- result = id.base_identifier.to_s
298
+ result = child_to_s(id.base)
222
299
  result += "/INT"
223
- result += "-#{id.int_year}" if id.int_year
300
+ result += "-#{id.year}" if id.year
224
301
  result
225
302
  end
226
303
 
227
304
  def render_conformance(id)
228
- return render_base(id) unless id.base_identifier
305
+ return render_base(id) unless id.base
229
306
 
230
- result = id.base_identifier.to_s
231
- result += "/Conformance#{id.conf_number}" if id.conf_number
232
- result += "-#{id.conf_year}" if id.conf_year
307
+ result = child_to_s(id.base)
308
+ result += "/Conformance#{id.number}" if id.number
309
+ result += "-#{id.year}" if id.year
233
310
  result
234
311
  end
235
312
 
236
313
  def render_multi_numbered(id)
237
- return id.primary_identifier.to_s unless id.secondary_identifier
314
+ return child_to_s(id.primary_identifier) unless id.secondary_identifier
315
+
316
+ # Co-equal designations: each carries its own mark, before its own
317
+ # suffixes, as IEEE prints them.
318
+ primary = child_to_s(id.primary_identifier)
319
+ secondary = child_to_s(id.secondary_identifier)
238
320
 
239
321
  secondary_code = id.secondary_identifier.code.to_s
240
322
  if secondary_code.start_with?("C") && secondary_code.match?(/^C\d+\./)
241
- "#{id.primary_identifier}/#{id.secondary_identifier}"
323
+ # A cross-reference prints the bare second designation after the
324
+ # slash — "IEEE Std 1299/C62.22.1-1996" — not a second full
325
+ # reference, so this branch must not reuse `secondary`, which
326
+ # carries its own "IEEE Std " prefix.
327
+ "#{primary}/#{secondary_code}"
242
328
  else
243
- "#{id.primary_identifier} and #{id.secondary_identifier}"
329
+ "#{primary} and #{secondary}"
244
330
  end
245
331
  end
246
332
 
247
333
  def render_parenthetical(id)
248
- result = id.base_identifier.to_s
334
+ # The mark belongs on the base; the parenthetical is a separate token.
335
+ result = child_to_s(id.base)
249
336
  result += " (#{id.parenthetical_identifier})" if id.parenthetical_identifier
250
337
  result
251
338
  end
252
339
 
253
340
  def render_csa_dual_published(id)
341
+ # csa_identifier is a Pubid::Csa object — never marked.
254
342
  csa_str = id.csa_identifier.to_s
255
343
  csa_str = "CSA #{csa_str}" unless csa_str.start_with?("CSA", "CAN/")
256
344
 
257
- "#{id.ieee_identifier}/#{csa_str}"
345
+ "#{child_to_s(id.ieee_identifier)}/#{csa_str}"
258
346
  end
259
347
 
260
348
  def render_iec_ieee_copublished(id)
261
349
  result = "IEC/IEEE"
262
- result += " #{id.copublished_number}" if id.copublished_number
350
+ # copublished_number glues the parts and the publication year onto the
351
+ # number, so the mark is spliced in by that single implementation
352
+ # rather than rebuilt here; with the flag off it is passed "".
353
+ if id.copublished_number
354
+ result += " #{id.copublished_number(mark(id.number,
355
+ publishers: %w[IEC IEEE]))}"
356
+ end
263
357
  result += id.draft_info if id.draft_info
264
358
  result += " IEC:#{id.iec_year}" if id.iec_year
265
359
  result += " #{id.date_info}" if id.date_info
@@ -279,8 +373,11 @@ module Pubid
279
373
  "SI"
280
374
  end
281
375
 
282
- # Code (number) with draft version for PSI
376
+ # Code (number) with draft version for PSI — the mark goes after the
377
+ # code, before the draft and the date.
283
378
  code_part = id.code.to_s
379
+ code_part += mark(id.code_obj&.number, id.code_obj&.prefix,
380
+ publishers: publishers_of(id))
284
381
  if id.draft_obj
285
382
  code_part += "/D#{id.draft_obj.version}"
286
383
  end
@@ -293,14 +390,18 @@ module Pubid
293
390
  parts << "-#{id.year}"
294
391
  end
295
392
 
296
- # Relationships (if present)
297
- result = parts.join(" ")
298
- if id.relationships && !id.relationships.empty?
299
- rel_strs = id.relationships.map(&:to_s)
300
- result += " (#{rel_strs.join(' / ')})"
301
- end
302
-
303
- result
393
+ # Join parts with spaces, but don't insert a space before parts
394
+ # that start with "-" or "," (e.g., "-2010", ", July 2014") so the
395
+ # SI form renders as "SI 10-2010" not "SI 10 -2010". The descriptive
396
+ # relationships narrative is deliberately kept out of to_s (see
397
+ # render_base); it stays reachable on id.relationships.
398
+ parts.each_with_object([]) do |part, acc|
399
+ if acc.empty? || part.to_s.start_with?("-", ",")
400
+ acc << part.to_s
401
+ else
402
+ acc << " " << part.to_s
403
+ end
404
+ end.join
304
405
  end
305
406
  end
306
407
  end
@@ -101,7 +101,7 @@ module Pubid
101
101
  ),
102
102
 
103
103
  Components::TypedStage.new(
104
- abbr: ["CD", "CD2", "CD3"],
104
+ abbr: ["CD", "CD1", "CD2", "CD3", "CD4"],
105
105
  stage_code: "committee_draft",
106
106
  type_code: "draft",
107
107
  ieee_draft_equivalent: "D2-D3",
@@ -110,6 +110,17 @@ module Pubid
110
110
  project_status: true,
111
111
  ),
112
112
 
113
+ # Committee Draft for Vote (IEC/ISO-led historical stage)
114
+ Components::TypedStage.new(
115
+ abbr: ["CDV"],
116
+ stage_code: "committee_draft_for_vote",
117
+ type_code: "draft",
118
+ ieee_draft_equivalent: "D2-D3",
119
+ iso_stage_equivalent: "CDV",
120
+ approval_status: "unapproved",
121
+ project_status: true,
122
+ ),
123
+
113
124
  Components::TypedStage.new(
114
125
  abbr: ["DIS"],
115
126
  stage_code: "draft_international_standard",
@@ -17,7 +17,8 @@ module Pubid
17
17
  cc = code_component
18
18
  parts << cc if cc
19
19
 
20
- parts << identifier.year if identifier.year
20
+ yc = year_component
21
+ parts << yc if yc
21
22
 
22
23
  dc = draft_component
23
24
  parts << dc if dc
@@ -39,11 +40,9 @@ module Pubid
39
40
  parts << "int"
40
41
  end
41
42
 
42
- if special_type != "conformance" && identifier.conf_number
43
- conf = "conf.#{identifier.conf_number}"
44
- conf += "-#{identifier.conf_year}" if identifier.conf_year
45
- parts << conf
46
- end
43
+ # Conformance is always a ConformanceIdentifier wrapper (special_type
44
+ # "conformance"), never inline on a base standard — the base no longer
45
+ # carries a conf_number attribute, so there is no inline conf part.
47
46
 
48
47
  if identifier.ashrae_number
49
48
  ashrae = "ashrae.#{identifier.ashrae_number}"
@@ -128,8 +127,7 @@ module Pubid
128
127
  end
129
128
 
130
129
  def publisher_component
131
- pub = identifier.publisher || "IEEE"
132
- pub = pub.to_s.downcase
130
+ pub = normalized_publisher
133
131
 
134
132
  if identifier.copublisher&.any?
135
133
  copubs = identifier.copublisher.map(&:to_s).map(&:downcase)
@@ -139,6 +137,18 @@ module Pubid
139
137
  pub
140
138
  end
141
139
 
140
+ # A dual-published document has TWO publishers, and
141
+ # DualPublished#publisher returns them as an Array — which `to_s`
142
+ # rendered into the URN as a literal Ruby array literal, brackets and
143
+ # quotes included: `urn:ieee:["ieee", "asme"]`. Join them the same way a
144
+ # copublisher list is joined above.
145
+ def normalized_publisher
146
+ names = Array(identifier.publisher)
147
+ .map { |p| p.to_s.downcase }.reject(&:empty?)
148
+
149
+ names.empty? ? "ieee" : names.join("-")
150
+ end
151
+
142
152
  def type_component
143
153
  return nil unless identifier.type
144
154
 
@@ -154,6 +164,23 @@ module Pubid
154
164
  identifier.code_obj.to_s
155
165
  end
156
166
 
167
+ # A multi-designation wrapper (AdoptedStandard, DualPublished,
168
+ # MultiNumberedIdentifier) carries no year of its own — the year sits on
169
+ # the designation it wraps — so the URN dropped it and two editions of
170
+ # one document produced the SAME urn: "AIEE No 15-1944" and
171
+ # "AIEE No 15-1959" both gave urn:ieee:aiee:15.
172
+ #
173
+ # Fixed here, in the one place that reads the year, rather than by
174
+ # defining a `#year` method on each wrapper: `year` is a lutaml attribute
175
+ # on the base and a method of that name would shadow its generated
176
+ # accessor. `#root` already walks to the wrapped designation.
177
+ def year_component
178
+ return identifier.year if identifier.year
179
+
180
+ root = identifier.root
181
+ root.equal?(identifier) ? nil : root.year
182
+ end
183
+
157
184
  def draft_component
158
185
  return nil unless identifier.draft_obj
159
186
 
data/lib/pubid/ieee.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Ieee
5
6
  extend Pubid::PrefixesSupport
@@ -12,12 +13,13 @@ module Pubid
12
13
 
13
14
  autoload :Aiee, "#{__dir__}/ieee/aiee"
14
15
  autoload :Builder, "#{__dir__}/ieee/builder"
15
- autoload :Identifier, "#{__dir__}/ieee/identifier"
16
+ autoload :Identifier, "#{__dir__}/ieee/identifiers/base"
16
17
  autoload :Identifiers, "#{__dir__}/ieee/identifiers"
17
18
  autoload :Ire, "#{__dir__}/ieee/ire"
18
19
  autoload :Nesc, "#{__dir__}/ieee/nesc"
19
20
  autoload :Parser, "#{__dir__}/ieee/parser"
20
21
  autoload :PreParser, "#{__dir__}/ieee/pre_parser"
22
+ autoload :Compaction, "#{__dir__}/ieee/compaction"
21
23
  autoload :Renderer, "#{__dir__}/ieee/renderer"
22
24
  autoload :TypedStages, "#{__dir__}/ieee/typed_stages"
23
25
  autoload :UrnGenerator, "#{__dir__}/ieee/urn_generator"
@@ -31,15 +33,72 @@ module Pubid
31
33
  autoload :TypedStage, "#{__dir__}/ieee/components/typed_stage"
32
34
  end
33
35
 
36
+ # Document-number series carrying an IEEE registered trademark ("®").
37
+ # 8802 is the ISO/IEC co-published form of the 802 series.
38
+ REGISTERED_SERIES = %w[802 8802 2030].freeze
39
+
40
+ # The ISO/IEC adoption of IEEE 802: the number alone identifies the series,
41
+ # whatever publishers are printed.
42
+ ISO_ADOPTED_SERIES = "8802"
43
+
34
44
  class << self
35
45
  def parse(input)
46
+ unless input.is_a?(String)
47
+ raise Pubid::Errors::InvalidInputError,
48
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
49
+ end
50
+
36
51
  if input.length > Pubid::MAX_INPUT_LENGTH
37
- raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
52
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
38
53
  end
39
54
 
40
55
  Identifier.parse(input)
41
56
  end
42
57
 
58
+ # True when the document number belongs to a registered-trademark series.
59
+ # A project number keeps its series identity, so a leading "P" is
60
+ # stripped. `prefix` is the code's letter series, which must be absent
61
+ # (or the bare project "P") — "C802.1" is a different series that merely
62
+ # starts with the same digits. `publishers` guards against claiming an
63
+ # IEEE registered mark for another body that happens to have numbered a
64
+ # document 802 or 2030 — "AIEE Std No. 802" predates the IEEE 802 series
65
+ # by two decades. It is optional: with no publishers given the number
66
+ # decides, which keeps the plain number lookup usable on its own.
67
+ # @param number [String, nil] bare document number ("802", "P802")
68
+ # @param prefix [String, nil] letter series of the code ("C" for C37.09)
69
+ # @param publishers [Array<String>, String, nil] printed publisher tokens
70
+ def registered_series?(number, prefix = nil, publishers: nil)
71
+ return false unless prefix.nil? || prefix.to_s.empty? ||
72
+ prefix.to_s == "P"
73
+
74
+ bare = number.to_s.delete_prefix("P")
75
+ return false unless REGISTERED_SERIES.include?(bare)
76
+ return true if bare == ISO_ADOPTED_SERIES || publishers.nil?
77
+
78
+ Array(publishers).any? { |p| p.to_s.split("/").include?("IEEE") }
79
+ end
80
+
81
+ # IEEE trademark symbol for a document number: ® for the registered
82
+ # series, ™ for everything else. This is the entry point render sites
83
+ # use, because they hold the identifier and so know its number — the
84
+ # symbol must not depend on where in the rendered string the mark lands.
85
+ def trademark_symbol_for(number, prefix = nil, publishers: nil)
86
+ if registered_series?(number, prefix, publishers: publishers)
87
+ "®"
88
+ else
89
+ "™"
90
+ end
91
+ end
92
+
93
+ # IEEE trademark symbol for a rendered identifier string. Kept for
94
+ # external callers only — every render site inside pubid passes the
95
+ # document number to #trademark_symbol_for instead, because the first
96
+ # numeric token of a rendered string is not reliably the document number
97
+ # (a NESC or IRE string starts with the publication year).
98
+ def trademark_symbol(rendered)
99
+ trademark_symbol_for(rendered.to_s[/(?<![0-9A-Za-z])P?(\d+)/, 1])
100
+ end
101
+
43
102
  # Auto-discover all identifier types from the Identifiers namespace
44
103
  # @return [Array<Class>] identifier classes that define a self.type Hash
45
104
  def identifier_types
@@ -101,5 +160,5 @@ end
101
160
  Pubid::Registry.register(:ieee, Pubid::Ieee)
102
161
 
103
162
  # Per-flavor format registry: inherits global formats, overrides :human
104
- Pubid::Ieee::Identifiers::Base.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
105
- Pubid::Ieee::Identifiers::Base.format_registry.register(:human, renderer: Pubid::Ieee::Renderer)
163
+ Pubid::Ieee::Identifier.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
164
+ Pubid::Ieee::Identifier.format_registry.register(:human, renderer: Pubid::Ieee::Renderer)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pubid"
3
4
  module Pubid
4
5
  module Ieee
5
6
  autoload :Aiee, "#{__dir__}/aiee"
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Ietf
5
+ # Turns the Parser's parse tree into a concrete identifier object, choosing
6
+ # the class from which fields are present.
7
+ class Builder
8
+ SUBSERIES_CLASSES = {
9
+ "BCP" => "Bcp",
10
+ "STD" => "Std",
11
+ "FYI" => "Fyi",
12
+ }.freeze
13
+
14
+ def self.build(parsed_data)
15
+ new.build(parsed_data)
16
+ end
17
+
18
+ def build(data)
19
+ if data.key?(:draft_rest)
20
+ build_draft(data)
21
+ elsif data[:series]
22
+ build_subseries(data)
23
+ else
24
+ build_rfc(data)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def build_rfc(data)
31
+ Identifiers::Rfc.new(number: unpad(data[:number]))
32
+ end
33
+
34
+ # The series token only selects the class: it is derived back from the
35
+ # class (Identifiers::Std::SERIES) rather than stored, since `_type`
36
+ # already carries it.
37
+ def build_subseries(data)
38
+ klass = Identifiers.const_get(
39
+ SUBSERIES_CLASSES.fetch(data[:series].to_s),
40
+ )
41
+ klass.new(number: unpad(data[:number]))
42
+ end
43
+
44
+ # Strip the zero-padding the RFC editor's rfc-index.xml writes ("STD0066",
45
+ # "RFC0001") so the canonical printed form is the unpadded one. The
46
+ # look-ahead keeps the last digit, so an all-zero number stays "0" rather
47
+ # than becoming empty.
48
+ def unpad(number)
49
+ number.to_s.sub(/\A0+(?=\d)/, "")
50
+ end
51
+
52
+ def build_draft(data)
53
+ full = "draft-#{data[:draft_rest]}"
54
+ slug, version = split_draft_version(full)
55
+ Identifiers::InternetDraft.new(number: slug, version: version)
56
+ end
57
+
58
+ # An Internet-Draft version is a trailing "-NN" of *exactly* two digits at
59
+ # the very end of the slug. A three-digit topic tail (e.g. "...-256") is
60
+ # NOT a version: there the char before the last two digits is itself a
61
+ # digit, not "-", so the guard below leaves it in the slug. This also
62
+ # means a (non-existent in practice) revision >= 100 would be read as part
63
+ # of the slug — IETF drafts are always two-digit-versioned, so that case
64
+ # never arises. Either way the printed string round-trips exactly.
65
+ #
66
+ # Dotted slugs need no special handling here: only the final three
67
+ # characters are inspected, so "draft-ietf-pilc-2.5g3g-12" splits into
68
+ # ("draft-ietf-pilc-2.5g3g", "12").
69
+ def split_draft_version(full)
70
+ if full.length > 3 && full[-3] == "-" && full[-2..].match?(/\A\d\d\z/)
71
+ [full[0...-3], full[-2..]]
72
+ else
73
+ [full, nil]
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pubid::Ietf::Identifier is the IETF base class and the flavor's parse entry
4
+ # point; its body lives in
5
+ # identifiers/base.rb (mirrors the AMCA layout).