pubid 2.0.0.pre.alpha.1 → 2.0.0.pre.alpha.3

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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +5 -1
  3. data/data/nist/update_codes.yaml +27 -0
  4. data/lib/pubid/amca/builder.rb +2 -2
  5. data/lib/pubid/amca/identifier.rb +7 -0
  6. data/lib/pubid/amca/identifiers/base.rb +0 -26
  7. data/lib/pubid/amca/identifiers/interpretation.rb +0 -17
  8. data/lib/pubid/amca/identifiers/publication.rb +0 -13
  9. data/lib/pubid/amca/renderer.rb +82 -0
  10. data/lib/pubid/amca/single_identifier.rb +0 -23
  11. data/lib/pubid/amca/urn_parser.rb +28 -0
  12. data/lib/pubid/amca.rb +42 -1
  13. data/lib/pubid/ansi/builder.rb +5 -3
  14. data/lib/pubid/ansi/identifier.rb +1 -1
  15. data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
  16. data/lib/pubid/ansi/identifiers/standard.rb +2 -3
  17. data/lib/pubid/ansi/renderer.rb +53 -0
  18. data/lib/pubid/ansi/single_identifier.rb +2 -31
  19. data/lib/pubid/ansi/urn_generator.rb +3 -38
  20. data/lib/pubid/ansi/urn_parser.rb +23 -0
  21. data/lib/pubid/ansi.rb +38 -3
  22. data/lib/pubid/api/builder.rb +29 -74
  23. data/lib/pubid/api/identifier.rb +0 -4
  24. data/lib/pubid/api/identifiers/base.rb +0 -2
  25. data/lib/pubid/api/identifiers/bulletin.rb +0 -2
  26. data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
  27. data/lib/pubid/api/identifiers/mpms.rb +1 -17
  28. data/lib/pubid/api/identifiers/publication.rb +0 -2
  29. data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
  30. data/lib/pubid/api/identifiers/specification.rb +0 -2
  31. data/lib/pubid/api/identifiers/standard.rb +0 -2
  32. data/lib/pubid/api/identifiers/technical_report.rb +0 -2
  33. data/lib/pubid/api/identifiers/typeless_standard.rb +1 -14
  34. data/lib/pubid/api/identifiers.rb +18 -0
  35. data/lib/pubid/api/renderer.rb +89 -0
  36. data/lib/pubid/api/single_identifier.rb +1 -13
  37. data/lib/pubid/api/urn_generator.rb +0 -18
  38. data/lib/pubid/api/urn_parser.rb +35 -0
  39. data/lib/pubid/api.rb +51 -5
  40. data/lib/pubid/ashrae/builder.rb +3 -3
  41. data/lib/pubid/ashrae/identifier.rb +6 -0
  42. data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
  43. data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
  44. data/lib/pubid/ashrae/identifiers/base.rb +3 -0
  45. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
  46. data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
  47. data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
  48. data/lib/pubid/ashrae/renderer.rb +117 -0
  49. data/lib/pubid/ashrae/single_identifier.rb +0 -13
  50. data/lib/pubid/ashrae/urn_generator.rb +0 -8
  51. data/lib/pubid/ashrae/urn_parser.rb +27 -0
  52. data/lib/pubid/ashrae.rb +42 -1
  53. data/lib/pubid/asme/components/code.rb +10 -2
  54. data/lib/pubid/asme/identifiers/base.rb +0 -60
  55. data/lib/pubid/asme/renderer.rb +66 -0
  56. data/lib/pubid/asme/urn_parser.rb +31 -0
  57. data/lib/pubid/asme.rb +42 -1
  58. data/lib/pubid/astm/components/code.rb +9 -0
  59. data/lib/pubid/{jis → astm}/components.rb +1 -1
  60. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  61. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  62. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  63. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  64. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  65. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  66. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  67. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  68. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  69. data/lib/pubid/astm/identifiers.rb +18 -0
  70. data/lib/pubid/astm/renderer.rb +172 -0
  71. data/lib/pubid/astm/single_identifier.rb +0 -10
  72. data/lib/pubid/astm/urn_parser.rb +30 -0
  73. data/lib/pubid/astm.rb +39 -27
  74. data/lib/pubid/bsi/builder.rb +21 -12
  75. data/lib/pubid/bsi/identifier.rb +8 -2
  76. data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
  77. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
  78. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
  79. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
  80. data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
  81. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
  82. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  83. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
  84. data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
  85. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
  86. data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
  87. data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
  88. data/lib/pubid/bsi/identifiers/disc.rb +1 -27
  89. data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
  90. data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
  91. data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
  92. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
  93. data/lib/pubid/bsi/identifiers/flex.rb +1 -33
  94. data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
  95. data/lib/pubid/bsi/identifiers/index.rb +1 -30
  96. data/lib/pubid/bsi/identifiers/method.rb +1 -39
  97. data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
  98. data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
  99. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
  100. data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
  101. data/lib/pubid/bsi/identifiers/section.rb +1 -28
  102. data/lib/pubid/bsi/identifiers/set.rb +3 -17
  103. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
  104. data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
  105. data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
  106. data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
  107. data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
  108. data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
  109. data/lib/pubid/bsi/identifiers.rb +0 -1
  110. data/lib/pubid/bsi/renderer.rb +1050 -0
  111. data/lib/pubid/bsi/single_identifier.rb +6 -70
  112. data/lib/pubid/bsi/urn_generator.rb +2 -3
  113. data/lib/pubid/bsi/urn_parser.rb +52 -0
  114. data/lib/pubid/bsi.rb +224 -1
  115. data/lib/pubid/builder/base.rb +57 -10
  116. data/lib/pubid/bundled_identifier.rb +0 -1
  117. data/lib/pubid/ccsds/builder.rb +4 -3
  118. data/lib/pubid/ccsds/identifier.rb +66 -1
  119. data/lib/pubid/ccsds/identifiers/base.rb +11 -50
  120. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  121. data/lib/pubid/ccsds/parser.rb +4 -2
  122. data/lib/pubid/ccsds/single_identifier.rb +4 -1
  123. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  124. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  125. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  126. data/lib/pubid/ccsds.rb +39 -1
  127. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  128. data/lib/pubid/cen_cenelec/identifier.rb +8 -2
  129. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
  130. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
  131. data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
  132. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  133. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  134. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
  135. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
  136. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  137. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
  138. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  139. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  140. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  141. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  143. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  144. data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
  145. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  146. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  147. data/lib/pubid/cen_cenelec.rb +168 -1
  148. data/lib/pubid/cie/components/code.rb +8 -0
  149. data/lib/pubid/cie/identifier.rb +6 -4
  150. data/lib/pubid/cie/urn_parser.rb +28 -0
  151. data/lib/pubid/cie.rb +43 -1
  152. data/lib/pubid/components/adoption.rb +104 -0
  153. data/lib/pubid/components/code.rb +22 -8
  154. data/lib/pubid/components/date.rb +23 -16
  155. data/lib/pubid/components/edition.rb +9 -6
  156. data/lib/pubid/components/iteration.rb +32 -0
  157. data/lib/pubid/components/language.rb +6 -4
  158. data/lib/pubid/components/locality.rb +10 -1
  159. data/lib/pubid/components/publisher.rb +9 -6
  160. data/lib/pubid/components/relationship.rb +151 -0
  161. data/lib/pubid/components/stage.rb +5 -14
  162. data/lib/pubid/components/supplement.rb +184 -0
  163. data/lib/pubid/components/type.rb +5 -15
  164. data/lib/pubid/components/typed_stage.rb +11 -8
  165. data/lib/pubid/components.rb +4 -0
  166. data/lib/pubid/core/update_codes.rb +28 -7
  167. data/lib/pubid/csa/identifier.rb +0 -3
  168. data/lib/pubid/csa/identifiers/base.rb +2 -122
  169. data/lib/pubid/csa/identifiers/cec.rb +2 -101
  170. data/lib/pubid/csa/identifiers/series.rb +2 -102
  171. data/lib/pubid/csa/renderer.rb +292 -0
  172. data/lib/pubid/csa/urn_generator.rb +1 -1
  173. data/lib/pubid/csa/urn_parser.rb +33 -0
  174. data/lib/pubid/csa.rb +42 -1
  175. data/lib/pubid/etsi/components/code.rb +9 -2
  176. data/lib/pubid/etsi/identifiers/base.rb +1 -4
  177. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
  178. data/lib/pubid/etsi/renderer.rb +42 -0
  179. data/lib/pubid/etsi/urn_parser.rb +34 -0
  180. data/lib/pubid/etsi.rb +42 -1
  181. data/lib/pubid/export/exporter.rb +4 -46
  182. data/lib/pubid/export/flavor_exporter.rb +111 -278
  183. data/lib/pubid/export.rb +0 -6
  184. data/lib/pubid/identifier.rb +10 -18
  185. data/lib/pubid/identifier_facade.rb +114 -0
  186. data/lib/pubid/identifier_metadata.rb +1 -1
  187. data/lib/pubid/idf/builder.rb +3 -3
  188. data/lib/pubid/idf/identifier.rb +3 -6
  189. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  190. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  191. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  192. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  193. data/lib/pubid/idf/parser.rb +3 -2
  194. data/lib/pubid/idf/renderer.rb +84 -0
  195. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  196. data/lib/pubid/idf/urn_generator.rb +4 -39
  197. data/lib/pubid/idf/urn_parser.rb +25 -0
  198. data/lib/pubid/idf.rb +51 -1
  199. data/lib/pubid/iec/builder.rb +48 -65
  200. data/lib/pubid/iec/components/code.rb +9 -32
  201. data/lib/pubid/iec/components/publisher.rb +1 -1
  202. data/lib/pubid/iec/components.rb +14 -0
  203. data/lib/pubid/iec/identifier.rb +276 -3
  204. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  205. data/lib/pubid/iec/identifiers/base.rb +8 -28
  206. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  207. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  208. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -30
  209. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  210. data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -26
  211. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  212. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  213. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  214. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  215. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  216. data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -15
  217. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  218. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  219. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  220. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  221. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  222. data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
  223. data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -23
  224. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  225. data/lib/pubid/iec/identifiers/working_document.rb +4 -48
  226. data/lib/pubid/iec/identifiers.rb +30 -0
  227. data/lib/pubid/iec/parser.rb +20 -14
  228. data/lib/pubid/iec/renderer.rb +254 -0
  229. data/lib/pubid/iec/single_identifier.rb +6 -12
  230. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  231. data/lib/pubid/iec/urn_generator.rb +57 -171
  232. data/lib/pubid/iec/urn_parser.rb +53 -252
  233. data/lib/pubid/iec.rb +40 -68
  234. data/lib/pubid/ieee/builder.rb +12 -12
  235. data/lib/pubid/ieee/components/code.rb +8 -0
  236. data/lib/pubid/ieee/components/draft.rb +14 -0
  237. data/lib/pubid/ieee/components/relationship.rb +5 -149
  238. data/lib/pubid/ieee/identifier.rb +6 -0
  239. data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
  240. data/lib/pubid/ieee/identifiers/base.rb +101 -458
  241. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
  242. data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
  243. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
  244. data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
  245. data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
  246. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
  247. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
  248. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  249. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
  250. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
  251. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  252. data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
  253. data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
  254. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  255. data/lib/pubid/ieee/pre_parser.rb +301 -0
  256. data/lib/pubid/ieee/renderer.rb +307 -0
  257. data/lib/pubid/ieee/urn_parser.rb +34 -0
  258. data/lib/pubid/ieee.rb +62 -1
  259. data/lib/pubid/ieee_debug.rb +0 -1
  260. data/lib/pubid/iho/builder.rb +2 -2
  261. data/lib/pubid/iho/identifier.rb +8 -0
  262. data/lib/pubid/iho/identifiers/base.rb +49 -10
  263. data/lib/pubid/iho/identifiers/bibliographic.rb +0 -4
  264. data/lib/pubid/iho/identifiers/circular_letter.rb +0 -4
  265. data/lib/pubid/iho/identifiers/miscellaneous.rb +0 -4
  266. data/lib/pubid/iho/identifiers/publication.rb +0 -4
  267. data/lib/pubid/iho/identifiers/standard.rb +0 -4
  268. data/lib/pubid/iho/parser.rb +3 -3
  269. data/lib/pubid/iho/renderer.rb +30 -0
  270. data/lib/pubid/iho/urn_generator.rb +3 -3
  271. data/lib/pubid/iho/urn_parser.rb +58 -0
  272. data/lib/pubid/iho.rb +50 -1
  273. data/lib/pubid/iso/builder.rb +59 -53
  274. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  275. data/lib/pubid/iso/components/code.rb +7 -19
  276. data/lib/pubid/iso/components/publisher.rb +10 -8
  277. data/lib/pubid/iso/components.rb +2 -4
  278. data/lib/pubid/iso/identifier.rb +233 -6
  279. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  280. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  281. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  282. data/lib/pubid/iso/identifiers/data.rb +0 -1
  283. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  284. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  285. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  286. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  287. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  288. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  289. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  290. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  291. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  292. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  293. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  294. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  295. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  296. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  297. data/lib/pubid/iso/identifiers.rb +0 -1
  298. data/lib/pubid/iso/normalizer.rb +89 -0
  299. data/lib/pubid/iso/parser.rb +26 -6
  300. data/lib/pubid/iso/single_identifier.rb +6 -3
  301. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  302. data/lib/pubid/iso/urn_generator.rb +74 -176
  303. data/lib/pubid/iso/urn_parser.rb +28 -9
  304. data/lib/pubid/iso.rb +173 -2
  305. data/lib/pubid/itu/builder.rb +0 -12
  306. data/lib/pubid/itu/components/code.rb +8 -0
  307. data/lib/pubid/itu/components.rb +11 -0
  308. data/lib/pubid/itu/identifier.rb +6 -39
  309. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  310. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  311. data/lib/pubid/itu/identifiers/base.rb +0 -6
  312. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  313. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  314. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  315. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  316. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  317. data/lib/pubid/itu/urn_parser.rb +23 -0
  318. data/lib/pubid/itu.rb +42 -1
  319. data/lib/pubid/jcgm/builder.rb +16 -8
  320. data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
  321. data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
  322. data/lib/pubid/jcgm/renderer.rb +68 -0
  323. data/lib/pubid/jcgm/single_identifier.rb +1 -5
  324. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  325. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  326. data/lib/pubid/jcgm.rb +43 -2
  327. data/lib/pubid/jis/builder.rb +44 -52
  328. data/lib/pubid/jis/identifier.rb +132 -3
  329. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  330. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  331. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  332. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  333. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  334. data/lib/pubid/jis/identifiers.rb +1 -1
  335. data/lib/pubid/jis/parser.rb +31 -5
  336. data/lib/pubid/jis/renderer.rb +69 -0
  337. data/lib/pubid/jis/single_identifier.rb +6 -12
  338. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  339. data/lib/pubid/jis/urn_parser.rb +23 -0
  340. data/lib/pubid/jis.rb +42 -2
  341. data/lib/pubid/nist/builder.rb +122 -1761
  342. data/lib/pubid/nist/caster.rb +1272 -0
  343. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  344. data/lib/pubid/nist/components/code.rb +9 -20
  345. data/lib/pubid/nist/components/edition.rb +16 -0
  346. data/lib/pubid/nist/components/supplement.rb +88 -21
  347. data/lib/pubid/nist/components.rb +0 -1
  348. data/lib/pubid/nist/identifier.rb +25 -0
  349. data/lib/pubid/nist/identifiers/base.rb +206 -64
  350. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  351. data/lib/pubid/nist/identifiers/circular_supplement.rb +3 -2
  352. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  353. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  354. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  355. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -11
  356. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  357. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +17 -16
  358. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  359. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  360. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  361. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  362. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  363. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  364. data/lib/pubid/nist/identifiers/report.rb +4 -3
  365. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  366. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  367. data/lib/pubid/nist/identifiers.rb +1 -0
  368. data/lib/pubid/nist/parser.rb +67 -424
  369. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  370. data/lib/pubid/nist/preprocessor.rb +416 -0
  371. data/lib/pubid/nist/renderer.rb +43 -0
  372. data/lib/pubid/nist/router.rb +148 -0
  373. data/lib/pubid/nist/series/base.rb +58 -0
  374. data/lib/pubid/nist/series/crpl.rb +13 -0
  375. data/lib/pubid/nist/series/fips.rb +14 -0
  376. data/lib/pubid/nist/series/ir.rb +60 -0
  377. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  378. data/lib/pubid/nist/series/mono.rb +19 -0
  379. data/lib/pubid/nist/series/ncstar.rb +20 -0
  380. data/lib/pubid/nist/series.rb +49 -0
  381. data/lib/pubid/nist/supplement_identifier.rb +11 -25
  382. data/lib/pubid/nist/urn_generator.rb +14 -8
  383. data/lib/pubid/nist/urn_parser.rb +67 -0
  384. data/lib/pubid/nist.rb +83 -4
  385. data/lib/pubid/oiml/components/code.rb +10 -0
  386. data/lib/pubid/oiml/identifiers/annex.rb +3 -45
  387. data/lib/pubid/oiml/identifiers/base.rb +2 -17
  388. data/lib/pubid/oiml/renderer.rb +161 -0
  389. data/lib/pubid/oiml/single_identifier.rb +6 -45
  390. data/lib/pubid/oiml/supplement_identifier.rb +4 -19
  391. data/lib/pubid/oiml/urn_generator.rb +0 -8
  392. data/lib/pubid/oiml/urn_parser.rb +22 -0
  393. data/lib/pubid/oiml.rb +42 -1
  394. data/lib/pubid/plateau/identifier.rb +23 -0
  395. data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
  396. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  397. data/lib/pubid/plateau/renderer.rb +51 -0
  398. data/lib/pubid/plateau/supplement_identifier.rb +1 -1
  399. data/lib/pubid/plateau/urn_parser.rb +43 -0
  400. data/lib/pubid/plateau.rb +44 -1
  401. data/lib/pubid/renderers/base.rb +34 -0
  402. data/lib/pubid/renderers/directives_renderer.rb +27 -14
  403. data/lib/pubid/renderers/guide_renderer.rb +7 -1
  404. data/lib/pubid/renderers/human_readable.rb +31 -8
  405. data/lib/pubid/renderers/iwa_renderer.rb +5 -1
  406. data/lib/pubid/renderers/supplement_renderer.rb +4 -1
  407. data/lib/pubid/rendering/context.rb +33 -21
  408. data/lib/pubid/rendering.rb +0 -3
  409. data/lib/pubid/sae/components/date.rb +8 -0
  410. data/lib/pubid/sae/components/type.rb +5 -1
  411. data/lib/pubid/sae/identifiers/base.rb +2 -16
  412. data/lib/pubid/sae/renderer.rb +36 -0
  413. data/lib/pubid/sae/urn_generator.rb +2 -10
  414. data/lib/pubid/sae/urn_parser.rb +36 -0
  415. data/lib/pubid/sae.rb +42 -1
  416. data/lib/pubid/urn_generator/base.rb +12 -12
  417. data/lib/pubid/urn_parser/base.rb +81 -0
  418. data/lib/pubid/urn_parser/errors.rb +9 -0
  419. data/lib/pubid/urn_parser.rb +14 -0
  420. data/lib/pubid/version.rb +1 -1
  421. data/lib/pubid.rb +29 -7
  422. data/lib/tasks/website-data.json +1940 -1882
  423. metadata +77 -43
  424. data/lib/pubid/amca/scheme.rb +0 -16
  425. data/lib/pubid/ansi/scheme.rb +0 -15
  426. data/lib/pubid/api/scheme.rb +0 -66
  427. data/lib/pubid/ashrae/scheme.rb +0 -53
  428. data/lib/pubid/asme/scheme.rb +0 -37
  429. data/lib/pubid/astm/scheme.rb +0 -55
  430. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  431. data/lib/pubid/bsi/scheme.rb +0 -243
  432. data/lib/pubid/ccsds/scheme.rb +0 -57
  433. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  434. data/lib/pubid/cie/scheme.rb +0 -64
  435. data/lib/pubid/csa/scheme.rb +0 -44
  436. data/lib/pubid/etsi/scheme.rb +0 -42
  437. data/lib/pubid/export/data_class_exporter.rb +0 -59
  438. data/lib/pubid/export/ieee_exporter.rb +0 -78
  439. data/lib/pubid/export/itu_exporter.rb +0 -66
  440. data/lib/pubid/export/nist_exporter.rb +0 -64
  441. data/lib/pubid/export/registry_exporter.rb +0 -90
  442. data/lib/pubid/export/scheme_exporter.rb +0 -70
  443. data/lib/pubid/identifier_registry.rb +0 -198
  444. data/lib/pubid/idf/scheme.rb +0 -61
  445. data/lib/pubid/iec/scheme.rb +0 -71
  446. data/lib/pubid/ieee/scheme.rb +0 -90
  447. data/lib/pubid/iho/scheme.rb +0 -29
  448. data/lib/pubid/iso/identifiers/base.rb +0 -115
  449. data/lib/pubid/iso/scheme.rb +0 -187
  450. data/lib/pubid/itu/scheme.rb +0 -174
  451. data/lib/pubid/jcgm/scheme.rb +0 -60
  452. data/lib/pubid/jis/components/code.rb +0 -59
  453. data/lib/pubid/jis/identifiers/base.rb +0 -72
  454. data/lib/pubid/jis/scheme.rb +0 -49
  455. data/lib/pubid/nist/components/publisher.rb +0 -24
  456. data/lib/pubid/nist/scheme.rb +0 -199
  457. data/lib/pubid/oiml/scheme.rb +0 -46
  458. data/lib/pubid/plateau/scheme.rb +0 -45
  459. data/lib/pubid/rendering/base.rb +0 -73
  460. data/lib/pubid/rendering/common.rb +0 -211
  461. data/lib/pubid/rendering/format.rb +0 -25
  462. data/lib/pubid/sae/scheme.rb +0 -47
  463. data/lib/pubid/scheme.rb +0 -207
@@ -1,6 +1,4 @@
1
- require_relative "base"
2
1
  # frozen_string_literal: true
3
- require_relative "../../components/stage"
4
2
 
5
3
  module Pubid
6
4
  module Iec
@@ -26,7 +24,8 @@ module Pubid
26
24
  PROJECT_STAGES = {}.freeze
27
25
 
28
26
  def self.type
29
- { key: :wd, title: "Working Document", short: "WD" }
27
+ { key: :wd,
28
+ web: :working_document, title: "Working Document", short: "WD" }
30
29
  end
31
30
 
32
31
  # Return stage object for PWI/PNW stage
@@ -44,51 +43,8 @@ module Pubid
44
43
  @stage ||= ::Pubid::Components::Stage.new(stage_code: stage_code)
45
44
  end
46
45
 
47
- def to_s(_format = :short)
48
- # Working Programme format: "PWI TR 100-36 ED1" or "IEC/PWI 60038"
49
- if wp_stage
50
- parts = []
51
- # Include publisher if present (for IEC/PWI format)
52
- if publisher
53
- parts << publisher.body
54
- if copublishers&.any?
55
- parts << "/#{copublishers.map(&:body).join('/')}"
56
- end
57
- parts << "/"
58
- end
59
- parts << wp_stage
60
- # Only add wp_type if it exists and is not empty/whitespace
61
- if wp_type && !wp_type.strip.empty?
62
- parts << " #{wp_type.strip}"
63
- end
64
-
65
- # Render full number with parts
66
- if number
67
- num_str = number.to_s
68
- num_str += "-#{part}" if part && part.to_s != ""
69
- num_str += "-#{subpart}" if subpart && subpart.to_s != ""
70
- parts << " #{num_str}"
71
- end
72
-
73
- parts << " #{edition}" if edition&.number
74
- return parts.join
75
- end
76
-
77
- # Working Document format: "100/3705(F)/FDIS"
78
- parts = []
79
-
80
- parts << technical_committee if technical_committee
81
-
82
- # Number with optional language
83
- if wd_number
84
- num_part = wd_number.to_s
85
- num_part += "(#{wd_language})" if wd_language
86
- parts << num_part
87
- end
88
-
89
- parts << wd_stage if wd_stage
90
-
91
- parts.join("/")
46
+ def to_s(**opts)
47
+ render(format: :human, **opts)
92
48
  end
93
49
  end
94
50
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iec
5
+ module Identifiers
6
+ autoload :Amendment, "#{__dir__}/identifiers/amendment"
7
+ autoload :Base, "#{__dir__}/identifiers/base"
8
+ autoload :ComponentSpecification, "#{__dir__}/identifiers/component_specification"
9
+ autoload :ConformityAssessment, "#{__dir__}/identifiers/conformity_assessment"
10
+ autoload :ConsolidatedIdentifier, "#{__dir__}/identifiers/consolidated_identifier"
11
+ autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
12
+ autoload :FragmentIdentifier, "#{__dir__}/identifiers/fragment_identifier"
13
+ autoload :Guide, "#{__dir__}/identifiers/guide"
14
+ autoload :InternationalStandard, "#{__dir__}/identifiers/international_standard"
15
+ autoload :InterpretationSheet, "#{__dir__}/identifiers/interpretation_sheet"
16
+ autoload :OperationalDocument, "#{__dir__}/identifiers/operational_document"
17
+ autoload :PubliclyAvailableSpecification, "#{__dir__}/identifiers/publicly_available_specification"
18
+ autoload :SheetIdentifier, "#{__dir__}/identifiers/sheet_identifier"
19
+ autoload :SocietalTechnologyTrendReport, "#{__dir__}/identifiers/societal_technology_trend_report"
20
+ autoload :SystemsReferenceDocument, "#{__dir__}/identifiers/systems_reference_document"
21
+ autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
22
+ autoload :TechnicalSpecification, "#{__dir__}/identifiers/technical_specification"
23
+ autoload :TechnologyReport, "#{__dir__}/identifiers/technology_report"
24
+ autoload :TestReportForm, "#{__dir__}/identifiers/test_report_form"
25
+ autoload :VapIdentifier, "#{__dir__}/identifiers/vap_identifier"
26
+ autoload :WhitePaper, "#{__dir__}/identifiers/white_paper"
27
+ autoload :WorkingDocument, "#{__dir__}/identifiers/working_document"
28
+ end
29
+ end
30
+ end
@@ -1,9 +1,5 @@
1
1
  require "parslet"
2
2
  # frozen_string_literal: true
3
- require_relative "../parser/common_parse_rules"
4
- require_relative "../parser/common_parse_methods"
5
- require_relative "identifier"
6
- require_relative "supplement_identifier"
7
3
 
8
4
  module Pubid
9
5
  module Iec
@@ -14,10 +10,9 @@ module Pubid
14
10
  DASH_CHARS = ["-", "‑", "‐"].freeze
15
11
 
16
12
  # We need to sort by length to match longest first because that's how Parslet works
17
- TYPED_STAGES = Pubid::Iec::Scheme.typed_stages
18
- .map(&:abbr).flatten.sort_by(&:length).reverse
19
- TYPED_STAGES_SUPPLEMENTS = Pubid::Iec::Scheme.supplement_typed_stages
13
+ TYPED_STAGES = Pubid::Iec.all_typed_stages
20
14
  .map(&:abbr).flatten.sort_by(&:length).reverse
15
+ TYPED_STAGES_SUPPLEMENTS = TYPED_STAGES
21
16
 
22
17
  root :identifier
23
18
 
@@ -136,8 +131,13 @@ module Pubid
136
131
  end
137
132
 
138
133
  rule(:number) do
139
- # Special case for VIM publication
140
- str("VIM") |
134
+ # ISO/IEC Directives: "DIR", "DIR 1", "DIR 1 IEC SUP", "DIR 2 IEC", "DIR IEC SUP"
135
+ # Captured as a flat number (no part/subpart) so it round-trips to the input
136
+ # and class-matches the IEC index. Must come before the IECEE [A-Z]{2,4} branch,
137
+ # which would otherwise match "DIR" alone and leave the trailing tokens unconsumed.
138
+ (str("DIR") >> (space >> match('[A-Z\d]').repeat(1)).repeat) |
139
+ # Special case for VIM publication
140
+ str("VIM") |
141
141
  # Special case for SYMBOL publication
142
142
  str("SYMBOL") |
143
143
  # IECEx TRF version notation: 62784v1a_ds, 62784v1A
@@ -272,16 +272,22 @@ module Pubid
272
272
  # EXV = Example version
273
273
  # PAC = Package
274
274
  # PRV = Preview version
275
- rule(:vap_suffix) do
276
- space >> (
277
- str("CSV") |
275
+ # Internal helper (no `.as`): a single VAP code. The capture key stays
276
+ # :vap_suffix below; this rule just lets the suffix be one or more codes.
277
+ rule(:vap_code) do
278
+ str("CSV") |
278
279
  str("CMV") |
279
280
  str("RLV") |
280
281
  str("SER") |
281
282
  str("EXV") |
282
283
  str("PAC") |
283
284
  str("PRV")
284
- ).as(:vap_suffix)
285
+ end
286
+
287
+ # One or more VAP codes joined by "-", captured whole, e.g. "CSV" or
288
+ # "EXV-CMV"; the builder splits it into the VapIdentifier `vap` array.
289
+ rule(:vap_suffix) do
290
+ space >> (vap_code >> (str("-") >> vap_code).repeat).as(:vap_suffix)
285
291
  end
286
292
 
287
293
  # Database suffix: " DB"
@@ -353,7 +359,7 @@ module Pubid
353
359
  end
354
360
 
355
361
  rule(:iso_identifier) do
356
- Iso::Parser.new.identifier
362
+ Pubid::Iso.joint_grammar_atom(:identifier)
357
363
  end
358
364
 
359
365
  rule(:supplement_type_with_stage) do
@@ -0,0 +1,254 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Iec
5
+ # Human-readable renderer for IEC identifiers.
6
+ #
7
+ # Components are accessed only through `component.render(context:)`.
8
+ #
9
+ # Produces strings like:
10
+ # "IEC 60038:2009"
11
+ # "IEC/CD 60038"
12
+ # "IEC 60038:2009/AMD1:2011"
13
+ # "IEC/FDAM 60038-1"
14
+ # "IEC 60529:1989+AMD1:1999 CSV"
15
+ #
16
+ # The renderer is registered as the `:human` format in the IEC format
17
+ # registry and invoked via `render(format: :human)`.
18
+ #
19
+ # For simple (non-wrapper) identifiers, the renderer delegates to the
20
+ # identifier's own `publisher_portion` / `number_portion` helpers so that
21
+ # per-type overrides (e.g. TR, TS, Guide) continue to work without
22
+ # duplication. Wrapper types (Consolidated, VAP, Sheet, Fragment,
23
+ # Supplement, WorkingDocument, TestReportForm) have rendering logic
24
+ # here because their structure differs fundamentally.
25
+ class Renderer < ::Pubid::Renderers::Base
26
+ def render(context: nil, **opts)
27
+ id = @id
28
+
29
+ case id
30
+ when Identifiers::ConsolidatedIdentifier
31
+ render_consolidated(id, opts, context)
32
+ when Identifiers::VapIdentifier
33
+ render_vap(id, opts, context)
34
+ when Identifiers::SheetIdentifier
35
+ render_sheet(id, opts, context)
36
+ when Identifiers::FragmentIdentifier
37
+ render_fragment(id, opts, context)
38
+ when Identifiers::WorkingDocument
39
+ render_working_document(id, context)
40
+ when Identifiers::TestReportForm
41
+ render_test_report_form(id, context)
42
+ when SupplementIdentifier
43
+ render_supplement(id, opts, context)
44
+ else
45
+ render_single(id, opts, context)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def render_single(id, opts, context)
52
+ parts = []
53
+ parts << id.publisher_portion
54
+ parts << id.number_portion
55
+
56
+ if id.is_a?(Identifiers::Base)
57
+ parts << " #{id.edition.render(context:)}" if id.edition&.number
58
+ elsif opts[:with_edition] && id.edition&.number
59
+ parts << " #{id.edition.render(context:)}"
60
+ end
61
+
62
+ # VAP codes live on VapIdentifier (rendered in render_vap), not Base.
63
+
64
+ if id.is_a?(Identifiers::Base) && id.database
65
+ parts << " DB"
66
+ end
67
+
68
+ parts << " (all parts)" if id.all_parts
69
+
70
+ result = parts.compact.join
71
+
72
+ result << id.language_portion(lang_single: opts[:lang_single]) if id.languages&.any?
73
+
74
+ result
75
+ end
76
+
77
+ def render_supplement(id, opts, context)
78
+ id.ensure_base_identifier
79
+
80
+ if id.synthetic_base?
81
+ render_supplement_standalone(id, context)
82
+ elsif id.base_identifier
83
+ render_supplement_attached(id, opts, context)
84
+ else
85
+ render_single(id, opts, context)
86
+ end
87
+ end
88
+
89
+ def render_supplement_standalone(id, context)
90
+ parts = []
91
+
92
+ if id.publisher
93
+ parts << id.publisher.render(context:)
94
+ if id.copublishers&.any?
95
+ parts << "/#{id.copublishers.map { |c| c.render(context:) }.join('/')}"
96
+ end
97
+ end
98
+
99
+ abbr = id.typed_stage.abbr.first
100
+ number_str = id.base_identifier.number.to_s
101
+ number_str += "-#{id.number}" if id.number
102
+ number_str += "-#{id.subpart}" if id.subpart
103
+ parts << "#{abbr} #{number_str}"
104
+
105
+ result = parts.join("/")
106
+ result += ":#{id.date.render(context:)}" if id.date
107
+ result += " #{id.edition.render(context:)}" if id.edition&.number
108
+ result
109
+ end
110
+
111
+ def render_supplement_attached(id, opts, context)
112
+ parts = []
113
+ parts << id.base_identifier.to_s(**opts)
114
+
115
+ abbr = id.typed_stage.abbr.first.upcase
116
+ supp_part = "/#{abbr}#{id.number}"
117
+ supp_part += ":#{id.date.render(context:)}" if id.date
118
+ parts << supp_part
119
+
120
+ parts << " #{id.edition.render(context:)}" if id.edition&.number
121
+
122
+ parts.join
123
+ end
124
+
125
+ def render_consolidated(id, opts, _context)
126
+ id.identifiers.map.with_index do |sub_id, idx|
127
+ if idx.zero?
128
+ sub_id.to_s(**opts)
129
+ elsif sub_id.is_a?(Identifiers::Amendment)
130
+ render_consolidated_amendment(sub_id)
131
+ elsif sub_id.is_a?(Identifiers::Corrigendum)
132
+ render_consolidated_corrigendum(sub_id)
133
+ else
134
+ "+#{sub_id.to_s(**opts)}"
135
+ end
136
+ end.join
137
+ end
138
+
139
+ def render_consolidated_amendment(id)
140
+ if id.date&.present?
141
+ "+AMD#{id.number}:#{id.date.render}"
142
+ else
143
+ "+AMD#{id.number}"
144
+ end
145
+ end
146
+
147
+ def render_consolidated_corrigendum(id)
148
+ if id.date&.present?
149
+ "+COR#{id.number}:#{id.date.render}"
150
+ else
151
+ "+COR#{id.number}"
152
+ end
153
+ end
154
+
155
+ def render_vap(id, opts, context)
156
+ parts = []
157
+
158
+ parts << id.base_identifier.to_s(**opts.merge(with_edition: false))
159
+ parts << " #{id.vap.join('-')}" if id.vap&.any?
160
+ parts << " #{id.edition.render(context:)}" if id.edition&.number
161
+
162
+ parts.compact.join
163
+ end
164
+
165
+ def render_sheet(id, opts, context)
166
+ parts = []
167
+ parts << id.base_identifier.to_s(**opts)
168
+ parts << "/#{id.sheet_number}"
169
+ parts << ":#{id.year}" if id.year
170
+ parts.join
171
+ end
172
+
173
+ def render_fragment(id, opts, context)
174
+ parts = []
175
+ parts << id.base_identifier.to_s(**opts)
176
+
177
+ parts << if id.base_identifier.is_a?(Identifiers::Corrigendum)
178
+ "/FRAGC#{id.fragment_number}"
179
+ else
180
+ "/FRAG#{id.fragment_number}"
181
+ end
182
+
183
+ parts << " #{id.edition.render(context:)}" if id.edition&.number
184
+
185
+ parts.join
186
+ end
187
+
188
+ def render_working_document(id, context)
189
+ if id.wp_stage
190
+ parts = []
191
+ if id.publisher
192
+ parts << id.publisher.render(context:)
193
+ if id.copublishers&.any?
194
+ parts << "/#{id.copublishers.map { |c| c.render(context:) }.join('/')}"
195
+ end
196
+ parts << "/"
197
+ end
198
+ parts << id.wp_stage
199
+ if id.wp_type && !id.wp_type.strip.empty?
200
+ parts << " #{id.wp_type.strip}"
201
+ end
202
+
203
+ if id.number
204
+ num_str = id.number.to_s
205
+ num_str += "-#{id.part}" if id.part && id.part.to_s != ""
206
+ num_str += "-#{id.subpart}" if id.subpart && id.subpart.to_s != ""
207
+ parts << " #{num_str}"
208
+ end
209
+
210
+ parts << " #{id.edition.render(context:)}" if id.edition&.number
211
+ return parts.join
212
+ end
213
+
214
+ parts = []
215
+ parts << id.technical_committee if id.technical_committee
216
+
217
+ if id.wd_number
218
+ num_part = id.wd_number.to_s
219
+ num_part += "(#{id.wd_language})" if id.wd_language
220
+ parts << num_part
221
+ end
222
+
223
+ parts << id.wd_stage if id.wd_stage
224
+
225
+ parts.join("/")
226
+ end
227
+
228
+ def render_test_report_form(id, context)
229
+ parts = []
230
+ parts << id.publisher_portion
231
+
232
+ if id.cispr_identifier
233
+ cispr_parts = []
234
+ cispr_parts << id.cispr_identifier.publisher.render(context:)
235
+
236
+ num_str = id.cispr_identifier.number.to_s
237
+ num_str += "-#{id.cispr_identifier.part}" if id.cispr_identifier.part && id.cispr_identifier.part.to_s != ""
238
+ cispr_parts << num_str
239
+
240
+ cispr_str = cispr_parts.join(" ")
241
+ cispr_str += ":#{id.date.render(context:)}" if id.date
242
+
243
+ parts << " #{cispr_str}"
244
+ else
245
+ parts << id.number_portion
246
+ end
247
+
248
+ parts << id.trf_info.to_s if id.trf_info && !id.trf_info.empty?
249
+
250
+ parts.compact.join
251
+ end
252
+ end
253
+ end
254
+ end
@@ -1,25 +1,19 @@
1
- require_relative "identifier"
2
1
  # frozen_string_literal: true
3
- require_relative "../components/typed_stage"
4
- require_relative "urn_generator"
5
2
 
6
3
  module Pubid
7
4
  module Iec
8
5
  class SingleIdentifier < Identifier
9
- attribute :typed_stage, Components::TypedStage
6
+ # Default to the class's published typed_stage so an omitted "stage" key
7
+ # reconstructs the published state on from_hash.
8
+ attribute :typed_stage, ::Pubid::Components::TypedStage,
9
+ default: -> { self.class.published_typed_stage }
10
10
 
11
11
  # Generate URN for this identifier
12
12
  #
13
13
  # @return [String] URN representation
14
14
 
15
- def to_s(lang: :en, lang_single: false, with_edition: false)
16
- [].tap do |parts|
17
- parts << publisher_portion(lang: lang)
18
- parts << number_portion(lang_single: lang_single)
19
- parts << edition_portion(lang: lang) if with_edition
20
- end.compact.join(" ").tap do |s|
21
- s << language_portion(lang_single: lang_single) if languages&.any?
22
- end
15
+ def to_s(**opts)
16
+ render(format: :human, **opts)
23
17
  end
24
18
 
25
19
  def publisher_portion(lang: :en)
@@ -1,5 +1,3 @@
1
- require_relative "identifier"
2
- require_relative "single_identifier"
3
1
  # frozen_string_literal: true
4
2
 
5
3
  module Pubid
@@ -8,6 +6,55 @@ module Pubid
8
6
  class SupplementIdentifier < SingleIdentifier
9
7
  attribute :base_identifier, Identifier, polymorphic: true
10
8
 
9
+ # Serialize the supplemented document under "base". The supplement's own
10
+ # number/date/stage come from the inherited common maps; route the nested
11
+ # base hash back through Identifier.from_hash so its concrete subclass (and
12
+ # any further nesting) is reconstructed.
13
+ key_value do
14
+ map "base", with: { to: :base_to_kv, from: :base_from_kv }
15
+ end
16
+
17
+ def base_to_kv(model, doc)
18
+ base = model.base_identifier
19
+ return unless base
20
+
21
+ # `base_identifier` synthesises a base for a supplement that has none
22
+ # (e.g. a bare "+AMD1:2008" nested in a consolidation): a fake doc whose
23
+ # number equals the supplement's own. It renders nothing and the getter
24
+ # recreates it identically on load, so don't persist it. A standalone
25
+ # supplement ("IEC/FDAM 60038-1") instead moves the real base number into
26
+ # the synthetic base (base.number != own number), which must be kept.
27
+ return if model.synthetic_base? && base.number.to_s == model.number.to_s
28
+
29
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("base",
30
+ base.to_hash))
31
+ end
32
+
33
+ def base_from_kv(model, value)
34
+ return unless value
35
+
36
+ base = ::Pubid::Iec::Identifier.from_hash(value)
37
+ model.base_identifier = base
38
+
39
+ # A base of the exact SingleIdentifier class is the synthetic self-base
40
+ # of a standalone supplement ("IEC/FDAM 60038-1"); a real attached base
41
+ # is always a concrete type (InternationalStandard, etc.). Re-engage the
42
+ # synthetic-base state so the supplement renders in standalone form
43
+ # (publisher/TYPE base-number-supp-number) instead of attached form.
44
+ if base.instance_of?(::Pubid::Iec::SingleIdentifier)
45
+ model.mark_synthetic_standalone!
46
+ end
47
+ end
48
+
49
+ # Re-engage the standalone synthetic-base state on a deserialized
50
+ # supplement. At this point `number` already holds the supplement number
51
+ # (set from the "number" key before "base"), so preserve it as the
52
+ # supplement number and flag the synthetic base.
53
+ def mark_synthetic_standalone!
54
+ @synthetic_base = true
55
+ @supplement_number = @number
56
+ end
57
+
11
58
  # Override base_identifier getter to ensure it's always created for standalone supplements
12
59
  def base_identifier
13
60
  @base_identifier || ensure_base_identifier
@@ -38,17 +85,21 @@ module Pubid
38
85
  end
39
86
  end
40
87
 
41
- # Delegate publisher and copublishers to base_identifier if not set
88
+ # Delegate publisher and copublishers to base_identifier whenever there is
89
+ # a base (a supplement carries the publisher of the document it
90
+ # supplements). Checking base first — rather than `@publisher || base` — is
91
+ # required now that the publisher attribute has an IEC default, which would
92
+ # otherwise mask the delegation.
42
93
  def publisher
43
94
  return @publisher if @ensuring_base
44
95
 
45
- @publisher || base_identifier&.publisher
96
+ base_identifier ? base_identifier.publisher : @publisher
46
97
  end
47
98
 
48
99
  def copublishers
49
100
  return @copublishers if @ensuring_base
50
101
 
51
- @copublishers || base_identifier&.copublishers
102
+ base_identifier ? base_identifier.copublishers : @copublishers
52
103
  end
53
104
 
54
105
  # Ensure we have a base_identifier for standalone supplements
@@ -83,7 +134,6 @@ module Pubid
83
134
 
84
135
  # Create typed_stage for the base - use "IS" (International Standard) type
85
136
  # not the supplement type
86
- require_relative "../components/typed_stage"
87
137
  base.typed_stage = Pubid::Components::TypedStage.new(
88
138
  abbr: ["IS"],
89
139
  type_code: :is,
@@ -107,54 +157,8 @@ module Pubid
107
157
  @synthetic_base ||= false
108
158
  end
109
159
 
110
- def to_s(lang: :en, lang_single: false, with_edition: false)
111
- # Ensure we have a base_identifier for standalone supplements
112
- ensure_base_identifier
113
-
114
- # For standalone supplements (synthetic base), use standalone format
115
- # IEC/FDAM 60038-1, not IEC/IS 60038/FDAM1
116
- if synthetic_base?
117
- parts = []
118
-
119
- # Publisher portion
120
- if publisher
121
- parts << publisher.body
122
- parts << "/#{copublishers.map(&:body).join('/')}" if copublishers&.any?
123
- end
124
-
125
- # Supplement type and number with part (use base number)
126
- abbr = typed_stage.abbr.first
127
- number_str = base_identifier.number.to_s
128
- number_str += "-#{number}" if number # supplement number
129
- number_str += "-#{subpart}" if subpart
130
- parts << "#{abbr} #{number_str}"
131
-
132
- result = parts.join("/")
133
- result += ":#{date.year}" if date
134
- result += " #{edition}" if edition&.number
135
- result
136
- elsif base_identifier
137
- # Normal supplement with real base identifier
138
- # Format: "IEC 60050-102:2007/AMD1:2017"
139
- parts = []
140
- parts << base_identifier.to_s(lang: lang, lang_single: lang_single,
141
- with_edition: with_edition)
142
-
143
- # Supplement notation
144
- # Use uppercase abbreviation without space: /AMD1, /COR1
145
- abbr = typed_stage.abbr.first.upcase
146
- supp_part = "/#{abbr}#{number}"
147
- supp_part += ":#{date.year}" if date
148
- parts << supp_part
149
-
150
- # Add edition if present
151
- parts << " #{edition}" if edition&.number
152
-
153
- parts.join
154
- else
155
- # Fallback - shouldn't happen
156
- super
157
- end
160
+ def to_s(**opts)
161
+ render(format: :human, **opts)
158
162
  end
159
163
  end
160
164
  end