pubid 2.0.0.pre.alpha.8 → 2.0.0.pre.alpha.9

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 (484) hide show
  1. checksums.yaml +4 -4
  2. data/data/bipm/update_codes.yaml +9 -0
  3. data/data/iec/update_codes.yaml +3 -0
  4. data/data/ieee/update_codes.yaml +107 -1
  5. data/data/nist/series.yaml +155 -0
  6. data/data/nist/update_codes.yaml +8 -0
  7. data/lib/pubid/adobe/builder.rb +52 -0
  8. data/lib/pubid/adobe/identifier.rb +49 -0
  9. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  10. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  11. data/lib/pubid/adobe/identifiers.rb +10 -0
  12. data/lib/pubid/adobe/parser.rb +128 -0
  13. data/lib/pubid/adobe/renderer.rb +39 -0
  14. data/lib/pubid/adobe/urn_generator.rb +42 -0
  15. data/lib/pubid/adobe/urn_parser.rb +69 -0
  16. data/lib/pubid/adobe.rb +60 -0
  17. data/lib/pubid/amca/builder.rb +2 -2
  18. data/lib/pubid/amca/identifier.rb +1 -3
  19. data/lib/pubid/amca/identifiers/base.rb +1 -6
  20. data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
  21. data/lib/pubid/amca/identifiers/publication.rb +1 -1
  22. data/lib/pubid/amca/identifiers/standard.rb +1 -1
  23. data/lib/pubid/amca/identifiers.rb +0 -1
  24. data/lib/pubid/amca/single_identifier.rb +1 -1
  25. data/lib/pubid/amca.rb +3 -3
  26. data/lib/pubid/ashrae/builder.rb +22 -22
  27. data/lib/pubid/ashrae/identifier.rb +3 -4
  28. data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
  29. data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
  30. data/lib/pubid/ashrae/identifiers/base.rb +14 -8
  31. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
  32. data/lib/pubid/ashrae/identifiers.rb +0 -1
  33. data/lib/pubid/ashrae/parser.rb +14 -9
  34. data/lib/pubid/ashrae/renderer.rb +19 -19
  35. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  36. data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
  37. data/lib/pubid/ashrae.rb +3 -3
  38. data/lib/pubid/bipm/builder.rb +107 -0
  39. data/lib/pubid/bipm/identifier.rb +160 -0
  40. data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
  41. data/lib/pubid/bipm/identifiers/guide.rb +24 -0
  42. data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
  43. data/lib/pubid/bipm/identifiers/mep.rb +21 -0
  44. data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
  45. data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
  46. data/lib/pubid/bipm/identifiers.rb +15 -0
  47. data/lib/pubid/bipm/parser.rb +184 -0
  48. data/lib/pubid/bipm/renderer.rb +110 -0
  49. data/lib/pubid/bipm/urn_generator.rb +58 -0
  50. data/lib/pubid/bipm/urn_parser.rb +52 -0
  51. data/lib/pubid/bipm.rb +86 -0
  52. data/lib/pubid/bsi/builder.rb +14 -14
  53. data/lib/pubid/bsi/identifier.rb +0 -1
  54. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  55. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  56. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  57. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  58. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  59. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  60. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  61. data/lib/pubid/bsi/renderer.rb +8 -8
  62. data/lib/pubid/bsi/single_identifier.rb +48 -0
  63. data/lib/pubid/builder/base.rb +5 -3
  64. data/lib/pubid/bundled_identifier.rb +3 -3
  65. data/lib/pubid/calconnect/builder.rb +38 -0
  66. data/lib/pubid/calconnect/identifier.rb +117 -0
  67. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  68. data/lib/pubid/calconnect/identifiers.rb +9 -0
  69. data/lib/pubid/calconnect/parser.rb +54 -0
  70. data/lib/pubid/calconnect/renderer.rb +36 -0
  71. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  72. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  73. data/lib/pubid/calconnect.rb +77 -0
  74. data/lib/pubid/ccsds/builder.rb +1 -1
  75. data/lib/pubid/ccsds/identifier.rb +1 -1
  76. data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
  77. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  78. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  79. data/lib/pubid/cen_cenelec/builder.rb +46 -12
  80. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
  81. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
  82. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
  83. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  84. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
  85. data/lib/pubid/cen_cenelec/renderer.rb +5 -5
  86. data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
  87. data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
  88. data/lib/pubid/cen_cenelec.rb +76 -72
  89. data/lib/pubid/cie/builder.rb +139 -24
  90. data/lib/pubid/cie/identifier.rb +7 -3
  91. data/lib/pubid/cie/identifiers/bundle.rb +32 -4
  92. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  93. data/lib/pubid/cie/identifiers/conference.rb +9 -4
  94. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  95. data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
  96. data/lib/pubid/cie/identifiers/identical.rb +7 -7
  97. data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
  98. data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
  99. data/lib/pubid/cie/identifiers/standard.rb +33 -7
  100. data/lib/pubid/cie/identifiers/supplement.rb +24 -22
  101. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
  102. data/lib/pubid/cie/identifiers.rb +2 -0
  103. data/lib/pubid/cie/parser.rb +54 -5
  104. data/lib/pubid/cie/single_identifier.rb +40 -1
  105. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  106. data/lib/pubid/cie/urn_generator.rb +11 -8
  107. data/lib/pubid/cie.rb +0 -1
  108. data/lib/pubid/components/date.rb +21 -5
  109. data/lib/pubid/csa/builder.rb +1 -1
  110. data/lib/pubid/csa/composite_identifier.rb +17 -1
  111. data/lib/pubid/csa/identifier.rb +48 -3
  112. data/lib/pubid/csa/identifiers/bundled.rb +6 -0
  113. data/lib/pubid/csa/identifiers/combined.rb +6 -0
  114. data/lib/pubid/csa/identifiers/package.rb +2 -2
  115. data/lib/pubid/csa/parser.rb +6 -6
  116. data/lib/pubid/csa/wrapper_identifier.rb +17 -0
  117. data/lib/pubid/doi/builder.rb +18 -0
  118. data/lib/pubid/doi/identifier.rb +46 -0
  119. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  120. data/lib/pubid/doi/identifiers.rb +9 -0
  121. data/lib/pubid/doi/parser.rb +52 -0
  122. data/lib/pubid/doi/renderer.rb +13 -0
  123. data/lib/pubid/doi.rb +55 -0
  124. data/lib/pubid/easc/builder.rb +55 -0
  125. data/lib/pubid/easc/identifier.rb +61 -0
  126. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  127. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  128. data/lib/pubid/easc/identifiers.rb +10 -0
  129. data/lib/pubid/easc/parser.rb +80 -0
  130. data/lib/pubid/easc/renderer.rb +48 -0
  131. data/lib/pubid/easc/urn_generator.rb +46 -0
  132. data/lib/pubid/easc/urn_parser.rb +57 -0
  133. data/lib/pubid/easc.rb +52 -0
  134. data/lib/pubid/ecma/builder.rb +31 -0
  135. data/lib/pubid/ecma/identifier.rb +76 -0
  136. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  137. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  138. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  139. data/lib/pubid/ecma/identifiers.rb +11 -0
  140. data/lib/pubid/ecma/parser.rb +41 -0
  141. data/lib/pubid/ecma/renderer.rb +46 -0
  142. data/lib/pubid/ecma/urn_generator.rb +25 -0
  143. data/lib/pubid/ecma/urn_parser.rb +35 -0
  144. data/lib/pubid/ecma.rb +67 -0
  145. data/lib/pubid/etsi/builder.rb +7 -3
  146. data/lib/pubid/etsi/identifier.rb +1 -3
  147. data/lib/pubid/etsi/identifiers/base.rb +28 -10
  148. data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
  149. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
  150. data/lib/pubid/etsi/identifiers.rb +0 -1
  151. data/lib/pubid/etsi/parser.rb +8 -2
  152. data/lib/pubid/etsi/renderer.rb +8 -2
  153. data/lib/pubid/etsi.rb +5 -5
  154. data/lib/pubid/export/exporter.rb +2 -1
  155. data/lib/pubid/export/flavor_exporter.rb +18 -3
  156. data/lib/pubid/gb/builder.rb +45 -0
  157. data/lib/pubid/gb/identifier.rb +64 -0
  158. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  159. data/lib/pubid/gb/identifiers.rb +9 -0
  160. data/lib/pubid/gb/parser.rb +63 -0
  161. data/lib/pubid/gb/renderer.rb +35 -0
  162. data/lib/pubid/gb.rb +87 -0
  163. data/lib/pubid/gost/builder.rb +148 -0
  164. data/lib/pubid/gost/identifier.rb +49 -0
  165. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  166. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  167. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  168. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  169. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  170. data/lib/pubid/gost/identifiers.rb +13 -0
  171. data/lib/pubid/gost/parser.rb +97 -0
  172. data/lib/pubid/gost/renderer.rb +48 -0
  173. data/lib/pubid/gost/urn_generator.rb +46 -0
  174. data/lib/pubid/gost/urn_parser.rb +52 -0
  175. data/lib/pubid/gost.rb +49 -0
  176. data/lib/pubid/iala/builder.rb +22 -27
  177. data/lib/pubid/iala/identifier.rb +27 -2
  178. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  179. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  180. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  181. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  182. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  183. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  184. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  185. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  186. data/lib/pubid/iala/identifiers/report.rb +1 -1
  187. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  188. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  189. data/lib/pubid/iala/identifiers.rb +0 -1
  190. data/lib/pubid/iala/renderer.rb +1 -1
  191. data/lib/pubid/iala/urn_generator.rb +1 -1
  192. data/lib/pubid/iala/urn_parser.rb +19 -2
  193. data/lib/pubid/iala.rb +4 -4
  194. data/lib/pubid/iana/builder.rb +20 -0
  195. data/lib/pubid/iana/identifier.rb +72 -0
  196. data/lib/pubid/iana/identifiers/registry.rb +33 -0
  197. data/lib/pubid/iana/identifiers.rb +9 -0
  198. data/lib/pubid/iana/parser.rb +38 -0
  199. data/lib/pubid/iana/renderer.rb +29 -0
  200. data/lib/pubid/iana/urn_generator.rb +15 -0
  201. data/lib/pubid/iana/urn_parser.rb +24 -0
  202. data/lib/pubid/iana.rb +69 -0
  203. data/lib/pubid/identifier.rb +210 -23
  204. data/lib/pubid/idf/builder.rb +1 -1
  205. data/lib/pubid/idf/parser.rb +2 -2
  206. data/lib/pubid/idf/renderer.rb +1 -1
  207. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  208. data/lib/pubid/iec/builder.rb +35 -25
  209. data/lib/pubid/iec/identifier.rb +47 -2
  210. data/lib/pubid/iec/identifiers/base.rb +2 -2
  211. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  212. data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
  213. data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
  214. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  215. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  216. data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
  217. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
  218. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  219. data/lib/pubid/iec/identifiers.rb +1 -0
  220. data/lib/pubid/iec/parser.rb +51 -10
  221. data/lib/pubid/iec/renderer.rb +18 -8
  222. data/lib/pubid/iec/single_identifier.rb +1 -1
  223. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  224. data/lib/pubid/iec.rb +1 -6
  225. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  226. data/lib/pubid/ieee/aiee/identifier.rb +45 -61
  227. data/lib/pubid/ieee/builder.rb +341 -68
  228. data/lib/pubid/ieee/compaction.rb +121 -0
  229. data/lib/pubid/ieee/components/draft.rb +47 -7
  230. data/lib/pubid/ieee/identifier.rb +1 -3
  231. data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
  232. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  233. data/lib/pubid/ieee/identifiers/base.rb +106 -13
  234. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  235. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  236. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  237. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
  238. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  239. data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
  240. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  241. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
  242. data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
  243. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
  244. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  245. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  246. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  247. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  248. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  249. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  250. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  251. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  252. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  253. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  254. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  255. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  256. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  257. data/lib/pubid/ieee/identifiers.rb +2 -1
  258. data/lib/pubid/ieee/ire/builder.rb +7 -6
  259. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  260. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  261. data/lib/pubid/ieee/nesc/parser.rb +15 -14
  262. data/lib/pubid/ieee/parser.rb +461 -43
  263. data/lib/pubid/ieee/pre_parser.rb +1 -1
  264. data/lib/pubid/ieee/renderer.rb +154 -57
  265. data/lib/pubid/ieee/typed_stages.rb +12 -1
  266. data/lib/pubid/ieee/urn_generator.rb +3 -5
  267. data/lib/pubid/ieee.rb +56 -3
  268. data/lib/pubid/ietf/builder.rb +62 -0
  269. data/lib/pubid/ietf/identifier.rb +5 -0
  270. data/lib/pubid/ietf/identifiers/base.rb +75 -0
  271. data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
  272. data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
  273. data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
  274. data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
  275. data/lib/pubid/ietf/identifiers/std.rb +25 -0
  276. data/lib/pubid/ietf/identifiers.rb +13 -0
  277. data/lib/pubid/ietf/parser.rb +43 -0
  278. data/lib/pubid/ietf/renderer.rb +26 -0
  279. data/lib/pubid/ietf/urn_generator.rb +23 -0
  280. data/lib/pubid/ietf/urn_parser.rb +35 -0
  281. data/lib/pubid/ietf.rb +76 -0
  282. data/lib/pubid/iho/identifier.rb +1 -3
  283. data/lib/pubid/iho/identifiers/base.rb +1 -7
  284. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  285. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  286. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  287. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  288. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  289. data/lib/pubid/iho/identifiers.rb +0 -1
  290. data/lib/pubid/iho.rb +7 -7
  291. data/lib/pubid/isbn/builder.rb +44 -0
  292. data/lib/pubid/isbn/check_digit.rb +53 -0
  293. data/lib/pubid/isbn/identifier.rb +63 -0
  294. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  295. data/lib/pubid/isbn/identifiers.rb +9 -0
  296. data/lib/pubid/isbn/parser.rb +45 -0
  297. data/lib/pubid/isbn/renderer.rb +16 -0
  298. data/lib/pubid/isbn.rb +52 -0
  299. data/lib/pubid/iso/builder.rb +9 -4
  300. data/lib/pubid/iso/combined_identifier.rb +2 -2
  301. data/lib/pubid/iso/identifier.rb +17 -1
  302. data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
  303. data/lib/pubid/iso/normalizer.rb +2 -2
  304. data/lib/pubid/iso/parser.rb +16 -12
  305. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  306. data/lib/pubid/iso/urn_generator.rb +4 -1
  307. data/lib/pubid/iso/urn_parser.rb +1 -1
  308. data/lib/pubid/itu/builder.rb +230 -29
  309. data/lib/pubid/itu/components/code.rb +48 -5
  310. data/lib/pubid/itu/components/designation.rb +35 -0
  311. data/lib/pubid/itu/components.rb +1 -0
  312. data/lib/pubid/itu/identifier.rb +1 -3
  313. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  314. data/lib/pubid/itu/identifiers/amendment.rb +6 -28
  315. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  316. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  317. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  318. data/lib/pubid/itu/identifiers/base.rb +341 -23
  319. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  320. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  321. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  322. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  323. data/lib/pubid/itu/identifiers/question.rb +63 -0
  324. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  325. data/lib/pubid/itu/identifiers/report.rb +39 -0
  326. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  327. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  328. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  329. data/lib/pubid/itu/identifiers.rb +10 -1
  330. data/lib/pubid/itu/model.rb +1 -1
  331. data/lib/pubid/itu/parser.rb +480 -26
  332. data/lib/pubid/itu/urn_generator.rb +36 -6
  333. data/lib/pubid/itu/urn_parser.rb +8 -0
  334. data/lib/pubid/itu.rb +11 -3
  335. data/lib/pubid/jcgm/builder.rb +23 -13
  336. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  337. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  338. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  339. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  340. data/lib/pubid/jcgm/identifiers.rb +2 -0
  341. data/lib/pubid/jcgm/parser.rb +66 -6
  342. data/lib/pubid/jcgm/renderer.rb +26 -12
  343. data/lib/pubid/jcgm/single_identifier.rb +74 -5
  344. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  345. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  346. data/lib/pubid/jcgm/urn_parser.rb +15 -3
  347. data/lib/pubid/jis/identifier.rb +52 -0
  348. data/lib/pubid/nist/builder.rb +29 -9
  349. data/lib/pubid/nist/caster.rb +7 -45
  350. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  351. data/lib/pubid/nist/components/supplement.rb +5 -2
  352. data/lib/pubid/nist/configuration.rb +7 -1
  353. data/lib/pubid/nist/identifier.rb +1 -3
  354. data/lib/pubid/nist/identifiers/base.rb +121 -37
  355. data/lib/pubid/nist/identifiers/circular.rb +1 -1
  356. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  357. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  358. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
  359. data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
  360. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  361. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  362. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  363. data/lib/pubid/nist/identifiers/handbook.rb +1 -1
  364. data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
  365. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  366. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
  367. data/lib/pubid/nist/identifiers/monograph.rb +1 -1
  368. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  369. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  370. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  371. data/lib/pubid/nist/identifiers/report.rb +1 -1
  372. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  373. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  374. data/lib/pubid/nist/identifiers.rb +0 -1
  375. data/lib/pubid/nist/parser.rb +26 -3
  376. data/lib/pubid/nist/preprocessor.rb +15 -0
  377. data/lib/pubid/nist/router.rb +2 -2
  378. data/lib/pubid/nist/series/ir.rb +0 -3
  379. data/lib/pubid/nist/supplement_identifier.rb +9 -9
  380. data/lib/pubid/nist.rb +12 -12
  381. data/lib/pubid/oasis/builder.rb +77 -0
  382. data/lib/pubid/oasis/identifier.rb +82 -0
  383. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  384. data/lib/pubid/oasis/identifiers.rb +9 -0
  385. data/lib/pubid/oasis/parser.rb +34 -0
  386. data/lib/pubid/oasis/renderer.rb +29 -0
  387. data/lib/pubid/oasis/urn_generator.rb +25 -0
  388. data/lib/pubid/oasis/urn_parser.rb +22 -0
  389. data/lib/pubid/oasis.rb +74 -0
  390. data/lib/pubid/ogc/builder.rb +33 -0
  391. data/lib/pubid/ogc/identifier.rb +77 -0
  392. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  393. data/lib/pubid/ogc/identifiers.rb +10 -0
  394. data/lib/pubid/ogc/parser.rb +40 -0
  395. data/lib/pubid/ogc/renderer.rb +33 -0
  396. data/lib/pubid/ogc/urn_generator.rb +14 -0
  397. data/lib/pubid/ogc/urn_parser.rb +22 -0
  398. data/lib/pubid/ogc.rb +71 -0
  399. data/lib/pubid/oiml/builder.rb +31 -7
  400. data/lib/pubid/oiml/identifier.rb +9 -1
  401. data/lib/pubid/oiml/parser.rb +11 -12
  402. data/lib/pubid/oiml/renderer.rb +13 -13
  403. data/lib/pubid/oiml/single_identifier.rb +20 -0
  404. data/lib/pubid/oiml/supplement_identifier.rb +9 -9
  405. data/lib/pubid/oiml/urn_parser.rb +23 -6
  406. data/lib/pubid/oiml.rb +4 -0
  407. data/lib/pubid/omg/builder.rb +19 -0
  408. data/lib/pubid/omg/identifier.rb +44 -0
  409. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  410. data/lib/pubid/omg/identifiers.rb +9 -0
  411. data/lib/pubid/omg/parser.rb +40 -0
  412. data/lib/pubid/omg/renderer.rb +19 -0
  413. data/lib/pubid/omg.rb +51 -0
  414. data/lib/pubid/parsers/mr_string.rb +101 -7
  415. data/lib/pubid/plateau/builder.rb +8 -4
  416. data/lib/pubid/plateau/identifier.rb +1 -3
  417. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  418. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  419. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  420. data/lib/pubid/plateau/identifiers.rb +0 -1
  421. data/lib/pubid/plateau/parser.rb +15 -5
  422. data/lib/pubid/plateau/renderer.rb +1 -1
  423. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  424. data/lib/pubid/plateau.rb +4 -4
  425. data/lib/pubid/renderers/human_readable.rb +3 -1
  426. data/lib/pubid/renderers/mr_string.rb +46 -4
  427. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  428. data/lib/pubid/rendering/supplement.rb +4 -4
  429. data/lib/pubid/sae/builder.rb +1 -1
  430. data/lib/pubid/sae/identifier.rb +1 -3
  431. data/lib/pubid/sae/identifiers/base.rb +10 -7
  432. data/lib/pubid/sae/identifiers.rb +0 -1
  433. data/lib/pubid/sae.rb +3 -3
  434. data/lib/pubid/tgpp/builder.rb +41 -0
  435. data/lib/pubid/tgpp/identifier.rb +91 -0
  436. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  437. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  438. data/lib/pubid/tgpp/identifiers.rb +11 -0
  439. data/lib/pubid/tgpp/parser.rb +62 -0
  440. data/lib/pubid/tgpp/renderer.rb +36 -0
  441. data/lib/pubid/tgpp/urn_generator.rb +20 -0
  442. data/lib/pubid/tgpp/urn_parser.rb +28 -0
  443. data/lib/pubid/tgpp.rb +78 -0
  444. data/lib/pubid/type_resolver.rb +59 -0
  445. data/lib/pubid/un/builder.rb +42 -0
  446. data/lib/pubid/un/identifier.rb +37 -0
  447. data/lib/pubid/un/identifiers/document.rb +24 -0
  448. data/lib/pubid/un/identifiers.rb +9 -0
  449. data/lib/pubid/un/parser.rb +25 -0
  450. data/lib/pubid/un/renderer.rb +11 -0
  451. data/lib/pubid/un.rb +46 -0
  452. data/lib/pubid/version.rb +1 -1
  453. data/lib/pubid/w3c/builder.rb +55 -0
  454. data/lib/pubid/w3c/identifier.rb +101 -0
  455. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  456. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  457. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  458. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  459. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  460. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  461. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  462. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  463. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  464. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  465. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  466. data/lib/pubid/w3c/identifiers.rb +25 -0
  467. data/lib/pubid/w3c/parser.rb +43 -0
  468. data/lib/pubid/w3c/renderer.rb +35 -0
  469. data/lib/pubid/w3c/urn_generator.rb +18 -0
  470. data/lib/pubid/w3c/urn_parser.rb +36 -0
  471. data/lib/pubid/w3c.rb +67 -0
  472. data/lib/pubid/xsf/builder.rb +17 -0
  473. data/lib/pubid/xsf/identifier.rb +62 -0
  474. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  475. data/lib/pubid/xsf/identifiers.rb +9 -0
  476. data/lib/pubid/xsf/parser.rb +25 -0
  477. data/lib/pubid/xsf/renderer.rb +23 -0
  478. data/lib/pubid/xsf/urn_generator.rb +13 -0
  479. data/lib/pubid/xsf/urn_parser.rb +18 -0
  480. data/lib/pubid/xsf.rb +76 -0
  481. data/lib/pubid.rb +25 -1
  482. metadata +205 -4
  483. data/lib/pubid/cie/components/code.rb +0 -80
  484. data/lib/pubid/iala/identifiers/base.rb +0 -14
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Omg
7
+ # Parslet grammar for OMG specification identifiers.
8
+ #
9
+ # Accepts:
10
+ # OMG {ACRONYM}[ {VERSION}]
11
+ #
12
+ # ACRONYM is uppercase letters/digits, at least 1 char.
13
+ # VERSION is digits/dots/spaces/beta+space+digit, e.g. "1.0", "2.5.1",
14
+ # "5 beta 3".
15
+ class Parser < Parslet::Parser
16
+ rule(:space) { str(" ") }
17
+
18
+ # Acronym: starts with uppercase, may contain uppercase + lowercase +
19
+ # digits (covers "SysML", "AMI4CCM", "UML", "CORBA", "BMM", ...).
20
+ rule(:acronym) { (match("[A-Z]") >> match("[A-Za-z0-9]").repeat).as(:acronym) }
21
+
22
+ # Version: digits with optional dots, optionally followed by " beta N".
23
+ rule(:version) do
24
+ (match("[0-9]").repeat(1) >>
25
+ (str(".") >> match("[0-9]").repeat(1)).repeat >>
26
+ (str(" beta ") >> match("[0-9]").repeat(1)).maybe).as(:version)
27
+ end
28
+
29
+ rule(:identifier) do
30
+ str("OMG") >> space >> acronym >> (space >> version).maybe
31
+ end
32
+
33
+ rule(:root) { identifier }
34
+
35
+ def self.parse(input)
36
+ new.parse(input)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Omg
5
+ # Human-readable renderer for OMG specification identifiers.
6
+ #
7
+ # Produces:
8
+ # "OMG AMI4CCM 1.0"
9
+ # "OMG UML 2.5.1"
10
+ # "OMG CORBA"
11
+ class Renderer < ::Pubid::Renderers::Base
12
+ def render(**_opts)
13
+ result = "OMG #{@id.acronym}"
14
+ result += " #{@id.version}" if @id.version && !@id.version.empty?
15
+ result
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/pubid/omg.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ # OMG (Object Management Group) specification flavor.
5
+ #
6
+ # Covers formal OMG specifications identified by an acronym (UML, SysML,
7
+ # CORBA, AMI4CCM, ...) with optional version (`1.0`, `2.5.1`,
8
+ # `5 beta 3`).
9
+ module Omg
10
+ extend Pubid::PrefixesSupport
11
+
12
+ PREFIXES = ["OMG"].freeze
13
+
14
+ autoload :Builder, "#{__dir__}/omg/builder"
15
+ autoload :Identifier, "#{__dir__}/omg/identifier"
16
+ autoload :Identifiers, "#{__dir__}/omg/identifiers"
17
+ autoload :Parser, "#{__dir__}/omg/parser"
18
+ autoload :Renderer, "#{__dir__}/omg/renderer"
19
+
20
+ def self.parse(identifier)
21
+ Identifier.parse(identifier)
22
+ end
23
+
24
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
25
+ Identifier.format_registry.register(:human, renderer: Omg::Renderer)
26
+
27
+ def self.identifier_types
28
+ @identifier_types ||= Identifiers.constants
29
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
30
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
31
+ .select { |c| c.type.is_a?(Hash) }
32
+ end
33
+
34
+ def self.all_typed_stages
35
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
36
+ klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
37
+ end
38
+ end
39
+
40
+ def self.locate_type(code)
41
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
42
+ end
43
+
44
+ def self.locate_stage(abbr)
45
+ abbr_str = abbr.to_s.upcase
46
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
47
+ end
48
+ end
49
+ end
50
+
51
+ Pubid::Registry.register(:omg, Pubid::Omg)
@@ -2,6 +2,28 @@
2
2
 
3
3
  module Pubid
4
4
  module Parsers
5
+ # Parses a machine-readable (MR) identifier string back into an Identifier.
6
+ #
7
+ # The MR format produced by `Renderers::MrString` mirrors the human form,
8
+ # lowercased and filename-safe:
9
+ #
10
+ # iso.9001.2015 → ISO 9001:2015
11
+ # iso-iec.17031-1.2020 → ISO/IEC 17031-1:2020
12
+ # iso.1234-1-2-3.2020 → ISO 1234-1-2-3:2020
13
+ # iso.tr.14627.2017 → ISO/TR 14627:2017
14
+ # iso.16634.-- → ISO 16634:--
15
+ # iso.9001.2015_amd.1.2020 → ISO 9001:2015/Amd 1:2020
16
+ # iso-iec.13818-1.2015_amd.3.2016_cor.1.2017 → ISO/IEC 13818-1:2015/Amd 3:2016/Cor 1:2017
17
+ #
18
+ # Copublishers join with `-` (`iso-iec`), supplements append with `_`
19
+ # (`iso.9001.2015_amd.1.2020`). Both round-trip back to `/` here. The
20
+ # flavor's own parser is case-insensitive on the type/publisher tokens
21
+ # we emit, so the lowercased slug re-parses cleanly.
22
+ #
23
+ # Note: NIST, CSA, IEEE, JIS, and SAE emit their own MR shapes that this
24
+ # parser does not attempt to reverse (their `to_s` already round-trips
25
+ # through the flavor's own parser, so callers should use that path for
26
+ # those flavors).
5
27
  class MrString < Base
6
28
  FLAVOR_MAP = {
7
29
  "ISO" => :iso,
@@ -59,6 +81,14 @@ module Pubid
59
81
  ccsds: :Ccsds,
60
82
  }.freeze
61
83
 
84
+ # Lower-case type codes the renderer emits as a separate MR segment
85
+ # (e.g. `iso.tr.14627`). When the parser sees one of these in the
86
+ # second position, it splits it back out as `/TYPE`.
87
+ TYPE_CODES = %w[
88
+ tr ts pas is amd cor suppl add ext guide spec
89
+ standard corrigendum amendment
90
+ ].freeze
91
+
62
92
  def self.parse(mr_string)
63
93
  flavor = detect_flavor(mr_string)
64
94
 
@@ -75,19 +105,83 @@ module Pubid
75
105
  end
76
106
 
77
107
  def self.detect_flavor(mr_string)
78
- publisher = mr_string.split(".").first.upcase
108
+ publisher = mr_string.split(/[._-]/).first.to_s.upcase
79
109
  FLAVOR_MAP[publisher] || :iso
80
110
  end
81
111
 
112
+ # Convert the MR slug back to a human-readable identifier string the
113
+ # flavor's own parser will accept. Splits on `_` first so each segment
114
+ # (head + each supplement) is converted independently, then re-joined
115
+ # with `/`. Within the head, the copublisher separator `-` (first
116
+ # segment only) is restored to `/`.
82
117
  def self.convert_to_human_readable(mr_string)
83
- parts = mr_string.split(".")
84
- if parts.size > 2
85
- year_part = parts.pop
86
- parts.join(" ") + ":#{year_part}"
87
- else
88
- parts.join(" ")
118
+ head, *supplements = mr_string.split("_")
119
+ human = convert_head(head)
120
+ return human if supplements.empty?
121
+
122
+ supplements.inject(human) do |acc, supp|
123
+ "#{acc}/#{convert_supplement(supp)}"
124
+ end
125
+ end
126
+
127
+ # Converts a head segment like `iso-iec.13818-1.2015` to
128
+ # `ISO/IEC 13818-1:2015`.
129
+ def self.convert_head(head)
130
+ parts = head.split(".")
131
+ return parts.join(" ").upcase if parts.length <= 1
132
+
133
+ publisher, *rest = parts
134
+
135
+ # Optional type code segment (iso.tr.14627.2017 → ISO/TR 14627:2017).
136
+ type_segment = nil
137
+ if rest.first && TYPE_CODES.include?(rest.first.downcase)
138
+ type_segment = rest.shift.upcase
139
+ end
140
+
141
+ # Trailing language segment — bare language code(s) with no parens.
142
+ # Detect by length <= 5 and all-alpha (en, fr, en-fr, ru).
143
+ language_segment = nil
144
+ if rest.last&.match?(/\A[a-z]{2}(-[a-z]{2})*\z/)
145
+ language_segment = rest.pop
89
146
  end
147
+
148
+ # Trailing year segment (may be `--` for undated, or YYYY[-MM[-DD]]).
149
+ year_segment = nil
150
+ if rest.any? && rest.last.match?(/\A(?:\d{4}(?:-\d{2}){0,2}|--)\z/)
151
+ year_segment = rest.pop
152
+ end
153
+
154
+ # Copublishers in the first segment: `iso-iec` → `ISO/IEC`. Multi-word
155
+ # publisher bodies (e.g. `cen-cenelec`) round-trip the same way.
156
+ publisher_part = publisher.split("-").map(&:upcase).join("/")
157
+ publisher_part = "#{publisher_part}/#{type_segment}" if type_segment
158
+
159
+ number_part = rest.join(" ")
160
+ result = publisher_part
161
+ result += " #{number_part}" unless number_part.empty?
162
+ result += ":#{year_segment}" if year_segment
163
+ if language_segment
164
+ langs = language_segment.split("-").join(",")
165
+ result += "(#{langs})"
166
+ end
167
+ result
168
+ end
169
+
170
+ # Converts a supplement segment like `amd.1.2020` to `Amd 1:2020`.
171
+ # The first token is the lowercase type code; remaining tokens are
172
+ # number and optional year.
173
+ def self.convert_supplement(supp)
174
+ tokens = supp.split(".")
175
+ type = tokens.shift&.upcase
176
+ year = tokens.last&.match?(/\A\d{4}\z/) ? tokens.pop : nil
177
+ number = tokens.join(" ")
178
+
179
+ result = type.to_s
180
+ result += " #{number}" unless number.empty?
181
+ result += ":#{year}" if year
182
+ result
90
183
  end
91
184
  end
92
185
  end
93
186
  end
187
+
@@ -9,7 +9,7 @@ module Pubid
9
9
 
10
10
  def build(parsed)
11
11
  # Check for annex supplement first
12
- if parsed[:base_identifier] && parsed[:annex_letter]
12
+ if parsed[:base] && parsed[:annex_letter]
13
13
  return build_annex(parsed)
14
14
  end
15
15
 
@@ -29,7 +29,11 @@ module Pubid
29
29
  }
30
30
 
31
31
  params[:annex] = parsed[:annex].to_s.to_i if parsed[:annex]
32
- params[:edition] = parsed[:edition].to_s if parsed[:edition]
32
+ # Only Handbook carries an edition; a legacy Latin TR captures the
33
+ # edition slice via the shared handbook rule, so drop it here.
34
+ if parsed[:edition] && klass == Identifiers::Handbook
35
+ params[:edition] = parsed[:edition].to_s
36
+ end
33
37
 
34
38
  klass.new(**params)
35
39
  end
@@ -38,10 +42,10 @@ module Pubid
38
42
 
39
43
  def build_annex(parsed)
40
44
  # Recursively parse base identifier
41
- base = build(parsed[:base_identifier])
45
+ base = build(parsed[:base])
42
46
 
43
47
  Identifiers::Annex.new(
44
- base_identifier: base,
48
+ base: base,
45
49
  letter: parsed[:annex_letter].to_s,
46
50
  )
47
51
  end
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Pubid::Plateau::Identifier is the PLATEAU base class (a real Pubid::Identifier
4
- # subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
5
- # live in identifiers/base.rb. This file just ensures it is loaded.
6
- require_relative "identifiers/base"
4
+ # subclass); its body and `.parse` live in identifiers/base.rb. This file just ensures it is loaded.
@@ -3,7 +3,7 @@
3
3
  module Pubid
4
4
  module Plateau
5
5
  # Base class for all PLATEAU identifiers. Canonical name
6
- # Pubid::Plateau::Identifier (Identifiers::Base is a back-compat alias).
6
+ # Pubid::Plateau::Identifier.
7
7
  class Identifier < ::Pubid::Identifier
8
8
  # Delegate to the flavor module so callers can use
9
9
  # `Pubid::Plateau::Identifier.parse` consistently with other flavors.
@@ -51,10 +51,5 @@ module Pubid
51
51
  end
52
52
  end
53
53
 
54
- module Identifiers
55
- # Backward-compatible alias: PLATEAU's base class used to be
56
- # Pubid::Plateau::Identifiers::Base. It is now Pubid::Plateau::Identifier.
57
- Base = Pubid::Plateau::Identifier
58
- end
59
54
  end
60
55
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  # PLATEAU Handbook
7
7
  # Format: PLATEAU Handbook #NN[-annex] [第X.Y版]
8
8
  # Example: PLATEAU Handbook #00 第1.0版
9
- class Handbook < Base
9
+ class Handbook < Identifier
10
10
  attribute :edition, :string, default: -> {}
11
11
 
12
12
  def type_string
@@ -6,7 +6,7 @@ module Pubid
6
6
  # PLATEAU Technical Report
7
7
  # Format: PLATEAU Technical Report #NN[-annex]
8
8
  # Example: PLATEAU Technical Report #01
9
- class TechnicalReport < Base
9
+ class TechnicalReport < Identifier
10
10
  def type_string
11
11
  "Technical Report"
12
12
  end
@@ -4,7 +4,6 @@ module Pubid
4
4
  module Plateau
5
5
  module Identifiers
6
6
  autoload :Annex, "#{__dir__}/identifiers/annex"
7
- autoload :Base, "#{__dir__}/identifiers/base"
8
7
  autoload :Handbook, "#{__dir__}/identifiers/handbook"
9
8
  autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
10
9
  end
@@ -21,17 +21,23 @@ module Pubid
21
21
  # Number: #00, #01, #46, etc.
22
22
  rule(:number) { hash >> digits.as(:number) }
23
23
 
24
- # Annex: -1, -2, etc.
25
- rule(:annex) { dash >> digits.as(:annex) }
24
+ # Annex: -1, -2, etc. Legacy Latin references use "_" as the sub-number
25
+ # separator (e.g. "#46_1"); both render as the canonical dash.
26
+ rule(:annex) { (dash | str("_")) >> digits.as(:annex) }
26
27
 
27
- # Edition: 第1.0版, 第2.3版, etc. (only for Handbook)
28
+ # Edition (Handbook only). Canonical form is 第X.Y版; legacy Latin
29
+ # references write the bare X.Y (e.g. "PLATEAU Handbook #00 1.0"). Both
30
+ # capture the same numeric :edition slice, so they build the same object
31
+ # and render to the canonical 第X.Y版.
28
32
  rule(:edition_part) do
29
33
  str("第") >>
30
34
  (digits >> str(".") >> digits).as(:edition) >>
31
35
  str("版")
32
36
  end
33
37
 
34
- rule(:edition) { space >> edition_part }
38
+ rule(:edition_latin) { (digits >> str(".") >> digits).as(:edition) }
39
+
40
+ rule(:edition) { space >> (edition_part | edition_latin) }
35
41
 
36
42
  # Annex supplement: "Annex A", "Annex B", etc.
37
43
  rule(:annex_letter) { match["A-Z"].as(:annex_letter) }
@@ -45,6 +51,10 @@ module Pubid
45
51
  number >> annex.maybe >> edition.maybe
46
52
  end
47
53
 
54
+ # Technical Report has no edition. A legacy Latin TR reference carrying a
55
+ # trailing edition (e.g. "#00 1.0") is matched by the `handbook` rule
56
+ # (doc_type matches either keyword, tried first); the builder dispatches
57
+ # on :type and drops the captured edition for Technical Report.
48
58
  rule(:technical_report) do
49
59
  publisher >> space >> doc_type >> space >>
50
60
  number >> annex.maybe
@@ -52,7 +62,7 @@ module Pubid
52
62
 
53
63
  # Annex identifier (supplement)
54
64
  rule(:annex_identifier) do
55
- (handbook | technical_report).as(:base_identifier) >> annex_supplement
65
+ (handbook | technical_report).as(:base) >> annex_supplement
56
66
  end
57
67
 
58
68
  rule(:identifier) { annex_identifier | handbook | technical_report }
@@ -44,7 +44,7 @@ module Pubid
44
44
  end
45
45
 
46
46
  def render_supplement(id)
47
- "#{id.base_identifier} #{id.supplement_string}"
47
+ "#{id.base} #{id.supplement_string}"
48
48
  end
49
49
  end
50
50
  end
@@ -7,7 +7,7 @@ module Pubid
7
7
  # Base class for PLATEAU supplements (Annex)
8
8
  # Supplements reference a base identifier
9
9
  class SupplementIdentifier < Pubid::Identifier
10
- attribute :base_identifier, Identifiers::Base
10
+ attribute :base, Identifier
11
11
  attribute :letter, :string, default: -> {}
12
12
 
13
13
  def publisher
@@ -19,20 +19,20 @@ module Pubid
19
19
  raise NotImplementedError, "Subclasses must implement supplement_string"
20
20
  end
21
21
 
22
- # Override base_hash to extract edition, type, and annex from base_identifier
22
+ # Override base_hash to extract edition, type, and annex from base
23
23
  def base_hash
24
24
  hash = super
25
25
  # For Plateau supplements, edition comes from the base identifier
26
- if base_identifier.class.attributes.key?(:edition) && base_identifier.edition
27
- hash[:edition] = base_identifier.edition
26
+ if base.class.attributes.key?(:edition) && base.edition
27
+ hash[:edition] = base.edition
28
28
  end
29
- # Include type from base_identifier
30
- if base_identifier.class.attributes.key?(:type_string) && base_identifier.type_string
31
- hash[:type] = base_identifier.type_string
29
+ # Include type from base
30
+ if base.class.attributes.key?(:type_string) && base.type_string
31
+ hash[:type] = base.type_string
32
32
  end
33
- # Include annex from base_identifier
34
- if base_identifier.class.attributes.key?(:annex) && base_identifier.annex
35
- hash[:annex] = base_identifier.annex
33
+ # Include annex from base
34
+ if base.class.attributes.key?(:annex) && base.annex
35
+ hash[:annex] = base.annex
36
36
  end
37
37
  hash
38
38
  end
@@ -60,7 +60,7 @@ module Pubid
60
60
  def ==(other)
61
61
  return false unless other.class == self.class
62
62
 
63
- base_identifier == other.base_identifier &&
63
+ base == other.base &&
64
64
  letter == other.letter
65
65
  end
66
66
  end
data/lib/pubid/plateau.rb CHANGED
@@ -10,7 +10,7 @@ module Pubid
10
10
  PREFIXES = ["PLATEAU"].freeze
11
11
 
12
12
  autoload :Builder, "#{__dir__}/plateau/builder"
13
- autoload :Identifier, "#{__dir__}/plateau/identifier"
13
+ autoload :Identifier, "#{__dir__}/plateau/identifiers/base"
14
14
  autoload :Identifiers, "#{__dir__}/plateau/identifiers"
15
15
  autoload :Parser, "#{__dir__}/plateau/parser"
16
16
  autoload :Renderer, "#{__dir__}/plateau/renderer"
@@ -27,9 +27,9 @@ module Pubid
27
27
  end
28
28
 
29
29
  # Per-flavor format registry: inherits global formats, overrides :human
30
- Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
31
- Identifiers::Base.format_registry.register(:human, renderer: Plateau::Renderer)
32
- SupplementIdentifier.format_registry = Identifiers::Base.format_registry
30
+ Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
31
+ Identifier.format_registry.register(:human, renderer: Plateau::Renderer)
32
+ SupplementIdentifier.format_registry = Identifier.format_registry
33
33
 
34
34
  # Auto-discover all identifier types from the Identifiers namespace
35
35
  # @return [Array<Class>] identifier classes that define a self.type Hash
@@ -3,7 +3,9 @@
3
3
  module Pubid
4
4
  module Renderers
5
5
  class HumanReadable < Base
6
- def render(context:, with_edition: false)
6
+ # `**_opts` absorbs render flags that only some flavors honour (e.g. the
7
+ # IEEE-specific `:trademark`), so the shared renderer tolerates them.
8
+ def render(context:, with_edition: false, **_opts)
7
9
  parts = []
8
10
  parts << render_publisher_and_stage(context)
9
11
  parts << render_number_portion(context)
@@ -2,13 +2,55 @@
2
2
 
3
3
  module Pubid
4
4
  module Renderers
5
+ # Machine-readable string renderer.
6
+ #
7
+ # Produces a lossless, dot-separated, all-lowercase, filename-safe slug:
8
+ #
9
+ # iso 9001:2015 -> iso.9001.2015
10
+ # iso/iec 17031-1:2020 -> iso-iec.17031-1.2020
11
+ # iso 1234-1-2-3:2020 -> iso.1234-1-2-3.2020
12
+ # iso/tr 14627:2017 -> iso.tr.14627.2017
13
+ # iso 16634:-- -> iso.16634.--
14
+ # iso 9001:2015/amd 1:2020 -> iso.9001.2015_amd.1.2020
15
+ # iso/iec 13818-1:2015/amd 3:2016/cor 1:2017
16
+ # -> iso-iec.13818-1.2015_amd.3.2016_cor.1.2017
17
+ #
18
+ # The renderer recurses into a supplement's `base` (one level per
19
+ # `mr_supplement_suffix`) so chained Cor-Amd-IS structures render fully,
20
+ # instead of every supplement layer collapsing onto its own
21
+ # type/number/year and dropping the base (issue #142).
22
+ #
23
+ # Character set is restricted to [a-z0-9.-] plus `_` (supplement
24
+ # separator), so `to_mr_string` doubles as a filesystem-/URL-safe slug.
25
+ # `Identifier#to_slug` delegates here; NIST is the one flavor that
26
+ # overrides `to_slug` because its MR shape is fixed by the pubid standard
27
+ # and stays uppercase.
5
28
  class MrString < Base
29
+ SEPARATOR_SUPPLEMENT = "_"
30
+
6
31
  def render(context: nil, **)
32
+ suffix = @id.mr_supplement_suffix
33
+
34
+ if suffix
35
+ base = @id.base
36
+ head = base ? self.class.new(base).render : ""
37
+ head.empty? ? suffix : "#{head}#{SEPARATOR_SUPPLEMENT}#{suffix}"
38
+ else
39
+ render_flat(@id)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def render_flat(id)
7
46
  parts = []
8
- parts << @id.mr_publisher
9
- parts << @id.mr_type
10
- parts << @id.mr_number_with_part
11
- parts << @id.mr_year
47
+ parts << id.mr_publisher
48
+ parts << id.mr_type
49
+ parts << id.mr_number_with_part
50
+ parts << id.mr_year
51
+ parts << id.mr_edition
52
+ parts << id.mr_languages
53
+ parts << id.mr_all_parts
12
54
  parts.compact.join(".")
13
55
  end
14
56
  end
@@ -6,7 +6,7 @@ module Pubid
6
6
  def render(context:, with_edition: false)
7
7
  parts = []
8
8
 
9
- base_str = @id.base_identifier.to_s(
9
+ base_str = @id.base.to_s(
10
10
  with_edition: with_edition,
11
11
  stage_format_long: context.stage_format_long,
12
12
  with_date: context.with_date,
@@ -4,14 +4,14 @@ module Pubid
4
4
  module Rendering
5
5
  module Supplement
6
6
  # Render supplement identifiers (amendment, corrigendum, addendum, etc.)
7
- # @param base_identifier [Identifier] base identifier
7
+ # @param base [Identifier] base identifier
8
8
  # @param supplements [Array<Hash>] list of supplements
9
9
  # @param options [Hash] rendering options
10
10
  # @return [String] formatted supplement string
11
- def render_supplements(base_identifier, supplements, **options)
12
- return base_identifier.to_s(**options) unless supplements&.any?
11
+ def render_supplements(base, supplements, **options)
12
+ return base.to_s(**options) unless supplements&.any?
13
13
 
14
- result = base_identifier.to_s(**options)
14
+ result = base.to_s(**options)
15
15
 
16
16
  supplements.each do |supp|
17
17
  result += render_single_supplement(supp, **options)
@@ -10,7 +10,7 @@ module Pubid
10
10
  private
11
11
 
12
12
  def default_identifier_class
13
- Identifiers::Base
13
+ Identifier
14
14
  end
15
15
 
16
16
  def cast(type, value)
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Pubid::Sae::Identifier is the SAE base class (a real Pubid::Identifier
4
- # subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
5
- # live in identifiers/base.rb. This file just ensures it is loaded.
6
- require_relative "identifiers/base"
4
+ # subclass); its body and `.parse` live in identifiers/base.rb. This file just ensures it is loaded.
@@ -2,8 +2,7 @@
2
2
 
3
3
  module Pubid
4
4
  module Sae
5
- # Base SAE Identifier. Canonical name Pubid::Sae::Identifier (Identifiers::Base
6
- # is a back-compat alias). SAE has a single identifier class that IS the
5
+ # Base SAE Identifier. Canonical name Pubid::Sae::Identifier. SAE has a single identifier class that IS the
7
6
  # document type, so this class is both the base and the only concrete type.
8
7
  # Handles all SAE document types (AMS, AIR, ARP, AS, MA).
9
8
  class Identifier < ::Pubid::Identifier
@@ -26,12 +25,16 @@ module Pubid
26
25
  def year
27
26
  date&.year
28
27
  end
29
- end
30
28
 
31
- module Identifiers
32
- # Backward-compatible alias: SAE's base class used to be
33
- # Pubid::Sae::Identifiers::Base. It is now Pubid::Sae::Identifier.
34
- Base = Pubid::Sae::Identifier
29
+ # SAE encodes the document class (AS, ARP, AMS, AIR, J, …) in `type.abbr`,
30
+ # not in `typed_stage.type_code`, so the generic mr_type returns nil.
31
+ # Losslessness requires the type letter to appear in MR — without it,
32
+ # `SAE J300` and `SAE AS300` would collide on `SAE.300.<year>`.
33
+ # Lowercased to match the all-lowercase MR convention (issue #142).
34
+ def mr_type
35
+ type&.abbr&.to_s&.downcase
36
+ end
35
37
  end
38
+
36
39
  end
37
40
  end
@@ -3,7 +3,6 @@
3
3
  module Pubid
4
4
  module Sae
5
5
  module Identifiers
6
- autoload :Base, "#{__dir__}/identifiers/base"
7
6
  end
8
7
  end
9
8
  end
data/lib/pubid/sae.rb CHANGED
@@ -10,7 +10,7 @@ module Pubid
10
10
 
11
11
  autoload :Builder, "#{__dir__}/sae/builder"
12
12
  autoload :Components, "#{__dir__}/sae/components"
13
- autoload :Identifier, "#{__dir__}/sae/identifier"
13
+ autoload :Identifier, "#{__dir__}/sae/identifiers/base"
14
14
  autoload :Identifiers, "#{__dir__}/sae/identifiers"
15
15
  autoload :Parser, "#{__dir__}/sae/parser"
16
16
  autoload :Renderer, "#{__dir__}/sae/renderer"
@@ -62,5 +62,5 @@ end
62
62
  Pubid::Registry.register(:sae, Pubid::Sae)
63
63
 
64
64
  # Per-flavor format registry: inherits global formats, overrides :human
65
- Pubid::Sae::Identifiers::Base.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
66
- Pubid::Sae::Identifiers::Base.format_registry.register(:human, renderer: Pubid::Sae::Renderer)
65
+ Pubid::Sae::Identifier.format_registry = Pubid::FormatRegistry.new(parent: Pubid::Identifier.format_registry)
66
+ Pubid::Sae::Identifier.format_registry.register(:human, renderer: Pubid::Sae::Renderer)