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
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Plateau
5
+ # Parses Plateau URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:plateau:{type}:{number}[:{annex}]
9
+ #
10
+ # type is one of: handbook, tr (technical report), an (annex), or another
11
+ # lowercase type string. Annex is a zero-padded 2-digit string when present.
12
+ #
13
+ # Examples:
14
+ # - urn:plateau:handbook:00 → PLATEAU Handbook #00
15
+ # - urn:plateau:tr:01 → PLATEAU Technical Report #01
16
+ class UrnParser < Pubid::UrnParser::Base
17
+ TYPE_MAP = {
18
+ "handbook" => "Handbook",
19
+ "tr" => "Technical Report",
20
+ "an" => "Annex",
21
+ }.freeze
22
+
23
+ def parse_urn(urn)
24
+ body = strip_namespace(urn)
25
+ parts = split_parts(body)
26
+
27
+ type_token = parts.fetch(0)
28
+ number = parts.fetch(1)
29
+ annex = parts[2]
30
+
31
+ text = "PLATEAU #{display_type(type_token)} ##{number}"
32
+ text += "-#{annex}" if annex
33
+ flavor_parse(text)
34
+ end
35
+
36
+ private
37
+
38
+ def display_type(token)
39
+ TYPE_MAP.fetch(token) { token.capitalize }
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/pubid/plateau.rb CHANGED
@@ -5,11 +5,13 @@ require "parslet"
5
5
  module Pubid
6
6
  module Plateau
7
7
  autoload :Builder, "#{__dir__}/plateau/builder"
8
+ autoload :Identifier, "#{__dir__}/plateau/identifier"
8
9
  autoload :Identifiers, "#{__dir__}/plateau/identifiers"
9
10
  autoload :Parser, "#{__dir__}/plateau/parser"
10
- autoload :Scheme, "#{__dir__}/plateau/scheme"
11
+ autoload :Renderer, "#{__dir__}/plateau/renderer"
11
12
  autoload :SupplementIdentifier, "#{__dir__}/plateau/supplement_identifier"
12
13
  autoload :UrnGenerator, "#{__dir__}/plateau/urn_generator"
14
+ autoload :UrnParser, "#{__dir__}/plateau/urn_parser"
13
15
 
14
16
  def self.parse(input)
15
17
  # Apply legacy update_codes normalization first
@@ -18,6 +20,47 @@ module Pubid
18
20
  parsed = parser.parse(normalized)
19
21
  Builder.build(parsed)
20
22
  end
23
+
24
+ # Per-flavor format registry: inherits global formats, overrides :human
25
+ Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
26
+ Identifiers::Base.format_registry.register(:human, renderer: Plateau::Renderer)
27
+ SupplementIdentifier.format_registry = Identifiers::Base.format_registry
28
+
29
+ # Auto-discover all identifier types from the Identifiers namespace
30
+ # @return [Array<Class>] identifier classes that define a self.type Hash
31
+ def self.identifier_types
32
+ @identifier_types ||= Identifiers.constants
33
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
34
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
35
+ .select { |c| c.type.is_a?(Hash) }
36
+ end
37
+
38
+ # Build typed stage index from identifier types
39
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
40
+ def self.all_typed_stages
41
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
42
+ if klass.const_defined?(:TYPED_STAGES)
43
+ klass.const_get(:TYPED_STAGES)
44
+ else
45
+ []
46
+ end
47
+ end
48
+ end
49
+
50
+ # Lookup: type code -> identifier class
51
+ # @param code [String, Symbol] the type key to find
52
+ # @return [Class, nil] the matching identifier class
53
+ def self.locate_type(code)
54
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
55
+ end
56
+
57
+ # Lookup: abbreviation -> typed stage
58
+ # @param abbr [String, Symbol] the abbreviation to find
59
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
60
+ def self.locate_stage(abbr)
61
+ abbr_str = abbr.to_s.upcase
62
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
63
+ end
21
64
  end
22
65
  end
23
66
 
@@ -14,6 +14,40 @@ module Pubid
14
14
  def self.render(identifier)
15
15
  new(identifier).render
16
16
  end
17
+
18
+ # Partitions a value into (leading separators, core, trailing separators)
19
+ # so "- : / space , ." stay OUTSIDE the annotation span (v1 parity).
20
+ SEMANTIC_SPLIT = %r{\A([-:/ ,.]*)(.*?)([-:/ ,.]*)\z}m
21
+
22
+ # type_code (a string) → semantic CSS class for the typed-stage token.
23
+ # Anything not listed (and not the default "is") renders as "doctype".
24
+ TYPED_STAGE_CSS = {
25
+ "amd" => "amendment",
26
+ "cor" => "corrigendum",
27
+ "add" => "addendum",
28
+ }.freeze
29
+
30
+ private
31
+
32
+ # Wrap a rendered value in a <span class="css_class"> when annotation is
33
+ # enabled, keeping leading/trailing separator chars outside the span.
34
+ def annotate(value, css_class, annotated:)
35
+ str = value.to_s
36
+ return value unless annotated && css_class && !str.empty?
37
+
38
+ lead, core, trail = str.match(SEMANTIC_SPLIT).captures
39
+ return value if core.empty?
40
+
41
+ %(#{lead}<span class="#{css_class}">#{core}</span>#{trail})
42
+ end
43
+
44
+ # Choose between "stage" and a type/supplement class for a typed stage.
45
+ def typed_stage_css(typed_stage)
46
+ code = typed_stage&.type_code.to_s
47
+ return "stage" if code.empty? || code == "is"
48
+
49
+ TYPED_STAGE_CSS[code] || "doctype"
50
+ end
17
51
  end
18
52
  end
19
53
  end
@@ -27,17 +27,17 @@ module Pubid
27
27
  private
28
28
 
29
29
  def render_publisher_portion(context)
30
- pub_str = @id.publisher.render(context:) if @id.publisher
30
+ ann = context.annotated
31
+ if @id.publisher
32
+ pub_str = annotate(@id.publisher.render(context:), "publisher",
33
+ annotated: ann)
34
+ end
31
35
  abbr = @id.typed_stage ? @id.typed_stage.abbreviation(format_long: false) : ""
32
- subgroup_str = @id.subgroup.render(context:) if @id.subgroup
33
-
34
- unless @id.publisher&.copublished?
35
- return [
36
- pub_str,
37
- (subgroup_str ? " #{subgroup_str}" : ""),
38
- (abbr.empty? ? "" : " #{abbr}"),
39
- ].join
36
+ unless abbr.empty?
37
+ abbr = annotate(abbr, typed_stage_css(@id.typed_stage),
38
+ annotated: ann)
40
39
  end
40
+ subgroup_str = @id.subgroup.render(context:) if @id.subgroup
41
41
 
42
42
  [
43
43
  pub_str,
@@ -47,13 +47,26 @@ module Pubid
47
47
  end
48
48
 
49
49
  def render_number_portion(context)
50
+ ann = context.annotated
50
51
  parts = []
51
- parts << @id.number.render(context:) if @id.number
52
- parts << " #{@id.part.render(context:)}" if @id.part
53
- parts << "-#{@id.subpart.render(context:)}" if @id.subpart
54
- parts << ".#{@id.stage_iteration.render(context:)}" if @id.stage_iteration
52
+ if @id.number
53
+ parts << annotate(@id.number.render(context:), "docnumber",
54
+ annotated: ann)
55
+ end
56
+ if @id.part
57
+ parts << " #{annotate(@id.part.render(context:), 'part',
58
+ annotated: ann)}"
59
+ end
60
+ if @id.subpart
61
+ parts << "-#{annotate(@id.subpart.render(context:), 'part',
62
+ annotated: ann)}"
63
+ end
64
+ if @id.stage_iteration
65
+ parts << ".#{annotate(@id.stage_iteration.render(context:),
66
+ 'iteration', annotated: ann)}"
67
+ end
55
68
  date_str = @id.date.render(context:) if @id.date && context.with_date
56
- parts << ":#{date_str}" if date_str
69
+ parts << ":#{annotate(date_str, 'year', annotated: ann)}" if date_str
57
70
  result = parts.join.strip
58
71
  result.empty? ? nil : result
59
72
  end
@@ -6,10 +6,16 @@ module Pubid
6
6
  private
7
7
 
8
8
  def render_publisher_and_stage(context)
9
- pub_str = @id.publisher.render(context:) if @id.publisher
9
+ ann = context.annotated
10
+ if @id.publisher
11
+ pub_str = annotate(@id.publisher.render(context:), "publisher",
12
+ annotated: ann)
13
+ end
10
14
  stage_str = @id.typed_stage.render(context:) if @id.typed_stage
11
15
 
12
16
  if stage_str && !stage_str.empty?
17
+ stage_str = annotate(stage_str, typed_stage_css(@id.typed_stage),
18
+ annotated: ann)
13
19
  "#{pub_str} #{stage_str}"
14
20
  else
15
21
  pub_str
@@ -17,12 +17,18 @@ module Pubid
17
17
  private
18
18
 
19
19
  def render_publisher_and_stage(context)
20
- pub_str = @id.publisher.render(context:) if @id.publisher
20
+ ann = context.annotated
21
+ if @id.publisher
22
+ pub_str = annotate(@id.publisher.render(context:), "publisher",
23
+ annotated: ann)
24
+ end
21
25
  stage_str = @id.typed_stage.render(context:) if @id.typed_stage
22
26
 
23
27
  if stage_str && !stage_str.empty?
24
28
  has_copub = @id.publisher&.copublished?
25
29
  sep = has_copub ? " " : "/"
30
+ stage_str = annotate(stage_str, typed_stage_css(@id.typed_stage),
31
+ annotated: ann)
26
32
  "#{pub_str}#{sep}#{stage_str}"
27
33
  else
28
34
  pub_str
@@ -30,18 +36,34 @@ module Pubid
30
36
  end
31
37
 
32
38
  def render_number_portion(context)
39
+ ann = context.annotated
33
40
  parts = []
34
- parts << @id.number.render(context:) if @id.number
35
- parts << "-#{@id.part.render(context:)}" if @id.part
36
- parts << "-#{@id.subpart.render(context:)}" if @id.subpart
37
- parts << ".#{@id.stage_iteration.render(context:)}" if @id.stage_iteration
41
+ if @id.number
42
+ parts << annotate(@id.number.render(context:), "docnumber",
43
+ annotated: ann)
44
+ end
45
+ if @id.part
46
+ parts << "-#{annotate(@id.part.render(context:), 'part',
47
+ annotated: ann)}"
48
+ end
49
+ if @id.subpart
50
+ parts << "-#{annotate(@id.subpart.render(context:), 'part',
51
+ annotated: ann)}"
52
+ end
53
+ if @id.stage_iteration
54
+ parts << ".#{annotate(@id.stage_iteration.render(context:),
55
+ 'iteration', annotated: ann)}"
56
+ end
38
57
  date_str = @id.date.render(context:) if @id.date && context.with_date
39
- parts << ":#{date_str}" if date_str
58
+ parts << ":#{annotate(date_str, 'year', annotated: ann)}" if date_str
40
59
  parts.join
41
60
  end
42
61
 
43
62
  def render_edition_portion(context)
44
- @id.edition.render(context:) if @id.edition&.number
63
+ return unless @id.edition&.number
64
+
65
+ annotate(@id.edition.render(context:), "edition",
66
+ annotated: context.annotated)
45
67
  end
46
68
 
47
69
  def render_language_portion(context, with_edition: false)
@@ -49,7 +71,8 @@ module Pubid
49
71
 
50
72
  use_single = with_edition ? false : context.with_language_code == :single
51
73
  rendered = @id.languages.map do |l|
52
- l.render(context:, lang_single: use_single)
74
+ annotate(l.render(context:, lang_single: use_single), "language",
75
+ annotated: context.annotated)
53
76
  end
54
77
  "(#{rendered.join(use_single ? '/' : ',')})"
55
78
  end
@@ -5,7 +5,11 @@ module Pubid
5
5
  class IwaRenderer < HumanReadable
6
6
  def render(context:, with_edition: false)
7
7
  parts = []
8
- parts << @id.typed_stage.render(context:) if @id.typed_stage
8
+ if @id.typed_stage
9
+ parts << annotate(@id.typed_stage.render(context:),
10
+ typed_stage_css(@id.typed_stage),
11
+ annotated: context.annotated)
12
+ end
9
13
  parts << render_number_portion(context)
10
14
  result = parts.compact.join(" ")
11
15
  result << render_language_portion(context, with_edition: with_edition)
@@ -10,9 +10,12 @@ module Pubid
10
10
  with_edition: with_edition,
11
11
  stage_format_long: context.stage_format_long,
12
12
  with_date: context.with_date,
13
+ annotated: context.annotated,
13
14
  )
14
15
 
15
- stage_str = @id.typed_stage.render(context:)
16
+ stage_str = annotate(@id.typed_stage.render(context:),
17
+ typed_stage_css(@id.typed_stage),
18
+ annotated: context.annotated)
16
19
  parts << "#{base_str}/#{stage_str}"
17
20
 
18
21
  num_port = render_number_portion(context)
@@ -2,30 +2,20 @@
2
2
 
3
3
  module Pubid
4
4
  module Rendering
5
- # Context object for flavor-specific rendering rules
6
- #
7
- # This encapsulates the rendering rules that vary between flavors,
8
- # allowing components to render themselves correctly based on context.
9
- #
10
- # == Usage
11
- #
12
- # context = RenderingContext.new(
13
- # stage_separator: "/",
14
- # stage_separator_with_copublisher: " ",
15
- # type_separator: "/",
16
- # type_separator_with_prefix: " ",
17
- # default_type_abbr: "IS"
18
- # )
19
- # identifier.to_s(context: context)
5
+ # Context object for flavor-specific and format-specific rendering rules
20
6
  #
7
+ # Encapsulates rendering rules that vary between flavors and between
8
+ # output formats (human-readable, URN, MR string). Components receive
9
+ # this context and render themselves accordingly — renderers and
10
+ # URN generators never reach into component internals.
21
11
  class RenderingContext
22
- attr_reader :stage_separator, :stage_separator_with_copublisher,
12
+ attr_reader :format, :stage_separator, :stage_separator_with_copublisher,
23
13
  :type_separator, :type_separator_with_prefix,
24
14
  :default_type_abbr, :lang, :lang_single,
25
- :with_language_code, :stage_format_long, :with_date
15
+ :with_language_code, :stage_format_long, :with_date,
16
+ :annotated
26
17
 
27
- # Initialize a new rendering context
28
- #
18
+ # @param format [Symbol] output format: :human, :urn, or :mr
29
19
  # @param stage_separator [String] separator before stage without copublisher
30
20
  # @param stage_separator_with_copublisher [String] separator before stage with copublisher
31
21
  # @param type_separator [String] separator before type (default)
@@ -33,7 +23,8 @@ module Pubid
33
23
  # @param default_type_abbr [String] default type abbreviation to skip rendering
34
24
  # @param lang [Symbol] language for rendering (:en or :fr)
35
25
  # @param lang_single [Boolean] use single char language format
36
- def initialize(stage_separator: "/",
26
+ def initialize(format: :human,
27
+ stage_separator: "/",
37
28
  stage_separator_with_copublisher: " ",
38
29
  type_separator: "/",
39
30
  type_separator_with_prefix: " ",
@@ -42,7 +33,9 @@ module Pubid
42
33
  lang_single: false,
43
34
  with_language_code: :none,
44
35
  stage_format_long: false,
45
- with_date: true)
36
+ with_date: true,
37
+ annotated: false)
38
+ @format = format
46
39
  @stage_separator = stage_separator
47
40
  @stage_separator_with_copublisher = stage_separator_with_copublisher
48
41
  @type_separator = type_separator
@@ -53,6 +46,19 @@ module Pubid
53
46
  @with_language_code = with_language_code
54
47
  @stage_format_long = stage_format_long
55
48
  @with_date = with_date
49
+ @annotated = annotated
50
+ end
51
+
52
+ def urn?
53
+ @format == :urn
54
+ end
55
+
56
+ def human?
57
+ @format == :human
58
+ end
59
+
60
+ def mr?
61
+ @format == :mr
56
62
  end
57
63
 
58
64
  # Get the appropriate stage separator based on whether there's a copublisher
@@ -115,6 +121,12 @@ module Pubid
115
121
  )
116
122
  end
117
123
 
124
+ # URN rendering context: components emit URN-format fragments
125
+ # @return [RenderingContext] URN-specific context
126
+ def self.urn
127
+ @urn ||= new(format: :urn)
128
+ end
129
+
118
130
  # Format factory methods — replace RenderingStyle hierarchy
119
131
  def self.ref_num_short
120
132
  new(with_language_code: :single, stage_format_long: false,
@@ -2,10 +2,7 @@
2
2
 
3
3
  module Pubid
4
4
  module Rendering
5
- autoload :Base, "pubid/rendering/base"
6
- autoload :Common, "pubid/rendering/common"
7
5
  autoload :Date, "pubid/rendering/date"
8
- autoload :Format, "pubid/rendering/format"
9
6
  autoload :Language, "pubid/rendering/language"
10
7
  autoload :Numbering, "pubid/rendering/numbering"
11
8
  autoload :Publisher, "pubid/rendering/publisher"
@@ -10,7 +10,15 @@ module Pubid
10
10
  class Date < Lutaml::Model::Serializable
11
11
  attribute :year, :integer
12
12
 
13
+ def present?
14
+ !year.nil?
15
+ end
16
+
13
17
  def to_s
18
+ render
19
+ end
20
+
21
+ def render(context: nil)
14
22
  year.to_s
15
23
  end
16
24
  end
@@ -6,11 +6,15 @@ module Pubid
6
6
  module Sae
7
7
  module Components
8
8
  # Type component for SAE document types
9
- # AMS, AIR,, ARP, AS, MA
9
+ # AMS, AIR, ARP, AS, MA
10
10
  class Type < Lutaml::Model::Serializable
11
11
  attribute :abbr, :string
12
12
 
13
13
  def to_s
14
+ render
15
+ end
16
+
17
+ def render(context: nil)
14
18
  abbr.to_s
15
19
  end
16
20
  end
@@ -15,22 +15,8 @@ module Pubid
15
15
  attribute :number, Sae::Components::Code
16
16
  attribute :date, Sae::Components::Date
17
17
 
18
- def to_s
19
- parts = []
20
-
21
- # Publisher and type
22
- parts << publisher if publisher
23
- parts << type.to_s if type
24
-
25
- # Number
26
- parts << number.to_s if number
27
-
28
- result = parts.join(" ")
29
-
30
- # Date
31
- result += ":#{date.year}" if date
32
-
33
- result
18
+ def self.type
19
+ { key: :base, web: :standard, title: "Standard", short: "SAE" }
34
20
  end
35
21
 
36
22
  def year
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Sae
5
+ # Human-readable renderer for SAE identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "SAE AS5553"
9
+ # "SAE ARP4754A"
10
+ # "SAE AMS2475:2023"
11
+ #
12
+ # The renderer is registered as the +:human+ format in the SAE format
13
+ # registry and invoked via +render(format: :human)+.
14
+ class Renderer < ::Pubid::Renderers::Base
15
+ def render(context: nil, **_opts)
16
+ id = @id
17
+
18
+ parts = []
19
+
20
+ # Publisher and type
21
+ parts << id.publisher if id.publisher
22
+ parts << id.type.to_s if id.type
23
+
24
+ # Number
25
+ parts << id.number.to_s if id.number
26
+
27
+ result = parts.join(" ")
28
+
29
+ # Date
30
+ result += ":#{id.date.render(context:)}" if id.date
31
+
32
+ result
33
+ end
34
+ end
35
+ end
36
+ end
@@ -9,18 +9,10 @@ module Pubid
9
9
  identifier.type.abbr.to_s.downcase
10
10
  end
11
11
 
12
- def urn_year
13
- if identifier.date&.year
14
- return identifier.date.year.to_s
15
- end
16
-
17
- identifier.year&.to_s
18
- end
19
-
20
12
  def urn_number
21
13
  return nil unless identifier.number
22
14
 
23
- identifier.number.value.to_s
15
+ identifier.number.render(context: URN_CONTEXT)
24
16
  end
25
17
 
26
18
  def generate
@@ -29,7 +21,7 @@ module Pubid
29
21
  parts << urn_number if urn_number
30
22
  parts << urn_year if urn_year
31
23
 
32
- parts[1] = identifier.publisher.to_s.downcase if identifier.publisher
24
+ parts[1] = urn_publisher if urn_publisher
33
25
 
34
26
  parts.join(":")
35
27
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Sae
5
+ # Parses SAE URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits:
8
+ # urn:sae:{type|std}:{number}:{year}
9
+ # where slot[1] is overwritten with the publisher string when a publisher
10
+ # is set. The common single-publisher case keeps slot[1] = "sae".
11
+ #
12
+ # Examples:
13
+ # - urn:sae:j:300:2019 → SAE J300:2019
14
+ # - urn:sae:air:500 → SAE AIR500
15
+ # - urn:sae:ams:5000:2020 → SAE AMS5000:2020
16
+ class UrnParser < Pubid::UrnParser::Base
17
+ def parse_urn(urn)
18
+ body = strip_namespace(urn)
19
+ parts = split_parts(body)
20
+
21
+ type_token, number, year = parts
22
+ text = build_text(type_token, number, year)
23
+ flavor_parse(text)
24
+ end
25
+
26
+ private
27
+
28
+ def build_text(type_token, number, year)
29
+ head = type_token == "std" ? "" : type_token.upcase
30
+ text = "SAE #{head}#{number}"
31
+ text += ":#{year}" if year
32
+ text
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/pubid/sae.rb CHANGED
@@ -7,13 +7,54 @@ module Pubid
7
7
  autoload :Identifier, "#{__dir__}/sae/identifier"
8
8
  autoload :Identifiers, "#{__dir__}/sae/identifiers"
9
9
  autoload :Parser, "#{__dir__}/sae/parser"
10
- autoload :Scheme, "#{__dir__}/sae/scheme"
10
+ autoload :Renderer, "#{__dir__}/sae/renderer"
11
11
  autoload :UrnGenerator, "#{__dir__}/sae/urn_generator"
12
+ autoload :UrnParser, "#{__dir__}/sae/urn_parser"
12
13
 
13
14
  def self.parse(input)
14
15
  Identifier.parse(input)
15
16
  end
17
+
18
+ # Auto-discover all identifier types from the Identifiers namespace.
19
+ # SAE has only one identifier class (Base), which IS the document type.
20
+ # @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
21
+ def self.identifier_types
22
+ @identifier_types ||= Identifiers.constants
23
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
24
+ .select { |c| c.is_a?(Class) && c < Pubid::Identifier }
25
+ end
26
+
27
+ # Build typed stage index from identifier types
28
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
29
+ def self.all_typed_stages
30
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
31
+ if klass.const_defined?(:TYPED_STAGES)
32
+ klass.const_get(:TYPED_STAGES)
33
+ else
34
+ []
35
+ end
36
+ end
37
+ end
38
+
39
+ # Lookup: type code -> identifier class
40
+ # @param code [String, Symbol] the type key to find
41
+ # @return [Class, nil] the matching identifier class
42
+ def self.locate_type(code)
43
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
44
+ end
45
+
46
+ # Lookup: abbreviation -> typed stage
47
+ # @param abbr [String, Symbol] the abbreviation to find
48
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
49
+ def self.locate_stage(abbr)
50
+ abbr_str = abbr.to_s.upcase
51
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
52
+ end
16
53
  end
17
54
  end
18
55
 
19
56
  Pubid::Registry.register(:sae, Pubid::Sae)
57
+
58
+ # Per-flavor format registry: inherits global formats, overrides :human
59
+ Pubid::Sae::Identifiers::Base.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
60
+ Pubid::Sae::Identifiers::Base.format_registry.register(:human, renderer: Pubid::Sae::Renderer)