pubid 2.0.0.pre.alpha.7 → 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.
- checksums.yaml +4 -4
- data/README.adoc +9 -50
- data/data/bipm/update_codes.yaml +9 -0
- data/data/iec/update_codes.yaml +3 -0
- data/data/ieee/update_codes.yaml +107 -1
- data/data/nist/series.yaml +155 -0
- data/data/nist/update_codes.yaml +8 -0
- data/lib/pubid/adobe/builder.rb +52 -0
- data/lib/pubid/adobe/identifier.rb +49 -0
- data/lib/pubid/adobe/identifiers/publication.rb +31 -0
- data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
- data/lib/pubid/adobe/identifiers.rb +10 -0
- data/lib/pubid/adobe/parser.rb +128 -0
- data/lib/pubid/adobe/renderer.rb +39 -0
- data/lib/pubid/adobe/urn_generator.rb +42 -0
- data/lib/pubid/adobe/urn_parser.rb +69 -0
- data/lib/pubid/adobe.rb +60 -0
- data/lib/pubid/amca/builder.rb +2 -2
- data/lib/pubid/amca/identifier.rb +1 -3
- data/lib/pubid/amca/identifiers/base.rb +1 -6
- data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
- data/lib/pubid/amca/identifiers/publication.rb +1 -1
- data/lib/pubid/amca/identifiers/standard.rb +1 -1
- data/lib/pubid/amca/identifiers.rb +0 -1
- data/lib/pubid/amca/single_identifier.rb +1 -1
- data/lib/pubid/amca.rb +3 -3
- data/lib/pubid/ashrae/builder.rb +22 -22
- data/lib/pubid/ashrae/identifier.rb +3 -4
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
- data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
- data/lib/pubid/ashrae/identifiers/base.rb +14 -8
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
- data/lib/pubid/ashrae/identifiers.rb +0 -1
- data/lib/pubid/ashrae/parser.rb +14 -9
- data/lib/pubid/ashrae/renderer.rb +19 -19
- data/lib/pubid/ashrae/single_identifier.rb +1 -1
- data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
- data/lib/pubid/ashrae.rb +3 -3
- data/lib/pubid/bipm/builder.rb +107 -0
- data/lib/pubid/bipm/identifier.rb +160 -0
- data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
- data/lib/pubid/bipm/identifiers/guide.rb +24 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
- data/lib/pubid/bipm/identifiers/mep.rb +21 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
- data/lib/pubid/bipm/identifiers.rb +15 -0
- data/lib/pubid/bipm/parser.rb +184 -0
- data/lib/pubid/bipm/renderer.rb +110 -0
- data/lib/pubid/bipm/urn_generator.rb +58 -0
- data/lib/pubid/bipm/urn_parser.rb +52 -0
- data/lib/pubid/bipm.rb +86 -0
- data/lib/pubid/bsi/builder.rb +14 -14
- data/lib/pubid/bsi/identifier.rb +0 -1
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
- data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
- data/lib/pubid/bsi/renderer.rb +8 -8
- data/lib/pubid/bsi/single_identifier.rb +48 -0
- data/lib/pubid/builder/base.rb +5 -3
- data/lib/pubid/bundled_identifier.rb +3 -3
- data/lib/pubid/calconnect/builder.rb +38 -0
- data/lib/pubid/calconnect/identifier.rb +117 -0
- data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
- data/lib/pubid/calconnect/identifiers.rb +9 -0
- data/lib/pubid/calconnect/parser.rb +54 -0
- data/lib/pubid/calconnect/renderer.rb +36 -0
- data/lib/pubid/calconnect/urn_generator.rb +33 -0
- data/lib/pubid/calconnect/urn_parser.rb +34 -0
- data/lib/pubid/calconnect.rb +77 -0
- data/lib/pubid/ccsds/builder.rb +1 -1
- data/lib/pubid/ccsds/identifier.rb +1 -1
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
- data/lib/pubid/ccsds/urn_generator.rb +3 -3
- data/lib/pubid/cen_cenelec/builder.rb +46 -12
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
- data/lib/pubid/cen_cenelec/renderer.rb +5 -5
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
- data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
- data/lib/pubid/cen_cenelec.rb +76 -72
- data/lib/pubid/cie/builder.rb +139 -24
- data/lib/pubid/cie/identifier.rb +7 -3
- data/lib/pubid/cie/identifiers/bundle.rb +32 -4
- data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
- data/lib/pubid/cie/identifiers/conference.rb +9 -4
- data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
- data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
- data/lib/pubid/cie/identifiers/identical.rb +7 -7
- data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
- data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
- data/lib/pubid/cie/identifiers/standard.rb +33 -7
- data/lib/pubid/cie/identifiers/supplement.rb +24 -22
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
- data/lib/pubid/cie/identifiers.rb +2 -0
- data/lib/pubid/cie/parser.rb +54 -5
- data/lib/pubid/cie/single_identifier.rb +40 -1
- data/lib/pubid/cie/supplement_identifier.rb +29 -16
- data/lib/pubid/cie/urn_generator.rb +11 -8
- data/lib/pubid/cie.rb +0 -1
- data/lib/pubid/components/date.rb +21 -5
- data/lib/pubid/csa/builder.rb +1 -1
- data/lib/pubid/csa/composite_identifier.rb +17 -1
- data/lib/pubid/csa/identifier.rb +48 -3
- data/lib/pubid/csa/identifiers/bundled.rb +6 -0
- data/lib/pubid/csa/identifiers/combined.rb +6 -0
- data/lib/pubid/csa/identifiers/package.rb +2 -2
- data/lib/pubid/csa/parser.rb +6 -6
- data/lib/pubid/csa/wrapper_identifier.rb +17 -0
- data/lib/pubid/doi/builder.rb +18 -0
- data/lib/pubid/doi/identifier.rb +46 -0
- data/lib/pubid/doi/identifiers/resource.rb +30 -0
- data/lib/pubid/doi/identifiers.rb +9 -0
- data/lib/pubid/doi/parser.rb +52 -0
- data/lib/pubid/doi/renderer.rb +13 -0
- data/lib/pubid/doi.rb +55 -0
- data/lib/pubid/easc/builder.rb +55 -0
- data/lib/pubid/easc/identifier.rb +61 -0
- data/lib/pubid/easc/identifiers/pmg.rb +20 -0
- data/lib/pubid/easc/identifiers/rmg.rb +19 -0
- data/lib/pubid/easc/identifiers.rb +10 -0
- data/lib/pubid/easc/parser.rb +80 -0
- data/lib/pubid/easc/renderer.rb +48 -0
- data/lib/pubid/easc/urn_generator.rb +46 -0
- data/lib/pubid/easc/urn_parser.rb +57 -0
- data/lib/pubid/easc.rb +52 -0
- data/lib/pubid/ecma/builder.rb +31 -0
- data/lib/pubid/ecma/identifier.rb +76 -0
- data/lib/pubid/ecma/identifiers/memento.rb +30 -0
- data/lib/pubid/ecma/identifiers/standard.rb +31 -0
- data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
- data/lib/pubid/ecma/identifiers.rb +11 -0
- data/lib/pubid/ecma/parser.rb +41 -0
- data/lib/pubid/ecma/renderer.rb +46 -0
- data/lib/pubid/ecma/urn_generator.rb +25 -0
- data/lib/pubid/ecma/urn_parser.rb +35 -0
- data/lib/pubid/ecma.rb +67 -0
- data/lib/pubid/etsi/builder.rb +7 -3
- data/lib/pubid/etsi/identifier.rb +1 -3
- data/lib/pubid/etsi/identifiers/base.rb +28 -10
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
- data/lib/pubid/etsi/identifiers.rb +0 -1
- data/lib/pubid/etsi/parser.rb +8 -2
- data/lib/pubid/etsi/renderer.rb +8 -2
- data/lib/pubid/etsi.rb +5 -5
- data/lib/pubid/export/exporter.rb +2 -1
- data/lib/pubid/export/flavor_exporter.rb +18 -3
- data/lib/pubid/gb/builder.rb +45 -0
- data/lib/pubid/gb/identifier.rb +64 -0
- data/lib/pubid/gb/identifiers/standard.rb +34 -0
- data/lib/pubid/gb/identifiers.rb +9 -0
- data/lib/pubid/gb/parser.rb +63 -0
- data/lib/pubid/gb/renderer.rb +35 -0
- data/lib/pubid/gb.rb +87 -0
- data/lib/pubid/gost/builder.rb +148 -0
- data/lib/pubid/gost/identifier.rb +49 -0
- data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
- data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
- data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
- data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
- data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
- data/lib/pubid/gost/identifiers.rb +13 -0
- data/lib/pubid/gost/parser.rb +97 -0
- data/lib/pubid/gost/renderer.rb +48 -0
- data/lib/pubid/gost/urn_generator.rb +46 -0
- data/lib/pubid/gost/urn_parser.rb +52 -0
- data/lib/pubid/gost.rb +49 -0
- data/lib/pubid/iala/builder.rb +22 -27
- data/lib/pubid/iala/identifier.rb +27 -2
- data/lib/pubid/iala/identifiers/advice.rb +1 -1
- data/lib/pubid/iala/identifiers/annex.rb +14 -12
- data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
- data/lib/pubid/iala/identifiers/guideline.rb +3 -1
- data/lib/pubid/iala/identifiers/letter.rb +1 -1
- data/lib/pubid/iala/identifiers/manual.rb +3 -1
- data/lib/pubid/iala/identifiers/model_course.rb +3 -1
- data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
- data/lib/pubid/iala/identifiers/report.rb +1 -1
- data/lib/pubid/iala/identifiers/resolution.rb +1 -1
- data/lib/pubid/iala/identifiers/standard.rb +3 -1
- data/lib/pubid/iala/identifiers.rb +0 -1
- data/lib/pubid/iala/renderer.rb +1 -1
- data/lib/pubid/iala/urn_generator.rb +1 -1
- data/lib/pubid/iala/urn_parser.rb +19 -2
- data/lib/pubid/iala.rb +4 -4
- data/lib/pubid/iana/builder.rb +20 -0
- data/lib/pubid/iana/identifier.rb +72 -0
- data/lib/pubid/iana/identifiers/registry.rb +33 -0
- data/lib/pubid/iana/identifiers.rb +9 -0
- data/lib/pubid/iana/parser.rb +38 -0
- data/lib/pubid/iana/renderer.rb +29 -0
- data/lib/pubid/iana/urn_generator.rb +15 -0
- data/lib/pubid/iana/urn_parser.rb +24 -0
- data/lib/pubid/iana.rb +69 -0
- data/lib/pubid/identifier.rb +210 -23
- data/lib/pubid/idf/builder.rb +1 -1
- data/lib/pubid/idf/parser.rb +2 -2
- data/lib/pubid/idf/renderer.rb +1 -1
- data/lib/pubid/idf/supplement_identifier.rb +3 -3
- data/lib/pubid/iec/builder.rb +35 -25
- data/lib/pubid/iec/identifier.rb +47 -2
- data/lib/pubid/iec/identifiers/base.rb +2 -2
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
- data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
- data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
- data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
- data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/parser.rb +51 -10
- data/lib/pubid/iec/renderer.rb +18 -8
- data/lib/pubid/iec/single_identifier.rb +1 -1
- data/lib/pubid/iec/supplement_identifier.rb +32 -19
- data/lib/pubid/iec.rb +1 -6
- data/lib/pubid/ieee/aiee/builder.rb +17 -3
- data/lib/pubid/ieee/aiee/identifier.rb +45 -61
- data/lib/pubid/ieee/builder.rb +341 -68
- data/lib/pubid/ieee/compaction.rb +121 -0
- data/lib/pubid/ieee/components/draft.rb +47 -7
- data/lib/pubid/ieee/identifier.rb +1 -3
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
- data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
- data/lib/pubid/ieee/identifiers/base.rb +106 -13
- data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
- data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
- data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
- data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
- data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
- data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
- data/lib/pubid/ieee/identifiers.rb +2 -1
- data/lib/pubid/ieee/ire/builder.rb +7 -6
- data/lib/pubid/ieee/ire/identifier.rb +48 -33
- data/lib/pubid/ieee/nesc/builder.rb +33 -20
- data/lib/pubid/ieee/nesc/parser.rb +15 -14
- data/lib/pubid/ieee/parser.rb +461 -43
- data/lib/pubid/ieee/pre_parser.rb +1 -1
- data/lib/pubid/ieee/renderer.rb +154 -57
- data/lib/pubid/ieee/typed_stages.rb +12 -1
- data/lib/pubid/ieee/urn_generator.rb +3 -5
- data/lib/pubid/ieee.rb +56 -3
- data/lib/pubid/ietf/builder.rb +62 -0
- data/lib/pubid/ietf/identifier.rb +5 -0
- data/lib/pubid/ietf/identifiers/base.rb +75 -0
- data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
- data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
- data/lib/pubid/ietf/identifiers/std.rb +25 -0
- data/lib/pubid/ietf/identifiers.rb +13 -0
- data/lib/pubid/ietf/parser.rb +43 -0
- data/lib/pubid/ietf/renderer.rb +26 -0
- data/lib/pubid/ietf/urn_generator.rb +23 -0
- data/lib/pubid/ietf/urn_parser.rb +35 -0
- data/lib/pubid/ietf.rb +76 -0
- data/lib/pubid/iho/identifier.rb +1 -3
- data/lib/pubid/iho/identifiers/base.rb +1 -7
- data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
- data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
- data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
- data/lib/pubid/iho/identifiers/publication.rb +1 -1
- data/lib/pubid/iho/identifiers/standard.rb +1 -1
- data/lib/pubid/iho/identifiers.rb +0 -1
- data/lib/pubid/iho.rb +7 -7
- data/lib/pubid/isbn/builder.rb +44 -0
- data/lib/pubid/isbn/check_digit.rb +53 -0
- data/lib/pubid/isbn/identifier.rb +63 -0
- data/lib/pubid/isbn/identifiers/book.rb +30 -0
- data/lib/pubid/isbn/identifiers.rb +9 -0
- data/lib/pubid/isbn/parser.rb +45 -0
- data/lib/pubid/isbn/renderer.rb +16 -0
- data/lib/pubid/isbn.rb +52 -0
- data/lib/pubid/iso/builder.rb +9 -4
- data/lib/pubid/iso/combined_identifier.rb +2 -2
- data/lib/pubid/iso/identifier.rb +17 -1
- data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
- data/lib/pubid/iso/normalizer.rb +2 -2
- data/lib/pubid/iso/parser.rb +16 -12
- data/lib/pubid/iso/supplement_identifier.rb +19 -6
- data/lib/pubid/iso/urn_generator.rb +4 -1
- data/lib/pubid/iso/urn_parser.rb +1 -1
- data/lib/pubid/itu/builder.rb +230 -29
- data/lib/pubid/itu/components/code.rb +48 -5
- data/lib/pubid/itu/components/designation.rb +35 -0
- data/lib/pubid/itu/components.rb +1 -0
- data/lib/pubid/itu/identifier.rb +1 -3
- data/lib/pubid/itu/identifiers/addendum.rb +15 -0
- data/lib/pubid/itu/identifiers/amendment.rb +6 -28
- data/lib/pubid/itu/identifiers/annex.rb +13 -2
- data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
- data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
- data/lib/pubid/itu/identifiers/base.rb +341 -23
- data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
- data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
- data/lib/pubid/itu/identifiers/errata.rb +15 -0
- data/lib/pubid/itu/identifiers/handbook.rb +38 -0
- data/lib/pubid/itu/identifiers/question.rb +63 -0
- data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
- data/lib/pubid/itu/identifiers/report.rb +39 -0
- data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
- data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
- data/lib/pubid/itu/identifiers/supplement.rb +119 -14
- data/lib/pubid/itu/identifiers.rb +10 -1
- data/lib/pubid/itu/model.rb +1 -1
- data/lib/pubid/itu/parser.rb +480 -26
- data/lib/pubid/itu/urn_generator.rb +36 -6
- data/lib/pubid/itu/urn_parser.rb +8 -0
- data/lib/pubid/itu.rb +11 -3
- data/lib/pubid/jcgm/builder.rb +23 -13
- data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
- data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
- data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
- data/lib/pubid/jcgm/identifiers.rb +2 -0
- data/lib/pubid/jcgm/parser.rb +66 -6
- data/lib/pubid/jcgm/renderer.rb +26 -12
- data/lib/pubid/jcgm/single_identifier.rb +74 -5
- data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
- data/lib/pubid/jcgm/urn_generator.rb +21 -13
- data/lib/pubid/jcgm/urn_parser.rb +15 -3
- data/lib/pubid/jis/identifier.rb +52 -0
- data/lib/pubid/nist/builder.rb +29 -9
- data/lib/pubid/nist/caster.rb +7 -45
- data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
- data/lib/pubid/nist/components/supplement.rb +5 -2
- data/lib/pubid/nist/configuration.rb +7 -1
- data/lib/pubid/nist/identifier.rb +1 -3
- data/lib/pubid/nist/identifiers/base.rb +121 -37
- data/lib/pubid/nist/identifiers/circular.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
- data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
- data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
- data/lib/pubid/nist/identifiers/handbook.rb +1 -1
- data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
- data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
- data/lib/pubid/nist/identifiers/monograph.rb +1 -1
- data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
- data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
- data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
- data/lib/pubid/nist/identifiers/report.rb +1 -1
- data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
- data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
- data/lib/pubid/nist/identifiers.rb +0 -1
- data/lib/pubid/nist/parser.rb +29 -4
- data/lib/pubid/nist/preprocessor.rb +15 -0
- data/lib/pubid/nist/router.rb +3 -2
- data/lib/pubid/nist/series/ir.rb +0 -3
- data/lib/pubid/nist/supplement_identifier.rb +9 -9
- data/lib/pubid/nist.rb +13 -12
- data/lib/pubid/oasis/builder.rb +77 -0
- data/lib/pubid/oasis/identifier.rb +82 -0
- data/lib/pubid/oasis/identifiers/standard.rb +29 -0
- data/lib/pubid/oasis/identifiers.rb +9 -0
- data/lib/pubid/oasis/parser.rb +34 -0
- data/lib/pubid/oasis/renderer.rb +29 -0
- data/lib/pubid/oasis/urn_generator.rb +25 -0
- data/lib/pubid/oasis/urn_parser.rb +22 -0
- data/lib/pubid/oasis.rb +74 -0
- data/lib/pubid/ogc/builder.rb +33 -0
- data/lib/pubid/ogc/identifier.rb +77 -0
- data/lib/pubid/ogc/identifiers/document.rb +26 -0
- data/lib/pubid/ogc/identifiers.rb +10 -0
- data/lib/pubid/ogc/parser.rb +40 -0
- data/lib/pubid/ogc/renderer.rb +33 -0
- data/lib/pubid/ogc/urn_generator.rb +14 -0
- data/lib/pubid/ogc/urn_parser.rb +22 -0
- data/lib/pubid/ogc.rb +71 -0
- data/lib/pubid/oiml/builder.rb +31 -7
- data/lib/pubid/oiml/identifier.rb +9 -1
- data/lib/pubid/oiml/parser.rb +11 -12
- data/lib/pubid/oiml/renderer.rb +13 -13
- data/lib/pubid/oiml/single_identifier.rb +20 -0
- data/lib/pubid/oiml/supplement_identifier.rb +9 -9
- data/lib/pubid/oiml/urn_parser.rb +23 -6
- data/lib/pubid/oiml.rb +4 -0
- data/lib/pubid/omg/builder.rb +19 -0
- data/lib/pubid/omg/identifier.rb +44 -0
- data/lib/pubid/omg/identifiers/specification.rb +32 -0
- data/lib/pubid/omg/identifiers.rb +9 -0
- data/lib/pubid/omg/parser.rb +40 -0
- data/lib/pubid/omg/renderer.rb +19 -0
- data/lib/pubid/omg.rb +51 -0
- data/lib/pubid/parsers/mr_string.rb +101 -7
- data/lib/pubid/plateau/builder.rb +8 -4
- data/lib/pubid/plateau/identifier.rb +1 -3
- data/lib/pubid/plateau/identifiers/base.rb +1 -6
- data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
- data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
- data/lib/pubid/plateau/identifiers.rb +0 -1
- data/lib/pubid/plateau/parser.rb +15 -5
- data/lib/pubid/plateau/renderer.rb +1 -1
- data/lib/pubid/plateau/supplement_identifier.rb +11 -11
- data/lib/pubid/plateau.rb +4 -4
- data/lib/pubid/renderers/human_readable.rb +3 -1
- data/lib/pubid/renderers/mr_string.rb +46 -4
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/rendering/supplement.rb +4 -4
- data/lib/pubid/sae/builder.rb +1 -1
- data/lib/pubid/sae/identifier.rb +1 -3
- data/lib/pubid/sae/identifiers/base.rb +10 -7
- data/lib/pubid/sae/identifiers.rb +0 -1
- data/lib/pubid/sae.rb +3 -3
- data/lib/pubid/tgpp/builder.rb +41 -0
- data/lib/pubid/tgpp/identifier.rb +91 -0
- data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
- data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
- data/lib/pubid/tgpp/identifiers.rb +11 -0
- data/lib/pubid/tgpp/parser.rb +62 -0
- data/lib/pubid/tgpp/renderer.rb +36 -0
- data/lib/pubid/tgpp/urn_generator.rb +20 -0
- data/lib/pubid/tgpp/urn_parser.rb +28 -0
- data/lib/pubid/tgpp.rb +78 -0
- data/lib/pubid/type_resolver.rb +59 -0
- data/lib/pubid/un/builder.rb +42 -0
- data/lib/pubid/un/identifier.rb +37 -0
- data/lib/pubid/un/identifiers/document.rb +24 -0
- data/lib/pubid/un/identifiers.rb +9 -0
- data/lib/pubid/un/parser.rb +25 -0
- data/lib/pubid/un/renderer.rb +11 -0
- data/lib/pubid/un.rb +46 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/builder.rb +55 -0
- data/lib/pubid/w3c/identifier.rb +101 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
- data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
- data/lib/pubid/w3c/identifiers/note.rb +30 -0
- data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/standard.rb +12 -0
- data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
- data/lib/pubid/w3c/identifiers.rb +25 -0
- data/lib/pubid/w3c/parser.rb +43 -0
- data/lib/pubid/w3c/renderer.rb +35 -0
- data/lib/pubid/w3c/urn_generator.rb +18 -0
- data/lib/pubid/w3c/urn_parser.rb +36 -0
- data/lib/pubid/w3c.rb +67 -0
- data/lib/pubid/xsf/builder.rb +17 -0
- data/lib/pubid/xsf/identifier.rb +62 -0
- data/lib/pubid/xsf/identifiers/xep.rb +31 -0
- data/lib/pubid/xsf/identifiers.rb +9 -0
- data/lib/pubid/xsf/parser.rb +25 -0
- data/lib/pubid/xsf/renderer.rb +23 -0
- data/lib/pubid/xsf/urn_generator.rb +13 -0
- data/lib/pubid/xsf/urn_parser.rb +18 -0
- data/lib/pubid/xsf.rb +76 -0
- data/lib/pubid.rb +25 -1
- metadata +205 -4
- data/lib/pubid/cie/components/code.rb +0 -80
- data/lib/pubid/iala/identifiers/base.rb +0 -14
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Sae
|
|
5
|
-
# Base SAE Identifier. Canonical name Pubid::Sae::Identifier
|
|
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
|
-
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
|
|
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
|
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/
|
|
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::
|
|
66
|
-
Pubid::Sae::
|
|
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)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Tgpp
|
|
5
|
+
class Builder
|
|
6
|
+
def self.build(parsed_data)
|
|
7
|
+
new.build(parsed_data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def build(data)
|
|
11
|
+
identifier_class(data[:type]).new(
|
|
12
|
+
number: data[:number].to_s,
|
|
13
|
+
suffix: data[:suffix]&.to_s,
|
|
14
|
+
parts: extract_part_strings(data[:parts]),
|
|
15
|
+
release: data[:release]&.to_s,
|
|
16
|
+
version: data[:version].to_s,
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def identifier_class(type)
|
|
23
|
+
if type.to_s == "TR"
|
|
24
|
+
Identifiers::TechnicalReport
|
|
25
|
+
else
|
|
26
|
+
Identifiers::TechnicalSpecification
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# parts_data is an array of `{ part: "1" }` hashes (or a single hash for a
|
|
31
|
+
# one-level part); return the part numbers as strings.
|
|
32
|
+
def extract_part_strings(parts_data)
|
|
33
|
+
case parts_data
|
|
34
|
+
when Array then parts_data.filter_map { |h| h[:part]&.to_s }
|
|
35
|
+
when Hash then [parts_data[:part]&.to_s].compact
|
|
36
|
+
else []
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
attribute :parts, :string, collection: true
|
|
18
|
+
# Raw release token, stored verbatim: "REL-4", "Ph1", "UMTS",
|
|
19
|
+
# "Release 2000".
|
|
20
|
+
attribute :release, :string
|
|
21
|
+
# Three-part version string, e.g. "2.0.0".
|
|
22
|
+
attribute :version, :string
|
|
23
|
+
|
|
24
|
+
# Polymorphic type map for lutaml::Model key_value (de)serialization.
|
|
25
|
+
# Keys are the `pubid:3gpp:…` names produced by polymorphic_name (below).
|
|
26
|
+
TGPP_TYPE_MAP = {
|
|
27
|
+
"pubid:3gpp:technical-report" =>
|
|
28
|
+
"Pubid::Tgpp::Identifiers::TechnicalReport",
|
|
29
|
+
"pubid:3gpp:technical-specification" =>
|
|
30
|
+
"Pubid::Tgpp::Identifiers::TechnicalSpecification",
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
key_value do
|
|
34
|
+
map "_type", to: :_type, polymorphic_map: TGPP_TYPE_MAP
|
|
35
|
+
map "number", to: :number
|
|
36
|
+
map "suffix", to: :suffix
|
|
37
|
+
map "parts", to: :parts
|
|
38
|
+
map "release", to: :release
|
|
39
|
+
map "version", to: :version
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Publisher token. A plain constant (not a `publisher` method) so it does
|
|
43
|
+
# not shadow the inherited lutaml `publisher` attribute.
|
|
44
|
+
PUBLISHER = "3GPP"
|
|
45
|
+
|
|
46
|
+
# The auto-derived polymorphic name would be "pubid:tgpp:…" (from the
|
|
47
|
+
# module constant). Force the "3gpp" segment so the `_type` tag matches
|
|
48
|
+
# the relaton flavor name and TGPP_TYPE_MAP.
|
|
49
|
+
def self.polymorphic_name
|
|
50
|
+
super&.sub(/\Apubid:tgpp:/, "pubid:3gpp:")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Rendering flag: whether to prefix the string with "3GPP ". Transient
|
|
54
|
+
# (not serialized). #to_s sets it, renders, then resets it to false in an
|
|
55
|
+
# ensure block, so a subsequent bare #render defaults to no publisher and
|
|
56
|
+
# the flag never leaks past the to_s call that set it.
|
|
57
|
+
attr_reader :with_publisher
|
|
58
|
+
|
|
59
|
+
# The rendered document code, e.g. "29.198-04-1" (number+suffix+parts).
|
|
60
|
+
def code
|
|
61
|
+
result = "#{number}#{suffix}"
|
|
62
|
+
result += parts.map { |p| "-#{p}" }.join if parts&.any?
|
|
63
|
+
result
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Basic string representation. Delegates to the :human renderer. Default
|
|
67
|
+
# omits the "3GPP " publisher token (matches the relaton index id);
|
|
68
|
+
# `to_s(with_publisher: true)` emits the printed "3GPP TS …" form.
|
|
69
|
+
def to_s(with_publisher: false, **opts)
|
|
70
|
+
@with_publisher = with_publisher
|
|
71
|
+
render(format: :human, **opts)
|
|
72
|
+
ensure
|
|
73
|
+
@with_publisher = false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Parse a 3GPP identifier string into an identifier object
|
|
77
|
+
# @param identifier [String] The 3GPP identifier string to parse
|
|
78
|
+
# @return [Identifier] The appropriate identifier object
|
|
79
|
+
def self.parse(identifier)
|
|
80
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
81
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
parsed = Parser.parse(identifier)
|
|
85
|
+
Builder.build(parsed)
|
|
86
|
+
rescue Parslet::ParseFailed => e
|
|
87
|
+
raise "Failed to parse 3GPP identifier '#{identifier}': #{e.message}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
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
|
|
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
|
|
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,62 @@
|
|
|
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
|
+
class Parser < Parslet::Parser
|
|
15
|
+
rule(:digit) { match["0-9"] }
|
|
16
|
+
rule(:digits) { digit.repeat(1) }
|
|
17
|
+
rule(:space) { str(" ") }
|
|
18
|
+
|
|
19
|
+
# Optional leading publisher token.
|
|
20
|
+
rule(:publisher_prefix) { str("3GPP") >> space }
|
|
21
|
+
|
|
22
|
+
# Document type.
|
|
23
|
+
rule(:type) { (str("TR") | str("TS")).as(:type) }
|
|
24
|
+
|
|
25
|
+
# Dotted number core, kept as a string (preserves leading zeros).
|
|
26
|
+
rule(:number_core) { (digits >> str(".") >> digits).as(:number) }
|
|
27
|
+
|
|
28
|
+
# Letter suffix directly after the number ("U"/"dcs"/"ext"…). Generic so
|
|
29
|
+
# future controlled-vocabulary values keep round-tripping.
|
|
30
|
+
rule(:suffix) { match["A-Za-z"].repeat(1).as(:suffix) }
|
|
31
|
+
|
|
32
|
+
# Hyphen parts.
|
|
33
|
+
rule(:part) { str("-") >> digits.as(:part) }
|
|
34
|
+
rule(:parts) { part.repeat(0).as(:parts) }
|
|
35
|
+
|
|
36
|
+
# Release token, stored verbatim: everything up to the version separator.
|
|
37
|
+
# Excludes ":" (as well as "/") so the ":"-delimited URN scheme can always
|
|
38
|
+
# encode it — every real release ("REL-4", "Ph1", "UMTS", "Release 2000")
|
|
39
|
+
# is colon-free.
|
|
40
|
+
rule(:release) { match["^/:"].repeat(1).as(:release) }
|
|
41
|
+
|
|
42
|
+
# Three-part version, kept as a string.
|
|
43
|
+
rule(:version) do
|
|
44
|
+
(digits >> str(".") >> digits >> str(".") >> digits).as(:version)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
rule(:identifier) do
|
|
48
|
+
publisher_prefix.maybe >>
|
|
49
|
+
type >> space >>
|
|
50
|
+
number_core >> suffix.maybe >> parts >>
|
|
51
|
+
(str(":") >> release).maybe >>
|
|
52
|
+
str("/") >> version
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
rule(:root) { identifier }
|
|
56
|
+
|
|
57
|
+
def self.parse(input)
|
|
58
|
+
new.parse(input)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
13
|
+
PUBLISHER = "3GPP"
|
|
14
|
+
|
|
15
|
+
def render(context: nil, **_opts)
|
|
16
|
+
id = @id
|
|
17
|
+
head = []
|
|
18
|
+
head << PUBLISHER if with_publisher?(id)
|
|
19
|
+
head << id.type_prefix
|
|
20
|
+
result = "#{head.join(' ')} #{id.code}"
|
|
21
|
+
# A handful of legacy records omit the release segment entirely
|
|
22
|
+
# (e.g. "TS 29.215/2.0.0").
|
|
23
|
+
result += ":#{id.release}" if id.release
|
|
24
|
+
"#{result}/#{id.version}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Default is no publisher token (the relaton index id form); the caller
|
|
30
|
+
# opts in via `to_s(with_publisher: true)`.
|
|
31
|
+
def with_publisher?(id)
|
|
32
|
+
id.with_publisher == true
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
class UrnGenerator < Pubid::UrnGenerator::Base
|
|
8
|
+
def generate
|
|
9
|
+
[
|
|
10
|
+
"urn",
|
|
11
|
+
"3gpp",
|
|
12
|
+
identifier.type_prefix.downcase,
|
|
13
|
+
identifier.code,
|
|
14
|
+
identifier.release,
|
|
15
|
+
identifier.version,
|
|
16
|
+
].join(":")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
# The rare no-release form (e.g. TS 29.215/2.0.0) serialises with an
|
|
20
|
+
# empty release chunk ("urn:3gpp:ts:29.215::2.0.0"); rebuild it without
|
|
21
|
+
# the release colon.
|
|
22
|
+
head = "#{type.upcase} #{code}"
|
|
23
|
+
head += ":#{release}" unless release.nil? || release.empty?
|
|
24
|
+
flavor_parse("#{head}/#{version}")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/pubid/tgpp.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
# 3GPP (3rd Generation Partnership Project) flavor.
|
|
5
|
+
#
|
|
6
|
+
# The Ruby constant is `Pubid::Tgpp` because a constant may not begin with a
|
|
7
|
+
# digit, but the external contract stays "3gpp": the registry key is "3gpp",
|
|
8
|
+
# the polymorphic `_type` is `pubid:3gpp:…`, and URNs use the `urn:3gpp:`
|
|
9
|
+
# namespace. Only the on-disk file names (lib/pubid/tgpp/…) follow the module.
|
|
10
|
+
module Tgpp
|
|
11
|
+
extend Pubid::PrefixesSupport
|
|
12
|
+
|
|
13
|
+
# Sole routing token. 3GPP references are printed as "3GPP TS 23.207:…";
|
|
14
|
+
# the bare document types (TR/TS) are ambiguous (JIS uses them too) and are
|
|
15
|
+
# excluded. The parser still accepts an optional leading "3GPP ".
|
|
16
|
+
PREFIXES = ["3GPP"].freeze
|
|
17
|
+
|
|
18
|
+
autoload :Builder, "#{__dir__}/tgpp/builder"
|
|
19
|
+
autoload :Identifier, "#{__dir__}/tgpp/identifier"
|
|
20
|
+
autoload :Identifiers, "#{__dir__}/tgpp/identifiers"
|
|
21
|
+
autoload :Parser, "#{__dir__}/tgpp/parser"
|
|
22
|
+
autoload :Renderer, "#{__dir__}/tgpp/renderer"
|
|
23
|
+
autoload :UrnGenerator, "#{__dir__}/tgpp/urn_generator"
|
|
24
|
+
autoload :UrnParser, "#{__dir__}/tgpp/urn_parser"
|
|
25
|
+
|
|
26
|
+
# Parse a 3GPP identifier string
|
|
27
|
+
def self.parse(identifier)
|
|
28
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
29
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Identifier.parse(identifier)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Per-flavor format registry: inherits global formats, overrides :human
|
|
36
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
37
|
+
Identifier.format_registry.register(:human, renderer: Tgpp::Renderer)
|
|
38
|
+
|
|
39
|
+
# Auto-discover all identifier types from the Identifiers namespace
|
|
40
|
+
# @return [Array<Class>] identifier classes that define a self.type Hash
|
|
41
|
+
def self.identifier_types
|
|
42
|
+
@identifier_types ||= Identifiers.constants
|
|
43
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
44
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
45
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Build typed stage index from identifier types
|
|
49
|
+
# @return [Array<Pubid::Components::TypedStage>] all typed stages
|
|
50
|
+
def self.all_typed_stages
|
|
51
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
52
|
+
if klass.const_defined?(:TYPED_STAGES)
|
|
53
|
+
klass.const_get(:TYPED_STAGES)
|
|
54
|
+
else
|
|
55
|
+
[]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Lookup: type code -> identifier class
|
|
61
|
+
# @param code [String, Symbol] the type key to find
|
|
62
|
+
# @return [Class, nil] the matching identifier class
|
|
63
|
+
def self.locate_type(code)
|
|
64
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Lookup: abbreviation -> typed stage
|
|
68
|
+
# @param abbr [String, Symbol] the abbreviation to find
|
|
69
|
+
# @return [Pubid::Components::TypedStage, nil] the matching typed stage
|
|
70
|
+
def self.locate_stage(abbr)
|
|
71
|
+
abbr_str = abbr.to_s.upcase
|
|
72
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Register 3GPP flavor with the registry (external key stays "3gpp").
|
|
78
|
+
Pubid::Registry.register(:"3gpp", Pubid::Tgpp)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
# Resolves a polymorphic `_type` string (e.g. "pubid:iso:technical-report")
|
|
5
|
+
# to the concrete Ruby class that owns it.
|
|
6
|
+
#
|
|
7
|
+
# Each flavor's Identifier base owns a `polymorphic_type_map` for the types
|
|
8
|
+
# defined in its own namespace. A nested polymorphic attribute (e.g. a GOST
|
|
9
|
+
# Harmonized identifier's adopted ISO identifier) carries a `_type` from a
|
|
10
|
+
# different flavor, so the owning flavor's map misses. This service routes
|
|
11
|
+
# the lookup to the registered flavor whose name appears in the type's
|
|
12
|
+
# second segment ("pubid:<flavor>:…"), giving every from_hash caller a
|
|
13
|
+
# single cross-flavor dispatch path.
|
|
14
|
+
class TypeResolver
|
|
15
|
+
TYPE_PREFIX = "pubid:"
|
|
16
|
+
SEGMENT_SEPARATOR = ":"
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
# @param type [String, nil] Polymorphic _type, e.g. "pubid:iso:technical-report".
|
|
20
|
+
# @return [Class<Pubid::Identifier>, nil] The concrete class, or nil if
|
|
21
|
+
# the type is blank, malformed, or unknown to its flavor.
|
|
22
|
+
def resolve(type)
|
|
23
|
+
return nil unless type.is_a?(String)
|
|
24
|
+
|
|
25
|
+
flavor_name = flavor_segment(type)
|
|
26
|
+
return nil unless flavor_name
|
|
27
|
+
|
|
28
|
+
# Ensure the flavor module is loaded so its self-register call has
|
|
29
|
+
# run; without this, Registry may know of flavors that haven't yet
|
|
30
|
+
# populated their Identifier base's polymorphic_type_map.
|
|
31
|
+
::Pubid.eager_load_flavors!
|
|
32
|
+
|
|
33
|
+
flavor = ::Pubid::Registry.get(flavor_name)
|
|
34
|
+
return nil unless flavor
|
|
35
|
+
|
|
36
|
+
identifier_base = flavor::Identifier
|
|
37
|
+
identifier_base.polymorphic_type_map[type]
|
|
38
|
+
rescue NameError
|
|
39
|
+
# Flavor module is registered but its Identifier base cannot be
|
|
40
|
+
# loaded (autoload failure). Treat as unresolvable.
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
# The flavor name is the segment between the leading "pubid:" and the
|
|
47
|
+
# type-name, e.g. "iso" in "pubid:iso:technical-report".
|
|
48
|
+
def flavor_segment(type)
|
|
49
|
+
return nil unless type.start_with?(TYPE_PREFIX)
|
|
50
|
+
|
|
51
|
+
remainder = type[TYPE_PREFIX.length..]
|
|
52
|
+
flavor_end = remainder.index(SEGMENT_SEPARATOR)
|
|
53
|
+
return nil unless flavor_end
|
|
54
|
+
|
|
55
|
+
remainder[0, flavor_end]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
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,37 @@
|
|
|
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
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
27
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
parsed = Parser.parse(identifier)
|
|
31
|
+
Builder.build(parsed)
|
|
32
|
+
rescue Parslet::ParseFailed => e
|
|
33
|
+
raise "Failed to parse UN identifier '#{identifier}': #{e.message}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
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
|