pubid 2.0.0.pre.alpha.2 → 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 (458) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +5 -1
  3. data/data/nist/update_codes.yaml +25 -0
  4. data/lib/pubid/amca/builder.rb +2 -2
  5. data/lib/pubid/amca/identifier.rb +7 -39
  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 -43
  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 -51
  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 -39
  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/identifier.rb +0 -46
  55. data/lib/pubid/asme/identifiers/base.rb +0 -60
  56. data/lib/pubid/asme/renderer.rb +66 -0
  57. data/lib/pubid/asme/urn_parser.rb +31 -0
  58. data/lib/pubid/asme.rb +42 -1
  59. data/lib/pubid/astm/components/code.rb +9 -0
  60. data/lib/pubid/{jis → astm}/components.rb +1 -1
  61. data/lib/pubid/astm/identifier.rb +0 -77
  62. data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
  63. data/lib/pubid/astm/identifiers/data_series.rb +0 -14
  64. data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
  65. data/lib/pubid/astm/identifiers/manual.rb +0 -27
  66. data/lib/pubid/astm/identifiers/monograph.rb +0 -14
  67. data/lib/pubid/astm/identifiers/research_report.rb +0 -7
  68. data/lib/pubid/astm/identifiers/standard.rb +0 -39
  69. data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
  70. data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
  71. data/lib/pubid/astm/identifiers.rb +18 -0
  72. data/lib/pubid/astm/renderer.rb +172 -0
  73. data/lib/pubid/astm/single_identifier.rb +0 -10
  74. data/lib/pubid/astm/urn_parser.rb +30 -0
  75. data/lib/pubid/astm.rb +39 -27
  76. data/lib/pubid/bsi/builder.rb +21 -12
  77. data/lib/pubid/bsi/identifier.rb +8 -62
  78. data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
  79. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
  80. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
  81. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
  82. data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
  83. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
  84. data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
  85. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
  86. data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
  87. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
  88. data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
  89. data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
  90. data/lib/pubid/bsi/identifiers/disc.rb +1 -27
  91. data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
  92. data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
  93. data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
  94. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
  95. data/lib/pubid/bsi/identifiers/flex.rb +1 -33
  96. data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
  97. data/lib/pubid/bsi/identifiers/index.rb +1 -30
  98. data/lib/pubid/bsi/identifiers/method.rb +1 -39
  99. data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
  100. data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
  101. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
  102. data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
  103. data/lib/pubid/bsi/identifiers/section.rb +1 -28
  104. data/lib/pubid/bsi/identifiers/set.rb +3 -17
  105. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
  106. data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
  107. data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
  108. data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
  109. data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
  110. data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
  111. data/lib/pubid/bsi/identifiers.rb +0 -1
  112. data/lib/pubid/bsi/renderer.rb +1050 -0
  113. data/lib/pubid/bsi/single_identifier.rb +6 -70
  114. data/lib/pubid/bsi/urn_generator.rb +2 -3
  115. data/lib/pubid/bsi/urn_parser.rb +52 -0
  116. data/lib/pubid/bsi.rb +224 -1
  117. data/lib/pubid/builder/base.rb +57 -10
  118. data/lib/pubid/bundled_identifier.rb +0 -1
  119. data/lib/pubid/ccsds/builder.rb +4 -3
  120. data/lib/pubid/ccsds/identifier.rb +63 -66
  121. data/lib/pubid/ccsds/identifiers/base.rb +11 -61
  122. data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
  123. data/lib/pubid/ccsds/parser.rb +4 -2
  124. data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
  125. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  126. data/lib/pubid/ccsds/urn_parser.rb +20 -0
  127. data/lib/pubid/ccsds.rb +39 -1
  128. data/lib/pubid/cen_cenelec/builder.rb +12 -14
  129. data/lib/pubid/cen_cenelec/identifier.rb +7 -38
  130. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
  131. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
  132. data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
  133. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
  134. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
  135. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
  136. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
  137. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
  138. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
  139. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
  140. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  141. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
  142. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
  143. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
  144. data/lib/pubid/cen_cenelec/renderer.rb +261 -0
  145. data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
  146. data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
  147. data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
  148. data/lib/pubid/cen_cenelec.rb +168 -1
  149. data/lib/pubid/cie/components/code.rb +8 -0
  150. data/lib/pubid/cie/identifier.rb +6 -57
  151. data/lib/pubid/cie/urn_parser.rb +28 -0
  152. data/lib/pubid/cie.rb +43 -1
  153. data/lib/pubid/components/adoption.rb +104 -0
  154. data/lib/pubid/components/code.rb +22 -8
  155. data/lib/pubid/components/date.rb +23 -16
  156. data/lib/pubid/components/edition.rb +9 -6
  157. data/lib/pubid/components/iteration.rb +32 -0
  158. data/lib/pubid/components/language.rb +6 -4
  159. data/lib/pubid/components/locality.rb +10 -1
  160. data/lib/pubid/components/publisher.rb +9 -6
  161. data/lib/pubid/components/relationship.rb +151 -0
  162. data/lib/pubid/components/stage.rb +5 -14
  163. data/lib/pubid/components/supplement.rb +184 -0
  164. data/lib/pubid/components/type.rb +5 -15
  165. data/lib/pubid/components/typed_stage.rb +10 -11
  166. data/lib/pubid/components.rb +4 -1
  167. data/lib/pubid/core/update_codes.rb +28 -7
  168. data/lib/pubid/csa/identifier.rb +0 -59
  169. data/lib/pubid/csa/identifiers/base.rb +2 -122
  170. data/lib/pubid/csa/identifiers/cec.rb +2 -101
  171. data/lib/pubid/csa/identifiers/series.rb +2 -102
  172. data/lib/pubid/csa/renderer.rb +292 -0
  173. data/lib/pubid/csa/urn_generator.rb +1 -1
  174. data/lib/pubid/csa/urn_parser.rb +33 -0
  175. data/lib/pubid/csa.rb +42 -1
  176. data/lib/pubid/etsi/components/code.rb +9 -2
  177. data/lib/pubid/etsi/identifier.rb +0 -43
  178. data/lib/pubid/etsi/identifiers/base.rb +1 -4
  179. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
  180. data/lib/pubid/etsi/renderer.rb +42 -0
  181. data/lib/pubid/etsi/urn_parser.rb +34 -0
  182. data/lib/pubid/etsi.rb +42 -1
  183. data/lib/pubid/export/exporter.rb +4 -46
  184. data/lib/pubid/export/flavor_exporter.rb +111 -278
  185. data/lib/pubid/export.rb +0 -6
  186. data/lib/pubid/identifier.rb +2 -17
  187. data/lib/pubid/identifier_facade.rb +114 -0
  188. data/lib/pubid/identifier_metadata.rb +1 -1
  189. data/lib/pubid/idf/builder.rb +3 -3
  190. data/lib/pubid/idf/identifier.rb +3 -66
  191. data/lib/pubid/idf/identifiers/amendment.rb +2 -1
  192. data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
  193. data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
  194. data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
  195. data/lib/pubid/idf/parser.rb +3 -2
  196. data/lib/pubid/idf/renderer.rb +84 -0
  197. data/lib/pubid/idf/supplement_identifier.rb +2 -10
  198. data/lib/pubid/idf/urn_generator.rb +4 -39
  199. data/lib/pubid/idf/urn_parser.rb +25 -0
  200. data/lib/pubid/idf.rb +51 -1
  201. data/lib/pubid/iec/builder.rb +46 -64
  202. data/lib/pubid/iec/components/code.rb +8 -32
  203. data/lib/pubid/iec/components/publisher.rb +0 -1
  204. data/lib/pubid/iec/components.rb +14 -0
  205. data/lib/pubid/iec/identifier.rb +251 -213
  206. data/lib/pubid/iec/identifiers/amendment.rb +2 -3
  207. data/lib/pubid/iec/identifiers/base.rb +8 -32
  208. data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
  209. data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
  210. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -26
  211. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -22
  213. data/lib/pubid/iec/identifiers/guide.rb +0 -2
  214. data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
  215. data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
  216. data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
  217. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
  218. data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -11
  219. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
  220. data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
  221. data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
  222. data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
  223. data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
  224. data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
  225. data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -19
  226. data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
  227. data/lib/pubid/iec/identifiers/working_document.rb +4 -48
  228. data/lib/pubid/iec/identifiers.rb +30 -0
  229. data/lib/pubid/iec/parser.rb +13 -12
  230. data/lib/pubid/iec/renderer.rb +254 -0
  231. data/lib/pubid/iec/single_identifier.rb +6 -12
  232. data/lib/pubid/iec/supplement_identifier.rb +58 -54
  233. data/lib/pubid/iec/urn_generator.rb +3 -3
  234. data/lib/pubid/iec/urn_parser.rb +3 -3
  235. data/lib/pubid/iec.rb +40 -68
  236. data/lib/pubid/ieee/builder.rb +12 -12
  237. data/lib/pubid/ieee/components/code.rb +8 -0
  238. data/lib/pubid/ieee/components/draft.rb +14 -0
  239. data/lib/pubid/ieee/components/relationship.rb +5 -149
  240. data/lib/pubid/ieee/identifier.rb +6 -41
  241. data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
  242. data/lib/pubid/ieee/identifiers/base.rb +101 -458
  243. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
  244. data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
  245. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
  246. data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
  247. data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
  248. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
  249. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
  250. data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
  251. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
  252. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
  253. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
  254. data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
  255. data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
  256. data/lib/pubid/ieee/identifiers/standard.rb +1 -1
  257. data/lib/pubid/ieee/pre_parser.rb +301 -0
  258. data/lib/pubid/ieee/renderer.rb +307 -0
  259. data/lib/pubid/ieee/urn_parser.rb +34 -0
  260. data/lib/pubid/ieee.rb +62 -1
  261. data/lib/pubid/ieee_debug.rb +0 -1
  262. data/lib/pubid/iho/builder.rb +2 -2
  263. data/lib/pubid/iho/identifier.rb +8 -42
  264. data/lib/pubid/iho/identifiers/base.rb +49 -10
  265. data/lib/pubid/iho/parser.rb +3 -3
  266. data/lib/pubid/iho/renderer.rb +30 -0
  267. data/lib/pubid/iho/urn_generator.rb +2 -2
  268. data/lib/pubid/iho/urn_parser.rb +58 -0
  269. data/lib/pubid/iho.rb +50 -1
  270. data/lib/pubid/iso/builder.rb +55 -53
  271. data/lib/pubid/iso/bundled_identifier.rb +51 -0
  272. data/lib/pubid/iso/components/code.rb +7 -19
  273. data/lib/pubid/iso/components/publisher.rb +10 -8
  274. data/lib/pubid/iso/components.rb +2 -4
  275. data/lib/pubid/iso/identifier.rb +218 -252
  276. data/lib/pubid/iso/identifiers/addendum.rb +9 -6
  277. data/lib/pubid/iso/identifiers/amendment.rb +8 -4
  278. data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
  279. data/lib/pubid/iso/identifiers/data.rb +0 -1
  280. data/lib/pubid/iso/identifiers/directives.rb +8 -2
  281. data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
  282. data/lib/pubid/iso/identifiers/extract.rb +2 -2
  283. data/lib/pubid/iso/identifiers/guide.rb +0 -1
  284. data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
  285. data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
  286. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
  287. data/lib/pubid/iso/identifiers/pas.rb +2 -2
  288. data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
  289. data/lib/pubid/iso/identifiers/supplement.rb +11 -3
  290. data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
  291. data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
  292. data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
  293. data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
  294. data/lib/pubid/iso/identifiers.rb +0 -1
  295. data/lib/pubid/iso/normalizer.rb +89 -0
  296. data/lib/pubid/iso/parser.rb +22 -4
  297. data/lib/pubid/iso/supplement_identifier.rb +15 -2
  298. data/lib/pubid/iso/urn_generator.rb +66 -182
  299. data/lib/pubid/iso/urn_parser.rb +12 -7
  300. data/lib/pubid/iso.rb +173 -2
  301. data/lib/pubid/itu/builder.rb +0 -12
  302. data/lib/pubid/itu/components/code.rb +8 -0
  303. data/lib/pubid/itu/components.rb +11 -0
  304. data/lib/pubid/itu/identifier.rb +6 -104
  305. data/lib/pubid/itu/identifiers/amendment.rb +0 -2
  306. data/lib/pubid/itu/identifiers/annex.rb +0 -2
  307. data/lib/pubid/itu/identifiers/base.rb +0 -6
  308. data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
  309. data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
  310. data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
  311. data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
  312. data/lib/pubid/itu/identifiers/supplement.rb +0 -2
  313. data/lib/pubid/itu/urn_parser.rb +23 -0
  314. data/lib/pubid/itu.rb +42 -1
  315. data/lib/pubid/jcgm/builder.rb +16 -8
  316. data/lib/pubid/jcgm/identifier.rb +0 -43
  317. data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
  318. data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
  319. data/lib/pubid/jcgm/renderer.rb +68 -0
  320. data/lib/pubid/jcgm/single_identifier.rb +1 -5
  321. data/lib/pubid/jcgm/urn_generator.rb +4 -6
  322. data/lib/pubid/jcgm/urn_parser.rb +23 -0
  323. data/lib/pubid/jcgm.rb +43 -2
  324. data/lib/pubid/jis/builder.rb +44 -52
  325. data/lib/pubid/jis/identifier.rb +132 -46
  326. data/lib/pubid/jis/identifiers/amendment.rb +1 -1
  327. data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
  328. data/lib/pubid/jis/identifiers/standard.rb +2 -1
  329. data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
  330. data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
  331. data/lib/pubid/jis/identifiers.rb +1 -1
  332. data/lib/pubid/jis/parser.rb +31 -5
  333. data/lib/pubid/jis/renderer.rb +69 -0
  334. data/lib/pubid/jis/single_identifier.rb +6 -12
  335. data/lib/pubid/jis/supplement_identifier.rb +17 -14
  336. data/lib/pubid/jis/urn_parser.rb +23 -0
  337. data/lib/pubid/jis.rb +42 -2
  338. data/lib/pubid/nist/builder.rb +63 -1871
  339. data/lib/pubid/nist/caster.rb +1272 -0
  340. data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
  341. data/lib/pubid/nist/components/code.rb +9 -20
  342. data/lib/pubid/nist/components/supplement.rb +2 -2
  343. data/lib/pubid/nist/components.rb +0 -1
  344. data/lib/pubid/nist/identifier.rb +11 -48
  345. data/lib/pubid/nist/identifiers/base.rb +110 -47
  346. data/lib/pubid/nist/identifiers/circular.rb +7 -2
  347. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
  348. data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
  349. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
  350. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
  351. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
  352. data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
  353. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
  354. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
  355. data/lib/pubid/nist/identifiers/handbook.rb +2 -1
  356. data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
  357. data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
  358. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
  359. data/lib/pubid/nist/identifiers/monograph.rb +7 -3
  360. data/lib/pubid/nist/identifiers/report.rb +4 -2
  361. data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
  362. data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
  363. data/lib/pubid/nist/identifiers.rb +1 -0
  364. data/lib/pubid/nist/parser.rb +62 -452
  365. data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
  366. data/lib/pubid/nist/preprocessor.rb +416 -0
  367. data/lib/pubid/nist/renderer.rb +43 -0
  368. data/lib/pubid/nist/router.rb +148 -0
  369. data/lib/pubid/nist/series/base.rb +58 -0
  370. data/lib/pubid/nist/series/crpl.rb +13 -0
  371. data/lib/pubid/nist/series/fips.rb +14 -0
  372. data/lib/pubid/nist/series/ir.rb +60 -0
  373. data/lib/pubid/nist/series/letter_preserving.rb +15 -0
  374. data/lib/pubid/nist/series/mono.rb +19 -0
  375. data/lib/pubid/nist/series/ncstar.rb +20 -0
  376. data/lib/pubid/nist/series.rb +49 -0
  377. data/lib/pubid/nist/supplement_identifier.rb +3 -1
  378. data/lib/pubid/nist/urn_parser.rb +67 -0
  379. data/lib/pubid/nist.rb +82 -4
  380. data/lib/pubid/oiml/components/code.rb +10 -0
  381. data/lib/pubid/oiml/identifier.rb +0 -50
  382. data/lib/pubid/oiml/identifiers/annex.rb +3 -45
  383. data/lib/pubid/oiml/identifiers/base.rb +2 -17
  384. data/lib/pubid/oiml/renderer.rb +161 -0
  385. data/lib/pubid/oiml/single_identifier.rb +6 -45
  386. data/lib/pubid/oiml/supplement_identifier.rb +4 -19
  387. data/lib/pubid/oiml/urn_generator.rb +0 -8
  388. data/lib/pubid/oiml/urn_parser.rb +22 -0
  389. data/lib/pubid/oiml.rb +42 -1
  390. data/lib/pubid/plateau/identifier.rb +7 -41
  391. data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
  392. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  393. data/lib/pubid/plateau/renderer.rb +51 -0
  394. data/lib/pubid/plateau/supplement_identifier.rb +1 -1
  395. data/lib/pubid/plateau/urn_parser.rb +43 -0
  396. data/lib/pubid/plateau.rb +43 -1
  397. data/lib/pubid/renderers/directives_renderer.rb +22 -8
  398. data/lib/pubid/renderers/guide_renderer.rb +4 -2
  399. data/lib/pubid/renderers/human_readable.rb +18 -7
  400. data/lib/pubid/rendering/context.rb +28 -19
  401. data/lib/pubid/rendering.rb +0 -3
  402. data/lib/pubid/sae/components/date.rb +8 -0
  403. data/lib/pubid/sae/components/type.rb +5 -1
  404. data/lib/pubid/sae/identifier.rb +0 -23
  405. data/lib/pubid/sae/identifiers/base.rb +2 -16
  406. data/lib/pubid/sae/renderer.rb +36 -0
  407. data/lib/pubid/sae/urn_generator.rb +2 -10
  408. data/lib/pubid/sae/urn_parser.rb +36 -0
  409. data/lib/pubid/sae.rb +42 -1
  410. data/lib/pubid/urn_generator/base.rb +12 -12
  411. data/lib/pubid/urn_parser/base.rb +81 -0
  412. data/lib/pubid/urn_parser/errors.rb +9 -0
  413. data/lib/pubid/urn_parser.rb +14 -0
  414. data/lib/pubid/version.rb +1 -1
  415. data/lib/pubid.rb +29 -7
  416. data/lib/tasks/website-data.json +1940 -1882
  417. metadata +75 -44
  418. data/lib/pubid/amca/scheme.rb +0 -16
  419. data/lib/pubid/ansi/scheme.rb +0 -15
  420. data/lib/pubid/api/scheme.rb +0 -66
  421. data/lib/pubid/ashrae/scheme.rb +0 -53
  422. data/lib/pubid/asme/scheme.rb +0 -37
  423. data/lib/pubid/astm/scheme.rb +0 -55
  424. data/lib/pubid/bsi/identifiers/base.rb +0 -11
  425. data/lib/pubid/bsi/scheme.rb +0 -243
  426. data/lib/pubid/ccsds/scheme.rb +0 -57
  427. data/lib/pubid/cen_cenelec/scheme.rb +0 -164
  428. data/lib/pubid/cie/scheme.rb +0 -64
  429. data/lib/pubid/components/factory.rb +0 -50
  430. data/lib/pubid/csa/scheme.rb +0 -44
  431. data/lib/pubid/etsi/scheme.rb +0 -42
  432. data/lib/pubid/export/data_class_exporter.rb +0 -59
  433. data/lib/pubid/export/ieee_exporter.rb +0 -78
  434. data/lib/pubid/export/itu_exporter.rb +0 -66
  435. data/lib/pubid/export/nist_exporter.rb +0 -64
  436. data/lib/pubid/export/registry_exporter.rb +0 -90
  437. data/lib/pubid/export/scheme_exporter.rb +0 -70
  438. data/lib/pubid/identifier_registry.rb +0 -198
  439. data/lib/pubid/idf/scheme.rb +0 -61
  440. data/lib/pubid/iec/scheme.rb +0 -71
  441. data/lib/pubid/ieee/scheme.rb +0 -90
  442. data/lib/pubid/iho/scheme.rb +0 -29
  443. data/lib/pubid/iso/identifiers/base.rb +0 -115
  444. data/lib/pubid/iso/scheme.rb +0 -193
  445. data/lib/pubid/itu/scheme.rb +0 -174
  446. data/lib/pubid/jcgm/scheme.rb +0 -60
  447. data/lib/pubid/jis/components/code.rb +0 -59
  448. data/lib/pubid/jis/identifiers/base.rb +0 -72
  449. data/lib/pubid/jis/scheme.rb +0 -49
  450. data/lib/pubid/nist/components/publisher.rb +0 -24
  451. data/lib/pubid/nist/scheme.rb +0 -199
  452. data/lib/pubid/oiml/scheme.rb +0 -46
  453. data/lib/pubid/plateau/scheme.rb +0 -45
  454. data/lib/pubid/rendering/base.rb +0 -73
  455. data/lib/pubid/rendering/common.rb +0 -211
  456. data/lib/pubid/rendering/format.rb +0 -25
  457. data/lib/pubid/sae/scheme.rb +0 -47
  458. data/lib/pubid/scheme.rb +0 -219
@@ -2,70 +2,19 @@
2
2
 
3
3
  module Pubid
4
4
  module Cie
5
- # Base Identifier class for CIE
6
- # Provides parse() entry point
7
- class Identifier < Lutaml::Model::Serializable
5
+ # Base Identifier class for CIE.
6
+ #
7
+ # Inherits the shared Pubid::Identifier contract (format_registry, render,
8
+ # to_urn, exclude, hash, eql?) while allowing CIE-specific attributes
9
+ # such as +style+ ("legacy" vs "current" date separator).
10
+ class Identifier < ::Pubid::Identifier
8
11
  attribute :style, :string # "legacy" or "current"
9
12
 
10
- # Parse CIE identifier string
11
13
  def self.parse(input)
12
14
  parsed = Parser.parse(input)
13
15
  builder = Builder.new
14
16
  builder.build(parsed, original_string: input)
15
17
  end
16
-
17
- # Factory that builds a CIE identifier from a hash of primitives.
18
- # Dispatch on `:type` to a SingleIdentifier subclass; default is
19
- # {Identifiers::Standard}.
20
- TYPE_KEY_TO_KLASS = {
21
- standard: "Standard",
22
- conference: "Conference",
23
- bundle: "Bundle",
24
- joint_published: "JointPublished",
25
- dual_published: "DualPublished",
26
- identical: "Identical",
27
- tutorial_bundle: "TutorialBundle",
28
- }.freeze
29
-
30
- def self.create(type: nil, **opts)
31
- klass = resolve_create_class(type)
32
- klass.new(**coerce_create_attrs(opts, klass: klass))
33
- end
34
-
35
- def self.resolve_create_class(type)
36
- return Identifiers::Standard if type.nil?
37
-
38
- klass_name = TYPE_KEY_TO_KLASS[type.to_sym]
39
- raise ArgumentError, "Unknown CIE type: #{type.inspect}" unless klass_name
40
-
41
- Identifiers.const_get(klass_name)
42
- end
43
-
44
- def self.coerce_create_attrs(opts, klass:)
45
- attrs = {}
46
- attrs[:year] = opts[:year].to_s if opts[:year]
47
- attrs[:date_separator] = opts[:date_separator].to_s if opts[:date_separator]
48
-
49
- if (v = opts[:code] || opts[:number])
50
- attrs[:code] = Pubid::Cie::Components::Code.new(
51
- number: v.to_s,
52
- part: opts[:part]&.to_s,
53
- iteration: opts[:iteration]&.to_s,
54
- style: opts[:style]&.to_s,
55
- part_separator: opts[:part_separator]&.to_s,
56
- )
57
- end
58
-
59
- # Standard-only attributes
60
- if klass.attributes.key?(:s_prefix) && opts.key?(:s_prefix)
61
- attrs[:s_prefix] = opts[:s_prefix]
62
- end
63
- if klass.attributes.key?(:stage) && opts[:stage]
64
- attrs[:stage] = opts[:stage].to_s
65
- end
66
- attrs
67
- end
68
- private_class_method :resolve_create_class, :coerce_create_attrs
69
18
  end
70
19
  end
71
20
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Cie
5
+ # Parses CIE URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:cie:cie:{code}:{year}:sep.colon
9
+ #
10
+ # The trailing `sep.colon` token records the code/year separator used
11
+ # in the human-readable form (`:`). The leading `cie` after the
12
+ # namespace is the lowercase publisher.
13
+ #
14
+ # Examples:
15
+ # - urn:cie:cie:015:2018:sep.colon → CIE 015:2018
16
+ class UrnParser < Pubid::UrnParser::Base
17
+ def parse_urn(urn)
18
+ body = strip_namespace(urn)
19
+ parts = split_parts(body).reject { |p| p.start_with?("sep.") }
20
+
21
+ _publisher, code, year = parts
22
+ text = "CIE #{code}"
23
+ text += ":#{year}" if year
24
+ flavor_parse(text)
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/pubid/cie.rb CHANGED
@@ -11,16 +11,58 @@ module Pubid
11
11
  autoload :Identifier, "#{__dir__}/cie/identifier"
12
12
  autoload :Identifiers, "#{__dir__}/cie/identifiers"
13
13
  autoload :Parser, "#{__dir__}/cie/parser"
14
- autoload :Scheme, "#{__dir__}/cie/scheme"
15
14
  autoload :SingleIdentifier, "#{__dir__}/cie/single_identifier"
16
15
  autoload :SupplementIdentifier, "#{__dir__}/cie/supplement_identifier"
17
16
  autoload :UrnGenerator, "#{__dir__}/cie/urn_generator"
17
+ autoload :UrnParser, "#{__dir__}/cie/urn_parser"
18
18
 
19
19
  # Main entry point for CIE identifiers
20
20
  # Delegates to Identifier.parse
21
21
  def self.parse(input)
22
22
  Identifier.parse(input)
23
23
  end
24
+
25
+ # Auto-discover all identifier types from the Identifiers namespace.
26
+ # CIE identifier classes extend Lutaml::Model::Serializable via
27
+ # SingleIdentifier / SupplementIdentifier, without a self.type Hash.
28
+ # We discover by checking for subclasses of those base types.
29
+ # @return [Array<Class>] identifier classes
30
+ def self.identifier_types
31
+ @identifier_types ||= Identifiers.constants
32
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
33
+ .select { |c| c.is_a?(Class) && (c < SingleIdentifier || c < SupplementIdentifier) }
34
+ end
35
+
36
+ # Build typed stage index from identifier types.
37
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
38
+ def self.all_typed_stages
39
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
40
+ if klass.const_defined?(:TYPED_STAGES)
41
+ klass.const_get(:TYPED_STAGES)
42
+ else
43
+ []
44
+ end
45
+ end
46
+ end
47
+
48
+ # Lookup: class name -> identifier class
49
+ # Since CIE lacks self.type, locate by class name suffix
50
+ # @param code [String, Symbol] the type key to find
51
+ # @return [Class, nil] the matching identifier class
52
+ def self.locate_type(code)
53
+ identifier_types.find do |t|
54
+ t.name.split("::").last.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "") == code.to_s.downcase ||
55
+ t.name.split("::").last.downcase == code.to_s.downcase
56
+ end
57
+ end
58
+
59
+ # Lookup: abbreviation -> typed stage
60
+ # @param abbr [String, Symbol] the abbreviation to find
61
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
62
+ def self.locate_stage(abbr)
63
+ abbr_str = abbr.to_s.upcase
64
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
65
+ end
24
66
  end
25
67
  end
26
68
 
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Pubid
6
+ module Components
7
+ # Adoption component — captures the metadata when one identifier adopts
8
+ # another. Originally surfaced as BSI's AdoptedInternationalStandard /
9
+ # AdoptedEuropeanNorm and CEN-CENELEC's AdoptedEuropeanNorm; the same
10
+ # shape applies to CSA adoptions and IEEE Adopted-Standard relationships.
11
+ #
12
+ # Shape (union across BSI, CEN-CENELEC, CSA, IEEE):
13
+ # - base: the adopted document (polymorphic Identifier).
14
+ # - adopter_publisher: the publisher doing the adopting (BS, EN,
15
+ # CAN/, CSA, IEEE).
16
+ # - edition: edition of the adoption (BSI-only).
17
+ # - date: adoption date (replaces ad-hoc year attrs).
18
+ # - translation_lang: translation language code (BSI-only).
19
+ # - translation_upper: upper-case translation marker (BSI-only).
20
+ # - translation_suffix_type: "version" or "Translation" (BSI-only).
21
+ # - reaffirmation_year: "(R2004)" reaffirmation notation (BSI, CSA).
22
+ # - expert_commentary: true when the adoption ships with commentary
23
+ # (BSI-only).
24
+ # - expert_commentary_topic: topic of the commentary (BSI-only).
25
+ # - publisher_prefix: CSA-specific dash-vs-space prefix.
26
+ #
27
+ # Render delegates to the base identifier; the adopter's renderer decides
28
+ # the prefix and any suffix notation (translation, reaffirmation,
29
+ # commentary) by calling adoption.render(context:).
30
+ class Adoption < Lutaml::Model::Serializable
31
+ attribute :base, ::Pubid::Identifier, polymorphic: true
32
+ attribute :adopter_publisher, ::Pubid::Components::Publisher
33
+ attribute :edition, :string
34
+ attribute :date, ::Pubid::Components::Date
35
+ attribute :translation_lang, :string
36
+ attribute :translation_upper, :string
37
+ attribute :translation_suffix_type, :string
38
+ attribute :reaffirmation_year, :string
39
+ attribute :expert_commentary, :boolean
40
+ attribute :expert_commentary_topic, :string
41
+ attribute :publisher_prefix, :string
42
+
43
+ IDENTITY_FIELDS = %i[
44
+ base adopter_publisher edition date translation_lang translation_upper
45
+ translation_suffix_type reaffirmation_year expert_commentary
46
+ expert_commentary_topic publisher_prefix
47
+ ].freeze
48
+
49
+ def present?
50
+ IDENTITY_FIELDS.any? { |f| present_value?(public_send(f)) }
51
+ end
52
+
53
+ def render(context: nil)
54
+ return "" unless base
55
+
56
+ body = base.to_s
57
+ body += translation_suffix if translation_lang
58
+ body += reaffirmation_suffix if reaffirmation_year
59
+ body += commentary_suffix if expert_commentary
60
+ body
61
+ end
62
+
63
+ def to_s(**opts)
64
+ render(context: opts[:context])
65
+ end
66
+
67
+ def ==(other)
68
+ return false unless other.is_a?(self.class)
69
+
70
+ IDENTITY_FIELDS.all? { |f| public_send(f) == other.public_send(f) }
71
+ end
72
+
73
+ alias eql? ==
74
+
75
+ def hash
76
+ @hash ||= [self.class, *IDENTITY_FIELDS.map { |f| public_send(f) }].hash
77
+ end
78
+
79
+ private
80
+
81
+ def present_value?(value)
82
+ return false if value.nil?
83
+ return value if [true, false].include?(value)
84
+
85
+ value.is_a?(String) ? !value.empty? : !value.nil?
86
+ end
87
+
88
+ def translation_suffix
89
+ type = translation_suffix_type || "Translation"
90
+ lang = translation_lang&.upcase
91
+ " #{lang}#{type}"
92
+ end
93
+
94
+ def reaffirmation_suffix
95
+ " (R#{reaffirmation_year})"
96
+ end
97
+
98
+ def commentary_suffix
99
+ topic = expert_commentary_topic
100
+ topic ? " (Commentary: #{topic})" : " (Commentary)"
101
+ end
102
+ end
103
+ end
104
+ end
@@ -2,32 +2,46 @@
2
2
 
3
3
  module Pubid
4
4
  module Components
5
+ # Document code/number component.
6
+ #
7
+ # Holds the structured fields that recur across flavors: the main +value+
8
+ # (always present), plus optional +prefix+ (series/type designator),
9
+ # +part+, +subpart+, and free-form +parts+. Subclasses own their
10
+ # composition rules — flavor-specific separators and orderings live in
11
+ # the subclass #to_s / #render override.
5
12
  class Code < Lutaml::Model::Serializable
6
13
  attribute :value, :string
14
+ attribute :prefix, :string
15
+ attribute :part, :string
16
+ attribute :subpart, :string
17
+ attribute :parts, :string, collection: true
7
18
 
8
19
  def to_s
9
20
  value.to_s
10
21
  end
11
22
 
23
+ # Format-aware render seam. Default returns the bare value; subclasses
24
+ # override to compose flavor-specific shapes (e.g. ISO joins parts
25
+ # with "-", NIST joins subpart with ".").
12
26
  def render(context: nil)
13
27
  value.to_s
14
28
  end
15
29
 
16
- # Returns hash code for code component
17
- # @return [Integer] hash code
18
- # @note Memoized for performance
19
30
  def hash
20
- @hash ||= value.hash
31
+ [value, prefix, part, subpart, parts].hash
21
32
  end
22
33
 
23
- # Checks equality with another code component
24
- # @param other [Object] object to compare with
25
- # @return [Boolean] true if equal
34
+ # rubocop:disable Metrics/AbcSize
26
35
  def eql?(other)
27
36
  return false unless other.is_a?(self.class)
28
37
 
29
- value == other.value
38
+ value == other.value &&
39
+ prefix == other.prefix &&
40
+ part == other.part &&
41
+ subpart == other.subpart &&
42
+ parts == other.parts
30
43
  end
44
+ # rubocop:enable Metrics/AbcSize
31
45
  end
32
46
  end
33
47
  end
@@ -5,40 +5,47 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Components
7
7
  # Publication date component
8
+ #
9
+ # Human render: "YYYY" or "YYYY-MM" or "YYYY-MM-DD".
10
+ # URN render: year only (RFC 5141-bis URN spec).
8
11
  class Date < Lutaml::Model::Serializable
9
12
  attribute :year, :string
10
13
  attribute :month, :string
11
14
  attribute :day, :string
12
15
 
13
- # Render date with optional context for flavor-specific formatting
14
- #
15
- # @param _context [RenderingContext] rendering context
16
- # (for future extensibility)
17
- # @param _include_month [Boolean] include month in output
18
- # (for future extensibility)
19
- # @return [String] rendered date string
16
+ # True when the year is set to a non-empty value.
17
+ def present?
18
+ !year.nil? && !year.to_s.empty?
19
+ end
20
+
20
21
  def render(context: nil)
21
- to_s
22
+ return nil unless present?
23
+ return year.to_s if context&.urn?
24
+ return year.to_s unless month
25
+
26
+ result = "#{year}-#{pad2(month)}"
27
+ result += "-#{pad2(day)}" if day
28
+ result
22
29
  end
23
30
 
24
31
  def to_s(_context: nil, _include_month: false)
25
32
  return year.to_s unless month
26
33
 
27
- result = "#{year}-#{month}"
28
- result += "-#{day}" if day
34
+ result = "#{year}-#{pad2(month)}"
35
+ result += "-#{pad2(day)}" if day
29
36
  result
30
37
  end
31
38
 
32
- # Returns hash code for date component
33
- # @return [Integer] hash code
34
- # @note Memoized for performance
39
+ private
40
+
41
+ def pad2(value)
42
+ value.to_s.rjust(2, "0")
43
+ end
44
+
35
45
  def hash
36
46
  @hash ||= [year, month, day].compact.map(&:hash).hash
37
47
  end
38
48
 
39
- # Checks equality with another date component
40
- # @param other [Object] object to compare with
41
- # @return [Boolean] true if equal
42
49
  def eql?(other)
43
50
  return false unless other.is_a?(self.class)
44
51
 
@@ -3,27 +3,30 @@
3
3
  module Pubid
4
4
  module Components
5
5
  # Edition component (typically a year and number)
6
+ #
7
+ # Human render: "ED#{number}".
8
+ # URN render: "ed-#{number}" per RFC 5141-bis.
6
9
  class Edition < Lutaml::Model::Serializable
7
10
  attribute :year, :string
8
- attribute :number, Lutaml::Model::Type::Value # Accept any value type
9
- attribute :original_text, :string # Store the exact parsed edition text
11
+ attribute :number, Lutaml::Model::Type::Value
12
+ attribute :original_text, :string
10
13
 
11
14
  def to_s
12
- # Always use canonical format for rendering
13
15
  number_value = number.is_a?(Components::Code) ? number.value : number
14
16
  number_value ? "ED#{number_value}" : nil
15
17
  end
16
18
 
17
- # V1 API compatibility - tests expect .value on edition itself
18
19
  def value
19
20
  number.is_a?(Components::Code) ? number.value : number
20
21
  end
21
22
 
22
23
  def render(context: nil)
23
- to_s
24
+ number_value = number.is_a?(Components::Code) ? number.value : number
25
+ return nil unless number_value
26
+
27
+ context&.urn? ? "ed-#{number_value}" : "ED#{number_value}"
24
28
  end
25
29
 
26
- # Method to get the original parsed format if needed
27
30
  def original_format
28
31
  original_text
29
32
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Components
5
+ # Stage iteration component — the numeric suffix on a stage (e.g., "WD.2").
6
+ #
7
+ # Renders as the bare number; the caller decides the separator (".")
8
+ # because URN, MR, and human formats position iteration differently
9
+ # relative to the stage abbreviation.
10
+ class Iteration < Lutaml::Model::Serializable
11
+ attribute :number, :string
12
+
13
+ def to_s
14
+ number.to_s
15
+ end
16
+
17
+ def render(context: nil)
18
+ number.to_s
19
+ end
20
+
21
+ def hash
22
+ @hash ||= number.hash
23
+ end
24
+
25
+ def eql?(other)
26
+ return false unless other.is_a?(self.class)
27
+
28
+ number == other.number
29
+ end
30
+ end
31
+ end
32
+ end
@@ -3,6 +3,9 @@
3
3
  module Pubid
4
4
  module Components
5
5
  # Language component (typically a language code)
6
+ #
7
+ # Human render: language code, optionally single-char.
8
+ # URN render: lowercase ISO 639-1 code (RFC 5141-bis).
6
9
  class Language < Lutaml::Model::Serializable
7
10
  CHAR_MAP = {
8
11
  "R" => "ru",
@@ -13,13 +16,10 @@ module Pubid
13
16
  "D" => "de",
14
17
  }.freeze
15
18
 
16
- # code is always an ISO 639-1 two-letter code
17
19
  attribute :code, :string, values: CHAR_MAP.values
18
- attribute :original_code, :string # Store the actual parsed format
20
+ attribute :original_code, :string
19
21
 
20
22
  def to_s(lang_single: false)
21
- # When multi-char format requested (lang_single: false) but original was
22
- # single-char, normalize to multi-char (for with_edition: true mode)
23
23
  if !lang_single && original_code&.length == 1
24
24
  code
25
25
  elsif original_code
@@ -30,6 +30,8 @@ module Pubid
30
30
  end
31
31
 
32
32
  def render(context: nil, **opts)
33
+ return code&.downcase if context&.urn?
34
+
33
35
  to_s(**opts)
34
36
  end
35
37
  end
@@ -2,9 +2,18 @@
2
2
 
3
3
  module Pubid
4
4
  module Components
5
- # Handles "all parts"
5
+ # Locality marker (e.g. "all parts")
6
+ #
7
+ # Renders the human-readable phrase "(all parts)" and a URN
8
+ # suffix that completes the locality segment.
6
9
  class Locality < Lutaml::Model::Serializable
7
10
  attribute :value, :string
11
+
12
+ def render(context: nil)
13
+ return "all" if context&.urn?
14
+
15
+ "(all parts)"
16
+ end
8
17
  end
9
18
  end
10
19
  end
@@ -5,6 +5,9 @@ require "lutaml/model"
5
5
  module Pubid
6
6
  module Components
7
7
  # Publisher ISO, IEC, etc.
8
+ #
9
+ # Human render: the publisher body (e.g. "ISO").
10
+ # URN render: lowercase body (e.g. "iso") per RFC 5141-bis.
8
11
  class Publisher < Lutaml::Model::Serializable
9
12
  attribute :body, :string
10
13
 
@@ -13,19 +16,19 @@ module Pubid
13
16
  end
14
17
 
15
18
  def render(context: nil)
19
+ return body&.downcase if context&.urn?
20
+
16
21
  body
17
22
  end
18
23
 
19
- # Returns hash code for publisher component
20
- # @return [Integer] hash code
21
- # @note Memoized for performance
24
+ def copublished?
25
+ false
26
+ end
27
+
22
28
  def hash
23
29
  @hash ||= body.hash
24
30
  end
25
31
 
26
- # Checks equality with another publisher component
27
- # @param other [Object] object to compare with
28
- # @return [Boolean] true if equal
29
32
  def eql?(other)
30
33
  return false unless other.is_a?(self.class)
31
34