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.
- checksums.yaml +4 -4
- data/README.adoc +33 -11
- data/conformance/pending.yaml +4 -0
- 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/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
- data/data/nist/update_codes.yaml +8 -0
- data/lib/pubid/adobe/builder.rb +52 -0
- data/lib/pubid/adobe/identifier.rb +47 -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 +136 -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 +61 -0
- data/lib/pubid/amca/builder.rb +4 -4
- data/lib/pubid/amca/identifier.rb +1 -3
- data/lib/pubid/amca/identifiers/base.rb +50 -33
- data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
- data/lib/pubid/amca/identifiers/publication.rb +14 -10
- data/lib/pubid/amca/identifiers/standard.rb +3 -1
- data/lib/pubid/amca/identifiers.rb +0 -1
- data/lib/pubid/amca/parser.rb +1 -1
- data/lib/pubid/amca/renderer.rb +4 -4
- data/lib/pubid/amca/single_identifier.rb +1 -1
- data/lib/pubid/amca/urn_generator.rb +2 -2
- data/lib/pubid/amca.rb +5 -4
- data/lib/pubid/ansi/builder.rb +2 -2
- data/lib/pubid/ansi/identifier.rb +18 -0
- data/lib/pubid/ansi/parser.rb +1 -1
- data/lib/pubid/ansi/renderer.rb +2 -2
- data/lib/pubid/ansi.rb +5 -5
- data/lib/pubid/api/builder.rb +16 -2
- data/lib/pubid/api/identifier.rb +25 -4
- data/lib/pubid/api/identifiers/mpms.rb +10 -8
- data/lib/pubid/api/parser.rb +1 -1
- data/lib/pubid/api/renderer.rb +16 -7
- data/lib/pubid/api/single_identifier.rb +5 -12
- data/lib/pubid/api.rb +1 -0
- data/lib/pubid/ashrae/builder.rb +53 -32
- data/lib/pubid/ashrae/identifier.rb +3 -4
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
- data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
- data/lib/pubid/ashrae/identifiers/base.rb +94 -12
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
- data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
- data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
- data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
- data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
- data/lib/pubid/ashrae/identifiers.rb +0 -1
- data/lib/pubid/ashrae/parser.rb +37 -17
- data/lib/pubid/ashrae/renderer.rb +20 -20
- data/lib/pubid/ashrae/single_identifier.rb +1 -1
- data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
- data/lib/pubid/ashrae/urn_generator.rb +8 -2
- data/lib/pubid/ashrae.rb +10 -4
- data/lib/pubid/asme/builder.rb +11 -2
- data/lib/pubid/asme/identifier.rb +9 -0
- data/lib/pubid/asme/identifiers/standard.rb +86 -2
- data/lib/pubid/asme/parser.rb +1 -1
- data/lib/pubid/asme/renderer.rb +3 -3
- data/lib/pubid/asme/single_identifier.rb +8 -1
- data/lib/pubid/asme/urn_generator.rb +2 -2
- data/lib/pubid/asme.rb +1 -0
- data/lib/pubid/astm/builder.rb +10 -3
- data/lib/pubid/astm/identifier.rb +9 -0
- data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
- data/lib/pubid/astm/identifiers/code_number.rb +81 -0
- data/lib/pubid/astm/identifiers/data_series.rb +2 -0
- data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
- data/lib/pubid/astm/identifiers/manual.rb +10 -0
- data/lib/pubid/astm/identifiers/monograph.rb +2 -0
- data/lib/pubid/astm/identifiers/research_report.rb +10 -0
- data/lib/pubid/astm/identifiers/standard.rb +10 -0
- data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
- data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
- data/lib/pubid/astm/identifiers.rb +1 -0
- data/lib/pubid/astm/parser.rb +1 -1
- data/lib/pubid/astm/renderer.rb +1 -1
- data/lib/pubid/astm/single_identifier.rb +31 -1
- data/lib/pubid/astm/urn_generator.rb +7 -5
- data/lib/pubid/astm.rb +1 -0
- data/lib/pubid/bipm/builder.rb +163 -0
- data/lib/pubid/bipm/identifier.rb +285 -0
- data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
- data/lib/pubid/bipm/identifiers/guide.rb +35 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
- data/lib/pubid/bipm/identifiers/mep.rb +33 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
- data/lib/pubid/bipm/identifiers.rb +15 -0
- data/lib/pubid/bipm/parser.rb +237 -0
- data/lib/pubid/bipm/renderer.rb +118 -0
- data/lib/pubid/bipm/urn_generator.rb +58 -0
- data/lib/pubid/bipm/urn_parser.rb +60 -0
- data/lib/pubid/bipm.rb +92 -0
- data/lib/pubid/bsi/builder.rb +62 -52
- data/lib/pubid/bsi/identifier.rb +0 -1
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
- data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
- data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
- 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/handbook.rb +0 -2
- data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
- data/lib/pubid/bsi/identifiers/set.rb +11 -0
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
- 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/parser.rb +1 -1
- data/lib/pubid/bsi/renderer.rb +71 -59
- data/lib/pubid/bsi/single_identifier.rb +64 -7
- data/lib/pubid/bsi/urn_generator.rb +11 -2
- data/lib/pubid/bsi.rb +7 -1
- data/lib/pubid/builder/base.rb +23 -11
- data/lib/pubid/bundled_identifier.rb +19 -9
- data/lib/pubid/calconnect/builder.rb +38 -0
- data/lib/pubid/calconnect/identifier.rb +121 -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 +83 -0
- data/lib/pubid/ccsds/builder.rb +1 -1
- data/lib/pubid/ccsds/identifier.rb +10 -3
- data/lib/pubid/ccsds/identifiers/base.rb +4 -2
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/ccsds/parser.rb +1 -1
- data/lib/pubid/ccsds/single_identifier.rb +2 -2
- data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
- data/lib/pubid/ccsds/urn_generator.rb +3 -3
- data/lib/pubid/ccsds.rb +1 -0
- data/lib/pubid/cen_cenelec/builder.rb +131 -72
- data/lib/pubid/cen_cenelec/identifier.rb +115 -3
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
- data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
- data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -14
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
- data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
- data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
- data/lib/pubid/cen_cenelec/parser.rb +1 -1
- data/lib/pubid/cen_cenelec/renderer.rb +55 -60
- data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
- data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
- data/lib/pubid/cen_cenelec.rb +104 -82
- data/lib/pubid/cie/builder.rb +149 -24
- data/lib/pubid/cie/identifier.rb +13 -4
- data/lib/pubid/cie/identifiers/bundle.rb +35 -5
- data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
- data/lib/pubid/cie/identifiers/conference.rb +11 -6
- data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
- data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
- data/lib/pubid/cie/identifiers/identical.rb +9 -9
- data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
- data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
- data/lib/pubid/cie/identifiers/standard.rb +43 -8
- data/lib/pubid/cie/identifiers/supplement.rb +27 -25
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
- data/lib/pubid/cie/identifiers.rb +2 -0
- data/lib/pubid/cie/parser.rb +55 -6
- 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 +7 -2
- data/lib/pubid/components/date.rb +21 -5
- data/lib/pubid/conformance/checks.rb +72 -0
- data/lib/pubid/conformance/corpus/case.rb +55 -0
- data/lib/pubid/conformance/corpus.rb +36 -0
- data/lib/pubid/conformance/generator.rb +212 -0
- data/lib/pubid/conformance/pending.rb +63 -0
- data/lib/pubid/conformance/runner.rb +153 -0
- data/lib/pubid/conformance.rb +55 -0
- data/lib/pubid/core.rb +2 -0
- data/lib/pubid/csa/builder.rb +48 -48
- data/lib/pubid/csa/composite_identifier.rb +18 -7
- data/lib/pubid/csa/identifier.rb +187 -80
- data/lib/pubid/csa/identifiers/bundled.rb +25 -9
- data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
- data/lib/pubid/csa/identifiers/cec.rb +44 -4
- data/lib/pubid/csa/identifiers/combined.rb +97 -69
- data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
- data/lib/pubid/csa/identifiers/package.rb +4 -4
- data/lib/pubid/csa/parser.rb +12 -8
- data/lib/pubid/csa/renderer.rb +13 -5
- data/lib/pubid/csa/single_identifier.rb +93 -4
- data/lib/pubid/csa/urn_generator.rb +9 -2
- data/lib/pubid/csa/wrapper_identifier.rb +43 -10
- data/lib/pubid/csa.rb +7 -1
- data/lib/pubid/doi/builder.rb +18 -0
- data/lib/pubid/doi/identifier.rb +49 -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 +56 -0
- data/lib/pubid/easc/builder.rb +55 -0
- data/lib/pubid/easc/identifier.rb +59 -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 +88 -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 +53 -0
- data/lib/pubid/ecma/builder.rb +45 -0
- data/lib/pubid/ecma/identifier.rb +147 -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 +76 -0
- data/lib/pubid/ecma/renderer.rb +67 -0
- data/lib/pubid/ecma/urn_generator.rb +46 -0
- data/lib/pubid/ecma/urn_parser.rb +51 -0
- data/lib/pubid/ecma.rb +68 -0
- data/lib/pubid/errors.rb +80 -0
- data/lib/pubid/etsi/builder.rb +13 -4
- data/lib/pubid/etsi/identifier.rb +1 -3
- data/lib/pubid/etsi/identifiers/base.rb +43 -11
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
- data/lib/pubid/etsi/identifiers.rb +0 -1
- data/lib/pubid/etsi/parser.rb +9 -3
- data/lib/pubid/etsi/renderer.rb +8 -2
- data/lib/pubid/etsi.rb +6 -5
- data/lib/pubid/evs/builder.rb +26 -0
- data/lib/pubid/evs/identifier.rb +37 -0
- data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
- data/lib/pubid/evs/identifiers.rb +9 -0
- data/lib/pubid/evs/parser.rb +27 -0
- data/lib/pubid/evs/renderer.rb +30 -0
- data/lib/pubid/evs/urn_generator.rb +30 -0
- data/lib/pubid/evs/urn_parser.rb +80 -0
- data/lib/pubid/evs.rb +90 -0
- data/lib/pubid/export/exporter.rb +2 -1
- data/lib/pubid/export/flavor_exporter.rb +18 -3
- data/lib/pubid/export.rb +1 -0
- data/lib/pubid/format_detector.rb +1 -0
- data/lib/pubid/gb/builder.rb +45 -0
- data/lib/pubid/gb/identifier.rb +67 -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 +88 -0
- data/lib/pubid/gost/builder.rb +185 -0
- data/lib/pubid/gost/identifier.rb +47 -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 +105 -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 +50 -0
- data/lib/pubid/iala/builder.rb +22 -27
- data/lib/pubid/iala/identifier.rb +36 -8
- data/lib/pubid/iala/identifiers/advice.rb +1 -1
- data/lib/pubid/iala/identifiers/annex.rb +10 -10
- 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/parser.rb +10 -2
- data/lib/pubid/iala/renderer.rb +1 -1
- data/lib/pubid/iala/urn_generator.rb +1 -1
- data/lib/pubid/iala/urn_parser.rb +24 -3
- data/lib/pubid/iala.rb +5 -4
- data/lib/pubid/iana/builder.rb +22 -0
- data/lib/pubid/iana/identifier.rb +140 -0
- data/lib/pubid/iana/identifiers/registry.rb +69 -0
- data/lib/pubid/iana/identifiers.rb +9 -0
- data/lib/pubid/iana/parser.rb +38 -0
- data/lib/pubid/iana/renderer.rb +32 -0
- data/lib/pubid/iana/urn_generator.rb +19 -0
- data/lib/pubid/iana/urn_parser.rb +24 -0
- data/lib/pubid/iana.rb +70 -0
- data/lib/pubid/identifier.rb +797 -26
- data/lib/pubid/identifier_metadata.rb +1 -0
- data/lib/pubid/idf/builder.rb +4 -4
- data/lib/pubid/idf/identifier.rb +18 -9
- data/lib/pubid/idf/parser.rb +3 -3
- data/lib/pubid/idf/renderer.rb +5 -5
- data/lib/pubid/idf/supplement_identifier.rb +3 -3
- data/lib/pubid/idf/urn_generator.rb +1 -1
- data/lib/pubid/idf.rb +7 -1
- data/lib/pubid/iec/builder.rb +49 -32
- data/lib/pubid/iec/components.rb +0 -1
- data/lib/pubid/iec/identifier.rb +112 -77
- data/lib/pubid/iec/identifiers/amendment.rb +6 -2
- data/lib/pubid/iec/identifiers/base.rb +2 -2
- data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
- data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
- data/lib/pubid/iec/identifiers/guide.rb +0 -16
- data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
- data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
- data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
- data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
- data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
- data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
- data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
- data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
- data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
- data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
- data/lib/pubid/iec/identifiers/working_document.rb +24 -10
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/parser.rb +53 -28
- data/lib/pubid/iec/renderer.rb +31 -18
- data/lib/pubid/iec/single_identifier.rb +34 -11
- data/lib/pubid/iec/supplement_identifier.rb +32 -19
- data/lib/pubid/iec/urn_generator.rb +227 -61
- data/lib/pubid/iec/urn_parser.rb +42 -4
- data/lib/pubid/iec.rb +2 -6
- data/lib/pubid/ieee/aiee/builder.rb +17 -3
- data/lib/pubid/ieee/aiee/identifier.rb +46 -62
- data/lib/pubid/ieee/aiee/parser.rb +1 -1
- data/lib/pubid/ieee/builder.rb +386 -69
- 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 +62 -5
- data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
- data/lib/pubid/ieee/identifiers/base.rb +148 -18
- 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 +24 -3
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
- data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
- 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/ire/parser.rb +1 -1
- data/lib/pubid/ieee/nesc/builder.rb +33 -20
- data/lib/pubid/ieee/nesc/parser.rb +16 -15
- data/lib/pubid/ieee/parser.rb +462 -44
- data/lib/pubid/ieee/pre_parser.rb +1 -1
- data/lib/pubid/ieee/renderer.rb +158 -57
- data/lib/pubid/ieee/typed_stages.rb +12 -1
- data/lib/pubid/ieee/urn_generator.rb +35 -8
- data/lib/pubid/ieee.rb +63 -4
- data/lib/pubid/ieee_debug.rb +1 -0
- data/lib/pubid/ietf/builder.rb +78 -0
- data/lib/pubid/ietf/identifier.rb +5 -0
- data/lib/pubid/ietf/identifiers/base.rb +72 -0
- data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
- data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
- data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
- data/lib/pubid/ietf/identifiers/std.rb +36 -0
- data/lib/pubid/ietf/identifiers.rb +14 -0
- data/lib/pubid/ietf/parser.rb +61 -0
- data/lib/pubid/ietf/renderer.rb +64 -0
- data/lib/pubid/ietf/urn_generator.rb +37 -0
- data/lib/pubid/ietf/urn_parser.rb +43 -0
- data/lib/pubid/ietf.rb +86 -0
- data/lib/pubid/iho/identifier.rb +1 -3
- data/lib/pubid/iho/identifiers/base.rb +11 -10
- 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/parser.rb +1 -1
- data/lib/pubid/iho.rb +8 -7
- data/lib/pubid/isbn/builder.rb +44 -0
- data/lib/pubid/isbn/check_digit.rb +53 -0
- data/lib/pubid/isbn/identifier.rb +81 -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 +53 -0
- data/lib/pubid/iso/builder.rb +9 -4
- data/lib/pubid/iso/bundled_identifier.rb +5 -3
- data/lib/pubid/iso/combined_identifier.rb +6 -4
- data/lib/pubid/iso/identifier.rb +29 -8
- data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
- data/lib/pubid/iso/normalizer.rb +2 -2
- data/lib/pubid/iso/parser.rb +17 -13
- 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/iso.rb +7 -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 +7 -29
- 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 +357 -25
- 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 +481 -27
- data/lib/pubid/itu/urn_generator.rb +36 -6
- data/lib/pubid/itu/urn_parser.rb +8 -0
- data/lib/pubid/itu.rb +12 -3
- data/lib/pubid/jcgm/builder.rb +24 -14
- data/lib/pubid/jcgm/identifier.rb +10 -0
- 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 +74 -7
- data/lib/pubid/jcgm/renderer.rb +33 -12
- data/lib/pubid/jcgm/single_identifier.rb +84 -6
- 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 +164 -10
- data/lib/pubid/jcgm.rb +10 -0
- data/lib/pubid/jis/identifier.rb +62 -3
- data/lib/pubid/jis/parser.rb +1 -1
- data/lib/pubid/jis.rb +1 -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/stage.rb +2 -2
- data/lib/pubid/nist/components/supplement.rb +5 -2
- data/lib/pubid/nist/configuration.rb +6 -2
- data/lib/pubid/nist/identifier.rb +1 -3
- data/lib/pubid/nist/identifiers/base.rb +133 -39
- data/lib/pubid/nist/identifiers/circular.rb +10 -3
- data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
- 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 +8 -2
- data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
- 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 +10 -3
- data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
- data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
- data/lib/pubid/nist/identifiers/monograph.rb +15 -8
- 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 +15 -7
- 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 +27 -4
- data/lib/pubid/nist/preprocessor.rb +15 -0
- data/lib/pubid/nist/router.rb +2 -2
- data/lib/pubid/nist/series/ir.rb +0 -3
- data/lib/pubid/nist/supplement_identifier.rb +24 -9
- data/lib/pubid/nist.rb +19 -13
- data/lib/pubid/oasis/builder.rb +79 -0
- data/lib/pubid/oasis/identifier.rb +160 -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 +80 -0
- data/lib/pubid/ogc/builder.rb +33 -0
- data/lib/pubid/ogc/identifier.rb +81 -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 +72 -0
- data/lib/pubid/oiml/builder.rb +36 -8
- data/lib/pubid/oiml/identifier.rb +9 -1
- data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
- data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
- data/lib/pubid/oiml/identifiers/document.rb +2 -0
- data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
- data/lib/pubid/oiml/identifiers/guide.rb +2 -0
- data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
- data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
- data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
- data/lib/pubid/oiml/identifiers.rb +1 -0
- data/lib/pubid/oiml/parser.rb +12 -13
- data/lib/pubid/oiml/renderer.rb +13 -13
- data/lib/pubid/oiml/single_identifier.rb +41 -37
- data/lib/pubid/oiml/supplement_identifier.rb +36 -9
- data/lib/pubid/oiml/urn_parser.rb +23 -6
- data/lib/pubid/oiml.rb +10 -0
- data/lib/pubid/omg/builder.rb +20 -0
- data/lib/pubid/omg/identifier.rb +61 -0
- data/lib/pubid/omg/identifiers/specification.rb +32 -0
- data/lib/pubid/omg/identifiers.rb +9 -0
- data/lib/pubid/omg/parser.rb +93 -0
- data/lib/pubid/omg/renderer.rb +31 -0
- data/lib/pubid/omg.rb +52 -0
- data/lib/pubid/parser/grammar.rb +74 -0
- data/lib/pubid/parser.rb +2 -0
- data/lib/pubid/parsers/mr_string.rb +120 -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 +16 -6
- data/lib/pubid/plateau/renderer.rb +1 -1
- data/lib/pubid/plateau/supplement_identifier.rb +11 -11
- data/lib/pubid/plateau.rb +14 -4
- data/lib/pubid/prefixes_support.rb +1 -0
- data/lib/pubid/renderers/annotator.rb +233 -0
- data/lib/pubid/renderers/base.rb +13 -0
- data/lib/pubid/renderers/directives_renderer.rb +3 -3
- data/lib/pubid/renderers/human_readable.rb +6 -4
- data/lib/pubid/renderers/mr_string.rb +54 -6
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/rendering/numbering.rb +25 -7
- data/lib/pubid/rendering/supplement.rb +4 -4
- data/lib/pubid/rendering.rb +1 -0
- data/lib/pubid/sae/builder.rb +1 -1
- data/lib/pubid/sae/identifier.rb +1 -3
- data/lib/pubid/sae/identifiers/base.rb +19 -9
- data/lib/pubid/sae/identifiers.rb +0 -1
- data/lib/pubid/sae/parser.rb +1 -1
- data/lib/pubid/sae.rb +4 -3
- data/lib/pubid/schema/declaration.rb +33 -0
- data/lib/pubid/schema/error.rb +14 -0
- data/lib/pubid/schema/identifier_type.rb +23 -0
- data/lib/pubid/schema/loader.rb +117 -0
- data/lib/pubid/schema/typed_stage.rb +24 -0
- data/lib/pubid/schema.rb +25 -0
- data/lib/pubid/tgpp/builder.rb +41 -0
- data/lib/pubid/tgpp/identifier.rb +107 -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 +78 -0
- data/lib/pubid/tgpp/renderer.rb +52 -0
- data/lib/pubid/tgpp/urn_generator.rb +39 -0
- data/lib/pubid/tgpp/urn_parser.rb +30 -0
- data/lib/pubid/tgpp.rb +84 -0
- data/lib/pubid/type_resolver.rb +74 -0
- data/lib/pubid/un/builder.rb +42 -0
- data/lib/pubid/un/identifier.rb +40 -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 +47 -0
- data/lib/pubid/urn_parser/errors.rb +8 -1
- data/lib/pubid/urn_parser.rb +1 -0
- data/lib/pubid/utils.rb +1 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/builder.rb +55 -0
- data/lib/pubid/w3c/identifier.rb +130 -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 +68 -0
- data/lib/pubid/xsf/builder.rb +17 -0
- data/lib/pubid/xsf/identifier.rb +66 -0
- data/lib/pubid/xsf/identifiers/xep.rb +31 -0
- data/lib/pubid/xsf/identifiers.rb +9 -0
- data/lib/pubid/xsf/parser.rb +38 -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 +82 -0
- data/lib/pubid.rb +424 -22
- data/lib/tasks/conformance.rake +34 -0
- data/lib/tasks/docs.rake +3 -3
- data/lib/tasks/schema.rake +88 -0
- data/schema/core/joint_prefixes.yaml +24 -0
- data/schema/iec.yaml +1017 -0
- data/schema/iso.yaml +1586 -0
- data/schema/schema.schema.yaml +96 -0
- metadata +241 -19
- data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
- data/archived-gems/pubid-iec/stages.yaml +0 -129
- data/archived-gems/pubid-iec/update_codes.yaml +0 -67
- data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
- data/archived-gems/pubid-iso/stages.yaml +0 -106
- data/archived-gems/pubid-iso/update_codes.yaml +0 -4
- data/archived-gems/pubid-itu/i18n.yaml +0 -13
- data/archived-gems/pubid-itu/series.yaml +0 -42
- data/archived-gems/pubid-nist/publishers.yaml +0 -6
- data/archived-gems/pubid-nist/update_codes.yaml +0 -93
- data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
- data/lib/pubid/cie/components/code.rb +0 -80
- data/lib/pubid/iala/identifiers/base.rb +0 -14
- data/lib/pubid/iec/components/code.rb +0 -36
- /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
|