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
@@ -32,7 +32,7 @@ module Pubid
32
32
  when :publisher
33
33
  return nil if value.nil? || value.to_s.strip.empty?
34
34
 
35
- # publisher is a plain string attribute (see Identifiers::Base).
35
+ # publisher is a plain string attribute (see Identifier).
36
36
  value.to_s
37
37
 
38
38
  when :dated_date
@@ -48,6 +48,11 @@ module Pubid
48
48
 
49
49
  { dated_seq: value.to_s }
50
50
 
51
+ when :year
52
+ # Bare 4-digit year (e.g. from "NIST Research Library (2022)").
53
+ # The Identifier#year attribute is typed as :integer.
54
+ value&.to_s&.to_i
55
+
51
56
  when :series
52
57
  return nil if value.nil? || value.to_s.strip.empty?
53
58
 
@@ -196,9 +201,6 @@ module Pubid
196
201
  value: data[:letter_suffix].to_s.upcase),
197
202
  edition: Components::Edition.new(type: "r",
198
203
  id: data[:revision_id].to_s),
199
- edition_component: Components::Edition.new(type: "r",
200
- id: data[:revision_id].to_s),
201
- revision: "r#{data[:revision_id]}",
202
204
  }
203
205
  end
204
206
 
@@ -633,7 +635,7 @@ module Pubid
633
635
 
634
636
  when :parsed_format
635
637
  # Format detection result from parser. :short is the render default
636
- # (a nil parsed_format renders short — see Identifiers::Base#to_s), so
638
+ # (a nil parsed_format renders short — see Identifier#to_s), so
637
639
  # store only non-default formats (e.g. "mr"); "short" stays unset and
638
640
  # is omitted from to_hash. detect_format only emits :mr or :short.
639
641
  v = value&.to_s
@@ -877,8 +879,6 @@ module Pubid
877
879
  # Store as id directly - renders as "e199206"
878
880
  {
879
881
  edition: Components::Edition.new(type: "e", id: edition_date),
880
- edition_component: Components::Edition.new(type: "e",
881
- id: edition_date),
882
882
  }
883
883
 
884
884
  when :edition_e
@@ -889,8 +889,6 @@ module Pubid
889
889
 
890
890
  {
891
891
  edition: Components::Edition.new(type: "e", id: edition_id),
892
- edition_component: Components::Edition.new(type: "e",
893
- id: edition_id),
894
892
  }
895
893
 
896
894
  when :edition_r
@@ -901,9 +899,6 @@ module Pubid
901
899
 
902
900
  {
903
901
  edition: Components::Edition.new(type: "r", id: edition_id),
904
- edition_component: Components::Edition.new(type: "r",
905
- id: edition_id),
906
- revision: "r#{edition_id}", # Also set revision string attribute for compatibility
907
902
  }
908
903
 
909
904
  when :edition_r_no_space
@@ -915,9 +910,6 @@ module Pubid
915
910
 
916
911
  {
917
912
  edition: Components::Edition.new(type: "r", id: edition_id),
918
- edition_component: Components::Edition.new(type: "r",
919
- id: edition_id),
920
- revision: "r#{edition_id}", # Also set revision string attribute for compatibility
921
913
  }
922
914
 
923
915
  when :edition_rev
@@ -928,9 +920,6 @@ module Pubid
928
920
 
929
921
  {
930
922
  edition: Components::Edition.new(type: "r", id: edition_id),
931
- edition_component: Components::Edition.new(type: "r",
932
- id: edition_id),
933
- revision: "r#{edition_id}", # Also set revision string attribute for compatibility
934
923
  }
935
924
 
936
925
  when :edition_r_letter
@@ -943,10 +932,6 @@ module Pubid
943
932
  {
944
933
  edition: Components::Edition.new(type: "r", id: edition_id,
945
934
  additional_text: edition_letter),
946
- edition_component: Components::Edition.new(type: "r",
947
- id: edition_id,
948
- additional_text: edition_letter),
949
- revision: "r#{edition_id}#{edition_letter}", # Also set revision string attribute for compatibility
950
935
  }
951
936
 
952
937
  when :edition_r_letter_only
@@ -957,9 +942,6 @@ module Pubid
957
942
 
958
943
  {
959
944
  edition: Components::Edition.new(type: "r", id: edition_letter),
960
- edition_component: Components::Edition.new(type: "r",
961
- id: edition_letter),
962
- revision: "r#{edition_letter}", # Also set revision string attribute for compatibility
963
945
  }
964
946
 
965
947
  when :edition_historical
@@ -970,8 +952,6 @@ module Pubid
970
952
 
971
953
  {
972
954
  edition: Components::Edition.new(type: "-", id: edition_id),
973
- edition_component: Components::Edition.new(type: "-",
974
- id: edition_id),
975
955
  }
976
956
 
977
957
  when :edition_r_with_space_letter
@@ -991,10 +971,6 @@ module Pubid
991
971
  {
992
972
  edition: Components::Edition.new(type: "r", id: edition_id,
993
973
  additional_text: edition_letter),
994
- edition_component: Components::Edition.new(type: "r",
995
- id: edition_id,
996
- additional_text: edition_letter),
997
- revision: "r#{edition_id}#{edition_letter}",
998
974
  }
999
975
  else
1000
976
  # Space was in original input - preserve format
@@ -1002,11 +978,6 @@ module Pubid
1002
978
  edition: Components::Edition.new(type: "r", id: edition_id,
1003
979
  additional_text: edition_letter,
1004
980
  original_prefix: " r"),
1005
- edition_component: Components::Edition.new(type: "r",
1006
- id: edition_id,
1007
- additional_text: edition_letter,
1008
- original_prefix: " r"),
1009
- revision: "r#{edition_id}#{edition_letter}",
1010
981
  }
1011
982
  end
1012
983
 
@@ -1027,19 +998,12 @@ module Pubid
1027
998
  # No original_prefix - space was added by preprocessing
1028
999
  {
1029
1000
  edition: Components::Edition.new(type: "r", id: edition_id),
1030
- edition_component: Components::Edition.new(type: "r",
1031
- id: edition_id),
1032
- revision: "r#{edition_id}",
1033
1001
  }
1034
1002
  else
1035
1003
  # Space was in original input - preserve format
1036
1004
  {
1037
1005
  edition: Components::Edition.new(type: "r", id: edition_id,
1038
1006
  original_prefix: " r"),
1039
- edition_component: Components::Edition.new(type: "r",
1040
- id: edition_id,
1041
- original_prefix: " r"),
1042
- revision: "r#{edition_id}",
1043
1007
  }
1044
1008
  end
1045
1009
 
@@ -1089,7 +1053,6 @@ module Pubid
1089
1053
  )
1090
1054
  return {
1091
1055
  edition: edition_obj,
1092
- edition_component: edition_obj,
1093
1056
  edition_year: edition_id.to_s,
1094
1057
  }
1095
1058
  else
@@ -1113,7 +1076,6 @@ module Pubid
1113
1076
  # Return as hash to set edition and edition_year
1114
1077
  {
1115
1078
  edition: edition_obj, # Main attribute for tests
1116
- edition_component: edition_obj, # V2 component
1117
1079
  edition_year: value.to_s, # Keep string for render logic
1118
1080
  }
1119
1081
 
@@ -25,7 +25,7 @@ module Pubid
25
25
  @builder = builder
26
26
  end
27
27
 
28
- # Build CircularSupplement with base_identifier wrapping
28
+ # Build CircularSupplement with base wrapping
29
29
  # @param parsed_hash [Hash] the parsed supplement data
30
30
  # Build a CIRC/LCIRC supplement. Most forms collapse onto the base
31
31
  # identifier's normal class (Circular / LetterCircular) with isolated
@@ -56,10 +56,12 @@ module Pubid
56
56
  ys = range[:supp_year_start]&.to_s
57
57
  me = range[:supp_month_end]&.to_s
58
58
  ye = range[:supp_year_end]&.to_s
59
+ # Month is optional: a year-only range ("sup1925-1926") passes just the
60
+ # bare year, which supplement_from parses into year/year_end.
59
61
  identifier.supplement = @builder.supplement_from(
60
62
  value: nil, has_revision: false,
61
- range_start: (ms && ys ? "#{ms}#{ys}" : nil),
62
- range_end: (me && ye ? "#{me}#{ye}" : nil)
63
+ range_start: (ys ? "#{ms}#{ys}" : nil),
64
+ range_end: (ye ? "#{me}#{ye}" : nil)
63
65
  )
64
66
  return identifier
65
67
  end
@@ -216,7 +218,7 @@ module Pubid
216
218
 
217
219
  # Recursively build base identifier
218
220
  # This will go through normal build() process which extracts edition from "101e2"
219
- supplement.base_identifier = @builder.build(base_hash)
221
+ supplement.base = @builder.build(base_hash)
220
222
 
221
223
  # NEW: Handle revision + implicit supplement pattern (e.g., "145r11/1925")
222
224
  # Create update format: "Upd1-{year}{revision_number}"
@@ -246,7 +248,7 @@ module Pubid
246
248
  }
247
249
 
248
250
  # Recursively build base identifier
249
- supplement.base_identifier = @builder.build(base_hash)
251
+ supplement.base = @builder.build(base_hash)
250
252
  end
251
253
 
252
254
  # Build supplement edition from captured data
@@ -16,10 +16,10 @@ module Pubid
16
16
  attribute :id, :string # i, f, 1-9
17
17
  attribute :type, :string # pd, wd, prd
18
18
 
19
- # Load stages from V1 YAML config
19
+ # Load stages from data/nist/stages.yaml
20
20
  STAGES = YAML.load_file(
21
21
  File.join(File.dirname(__FILE__),
22
- "../../../../archived-gems/pubid-nist/stages.yaml"),
22
+ "../../../../data/nist/stages.yaml"),
23
23
  ).freeze
24
24
 
25
25
  # Render stage in specified format
@@ -139,8 +139,9 @@ module Pubid
139
139
  end
140
140
 
141
141
  # A range is marked by the presence of an END; START reuses month/year.
142
+ # Months are optional, so a year-only range ("1925-1926") also counts.
142
143
  def date_range?
143
- month && year && month_end && year_end
144
+ year && year_end
144
145
  end
145
146
 
146
147
  def build_date_range_format
@@ -164,7 +165,9 @@ module Pubid
164
165
  end
165
166
 
166
167
  def build_long_date_range_format
167
- "Supplement #{month} #{year}-#{month_end} #{year_end}"
168
+ start = [month, year].compact.join(" ")
169
+ finish = [month_end, year_end].compact.join(" ")
170
+ "Supplement #{start}-#{finish}"
168
171
  end
169
172
 
170
173
  def build_long_month_year_format
@@ -58,7 +58,7 @@ module Pubid
58
58
  private
59
59
 
60
60
  def default_series_path
61
- File.join(__dir__, "../../../gems/pubid-nist/series.yaml")
61
+ File.join(__dir__, "../../../data/nist/series.yaml")
62
62
  end
63
63
 
64
64
  def load_series
@@ -72,6 +72,10 @@ module Pubid
72
72
  end
73
73
  end
74
74
 
75
- class ConfigurationError < StandardError; end
75
+ # Raised when the NIST series YAML cannot be loaded. Included in the
76
+ # marker module so `rescue Pubid::Errors::Error` stays exhaustive.
77
+ class ConfigurationError < StandardError
78
+ include ::Pubid::Errors::Error
79
+ end
76
80
  end
77
81
  end
@@ -3,8 +3,6 @@
3
3
  # The NIST flavor base class is Pubid::Nist::Identifier — a real
4
4
  # Pubid::Identifier subclass that every concrete NIST identifier descends from,
5
5
  # so `id.is_a?(Pubid::Nist::Identifier)` and the shared polymorphic `from_hash`
6
- # work natively (no facade needed). Its full body, `.parse`, and the
7
- # Identifiers::Base back-compat alias are defined in identifiers/base.rb to keep
6
+ # work natively (no facade needed). Its full body and `.parse` are defined in identifiers/base.rb to keep
8
7
  # that large body in one place; this file just ensures it is loaded when a
9
8
  # consumer references Pubid::Nist::Identifier directly.
10
- require_relative "identifiers/base"
@@ -3,9 +3,7 @@
3
3
  module Pubid
4
4
  module Nist
5
5
  # NIST/NBS flavor base class. Canonical name Pubid::Nist::Identifier; every
6
- # concrete NIST identifier (Identifiers::*) descends from it, and
7
- # Identifiers::Base — aliased at the foot of this file — points back to it
8
- # for backward compatibility. Being a real Pubid::Identifier subclass gives
6
+ # concrete NIST identifier (Identifiers::*) descends from it. Being a real Pubid::Identifier subclass gives
9
7
  # native `is_a?` identity and the shared polymorphic `from_hash`.
10
8
  class Identifier < ::Pubid::Identifier
11
9
  # Delegate to the flavor module so callers can use
@@ -14,6 +12,77 @@ module Pubid
14
12
  Pubid::Nist.parse(identifier)
15
13
  end
16
14
 
15
+ # Compact, index-friendly serialization (mirrors the key_value flavors
16
+ # ISO/ITU/ETSI, without a 38-field key_value block). Two transforms,
17
+ # applied symmetrically by to_hash/from_hash so the round-trip stays
18
+ # idempotent:
19
+ # - flatten the single-value Code components (series, number) to bare
20
+ # scalars — `value` is the only stored field. NIST's
21
+ # `Components::Code#part` is a *computed* reader
22
+ # (`value.split("-").last`), and prefix/subpart/parts are never
23
+ # assigned on series/number, so the scalar `value` is lossless:
24
+ # expand recomputes exactly what the object would compute anyway;
25
+ # - flatten the plain single-value components (volume) to bare scalars
26
+ # too — `Components::Volume` holds only `value`, so it expands to a
27
+ # bare { "value" => … } with no part;
28
+ # - drop the redundant build artifacts, decomposed pieces of the
29
+ # canonical number that identity/rendering never read.
30
+ COMPACT_FLAT_CODES = %w[series number subseries].freeze
31
+ COMPACT_FLAT_VALUES = %w[volume].freeze
32
+ COMPACT_DROP_ATTRS = %w[first_number second_number].freeze
33
+
34
+ # Deserialize a (possibly compact) hash: expand the flattened scalars
35
+ # back into Code sub-hashes, then let the shared polymorphic from_hash
36
+ # do the real work. Nested `base` documents are expanded recursively by
37
+ # their own from_hash via apply_mappings, so only this level is touched.
38
+ def self.from_hash(data, options = {})
39
+ super(expand_compact_hash(data), options)
40
+ end
41
+
42
+ # Expand a compact hash in place-safe fashion: a scalar series/number
43
+ # becomes { "value" => …, "part" => <last-dash segment> }.
44
+ def self.expand_compact_hash(data)
45
+ return data unless data.is_a?(::Hash)
46
+
47
+ out = data.dup
48
+ COMPACT_FLAT_CODES.each do |key|
49
+ out[key] = expand_code(out[key]) if out[key].is_a?(::String)
50
+ end
51
+ COMPACT_FLAT_VALUES.each do |key|
52
+ out[key] = { "value" => out[key] } if out[key].is_a?(::String)
53
+ end
54
+ out
55
+ end
56
+
57
+ # A flattened Code scalar -> { "value" => …, "part" => <last-dash seg> }.
58
+ def self.expand_code(value)
59
+ code = { "value" => value }
60
+ code["part"] = value.split("-").last if value.include?("-")
61
+ code
62
+ end
63
+
64
+ # Serialize, then apply the compact transforms (recursing into a nested
65
+ # `base`, which lutaml serialized via its own transform — bypassing this
66
+ # override — so it is not compacted otherwise).
67
+ def to_hash(*args)
68
+ hash = super
69
+ compact_hash!(hash) if hash.is_a?(::Hash)
70
+ hash
71
+ end
72
+
73
+ def compact_hash!(hash)
74
+ COMPACT_DROP_ATTRS.each { |key| hash.delete(key) }
75
+ (COMPACT_FLAT_CODES + COMPACT_FLAT_VALUES).each do |key|
76
+ value = hash[key]
77
+ next unless value.is_a?(::Hash) && value.key?("value")
78
+
79
+ hash[key] = value["value"]
80
+ end
81
+ compact_hash!(hash["base"]) if hash["base"].is_a?(::Hash)
82
+ hash
83
+ end
84
+ private :compact_hash!
85
+
17
86
  # Default: no typed stages. Subclasses override as needed.
18
87
  def self.typed_stages
19
88
  []
@@ -29,11 +98,23 @@ module Pubid
29
98
  # raw string the circular/supplement builders pass straight through.
30
99
  attribute :publisher, :string
31
100
  attribute :series, Components::Code # Set by Builder from parsed data
101
+ # SP subseries (Appendix A.2 of the NIST PubID Syntax): for "NIST SP 800-53"
102
+ # the subseries is "800" and the sequence is "53". Populated by the Builder
103
+ # when the series is "SP" and the first number matches a known subseries
104
+ # code. Informational metadata derived from series+number — ignored in
105
+ # equality so a manually-built id (without subseries set) still equals a
106
+ # parsed one.
107
+ attribute :subseries, Components::Code
32
108
  attribute :number, Components::Code
33
109
 
34
110
  # V2 COMPONENTS (Lutaml::Model objects) - PROPER SEPARATION
111
+ # `edition` (Components::Edition: type + id + additional_text) is the
112
+ # single source of truth for edition/revision. The former
113
+ # `edition_component` (a byte-identical duplicate) and the `revision`
114
+ # string (always "#{edition.type}#{edition.id}") were unfinished V1->V2
115
+ # migration aliases; both removed. `#revision` survives as a derived
116
+ # reader below.
35
117
  attribute :edition, Components::Edition # Edition (type + id): e2, e2021, r5, -3
36
- attribute :edition_component, Components::Edition # V2 edition component (alias)
37
118
  attribute :volume, Components::Volume # Volume component (v6)
38
119
  attribute :part, Components::Part # Part component (n1 or pt1)
39
120
  attribute :stage, Components::Stage
@@ -52,7 +133,6 @@ module Pubid
52
133
 
53
134
  # LEGACY attributes (keep for backward compatibility during migration)
54
135
  attribute :parts, Components::Code, collection: true
55
- attribute :revision, :string
56
136
  attribute :revision_year, :string # Year for revision (e.g., r6/1925, r1963, rJun1992)
57
137
  attribute :revision_month, :string # Month for revision (e.g., rJun1992)
58
138
  attribute :edition_year, :string # Legacy edition year for backward compatibility
@@ -90,6 +170,10 @@ module Pubid
90
170
  end
91
171
 
92
172
  def initialize(**attributes)
173
+ # This override calls `super()` with no attributes and assigns through
174
+ # setters instead, so it bypasses the base constructor's coercion and
175
+ # unknown-key check. Apply them here to keep the cross-flavor contract.
176
+ attributes = self.class.normalize_init_attributes(attributes)
93
177
  super()
94
178
 
95
179
  attrs = self.class.attributes
@@ -108,12 +192,15 @@ module Pubid
108
192
  # Attributes that are build artifacts or rendering aliases, not part
109
193
  # of an identifier's logical identity. They diverge between equally-
110
194
  # valid spellings of the same id (e.g. long "Rev. 1" vs short "r1"):
111
- # - edition_component: redundant alias of :edition
112
195
  # - first_number/second_number: decomposed parts of the canonical
113
196
  # :number, retained from the parse for building
114
197
  # - parsed_format: records the input format for round-trip rendering
198
+ # - subseries: derived from series+number (which SP subseries the
199
+ # document belongs to); populated by the Builder for known SP
200
+ # subseries codes. Ignored in equality so a manually-built id
201
+ # without subseries set still equals a parsed one.
115
202
  EQUALITY_IGNORED_ATTRS = %i[
116
- edition_component first_number second_number parsed_format
203
+ first_number second_number parsed_format subseries
117
204
  ].freeze
118
205
 
119
206
  # Logical identity comparison: equal when every attribute except the
@@ -161,21 +248,11 @@ module Pubid
161
248
  end
162
249
  end
163
250
 
164
- # Return a copy with the named attributes nil'd. Overrides
165
- # Pubid::Identifier#exclude because NIST's initialize is keyword-only
166
- # (initialize(**attributes)) while the inherited exclude rebuilds via
167
- # the positional self.class.new(attrs) form — passing a positional
168
- # hash to a keyword-only initializer raises ArgumentError. Rebuild
169
- # with the keyword splat instead.
170
- def exclude(*args)
171
- excluded_args = args.dup
172
- excluded_args << :date if excluded_args.delete(:year)
173
-
174
- attrs = self.class.attributes.each_with_object({}) do |(name, _), h|
175
- h[name] = excluded_args.include?(name) ? nil : public_send(name)
176
- end
177
- self.class.new(**attrs)
178
- end
251
+ # NIST inherits Pubid::Identifier#exclude directly: it now rebuilds via
252
+ # `self.class.new(**attrs)`, so NIST's keyword-only initialize
253
+ # (initialize(**attributes)) works without a local override, and the base
254
+ # version additionally carries the nested-identifier recursion this class's
255
+ # old copy lacked.
179
256
 
180
257
  # Short-form supplement fragment ("sup", "sup1924", "supJan1924",
181
258
  # "suprev", " supJun1925-Jun1926"), rendered from the structured
@@ -190,15 +267,12 @@ module Pubid
190
267
  prefix + (rendered.empty? ? "sup" : rendered)
191
268
  end
192
269
 
193
- # Compute revision from edition component for backward compatibility
270
+ # Derived, read-only revision string ("r5", "e1979", "-3") for backward
271
+ # compatibility. `edition` is the single stored representation; this is
272
+ # never persisted, compared, or merged — just a convenience view of it.
194
273
  # @return [String, nil] revision string (e.g., "r5") or nil
195
274
  def revision
196
- return @revision if @revision
197
-
198
- # Compute from edition component if available
199
- if edition&.type && edition.id
200
- "#{edition.type}#{edition.id}"
201
- end
275
+ "#{edition.type}#{edition.id}" if edition&.type && edition.id
202
276
  end
203
277
 
204
278
  # Backward compatibility: translation method returns translation_component
@@ -234,13 +308,34 @@ module Pubid
234
308
  # @param format [:full, :long, :abbreviated, :short, :mr] output format
235
309
  def to_s(format = nil)
236
310
  # Handle both keyword argument (hash) and positional argument (symbol/string)
311
+ annotated = format.is_a?(Hash) ? format[:annotated] : nil
237
312
  format = format[:format] if format.is_a?(Hash)
238
313
 
239
314
  # Default to parsed_format if available (preserves input format on round-trip)
240
315
  # Falls back to :short format for output (normalization)
241
316
  # Explicit format parameter always overrides parsed_format
242
- render(format: :human,
243
- nist_format: format || parsed_format&.to_sym || :short)
317
+ rendered = render(format: :human,
318
+ nist_format: format || parsed_format&.to_sym || :short)
319
+
320
+ # NIST's `to_s` takes a POSITIONAL format and its `render` override
321
+ # builds no rendering context, so neither the flag nor the context
322
+ # reaches the shared hook. Apply the annotation fallback here.
323
+ annotate_plain_render(rendered, annotated: annotated)
324
+ end
325
+
326
+ # NIST has its own defined MR format (to_mr_style) used by relaton-nist
327
+ # and downstream tooling. The generic Renderers::MrString does not know
328
+ # about NIST series, revisions, supplements, etc., so delegate to the
329
+ # established style for losslessness (issue #142).
330
+ def to_mr_string
331
+ to_mr_style
332
+ end
333
+
334
+ # NIST's MR shape is fixed by the pubid standard and stays uppercase
335
+ # (e.g. `NIST.SP.800-53`). The slug, however, must be lowercase to
336
+ # match the cross-flavor convention; project the MR through `downcase`.
337
+ def to_slug
338
+ to_mr_string.downcase
244
339
  end
245
340
 
246
341
  # Returns weight based on amount of defined attributes
@@ -248,6 +343,8 @@ module Pubid
248
343
  # @return [Integer] weight score (higher = more specific)
249
344
  def weight
250
345
  self.class.attributes.keys.inject(0) do |sum, key|
346
+ next sum if EQUALITY_IGNORED_ATTRS.include?(key)
347
+
251
348
  val = public_send(key)
252
349
  val && !val.to_s.empty? ? sum + 1 : sum
253
350
  end
@@ -275,7 +372,7 @@ module Pubid
275
372
  when :edition
276
373
  current_val.nil? || edition_greater?(new_val,
277
374
  current_val)
278
- when :volume, :part, :version, :revision
375
+ when :volume, :part, :version
279
376
  current_val.nil? || (new_val.to_s.length > current_val.to_s.length)
280
377
  when :supplement, :errata, :index, :insert, :section, :appendix, :translation
281
378
  true
@@ -411,6 +508,10 @@ module Pubid
411
508
  result += " #{number}" if number
412
509
  result += parts.map { |p| "-#{p}" }.join if parts&.any?
413
510
 
511
+ # "NIST Research Library (YYYY)" — oddball identifier with no number;
512
+ # the year appears in parens rather than as a date component.
513
+ result += " (#{year})" if year && !number
514
+
414
515
  # Append every optional component the parser may have attached
415
516
  # (volume, part, edition, version, supplement, update, stage, ...).
416
517
  # Shared with the lossy subclasses so they cannot silently drop a
@@ -639,12 +740,5 @@ module Pubid
639
740
  end
640
741
  end
641
742
 
642
- module Identifiers
643
- # Backward-compatible alias: NIST's base class used to be
644
- # Pubid::Nist::Identifiers::Base. It is now Pubid::Nist::Identifier; keep
645
- # the old constant working for `class Foo < Base` declarations and any
646
- # external reference.
647
- Base = Pubid::Nist::Identifier
648
- end
649
743
  end
650
744
  end
@@ -7,7 +7,7 @@ module Pubid
7
7
  # Examples:
8
8
  # - "NBS CIRC 13e2revJune1908" = Circular 13, edition 2, revised June 1908
9
9
  # - "NBS CIRC 13" = Circular 13
10
- class Circular < Base
10
+ class Circular < Identifier
11
11
  TYPED_STAGES = [
12
12
  Pubid::Components::TypedStage.new(
13
13
  abbr: ["CIRC", "NBS CIRC"],
@@ -53,7 +53,14 @@ module Pubid
53
53
  # Override to_s for CIRC-specific edition+year rendering
54
54
  # CIRC uses dot notation: "NBS CIRC 11e2.1915" instead of "NBS CIRC 11e2-1915"
55
55
  def to_s(format = nil)
56
- result = super
56
+ # The rewrite below is `$`-anchored, so it has to run on the PLAIN
57
+ # string: with the flag set, `super` returns a string ending in
58
+ # "</span>" and the anchor no longer matches. Render plain, rewrite,
59
+ # then annotate.
60
+ annotated = format.is_a?(Hash) ? format[:annotated] : nil
61
+ format = format[:format] if format.is_a?(Hash)
62
+
63
+ result = super(format)
57
64
 
58
65
  # For CIRC edition patterns with additional_text (year), render with dot notation
59
66
  # "11e2-1915" format: edition.id="2", additional_text="1915" → render as "11e2.1915"
@@ -65,7 +72,7 @@ module Pubid
65
72
  "e#{edition.id || '?'}.#{edition.additional_text}")
66
73
  end
67
74
 
68
- result
75
+ annotate_plain_render(result, annotated: annotated)
69
76
  end
70
77
  end
71
78
  end
@@ -37,13 +37,22 @@ module Pubid
37
37
  attribute :implicit_supplement, :boolean # true for implicit supplements (e.g., "145r11/1925")
38
38
 
39
39
  def to_s(format = :short)
40
+ # A caller passing `annotated:` reaches this positional parameter as a
41
+ # Hash. Normalise it away before `super`, so the annotation is applied
42
+ # once, here, and covers the date-range branch too — that branch
43
+ # returns a hand-composed string and never reached `super` at all.
44
+ annotated = format.is_a?(Hash) ? format[:annotated] : nil
45
+ format = format[:format] || :short if format.is_a?(Hash)
46
+
40
47
  # Handle date range supplements (no base identifier)
41
- if supplement_date_range_start && supplement_date_range_end
42
- return "NBS CIRC sup#{supplement_date_range_start}-#{supplement_date_range_end}"
43
- end
48
+ result = if supplement_date_range_start && supplement_date_range_end
49
+ "NBS CIRC sup#{supplement_date_range_start}-#{supplement_date_range_end}"
50
+ else
51
+ # Use parent's rendering for base + supplement
52
+ super(format)
53
+ end
44
54
 
45
- # Use parent's rendering for base + supplement
46
- super
55
+ annotate_plain_render(result, annotated: annotated)
47
56
  end
48
57
  end
49
58
  end
@@ -9,7 +9,7 @@ module Pubid
9
9
  # - "NBS CS 102" - Basic commercial standard
10
10
  # - "NBS CS 102E-42" - With letter suffix and number
11
11
  # - "CS 190-58" - With year
12
- class CommercialStandard < Base
12
+ class CommercialStandard < Identifier
13
13
  TYPED_STAGES = [
14
14
  Pubid::Components::TypedStage.new(
15
15
  abbr: ["CS", "NBS CS"],
@@ -6,7 +6,7 @@ module Pubid
6
6
  # NBS Commercial Standard (Emergency) Identifier
7
7
  # Format: NBS CS eNNN-YY where NNN is edition number, YY is 2-digit year
8
8
  # Example: "NBS CS e104-43" = Commercial Standard Emergency edition 104, year 1943
9
- class CommercialStandardEmergency < Base
9
+ class CommercialStandardEmergency < Identifier
10
10
  TYPED_STAGES = [
11
11
  Pubid::Components::TypedStage.new(
12
12
  abbr: ["CS-E", "NBS CS-E"],
@@ -6,7 +6,7 @@ module Pubid
6
6
  # NBS Commercial Standards Monthly Identifier
7
7
  # Format: NBS CSM N where N is simple number
8
8
  # Example: "NBS CSM 1", "NBS CSM 40"
9
- class CommercialStandardsMonthly < Base
9
+ class CommercialStandardsMonthly < Identifier
10
10
  TYPED_STAGES = [
11
11
  Pubid::Components::TypedStage.new(
12
12
  abbr: ["CSM", "NBS CSM"],
@@ -41,6 +41,12 @@ module Pubid
41
41
  end
42
42
 
43
43
  def to_s(format = nil)
44
+ # A caller passing `annotated:` reaches this positional parameter as
45
+ # a Hash — Ruby converts keywords for a method that accepts none.
46
+ # The same idiom `Identifiers::Base#to_s` uses. This renderer
47
+ # ignores `format`, so only the flag is read.
48
+ annotated = format.is_a?(Hash) ? format[:annotated] : nil
49
+
44
50
  result = "#{publisher} #{series}"
45
51
 
46
52
  # Proper Volume and Part components
@@ -55,7 +61,7 @@ module Pubid
55
61
  result += " #{vol_str}n#{issue_number.number}"
56
62
  end
57
63
 
58
- result
64
+ annotate_plain_render(result, annotated: annotated)
59
65
  end
60
66
  end
61
67
  end