pubid 2.0.0.pre.alpha.8 → 2.0.0.pre.alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (672) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +33 -11
  3. data/conformance/pending.yaml +4 -0
  4. data/data/bipm/update_codes.yaml +9 -0
  5. data/data/iec/update_codes.yaml +3 -0
  6. data/data/ieee/update_codes.yaml +107 -1
  7. data/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
  8. data/data/nist/update_codes.yaml +8 -0
  9. data/lib/pubid/adobe/builder.rb +52 -0
  10. data/lib/pubid/adobe/identifier.rb +47 -0
  11. data/lib/pubid/adobe/identifiers/publication.rb +31 -0
  12. data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
  13. data/lib/pubid/adobe/identifiers.rb +10 -0
  14. data/lib/pubid/adobe/parser.rb +136 -0
  15. data/lib/pubid/adobe/renderer.rb +39 -0
  16. data/lib/pubid/adobe/urn_generator.rb +42 -0
  17. data/lib/pubid/adobe/urn_parser.rb +69 -0
  18. data/lib/pubid/adobe.rb +61 -0
  19. data/lib/pubid/amca/builder.rb +4 -4
  20. data/lib/pubid/amca/identifier.rb +1 -3
  21. data/lib/pubid/amca/identifiers/base.rb +50 -33
  22. data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
  23. data/lib/pubid/amca/identifiers/publication.rb +14 -10
  24. data/lib/pubid/amca/identifiers/standard.rb +3 -1
  25. data/lib/pubid/amca/identifiers.rb +0 -1
  26. data/lib/pubid/amca/parser.rb +1 -1
  27. data/lib/pubid/amca/renderer.rb +4 -4
  28. data/lib/pubid/amca/single_identifier.rb +1 -1
  29. data/lib/pubid/amca/urn_generator.rb +2 -2
  30. data/lib/pubid/amca.rb +5 -4
  31. data/lib/pubid/ansi/builder.rb +2 -2
  32. data/lib/pubid/ansi/identifier.rb +18 -0
  33. data/lib/pubid/ansi/parser.rb +1 -1
  34. data/lib/pubid/ansi/renderer.rb +2 -2
  35. data/lib/pubid/ansi.rb +5 -5
  36. data/lib/pubid/api/builder.rb +16 -2
  37. data/lib/pubid/api/identifier.rb +25 -4
  38. data/lib/pubid/api/identifiers/mpms.rb +10 -8
  39. data/lib/pubid/api/parser.rb +1 -1
  40. data/lib/pubid/api/renderer.rb +16 -7
  41. data/lib/pubid/api/single_identifier.rb +5 -12
  42. data/lib/pubid/api.rb +1 -0
  43. data/lib/pubid/ashrae/builder.rb +53 -32
  44. data/lib/pubid/ashrae/identifier.rb +3 -4
  45. data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
  46. data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
  47. data/lib/pubid/ashrae/identifiers/base.rb +94 -12
  48. data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
  49. data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
  50. data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
  51. data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
  52. data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
  53. data/lib/pubid/ashrae/identifiers.rb +0 -1
  54. data/lib/pubid/ashrae/parser.rb +37 -17
  55. data/lib/pubid/ashrae/renderer.rb +20 -20
  56. data/lib/pubid/ashrae/single_identifier.rb +1 -1
  57. data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
  58. data/lib/pubid/ashrae/urn_generator.rb +8 -2
  59. data/lib/pubid/ashrae.rb +10 -4
  60. data/lib/pubid/asme/builder.rb +11 -2
  61. data/lib/pubid/asme/identifier.rb +9 -0
  62. data/lib/pubid/asme/identifiers/standard.rb +86 -2
  63. data/lib/pubid/asme/parser.rb +1 -1
  64. data/lib/pubid/asme/renderer.rb +3 -3
  65. data/lib/pubid/asme/single_identifier.rb +8 -1
  66. data/lib/pubid/asme/urn_generator.rb +2 -2
  67. data/lib/pubid/asme.rb +1 -0
  68. data/lib/pubid/astm/builder.rb +10 -3
  69. data/lib/pubid/astm/identifier.rb +9 -0
  70. data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
  71. data/lib/pubid/astm/identifiers/code_number.rb +81 -0
  72. data/lib/pubid/astm/identifiers/data_series.rb +2 -0
  73. data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
  74. data/lib/pubid/astm/identifiers/manual.rb +10 -0
  75. data/lib/pubid/astm/identifiers/monograph.rb +2 -0
  76. data/lib/pubid/astm/identifiers/research_report.rb +10 -0
  77. data/lib/pubid/astm/identifiers/standard.rb +10 -0
  78. data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
  79. data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
  80. data/lib/pubid/astm/identifiers.rb +1 -0
  81. data/lib/pubid/astm/parser.rb +1 -1
  82. data/lib/pubid/astm/renderer.rb +1 -1
  83. data/lib/pubid/astm/single_identifier.rb +31 -1
  84. data/lib/pubid/astm/urn_generator.rb +7 -5
  85. data/lib/pubid/astm.rb +1 -0
  86. data/lib/pubid/bipm/builder.rb +163 -0
  87. data/lib/pubid/bipm/identifier.rb +285 -0
  88. data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
  89. data/lib/pubid/bipm/identifiers/guide.rb +35 -0
  90. data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
  91. data/lib/pubid/bipm/identifiers/mep.rb +33 -0
  92. data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
  93. data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
  94. data/lib/pubid/bipm/identifiers.rb +15 -0
  95. data/lib/pubid/bipm/parser.rb +237 -0
  96. data/lib/pubid/bipm/renderer.rb +118 -0
  97. data/lib/pubid/bipm/urn_generator.rb +58 -0
  98. data/lib/pubid/bipm/urn_parser.rb +60 -0
  99. data/lib/pubid/bipm.rb +92 -0
  100. data/lib/pubid/bsi/builder.rb +62 -52
  101. data/lib/pubid/bsi/identifier.rb +0 -1
  102. data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
  103. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
  104. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
  105. data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
  106. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
  107. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
  108. data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
  109. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
  110. data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
  111. data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
  112. data/lib/pubid/bsi/identifiers/handbook.rb +0 -2
  113. data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
  114. data/lib/pubid/bsi/identifiers/set.rb +11 -0
  115. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
  116. data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
  117. data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
  118. data/lib/pubid/bsi/parser.rb +1 -1
  119. data/lib/pubid/bsi/renderer.rb +71 -59
  120. data/lib/pubid/bsi/single_identifier.rb +64 -7
  121. data/lib/pubid/bsi/urn_generator.rb +11 -2
  122. data/lib/pubid/bsi.rb +7 -1
  123. data/lib/pubid/builder/base.rb +23 -11
  124. data/lib/pubid/bundled_identifier.rb +19 -9
  125. data/lib/pubid/calconnect/builder.rb +38 -0
  126. data/lib/pubid/calconnect/identifier.rb +121 -0
  127. data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
  128. data/lib/pubid/calconnect/identifiers.rb +9 -0
  129. data/lib/pubid/calconnect/parser.rb +54 -0
  130. data/lib/pubid/calconnect/renderer.rb +36 -0
  131. data/lib/pubid/calconnect/urn_generator.rb +33 -0
  132. data/lib/pubid/calconnect/urn_parser.rb +34 -0
  133. data/lib/pubid/calconnect.rb +83 -0
  134. data/lib/pubid/ccsds/builder.rb +1 -1
  135. data/lib/pubid/ccsds/identifier.rb +10 -3
  136. data/lib/pubid/ccsds/identifiers/base.rb +4 -2
  137. data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
  138. data/lib/pubid/ccsds/parser.rb +1 -1
  139. data/lib/pubid/ccsds/single_identifier.rb +2 -2
  140. data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
  141. data/lib/pubid/ccsds/urn_generator.rb +3 -3
  142. data/lib/pubid/ccsds.rb +1 -0
  143. data/lib/pubid/cen_cenelec/builder.rb +131 -72
  144. data/lib/pubid/cen_cenelec/identifier.rb +115 -3
  145. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
  146. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
  147. data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
  148. data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
  149. data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
  150. data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
  151. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -14
  152. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
  153. data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
  154. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
  155. data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
  156. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
  157. data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
  158. data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
  159. data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
  160. data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
  161. data/lib/pubid/cen_cenelec/parser.rb +1 -1
  162. data/lib/pubid/cen_cenelec/renderer.rb +55 -60
  163. data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
  164. data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
  165. data/lib/pubid/cen_cenelec.rb +104 -82
  166. data/lib/pubid/cie/builder.rb +149 -24
  167. data/lib/pubid/cie/identifier.rb +13 -4
  168. data/lib/pubid/cie/identifiers/bundle.rb +35 -5
  169. data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
  170. data/lib/pubid/cie/identifiers/conference.rb +11 -6
  171. data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
  172. data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
  173. data/lib/pubid/cie/identifiers/identical.rb +9 -9
  174. data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
  175. data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
  176. data/lib/pubid/cie/identifiers/standard.rb +43 -8
  177. data/lib/pubid/cie/identifiers/supplement.rb +27 -25
  178. data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
  179. data/lib/pubid/cie/identifiers.rb +2 -0
  180. data/lib/pubid/cie/parser.rb +55 -6
  181. data/lib/pubid/cie/single_identifier.rb +40 -1
  182. data/lib/pubid/cie/supplement_identifier.rb +29 -16
  183. data/lib/pubid/cie/urn_generator.rb +11 -8
  184. data/lib/pubid/cie.rb +7 -2
  185. data/lib/pubid/components/date.rb +21 -5
  186. data/lib/pubid/conformance/checks.rb +72 -0
  187. data/lib/pubid/conformance/corpus/case.rb +55 -0
  188. data/lib/pubid/conformance/corpus.rb +36 -0
  189. data/lib/pubid/conformance/generator.rb +212 -0
  190. data/lib/pubid/conformance/pending.rb +63 -0
  191. data/lib/pubid/conformance/runner.rb +153 -0
  192. data/lib/pubid/conformance.rb +55 -0
  193. data/lib/pubid/core.rb +2 -0
  194. data/lib/pubid/csa/builder.rb +48 -48
  195. data/lib/pubid/csa/composite_identifier.rb +18 -7
  196. data/lib/pubid/csa/identifier.rb +187 -80
  197. data/lib/pubid/csa/identifiers/bundled.rb +25 -9
  198. data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
  199. data/lib/pubid/csa/identifiers/cec.rb +44 -4
  200. data/lib/pubid/csa/identifiers/combined.rb +97 -69
  201. data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
  202. data/lib/pubid/csa/identifiers/package.rb +4 -4
  203. data/lib/pubid/csa/parser.rb +12 -8
  204. data/lib/pubid/csa/renderer.rb +13 -5
  205. data/lib/pubid/csa/single_identifier.rb +93 -4
  206. data/lib/pubid/csa/urn_generator.rb +9 -2
  207. data/lib/pubid/csa/wrapper_identifier.rb +43 -10
  208. data/lib/pubid/csa.rb +7 -1
  209. data/lib/pubid/doi/builder.rb +18 -0
  210. data/lib/pubid/doi/identifier.rb +49 -0
  211. data/lib/pubid/doi/identifiers/resource.rb +30 -0
  212. data/lib/pubid/doi/identifiers.rb +9 -0
  213. data/lib/pubid/doi/parser.rb +52 -0
  214. data/lib/pubid/doi/renderer.rb +13 -0
  215. data/lib/pubid/doi.rb +56 -0
  216. data/lib/pubid/easc/builder.rb +55 -0
  217. data/lib/pubid/easc/identifier.rb +59 -0
  218. data/lib/pubid/easc/identifiers/pmg.rb +20 -0
  219. data/lib/pubid/easc/identifiers/rmg.rb +19 -0
  220. data/lib/pubid/easc/identifiers.rb +10 -0
  221. data/lib/pubid/easc/parser.rb +88 -0
  222. data/lib/pubid/easc/renderer.rb +48 -0
  223. data/lib/pubid/easc/urn_generator.rb +46 -0
  224. data/lib/pubid/easc/urn_parser.rb +57 -0
  225. data/lib/pubid/easc.rb +53 -0
  226. data/lib/pubid/ecma/builder.rb +45 -0
  227. data/lib/pubid/ecma/identifier.rb +147 -0
  228. data/lib/pubid/ecma/identifiers/memento.rb +30 -0
  229. data/lib/pubid/ecma/identifiers/standard.rb +31 -0
  230. data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
  231. data/lib/pubid/ecma/identifiers.rb +11 -0
  232. data/lib/pubid/ecma/parser.rb +76 -0
  233. data/lib/pubid/ecma/renderer.rb +67 -0
  234. data/lib/pubid/ecma/urn_generator.rb +46 -0
  235. data/lib/pubid/ecma/urn_parser.rb +51 -0
  236. data/lib/pubid/ecma.rb +68 -0
  237. data/lib/pubid/errors.rb +80 -0
  238. data/lib/pubid/etsi/builder.rb +13 -4
  239. data/lib/pubid/etsi/identifier.rb +1 -3
  240. data/lib/pubid/etsi/identifiers/base.rb +43 -11
  241. data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
  242. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
  243. data/lib/pubid/etsi/identifiers.rb +0 -1
  244. data/lib/pubid/etsi/parser.rb +9 -3
  245. data/lib/pubid/etsi/renderer.rb +8 -2
  246. data/lib/pubid/etsi.rb +6 -5
  247. data/lib/pubid/evs/builder.rb +26 -0
  248. data/lib/pubid/evs/identifier.rb +37 -0
  249. data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
  250. data/lib/pubid/evs/identifiers.rb +9 -0
  251. data/lib/pubid/evs/parser.rb +27 -0
  252. data/lib/pubid/evs/renderer.rb +30 -0
  253. data/lib/pubid/evs/urn_generator.rb +30 -0
  254. data/lib/pubid/evs/urn_parser.rb +80 -0
  255. data/lib/pubid/evs.rb +90 -0
  256. data/lib/pubid/export/exporter.rb +2 -1
  257. data/lib/pubid/export/flavor_exporter.rb +18 -3
  258. data/lib/pubid/export.rb +1 -0
  259. data/lib/pubid/format_detector.rb +1 -0
  260. data/lib/pubid/gb/builder.rb +45 -0
  261. data/lib/pubid/gb/identifier.rb +67 -0
  262. data/lib/pubid/gb/identifiers/standard.rb +34 -0
  263. data/lib/pubid/gb/identifiers.rb +9 -0
  264. data/lib/pubid/gb/parser.rb +63 -0
  265. data/lib/pubid/gb/renderer.rb +35 -0
  266. data/lib/pubid/gb.rb +88 -0
  267. data/lib/pubid/gost/builder.rb +185 -0
  268. data/lib/pubid/gost/identifier.rb +47 -0
  269. data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
  270. data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
  271. data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
  272. data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
  273. data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
  274. data/lib/pubid/gost/identifiers.rb +13 -0
  275. data/lib/pubid/gost/parser.rb +105 -0
  276. data/lib/pubid/gost/renderer.rb +48 -0
  277. data/lib/pubid/gost/urn_generator.rb +46 -0
  278. data/lib/pubid/gost/urn_parser.rb +52 -0
  279. data/lib/pubid/gost.rb +50 -0
  280. data/lib/pubid/iala/builder.rb +22 -27
  281. data/lib/pubid/iala/identifier.rb +36 -8
  282. data/lib/pubid/iala/identifiers/advice.rb +1 -1
  283. data/lib/pubid/iala/identifiers/annex.rb +10 -10
  284. data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
  285. data/lib/pubid/iala/identifiers/guideline.rb +3 -1
  286. data/lib/pubid/iala/identifiers/letter.rb +1 -1
  287. data/lib/pubid/iala/identifiers/manual.rb +3 -1
  288. data/lib/pubid/iala/identifiers/model_course.rb +3 -1
  289. data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
  290. data/lib/pubid/iala/identifiers/report.rb +1 -1
  291. data/lib/pubid/iala/identifiers/resolution.rb +1 -1
  292. data/lib/pubid/iala/identifiers/standard.rb +3 -1
  293. data/lib/pubid/iala/identifiers.rb +0 -1
  294. data/lib/pubid/iala/parser.rb +10 -2
  295. data/lib/pubid/iala/renderer.rb +1 -1
  296. data/lib/pubid/iala/urn_generator.rb +1 -1
  297. data/lib/pubid/iala/urn_parser.rb +24 -3
  298. data/lib/pubid/iala.rb +5 -4
  299. data/lib/pubid/iana/builder.rb +22 -0
  300. data/lib/pubid/iana/identifier.rb +140 -0
  301. data/lib/pubid/iana/identifiers/registry.rb +69 -0
  302. data/lib/pubid/iana/identifiers.rb +9 -0
  303. data/lib/pubid/iana/parser.rb +38 -0
  304. data/lib/pubid/iana/renderer.rb +32 -0
  305. data/lib/pubid/iana/urn_generator.rb +19 -0
  306. data/lib/pubid/iana/urn_parser.rb +24 -0
  307. data/lib/pubid/iana.rb +70 -0
  308. data/lib/pubid/identifier.rb +797 -26
  309. data/lib/pubid/identifier_metadata.rb +1 -0
  310. data/lib/pubid/idf/builder.rb +4 -4
  311. data/lib/pubid/idf/identifier.rb +18 -9
  312. data/lib/pubid/idf/parser.rb +3 -3
  313. data/lib/pubid/idf/renderer.rb +5 -5
  314. data/lib/pubid/idf/supplement_identifier.rb +3 -3
  315. data/lib/pubid/idf/urn_generator.rb +1 -1
  316. data/lib/pubid/idf.rb +7 -1
  317. data/lib/pubid/iec/builder.rb +49 -32
  318. data/lib/pubid/iec/components.rb +0 -1
  319. data/lib/pubid/iec/identifier.rb +112 -77
  320. data/lib/pubid/iec/identifiers/amendment.rb +6 -2
  321. data/lib/pubid/iec/identifiers/base.rb +2 -2
  322. data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
  323. data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
  324. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
  325. data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
  326. data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
  327. data/lib/pubid/iec/identifiers/guide.rb +0 -16
  328. data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
  329. data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
  330. data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
  331. data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
  332. data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
  333. data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
  334. data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
  335. data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
  336. data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
  337. data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
  338. data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
  339. data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
  340. data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
  341. data/lib/pubid/iec/identifiers/working_document.rb +24 -10
  342. data/lib/pubid/iec/identifiers.rb +1 -0
  343. data/lib/pubid/iec/parser.rb +53 -28
  344. data/lib/pubid/iec/renderer.rb +31 -18
  345. data/lib/pubid/iec/single_identifier.rb +34 -11
  346. data/lib/pubid/iec/supplement_identifier.rb +32 -19
  347. data/lib/pubid/iec/urn_generator.rb +227 -61
  348. data/lib/pubid/iec/urn_parser.rb +42 -4
  349. data/lib/pubid/iec.rb +2 -6
  350. data/lib/pubid/ieee/aiee/builder.rb +17 -3
  351. data/lib/pubid/ieee/aiee/identifier.rb +46 -62
  352. data/lib/pubid/ieee/aiee/parser.rb +1 -1
  353. data/lib/pubid/ieee/builder.rb +386 -69
  354. data/lib/pubid/ieee/compaction.rb +121 -0
  355. data/lib/pubid/ieee/components/draft.rb +47 -7
  356. data/lib/pubid/ieee/identifier.rb +1 -3
  357. data/lib/pubid/ieee/identifiers/adopted_standard.rb +62 -5
  358. data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
  359. data/lib/pubid/ieee/identifiers/base.rb +148 -18
  360. data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
  361. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
  362. data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
  363. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +24 -3
  364. data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
  365. data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
  366. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
  367. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
  368. data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
  369. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
  370. data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
  371. data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
  372. data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
  373. data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
  374. data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
  375. data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
  376. data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
  377. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
  378. data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
  379. data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
  380. data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
  381. data/lib/pubid/ieee/identifiers/standard.rb +4 -1
  382. data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
  383. data/lib/pubid/ieee/identifiers.rb +2 -1
  384. data/lib/pubid/ieee/ire/builder.rb +7 -6
  385. data/lib/pubid/ieee/ire/identifier.rb +48 -33
  386. data/lib/pubid/ieee/ire/parser.rb +1 -1
  387. data/lib/pubid/ieee/nesc/builder.rb +33 -20
  388. data/lib/pubid/ieee/nesc/parser.rb +16 -15
  389. data/lib/pubid/ieee/parser.rb +462 -44
  390. data/lib/pubid/ieee/pre_parser.rb +1 -1
  391. data/lib/pubid/ieee/renderer.rb +158 -57
  392. data/lib/pubid/ieee/typed_stages.rb +12 -1
  393. data/lib/pubid/ieee/urn_generator.rb +35 -8
  394. data/lib/pubid/ieee.rb +63 -4
  395. data/lib/pubid/ieee_debug.rb +1 -0
  396. data/lib/pubid/ietf/builder.rb +78 -0
  397. data/lib/pubid/ietf/identifier.rb +5 -0
  398. data/lib/pubid/ietf/identifiers/base.rb +72 -0
  399. data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
  400. data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
  401. data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
  402. data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
  403. data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
  404. data/lib/pubid/ietf/identifiers/std.rb +36 -0
  405. data/lib/pubid/ietf/identifiers.rb +14 -0
  406. data/lib/pubid/ietf/parser.rb +61 -0
  407. data/lib/pubid/ietf/renderer.rb +64 -0
  408. data/lib/pubid/ietf/urn_generator.rb +37 -0
  409. data/lib/pubid/ietf/urn_parser.rb +43 -0
  410. data/lib/pubid/ietf.rb +86 -0
  411. data/lib/pubid/iho/identifier.rb +1 -3
  412. data/lib/pubid/iho/identifiers/base.rb +11 -10
  413. data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
  414. data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
  415. data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
  416. data/lib/pubid/iho/identifiers/publication.rb +1 -1
  417. data/lib/pubid/iho/identifiers/standard.rb +1 -1
  418. data/lib/pubid/iho/identifiers.rb +0 -1
  419. data/lib/pubid/iho/parser.rb +1 -1
  420. data/lib/pubid/iho.rb +8 -7
  421. data/lib/pubid/isbn/builder.rb +44 -0
  422. data/lib/pubid/isbn/check_digit.rb +53 -0
  423. data/lib/pubid/isbn/identifier.rb +81 -0
  424. data/lib/pubid/isbn/identifiers/book.rb +30 -0
  425. data/lib/pubid/isbn/identifiers.rb +9 -0
  426. data/lib/pubid/isbn/parser.rb +45 -0
  427. data/lib/pubid/isbn/renderer.rb +16 -0
  428. data/lib/pubid/isbn.rb +53 -0
  429. data/lib/pubid/iso/builder.rb +9 -4
  430. data/lib/pubid/iso/bundled_identifier.rb +5 -3
  431. data/lib/pubid/iso/combined_identifier.rb +6 -4
  432. data/lib/pubid/iso/identifier.rb +29 -8
  433. data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
  434. data/lib/pubid/iso/normalizer.rb +2 -2
  435. data/lib/pubid/iso/parser.rb +17 -13
  436. data/lib/pubid/iso/supplement_identifier.rb +19 -6
  437. data/lib/pubid/iso/urn_generator.rb +4 -1
  438. data/lib/pubid/iso/urn_parser.rb +1 -1
  439. data/lib/pubid/iso.rb +7 -1
  440. data/lib/pubid/itu/builder.rb +230 -29
  441. data/lib/pubid/itu/components/code.rb +48 -5
  442. data/lib/pubid/itu/components/designation.rb +35 -0
  443. data/lib/pubid/itu/components.rb +1 -0
  444. data/lib/pubid/itu/identifier.rb +1 -3
  445. data/lib/pubid/itu/identifiers/addendum.rb +15 -0
  446. data/lib/pubid/itu/identifiers/amendment.rb +7 -29
  447. data/lib/pubid/itu/identifiers/annex.rb +13 -2
  448. data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
  449. data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
  450. data/lib/pubid/itu/identifiers/base.rb +357 -25
  451. data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
  452. data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
  453. data/lib/pubid/itu/identifiers/errata.rb +15 -0
  454. data/lib/pubid/itu/identifiers/handbook.rb +38 -0
  455. data/lib/pubid/itu/identifiers/question.rb +63 -0
  456. data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
  457. data/lib/pubid/itu/identifiers/report.rb +39 -0
  458. data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
  459. data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
  460. data/lib/pubid/itu/identifiers/supplement.rb +119 -14
  461. data/lib/pubid/itu/identifiers.rb +10 -1
  462. data/lib/pubid/itu/model.rb +1 -1
  463. data/lib/pubid/itu/parser.rb +481 -27
  464. data/lib/pubid/itu/urn_generator.rb +36 -6
  465. data/lib/pubid/itu/urn_parser.rb +8 -0
  466. data/lib/pubid/itu.rb +12 -3
  467. data/lib/pubid/jcgm/builder.rb +24 -14
  468. data/lib/pubid/jcgm/identifier.rb +10 -0
  469. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
  470. data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
  471. data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
  472. data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
  473. data/lib/pubid/jcgm/identifiers.rb +2 -0
  474. data/lib/pubid/jcgm/parser.rb +74 -7
  475. data/lib/pubid/jcgm/renderer.rb +33 -12
  476. data/lib/pubid/jcgm/single_identifier.rb +84 -6
  477. data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
  478. data/lib/pubid/jcgm/urn_generator.rb +21 -13
  479. data/lib/pubid/jcgm/urn_parser.rb +164 -10
  480. data/lib/pubid/jcgm.rb +10 -0
  481. data/lib/pubid/jis/identifier.rb +62 -3
  482. data/lib/pubid/jis/parser.rb +1 -1
  483. data/lib/pubid/jis.rb +1 -0
  484. data/lib/pubid/nist/builder.rb +29 -9
  485. data/lib/pubid/nist/caster.rb +7 -45
  486. data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
  487. data/lib/pubid/nist/components/stage.rb +2 -2
  488. data/lib/pubid/nist/components/supplement.rb +5 -2
  489. data/lib/pubid/nist/configuration.rb +6 -2
  490. data/lib/pubid/nist/identifier.rb +1 -3
  491. data/lib/pubid/nist/identifiers/base.rb +133 -39
  492. data/lib/pubid/nist/identifiers/circular.rb +10 -3
  493. data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
  494. data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
  495. data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
  496. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +8 -2
  497. data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
  498. data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
  499. data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
  500. data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
  501. data/lib/pubid/nist/identifiers/handbook.rb +10 -3
  502. data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
  503. data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
  504. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
  505. data/lib/pubid/nist/identifiers/monograph.rb +15 -8
  506. data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
  507. data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
  508. data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
  509. data/lib/pubid/nist/identifiers/report.rb +15 -7
  510. data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
  511. data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
  512. data/lib/pubid/nist/identifiers.rb +0 -1
  513. data/lib/pubid/nist/parser.rb +27 -4
  514. data/lib/pubid/nist/preprocessor.rb +15 -0
  515. data/lib/pubid/nist/router.rb +2 -2
  516. data/lib/pubid/nist/series/ir.rb +0 -3
  517. data/lib/pubid/nist/supplement_identifier.rb +24 -9
  518. data/lib/pubid/nist.rb +19 -13
  519. data/lib/pubid/oasis/builder.rb +79 -0
  520. data/lib/pubid/oasis/identifier.rb +160 -0
  521. data/lib/pubid/oasis/identifiers/standard.rb +29 -0
  522. data/lib/pubid/oasis/identifiers.rb +9 -0
  523. data/lib/pubid/oasis/parser.rb +34 -0
  524. data/lib/pubid/oasis/renderer.rb +29 -0
  525. data/lib/pubid/oasis/urn_generator.rb +25 -0
  526. data/lib/pubid/oasis/urn_parser.rb +22 -0
  527. data/lib/pubid/oasis.rb +80 -0
  528. data/lib/pubid/ogc/builder.rb +33 -0
  529. data/lib/pubid/ogc/identifier.rb +81 -0
  530. data/lib/pubid/ogc/identifiers/document.rb +26 -0
  531. data/lib/pubid/ogc/identifiers.rb +10 -0
  532. data/lib/pubid/ogc/parser.rb +40 -0
  533. data/lib/pubid/ogc/renderer.rb +33 -0
  534. data/lib/pubid/ogc/urn_generator.rb +14 -0
  535. data/lib/pubid/ogc/urn_parser.rb +22 -0
  536. data/lib/pubid/ogc.rb +72 -0
  537. data/lib/pubid/oiml/builder.rb +36 -8
  538. data/lib/pubid/oiml/identifier.rb +9 -1
  539. data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
  540. data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
  541. data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
  542. data/lib/pubid/oiml/identifiers/document.rb +2 -0
  543. data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
  544. data/lib/pubid/oiml/identifiers/guide.rb +2 -0
  545. data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
  546. data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
  547. data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
  548. data/lib/pubid/oiml/identifiers.rb +1 -0
  549. data/lib/pubid/oiml/parser.rb +12 -13
  550. data/lib/pubid/oiml/renderer.rb +13 -13
  551. data/lib/pubid/oiml/single_identifier.rb +41 -37
  552. data/lib/pubid/oiml/supplement_identifier.rb +36 -9
  553. data/lib/pubid/oiml/urn_parser.rb +23 -6
  554. data/lib/pubid/oiml.rb +10 -0
  555. data/lib/pubid/omg/builder.rb +20 -0
  556. data/lib/pubid/omg/identifier.rb +61 -0
  557. data/lib/pubid/omg/identifiers/specification.rb +32 -0
  558. data/lib/pubid/omg/identifiers.rb +9 -0
  559. data/lib/pubid/omg/parser.rb +93 -0
  560. data/lib/pubid/omg/renderer.rb +31 -0
  561. data/lib/pubid/omg.rb +52 -0
  562. data/lib/pubid/parser/grammar.rb +74 -0
  563. data/lib/pubid/parser.rb +2 -0
  564. data/lib/pubid/parsers/mr_string.rb +120 -7
  565. data/lib/pubid/plateau/builder.rb +8 -4
  566. data/lib/pubid/plateau/identifier.rb +1 -3
  567. data/lib/pubid/plateau/identifiers/base.rb +1 -6
  568. data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
  569. data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
  570. data/lib/pubid/plateau/identifiers.rb +0 -1
  571. data/lib/pubid/plateau/parser.rb +16 -6
  572. data/lib/pubid/plateau/renderer.rb +1 -1
  573. data/lib/pubid/plateau/supplement_identifier.rb +11 -11
  574. data/lib/pubid/plateau.rb +14 -4
  575. data/lib/pubid/prefixes_support.rb +1 -0
  576. data/lib/pubid/renderers/annotator.rb +233 -0
  577. data/lib/pubid/renderers/base.rb +13 -0
  578. data/lib/pubid/renderers/directives_renderer.rb +3 -3
  579. data/lib/pubid/renderers/human_readable.rb +6 -4
  580. data/lib/pubid/renderers/mr_string.rb +54 -6
  581. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  582. data/lib/pubid/renderers.rb +1 -0
  583. data/lib/pubid/rendering/numbering.rb +25 -7
  584. data/lib/pubid/rendering/supplement.rb +4 -4
  585. data/lib/pubid/rendering.rb +1 -0
  586. data/lib/pubid/sae/builder.rb +1 -1
  587. data/lib/pubid/sae/identifier.rb +1 -3
  588. data/lib/pubid/sae/identifiers/base.rb +19 -9
  589. data/lib/pubid/sae/identifiers.rb +0 -1
  590. data/lib/pubid/sae/parser.rb +1 -1
  591. data/lib/pubid/sae.rb +4 -3
  592. data/lib/pubid/schema/declaration.rb +33 -0
  593. data/lib/pubid/schema/error.rb +14 -0
  594. data/lib/pubid/schema/identifier_type.rb +23 -0
  595. data/lib/pubid/schema/loader.rb +117 -0
  596. data/lib/pubid/schema/typed_stage.rb +24 -0
  597. data/lib/pubid/schema.rb +25 -0
  598. data/lib/pubid/tgpp/builder.rb +41 -0
  599. data/lib/pubid/tgpp/identifier.rb +107 -0
  600. data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
  601. data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
  602. data/lib/pubid/tgpp/identifiers.rb +11 -0
  603. data/lib/pubid/tgpp/parser.rb +78 -0
  604. data/lib/pubid/tgpp/renderer.rb +52 -0
  605. data/lib/pubid/tgpp/urn_generator.rb +39 -0
  606. data/lib/pubid/tgpp/urn_parser.rb +30 -0
  607. data/lib/pubid/tgpp.rb +84 -0
  608. data/lib/pubid/type_resolver.rb +74 -0
  609. data/lib/pubid/un/builder.rb +42 -0
  610. data/lib/pubid/un/identifier.rb +40 -0
  611. data/lib/pubid/un/identifiers/document.rb +24 -0
  612. data/lib/pubid/un/identifiers.rb +9 -0
  613. data/lib/pubid/un/parser.rb +25 -0
  614. data/lib/pubid/un/renderer.rb +11 -0
  615. data/lib/pubid/un.rb +47 -0
  616. data/lib/pubid/urn_parser/errors.rb +8 -1
  617. data/lib/pubid/urn_parser.rb +1 -0
  618. data/lib/pubid/utils.rb +1 -0
  619. data/lib/pubid/version.rb +1 -1
  620. data/lib/pubid/w3c/builder.rb +55 -0
  621. data/lib/pubid/w3c/identifier.rb +130 -0
  622. data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
  623. data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
  624. data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
  625. data/lib/pubid/w3c/identifiers/note.rb +30 -0
  626. data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
  627. data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
  628. data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
  629. data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
  630. data/lib/pubid/w3c/identifiers/standard.rb +12 -0
  631. data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
  632. data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
  633. data/lib/pubid/w3c/identifiers.rb +25 -0
  634. data/lib/pubid/w3c/parser.rb +43 -0
  635. data/lib/pubid/w3c/renderer.rb +35 -0
  636. data/lib/pubid/w3c/urn_generator.rb +18 -0
  637. data/lib/pubid/w3c/urn_parser.rb +36 -0
  638. data/lib/pubid/w3c.rb +68 -0
  639. data/lib/pubid/xsf/builder.rb +17 -0
  640. data/lib/pubid/xsf/identifier.rb +66 -0
  641. data/lib/pubid/xsf/identifiers/xep.rb +31 -0
  642. data/lib/pubid/xsf/identifiers.rb +9 -0
  643. data/lib/pubid/xsf/parser.rb +38 -0
  644. data/lib/pubid/xsf/renderer.rb +23 -0
  645. data/lib/pubid/xsf/urn_generator.rb +13 -0
  646. data/lib/pubid/xsf/urn_parser.rb +18 -0
  647. data/lib/pubid/xsf.rb +82 -0
  648. data/lib/pubid.rb +424 -22
  649. data/lib/tasks/conformance.rake +34 -0
  650. data/lib/tasks/docs.rake +3 -3
  651. data/lib/tasks/schema.rake +88 -0
  652. data/schema/core/joint_prefixes.yaml +24 -0
  653. data/schema/iec.yaml +1017 -0
  654. data/schema/iso.yaml +1586 -0
  655. data/schema/schema.schema.yaml +96 -0
  656. metadata +241 -19
  657. data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
  658. data/archived-gems/pubid-iec/stages.yaml +0 -129
  659. data/archived-gems/pubid-iec/update_codes.yaml +0 -67
  660. data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
  661. data/archived-gems/pubid-iso/stages.yaml +0 -106
  662. data/archived-gems/pubid-iso/update_codes.yaml +0 -4
  663. data/archived-gems/pubid-itu/i18n.yaml +0 -13
  664. data/archived-gems/pubid-itu/series.yaml +0 -42
  665. data/archived-gems/pubid-nist/publishers.yaml +0 -6
  666. data/archived-gems/pubid-nist/update_codes.yaml +0 -93
  667. data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
  668. data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
  669. data/lib/pubid/cie/components/code.rb +0 -80
  670. data/lib/pubid/iala/identifiers/base.rb +0 -14
  671. data/lib/pubid/iec/components/code.rb +0 -36
  672. /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ # Base class for every 3GPP identifier AND the flavor's parse entry point —
6
+ # mirrors Pubid::Jis::Identifier. Concrete identifiers under
7
+ # Pubid::Tgpp::Identifiers descend from this class, so a parsed 3GPP id is
8
+ # an instance of Pubid::Tgpp::Identifier.
9
+ class Identifier < ::Pubid::Identifier
10
+ # The dotted core (e.g. "23.207") kept as a string to preserve leading
11
+ # zeros. `number` overrides the base Components::Code attribute.
12
+ attribute :number, :string
13
+ # Optional letter suffix directly after the number: "U", "dcs", "ext"…
14
+ attribute :suffix, :string
15
+ # 1–2 hyphen parts (e.g. "26.171-1", "29.198-04-1"); strings preserve any
16
+ # zero-padding.
17
+ # `initialize_empty` makes a part-less identifier hold `[]` on BOTH
18
+ # construction paths: Builder always passes an array, but the serialized
19
+ # hash carries no `parts` key, so from_hash used to leave it nil and the
20
+ # two compared unequal — which silently broke `#matches?` (and so every
21
+ # part-less relaton index lookup). It does not change the serialized
22
+ # shape: lutaml omits an empty collection either way. See CLAUDE.md.
23
+ attribute :parts, :string, collection: true, initialize_empty: true
24
+ # Raw release token, stored verbatim: "REL-4", "Ph1", "UMTS",
25
+ # "Release 2000".
26
+ attribute :release, :string
27
+ # Three-part version string, e.g. "2.0.0".
28
+ attribute :version, :string
29
+
30
+ # Polymorphic type map for lutaml::Model key_value (de)serialization.
31
+ # Keys are the `pubid:3gpp:…` names produced by polymorphic_name (below).
32
+ TGPP_TYPE_MAP = {
33
+ "pubid:3gpp:technical-report" =>
34
+ "Pubid::Tgpp::Identifiers::TechnicalReport",
35
+ "pubid:3gpp:technical-specification" =>
36
+ "Pubid::Tgpp::Identifiers::TechnicalSpecification",
37
+ }.freeze
38
+
39
+ key_value do
40
+ map "_type", to: :_type, polymorphic_map: TGPP_TYPE_MAP
41
+ map "number", to: :number
42
+ map "suffix", to: :suffix
43
+ map "parts", to: :parts
44
+ map "release", to: :release
45
+ map "version", to: :version
46
+ end
47
+
48
+ # Publisher token. A plain constant (not a `publisher` method) so it does
49
+ # not shadow the inherited lutaml `publisher` attribute.
50
+ PUBLISHER = "3GPP"
51
+
52
+ # The auto-derived polymorphic name would be "pubid:tgpp:…" (from the
53
+ # module constant). Force the "3gpp" segment so the `_type` tag matches
54
+ # the relaton flavor name and TGPP_TYPE_MAP.
55
+ def self.polymorphic_name
56
+ super&.sub(/\Apubid:tgpp:/, "pubid:3gpp:")
57
+ end
58
+
59
+ # Rendering flag: whether to prefix the string with "3GPP ". Transient
60
+ # (not serialized). #to_s sets it, renders, then resets it to false in an
61
+ # ensure block, so a subsequent bare #render defaults to no publisher and
62
+ # the flag never leaks past the to_s call that set it.
63
+ attr_reader :with_publisher
64
+
65
+ # The rendered document code, e.g. "29.198-04-1" (number+suffix+parts).
66
+ def code
67
+ result = "#{number}#{suffix}"
68
+ result += parts.map { |p| "-#{p}" }.join if parts&.any?
69
+ result
70
+ end
71
+
72
+ # Basic string representation. Delegates to the :human renderer. Default
73
+ # omits the "3GPP " publisher token (matches the relaton index id);
74
+ # `to_s(with_publisher: true)` emits the printed "3GPP TS …" form.
75
+ def to_s(with_publisher: false, **opts)
76
+ @with_publisher = with_publisher
77
+ render(format: :human, **opts)
78
+ ensure
79
+ @with_publisher = false
80
+ end
81
+
82
+ # Parse a 3GPP identifier string into an identifier object.
83
+ #
84
+ # Let Parslet::ParseFailed propagate on a bad reference (matching ISO and
85
+ # ETSI), so relaton-cli's `rescue Parslet::ParseFailed` fetch handler
86
+ # catches it instead of a bare RuntimeError. The length guard keeps its
87
+ # ArgumentError — that is a different failure (input too long, not
88
+ # unparseable) and it is the ReDoS barrier.
89
+ #
90
+ # @param identifier [String] The 3GPP identifier string to parse
91
+ # @return [Identifier] The appropriate identifier object
92
+ def self.parse(identifier)
93
+ unless identifier.is_a?(String)
94
+ raise Pubid::Errors::InvalidInputError,
95
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
96
+ end
97
+
98
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
99
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
100
+ end
101
+
102
+ parsed = Parser.parse(identifier)
103
+ Builder.build(parsed)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ module Identifiers
6
+ # Technical Report identifier type.
7
+ # Format: [3GPP ]TR NN.NNN[suffix][-part…][:<release>][/<version>]
8
+ # Example: TR 00.01U:UMTS/3.0.0, or the partial "TR 00.01U".
9
+ class TechnicalReport < Pubid::Tgpp::Identifier
10
+ TYPED_STAGES = [
11
+ Pubid::Components::TypedStage.new(
12
+ code: :tr,
13
+ stage_code: :published,
14
+ type_code: :tr,
15
+ abbr: ["TR"],
16
+ name: "Technical Report",
17
+ harmonized_stages: [],
18
+ ),
19
+ ].freeze
20
+
21
+ def self.type
22
+ { key: :tr,
23
+ web: :technical_report, title: "Technical Report", short: "TR" }
24
+ end
25
+
26
+ def type_prefix
27
+ "TR"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ module Identifiers
6
+ # Technical Specification identifier type.
7
+ # Format: [3GPP ]TS NN.NNN[suffix][-part…][:<release>][/<version>]
8
+ # Example: TS 23.207:REL-4/2.0.0, or the partial "TS 23.207".
9
+ class TechnicalSpecification < Pubid::Tgpp::Identifier
10
+ TYPED_STAGES = [
11
+ Pubid::Components::TypedStage.new(
12
+ code: :ts,
13
+ stage_code: :published,
14
+ type_code: :ts,
15
+ abbr: ["TS"],
16
+ name: "Technical Specification",
17
+ harmonized_stages: [],
18
+ ),
19
+ ].freeze
20
+
21
+ def self.type
22
+ { key: :ts,
23
+ web: :technical_specification,
24
+ title: "Technical Specification", short: "TS" }
25
+ end
26
+
27
+ def type_prefix
28
+ "TS"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ module Identifiers
6
+ autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
7
+ autoload :TechnicalSpecification,
8
+ "#{__dir__}/identifiers/technical_specification"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Pubid
6
+ module Tgpp
7
+ # Parslet grammar for 3GPP identifiers.
8
+ #
9
+ # Form: `[3GPP ]<TR|TS> <NN.NNN>[suffix][-part…][:<release>][/<version>]`
10
+ # TS 23.207:REL-4/2.0.0
11
+ # 3GPP TR 00.01U:UMTS/3.0.0
12
+ # TS 29.198-04-1:REL-5/5.0.0
13
+ # TS 02.68:Release 2000/9.0.0
14
+ # 3GPP TS 23.207 (bare reference)
15
+ #
16
+ # The release and the version are both optional: a user reference names the
17
+ # document alone ("3GPP TS 23.207"), and relaton parses that bare form to
18
+ # search the index. Only the type and the dotted number core are required,
19
+ # so "TS" and "TS foo" are still rejected.
20
+ class Parser < ::Pubid::Parser::Grammar
21
+ rule(:digit) { match["0-9"] }
22
+ rule(:digits) { digit.repeat(1) }
23
+ rule(:space) { str(" ") }
24
+
25
+ # Optional leading publisher token.
26
+ rule(:publisher_prefix) { str("3GPP") >> space }
27
+
28
+ # Document type.
29
+ rule(:type) { (str("TR") | str("TS")).as(:type) }
30
+
31
+ # Dotted number core, kept as a string (preserves leading zeros).
32
+ rule(:number_core) { (digits >> str(".") >> digits).as(:number) }
33
+
34
+ # Letter suffix directly after the number ("U"/"dcs"/"ext"…). Generic so
35
+ # future controlled-vocabulary values keep round-tripping.
36
+ rule(:suffix) { match["A-Za-z"].repeat(1).as(:suffix) }
37
+
38
+ # Hyphen parts.
39
+ rule(:part) { str("-") >> digits.as(:part) }
40
+ rule(:parts) { part.repeat(0).as(:parts) }
41
+
42
+ # Release token, stored verbatim: everything up to the version separator.
43
+ # Excludes ":" (as well as "/") so the ":"-delimited URN scheme can always
44
+ # encode it — every real release ("REL-4", "Ph1", "UMTS", "Release 2000")
45
+ # is colon-free.
46
+ #
47
+ # A trailing segment shaped exactly like a version is a mistyped "/"
48
+ # separator ("TS 23.207:2.0.0"), not a release: no release in the 88,464
49
+ # published index rows contains a dot at all. Reject it rather than
50
+ # silently misfiling the version as the release — which only became
51
+ # reachable once the version segment was made optional.
52
+ rule(:release) do
53
+ (version_core >> any.absent?).absent? >>
54
+ match["^/:"].repeat(1).as(:release)
55
+ end
56
+
57
+ # Three-part version, kept as a string.
58
+ rule(:version_core) do
59
+ digits >> str(".") >> digits >> str(".") >> digits
60
+ end
61
+ rule(:version) { version_core.as(:version) }
62
+
63
+ rule(:identifier) do
64
+ publisher_prefix.maybe >>
65
+ type >> space >>
66
+ number_core >> suffix.maybe >> parts >>
67
+ (str(":") >> release).maybe >>
68
+ (str("/") >> version).maybe
69
+ end
70
+
71
+ rule(:root) { identifier }
72
+
73
+ def self.parse(input)
74
+ new.parse(input)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ # Human-readable renderer for 3GPP identifiers.
6
+ #
7
+ # Produces strings like:
8
+ # "TS 23.207:REL-4/2.0.0" (default, no publisher)
9
+ # "3GPP TS 23.207:REL-4/2.0.0" (with_publisher: true)
10
+ # "TS 29.198-04-1:REL-5/5.0.0" (parts)
11
+ # "TR 00.01U:UMTS/3.0.0" (suffix)
12
+ # "TS 23.207" (partial reference)
13
+ class Renderer < ::Pubid::Renderers::Base
14
+ PUBLISHER = "3GPP"
15
+
16
+ def render(context: nil, **_opts)
17
+ id = @id
18
+ head = []
19
+ head << PUBLISHER if with_publisher?(id)
20
+ head << id.type_prefix
21
+ "#{head.join(' ')} #{id.code}#{qualifiers(id)}"
22
+ end
23
+
24
+ private
25
+
26
+ # The trailing ":<release>" and "/<version>" qualifiers. Both are
27
+ # optional: a handful of legacy records omit the release entirely
28
+ # (e.g. "TS 29.215/2.0.0"), and a partial user reference omits both
29
+ # (e.g. "TS 23.207"). Render no separator for an absent one.
30
+ #
31
+ # Blank, not just nil: the grammar cannot produce "", but a hand-built
32
+ # hash can, and a dangling "TS 23.207:" would not re-parse. This mirrors
33
+ # the same guard in UrnGenerator#tail_segments.
34
+ def qualifiers(id)
35
+ result = +""
36
+ result << ":#{id.release}" unless blank?(id.release)
37
+ result << "/#{id.version}" unless blank?(id.version)
38
+ result
39
+ end
40
+
41
+ def blank?(value)
42
+ value.nil? || value.empty?
43
+ end
44
+
45
+ # Default is no publisher token (the relaton index id form); the caller
46
+ # opts in via `to_s(with_publisher: true)`.
47
+ def with_publisher?(id)
48
+ id.with_publisher == true
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ # Emits `urn:3gpp:<type>:<code>:<release>:<version>`, e.g.
6
+ # `urn:3gpp:ts:23.207:REL-4:2.0.0`. `<code>` is number+suffix+parts.
7
+ #
8
+ # A partial identifier has no release, no version, or neither. Only the
9
+ # TRAILING empty segments are dropped, so a bare reference gets the clean
10
+ # `urn:3gpp:ts:23.207` rather than a malformed `urn:3gpp:ts:23.207::`. An
11
+ # INTERIOR empty segment is kept, so the release-less form keeps the URN it
12
+ # has always emitted: `TS 29.215/2.0.0` -> `urn:3gpp:ts:29.215::2.0.0`.
13
+ class UrnGenerator < Pubid::UrnGenerator::Base
14
+ def generate
15
+ (head_segments + tail_segments).join(":")
16
+ end
17
+
18
+ private
19
+
20
+ # The namespace, the document type and the code. Always present.
21
+ def head_segments
22
+ ["urn", "3gpp", identifier.type_prefix.downcase, identifier.code]
23
+ end
24
+
25
+ # The two optional qualifiers, with the trailing empty ones removed.
26
+ def tail_segments
27
+ segments = [identifier.release, identifier.version]
28
+ # NOTE: `empty?`, not `any?` — a bare `Array#any?` tests element
29
+ # truthiness, so `[nil, nil].any?` is false and would strip nothing.
30
+ segments.pop until segments.empty? || !blank?(segments.last)
31
+ segments.map(&:to_s)
32
+ end
33
+
34
+ def blank?(value)
35
+ value.nil? || value.empty?
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Tgpp
5
+ # Parses 3GPP URNs back into identifiers.
6
+ #
7
+ # UrnGenerator emits `urn:3gpp:<type>:<code>:<release>:<version>`; the code,
8
+ # release and version chunks never contain ":", so a plain split recovers
9
+ # them. Example: urn:3gpp:ts:23.207:REL-4:2.0.0 → TS 23.207:REL-4/2.0.0
10
+ class UrnParser < Pubid::UrnParser::Base
11
+ # The module is Tgpp but the URN namespace is "3gpp".
12
+ def flavor_name
13
+ "3gpp"
14
+ end
15
+
16
+ def parse_urn(urn)
17
+ body = strip_namespace(urn)
18
+ type, code, release, version = split_parts(body)
19
+ # A partial identifier drops its trailing segments, and the no-release
20
+ # form (e.g. TS 29.215/2.0.0) serialises with an empty release chunk
21
+ # ("urn:3gpp:ts:29.215::2.0.0"). Rebuild only the segments present, so
22
+ # neither the release colon nor the version slash dangles.
23
+ result = "#{type.upcase} #{code}"
24
+ result += ":#{release}" unless release.nil? || release.empty?
25
+ result += "/#{version}" unless version.nil? || version.empty?
26
+ flavor_parse(result)
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/pubid/tgpp.rb ADDED
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ module Pubid
5
+ # 3GPP (3rd Generation Partnership Project) flavor.
6
+ #
7
+ # The Ruby constant is `Pubid::Tgpp` because a constant may not begin with a
8
+ # digit, but the external contract stays "3gpp": the registry key is "3gpp",
9
+ # the polymorphic `_type` is `pubid:3gpp:…`, and URNs use the `urn:3gpp:`
10
+ # namespace. Only the on-disk file names (lib/pubid/tgpp/…) follow the module.
11
+ module Tgpp
12
+ extend Pubid::PrefixesSupport
13
+
14
+ # Sole routing token. 3GPP references are printed as "3GPP TS 23.207:…";
15
+ # the bare document types (TR/TS) are ambiguous (JIS uses them too) and are
16
+ # excluded. The parser still accepts an optional leading "3GPP ".
17
+ PREFIXES = ["3GPP"].freeze
18
+
19
+ autoload :Builder, "#{__dir__}/tgpp/builder"
20
+ autoload :Identifier, "#{__dir__}/tgpp/identifier"
21
+ autoload :Identifiers, "#{__dir__}/tgpp/identifiers"
22
+ autoload :Parser, "#{__dir__}/tgpp/parser"
23
+ autoload :Renderer, "#{__dir__}/tgpp/renderer"
24
+ autoload :UrnGenerator, "#{__dir__}/tgpp/urn_generator"
25
+ autoload :UrnParser, "#{__dir__}/tgpp/urn_parser"
26
+
27
+ # Parse a 3GPP identifier string
28
+ def self.parse(identifier)
29
+ unless identifier.is_a?(String)
30
+ raise Pubid::Errors::InvalidInputError,
31
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
32
+ end
33
+
34
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
35
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
36
+ end
37
+
38
+ Identifier.parse(identifier)
39
+ end
40
+
41
+ # Per-flavor format registry: inherits global formats, overrides :human
42
+ Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
43
+ Identifier.format_registry.register(:human, renderer: Tgpp::Renderer)
44
+
45
+ # Auto-discover all identifier types from the Identifiers namespace
46
+ # @return [Array<Class>] identifier classes that define a self.type Hash
47
+ def self.identifier_types
48
+ @identifier_types ||= Identifiers.constants
49
+ .filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
50
+ .select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
51
+ .select { |c| c.type.is_a?(Hash) }
52
+ end
53
+
54
+ # Build typed stage index from identifier types
55
+ # @return [Array<Pubid::Components::TypedStage>] all typed stages
56
+ def self.all_typed_stages
57
+ @all_typed_stages ||= identifier_types.flat_map do |klass|
58
+ if klass.const_defined?(:TYPED_STAGES)
59
+ klass.const_get(:TYPED_STAGES)
60
+ else
61
+ []
62
+ end
63
+ end
64
+ end
65
+
66
+ # Lookup: type code -> identifier class
67
+ # @param code [String, Symbol] the type key to find
68
+ # @return [Class, nil] the matching identifier class
69
+ def self.locate_type(code)
70
+ identifier_types.find { |t| t.type[:key].to_s == code.to_s }
71
+ end
72
+
73
+ # Lookup: abbreviation -> typed stage
74
+ # @param abbr [String, Symbol] the abbreviation to find
75
+ # @return [Pubid::Components::TypedStage, nil] the matching typed stage
76
+ def self.locate_stage(abbr)
77
+ abbr_str = abbr.to_s.upcase
78
+ all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
79
+ end
80
+ end
81
+ end
82
+
83
+ # Register 3GPP flavor with the registry (external key stays "3gpp").
84
+ Pubid::Registry.register(:"3gpp", Pubid::Tgpp)
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ module Pubid
5
+ # Resolves a polymorphic `_type` string (e.g. "pubid:iso:technical-report")
6
+ # to the concrete Ruby class that owns it.
7
+ #
8
+ # Each flavor's Identifier base owns a `polymorphic_type_map` for the types
9
+ # defined in its own namespace. A nested polymorphic attribute (e.g. a GOST
10
+ # Harmonized identifier's adopted ISO identifier) carries a `_type` from a
11
+ # different flavor, so the owning flavor's map misses. This service routes
12
+ # the lookup to the registered flavor whose name appears in the type's
13
+ # second segment ("pubid:<flavor>:…"), giving every from_hash caller a
14
+ # single cross-flavor dispatch path.
15
+ class TypeResolver
16
+ TYPE_PREFIX = "pubid:"
17
+ SEGMENT_SEPARATOR = ":"
18
+
19
+ class << self
20
+ # @param type [String, nil] Polymorphic _type, e.g. "pubid:iso:technical-report".
21
+ # @return [Class<Pubid::Identifier>, nil] The concrete class, or nil if
22
+ # the type is blank, malformed, or unknown to its flavor.
23
+ def resolve(type)
24
+ return nil unless type.is_a?(String)
25
+
26
+ flavor_name = flavor_segment(type)
27
+ return nil unless flavor_name
28
+
29
+ # Ensure the flavor module is loaded so its self-register call has
30
+ # run; without this, Registry may know of flavors that haven't yet
31
+ # populated their Identifier base's polymorphic_type_map.
32
+ ::Pubid.eager_load_flavors!
33
+
34
+ flavor = ::Pubid::Registry.get(flavor_name) ||
35
+ flavor_by_module_segment(flavor_name)
36
+ return nil unless flavor
37
+
38
+ identifier_base = flavor::Identifier
39
+ identifier_base.polymorphic_type_map[type]
40
+ rescue NameError
41
+ # Flavor module is registered but its Identifier base cannot be
42
+ # loaded (autoload failure). Treat as unresolvable.
43
+ nil
44
+ end
45
+
46
+ private
47
+
48
+ # The registered flavor whose module constant gives +segment+.
49
+ # Identifier.polymorphic_name takes the segment from the module name
50
+ # ("Pubid::CenCenelec" -> "cencenelec"), and a flavor can be registered
51
+ # under other names ("cen_cenelec", "cen"). Without this fallback no
52
+ # CEN/CENELEC `_type` resolved, so the root class and a nested
53
+ # attribute of another flavor (BSI) read a CEN hash as the abstract
54
+ # root.
55
+ def flavor_by_module_segment(segment)
56
+ ::Pubid::Registry.flavors.each_value.find do |flavor_module|
57
+ flavor_module.name.to_s.split("::")[1]&.downcase == segment
58
+ end
59
+ end
60
+
61
+ # The flavor name is the segment between the leading "pubid:" and the
62
+ # type-name, e.g. "iso" in "pubid:iso:technical-report".
63
+ def flavor_segment(type)
64
+ return nil unless type.start_with?(TYPE_PREFIX)
65
+
66
+ remainder = type[TYPE_PREFIX.length..]
67
+ flavor_end = remainder.index(SEGMENT_SEPARATOR)
68
+ return nil unless flavor_end
69
+
70
+ remainder[0, flavor_end]
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Un
5
+ class Builder
6
+ YEAR_REGEX = /\A\d{4}\z/.freeze
7
+
8
+ def self.build(parsed_data)
9
+ new.build(parsed_data)
10
+ end
11
+
12
+ def build(data)
13
+ tokens = extract_tokens(data)
14
+ raise "UN identifier has no tokens" if tokens.empty?
15
+
16
+ number = tokens.last
17
+ path = tokens[0...-1]
18
+ year_token = path.reverse.find { |t| t.match?(YEAR_REGEX) }
19
+
20
+ Identifiers::Document.new(
21
+ path: path,
22
+ number: number,
23
+ date: year_token ? ::Pubid::Components::Date.new(year: year_token) : nil,
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ def extract_tokens(data)
30
+ raw = data.is_a?(Hash) ? data[:token] : data
31
+ case raw
32
+ when Array
33
+ raw.map { |h| h.is_a?(Hash) ? h[:token].to_s : h.to_s }
34
+ when Hash
35
+ [raw[:token].to_s]
36
+ else
37
+ [raw.to_s]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Un
5
+ class Identifier < ::Pubid::Identifier
6
+ attribute :path, :string, collection: true, default: []
7
+ attribute :number, :string
8
+
9
+ UN_TYPE_MAP = {
10
+ "pubid:un:document" => "Pubid::Un::Identifiers::Document",
11
+ }.freeze
12
+
13
+ key_value do
14
+ map "_type", to: :_type, polymorphic_map: UN_TYPE_MAP
15
+ map "path", to: :path
16
+ map "number", to: :number
17
+ end
18
+
19
+ PUBLISHER = "UN"
20
+
21
+ def to_s(**opts)
22
+ render(format: :human, **opts)
23
+ end
24
+
25
+ def self.parse(identifier)
26
+ unless identifier.is_a?(String)
27
+ raise Pubid::Errors::InvalidInputError,
28
+ Pubid::INPUT_NOT_A_STRING_MESSAGE
29
+ end
30
+
31
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
32
+ raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
33
+ end
34
+
35
+ parsed = Parser.parse(identifier)
36
+ Builder.build(parsed)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Un
5
+ module Identifiers
6
+ class Document < Identifier
7
+ TYPED_STAGES = [
8
+ Pubid::Components::TypedStage.new(
9
+ code: :pubun,
10
+ stage_code: :published,
11
+ type_code: :un,
12
+ abbr: ["UN"],
13
+ name: "UN Document",
14
+ harmonized_stages: %w[60.00 60.60],
15
+ ),
16
+ ].freeze
17
+
18
+ def self.type
19
+ { key: :un, web: :document, title: "UN Document", short: "UN" }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pubid
4
+ module Un
5
+ module Identifiers
6
+ autoload :Document, "#{__dir__}/identifiers/document"
7
+ end
8
+ end
9
+ end