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
data/lib/pubid/errors.rb
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pubid"
|
|
4
|
+
require "parslet"
|
|
5
|
+
|
|
6
|
+
module Pubid
|
|
7
|
+
# Every failure pubid raises.
|
|
8
|
+
#
|
|
9
|
+
# The three classes below have three different superclasses, chosen so that
|
|
10
|
+
# code written against the old contract keeps working: relaton-cli rescues
|
|
11
|
+
# `Parslet::ParseFailed`, and the input guards have always raised
|
|
12
|
+
# `ArgumentError`. What unifies them is the marker module
|
|
13
|
+
# {Pubid::Errors::Error}, which every one of them includes, so a caller that
|
|
14
|
+
# wants "pubid could not do this" writes one rescue:
|
|
15
|
+
#
|
|
16
|
+
# begin
|
|
17
|
+
# Pubid::Iso.parse(reference)
|
|
18
|
+
# rescue Pubid::Errors::Error => e
|
|
19
|
+
# warn e.message
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# A URN failure deliberately does not inherit `Parslet::ParseFailed`: no
|
|
23
|
+
# grammar runs, so there is no parse failure to report.
|
|
24
|
+
module Errors
|
|
25
|
+
# Marker module included by every pubid error. Rescue this to catch all
|
|
26
|
+
# of them, whatever their superclass.
|
|
27
|
+
module Error; end
|
|
28
|
+
|
|
29
|
+
# A printed identifier could not be turned into an identifier object.
|
|
30
|
+
#
|
|
31
|
+
# Raised for a grammar rejection, and also for the few flavors that reject
|
|
32
|
+
# an input before the grammar runs (a CSA comment line, a bad ISBN check
|
|
33
|
+
# digit). Those synthetic failures carry no parslet cause, so
|
|
34
|
+
# {#parse_failure_cause} is nillable — check it before calling
|
|
35
|
+
# `ascii_tree` on it.
|
|
36
|
+
#
|
|
37
|
+
# v1's `Pubid::Core::Errors::ParseError` flattened the cause into the
|
|
38
|
+
# message and threw the object away. This one keeps it.
|
|
39
|
+
class ParseError < ::Parslet::ParseFailed
|
|
40
|
+
include Error
|
|
41
|
+
|
|
42
|
+
# The string that could not be parsed, when it is known.
|
|
43
|
+
# @return [String, nil]
|
|
44
|
+
attr_reader :input
|
|
45
|
+
|
|
46
|
+
# The flavor whose grammar rejected the input, lowercased ("iso").
|
|
47
|
+
#
|
|
48
|
+
# This is the flavor that actually ran, which is not always the one the
|
|
49
|
+
# caller named: `Pubid::Iso.parse("ITU-T G.711")` routes through the
|
|
50
|
+
# MR-string parser into ITU, and reports "itu".
|
|
51
|
+
# @return [String, nil]
|
|
52
|
+
attr_reader :flavor
|
|
53
|
+
|
|
54
|
+
# @param message [String]
|
|
55
|
+
# @param parse_failure_cause [Parslet::Cause, nil] parslet's structured
|
|
56
|
+
# cause, nil for a failure raised without running a grammar
|
|
57
|
+
# @param input [String, nil]
|
|
58
|
+
# @param flavor [String, nil]
|
|
59
|
+
def initialize(message, parse_failure_cause = nil, input: nil,
|
|
60
|
+
flavor: nil)
|
|
61
|
+
super(message, parse_failure_cause)
|
|
62
|
+
@input = input
|
|
63
|
+
@flavor = flavor
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# A URN could not be turned into an identifier object.
|
|
68
|
+
class UrnParseError < ::StandardError
|
|
69
|
+
include Error
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The input was not a String, or was longer than {Pubid::MAX_INPUT_LENGTH}.
|
|
73
|
+
#
|
|
74
|
+
# Inherits `ArgumentError` because that is what the guards have always
|
|
75
|
+
# raised, and because the input is wrong in kind rather than unparseable.
|
|
76
|
+
class InvalidInputError < ::ArgumentError
|
|
77
|
+
include Error
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/pubid/etsi/builder.rb
CHANGED
|
@@ -52,9 +52,14 @@ module Pubid
|
|
|
52
52
|
version = build_version(data)
|
|
53
53
|
date = build_date(data)
|
|
54
54
|
|
|
55
|
+
# The code fields are stored as flat index columns on the leaf (see
|
|
56
|
+
# EtsiStandard) — `number` is what relaton-index keys on — so the Code
|
|
57
|
+
# object built above is unpacked rather than assigned.
|
|
55
58
|
Identifiers::EtsiStandard.new(
|
|
56
59
|
type: data[:type].to_s,
|
|
57
|
-
|
|
60
|
+
number: code.number,
|
|
61
|
+
minor: code.minor,
|
|
62
|
+
parts: code.parts || [],
|
|
58
63
|
version: version,
|
|
59
64
|
date: date,
|
|
60
65
|
)
|
|
@@ -95,19 +100,23 @@ module Pubid
|
|
|
95
100
|
end
|
|
96
101
|
|
|
97
102
|
def build_version(data)
|
|
98
|
-
# Handle both version and edition
|
|
103
|
+
# Handle both version and edition. A partial reference omits both, in
|
|
104
|
+
# which case version is left nil (not defaulted) so exclude/matches?
|
|
105
|
+
# treat it as a wildcard.
|
|
99
106
|
if data[:version]
|
|
100
107
|
Components::Version.new(version: data[:version].to_s,
|
|
101
108
|
is_edition: false)
|
|
102
109
|
elsif data[:edition]
|
|
103
110
|
Components::Version.new(version: data[:edition].to_s,
|
|
104
111
|
is_edition: true)
|
|
105
|
-
else
|
|
106
|
-
Components::Version.new(version: "1.0.0", is_edition: false)
|
|
107
112
|
end
|
|
108
113
|
end
|
|
109
114
|
|
|
110
115
|
def build_date(data)
|
|
116
|
+
# A partial reference omits the date; leave it nil rather than building
|
|
117
|
+
# an empty Date, so the canonical to_hash drops it entirely.
|
|
118
|
+
return nil unless data[:year]
|
|
119
|
+
|
|
111
120
|
Pubid::Components::Date.new(
|
|
112
121
|
year: data[:year].to_s,
|
|
113
122
|
month: data[:month].to_s,
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Pubid::Etsi::Identifier is the ETSI base class (a real Pubid::Identifier
|
|
4
|
-
# subclass); its body
|
|
5
|
-
# live in identifiers/base.rb. This file just ensures it is loaded.
|
|
6
|
-
require_relative "identifiers/base"
|
|
4
|
+
# subclass); its body and `.parse` live in identifiers/base.rb. This file just ensures it is loaded.
|
|
@@ -2,19 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Etsi
|
|
5
|
-
# Base class for all ETSI identifiers. Canonical name Pubid::Etsi::Identifier
|
|
6
|
-
#
|
|
7
|
-
# descends from it.
|
|
5
|
+
# Base class for all ETSI identifiers. Canonical name Pubid::Etsi::Identifier;
|
|
6
|
+
# every concrete ETSI identifier descends from it.
|
|
8
7
|
class Identifier < ::Pubid::Identifier
|
|
8
|
+
# Let Parslet::ParseFailed propagate on a bad reference (matching ISO), so
|
|
9
|
+
# relaton-cli's `rescue Parslet::ParseFailed` fetch handler catches it
|
|
10
|
+
# instead of a bare RuntimeError.
|
|
9
11
|
def self.parse(identifier)
|
|
12
|
+
unless identifier.is_a?(String)
|
|
13
|
+
raise Pubid::Errors::InvalidInputError,
|
|
14
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
18
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
19
|
+
end
|
|
20
|
+
|
|
10
21
|
parsed = Parser.parse(identifier)
|
|
11
22
|
Builder.build(parsed)
|
|
12
|
-
rescue Parslet::ParseFailed => e
|
|
13
|
-
raise "Failed to parse ETSI identifier '#{identifier}': #{e.message}"
|
|
14
23
|
end
|
|
15
24
|
|
|
16
25
|
attribute :type, :string
|
|
17
|
-
attribute :code, Pubid::Etsi::Components::Code
|
|
18
26
|
attribute :version, Pubid::Etsi::Components::Version
|
|
19
27
|
attribute :date, Pubid::Components::Date
|
|
20
28
|
# Stored as a plain string (always "ETSI") so it round-trips through
|
|
@@ -31,12 +39,36 @@ module Pubid
|
|
|
31
39
|
version == other.version &&
|
|
32
40
|
date == other.date
|
|
33
41
|
end
|
|
34
|
-
end
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
|
|
43
|
+
# The document code is composed from the split index columns declared on
|
|
44
|
+
# EtsiStandard (`number`/`minor`/`parts`). Returning nil here keeps `==`
|
|
45
|
+
# and the URN generator total for the abstract base and for a supplement
|
|
46
|
+
# whose own base is missing; EtsiStandard composes the real value and
|
|
47
|
+
# SupplementIdentifier delegates to its base.
|
|
48
|
+
def code
|
|
49
|
+
nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# `parts` is a plain collection attribute on the leaf, so the base
|
|
53
|
+
# #exclude reaches it directly and nils it. It must come back as an EMPTY
|
|
54
|
+
# ARRAY instead: a part-less reference parses with `parts` defaulting to
|
|
55
|
+
# [], so a nil here would make `==` — and therefore #matches? — fail
|
|
56
|
+
# against exactly the reference this exclusion exists to match. Same
|
|
57
|
+
# "reset the whole cluster" rule recorded for CSA's year and IEEE's
|
|
58
|
+
# year/month/day in CLAUDE.md.
|
|
59
|
+
#
|
|
60
|
+
# This also covers supplements: the base #exclude recurses into the
|
|
61
|
+
# nested `base` identifier through exclude_from_nested, which re-enters
|
|
62
|
+
# this method on the inner EtsiStandard.
|
|
63
|
+
def exclude(*args)
|
|
64
|
+
result = super
|
|
65
|
+
part_keys = args & %i[part parts]
|
|
66
|
+
if !part_keys.empty? && result.respond_to?(:parts=)
|
|
67
|
+
result.parts = []
|
|
68
|
+
end
|
|
69
|
+
result
|
|
70
|
+
end
|
|
40
71
|
end
|
|
72
|
+
|
|
41
73
|
end
|
|
42
74
|
end
|
|
@@ -4,15 +4,218 @@ module Pubid
|
|
|
4
4
|
module Etsi
|
|
5
5
|
module Identifiers
|
|
6
6
|
# Single class for all ETSI standard types
|
|
7
|
-
# Type is passed as parameter: EN, ES, EG, TS, ETR, ETS, I-ETS, TBR,
|
|
7
|
+
# Type is passed as parameter: EN, ES, EG, TS, ETR, ETS, I-ETS, TBR,
|
|
8
|
+
# TCRTR, NET, GR, GS, SR, TR, GTS
|
|
8
9
|
# Format: ETSI TYPE CODE VERSION (DATE)
|
|
9
10
|
# Examples:
|
|
10
11
|
# ETSI GS ZSM 012 V1.1.1 (2022-12)
|
|
11
12
|
# ETSI GR ZSM 009-3 V1.1.1 (2023-08)
|
|
12
13
|
# ETSI GTS GSM 02.01 V5.5.0 (1999-01)
|
|
13
|
-
class EtsiStandard <
|
|
14
|
-
# Type is stored in @type attribute from
|
|
15
|
-
# All rendering handled by
|
|
14
|
+
class EtsiStandard < Identifier
|
|
15
|
+
# Type is stored in @type attribute from Identifier
|
|
16
|
+
# All rendering handled by Identifier class
|
|
17
|
+
|
|
18
|
+
# --- Index columns -------------------------------------------------
|
|
19
|
+
#
|
|
20
|
+
# relaton-index sorts and bsearches every row on `id.root.number.to_s`,
|
|
21
|
+
# so the document number must be reachable as `number`. ETSI used to
|
|
22
|
+
# keep it inside an Etsi::Components::Code under a `code` attribute,
|
|
23
|
+
# leaving the inherited `number` nil and every index row keyed "".
|
|
24
|
+
#
|
|
25
|
+
# The three Code fields are now plain sibling attributes, which is the
|
|
26
|
+
# shape the serialized hash ALREADY had — the converters below merely
|
|
27
|
+
# read them directly instead of reaching through `code`, so the wire
|
|
28
|
+
# format is byte-identical and relaton-data-etsi's published index-v2
|
|
29
|
+
# needs no regeneration.
|
|
30
|
+
#
|
|
31
|
+
# `number` holds the BARE number ("300 175"), never the part, so all
|
|
32
|
+
# parts of a document share one index bucket and a part-less reference
|
|
33
|
+
# finds them all — the IEEE/ISO semantics documented in CLAUDE.md.
|
|
34
|
+
#
|
|
35
|
+
# LANDMINE: these redeclare attributes inherited from ::Pubid::Identifier
|
|
36
|
+
# (`number` is a Components::Code there, and Etsi::Components::Code is
|
|
37
|
+
# NOT a subclass of it). That resolves nondeterministically under
|
|
38
|
+
# multi-flavor load when declared on a class others inherit from, so it
|
|
39
|
+
# is confined to this LEAF — EtsiStandard has no subclasses, while the
|
|
40
|
+
# shared Pubid::Etsi::Identifier is also SupplementIdentifier's parent
|
|
41
|
+
# and must stay untouched. spec/pubid/etsi/root_number_spec.rb carries
|
|
42
|
+
# the tripwire and is only meaningful under the full `rake` suite.
|
|
43
|
+
attribute :number, :string
|
|
44
|
+
attribute :minor, :string
|
|
45
|
+
attribute :parts, :string, collection: true, default: -> { [] }
|
|
46
|
+
|
|
47
|
+
# Compact serialization (mirrors ISO/JCGM/OIML): the code fields are
|
|
48
|
+
# bare scalars (`number`, a `parts` array and, rarely, a `minor`);
|
|
49
|
+
# Version flattens to a scalar `version` string with an `is_edition`
|
|
50
|
+
# boolean flag (omitted when false); Date flattens to top-level
|
|
51
|
+
# year/month/day. The constant `publisher` ("ETSI") is intentionally
|
|
52
|
+
# NOT mapped — it is reconstructed on load from its attribute default,
|
|
53
|
+
# keeping the hash compact.
|
|
54
|
+
#
|
|
55
|
+
# This block lives on EtsiStandard (a leaf) rather than the shared Identifier:
|
|
56
|
+
# SupplementIdentifier is a sibling that DELEGATES type/code/version and
|
|
57
|
+
# date to its inner `base`, so a block on Identifier would be inherited-and-
|
|
58
|
+
# merged by the supplement and re-emit every delegated field at the top.
|
|
59
|
+
key_value do
|
|
60
|
+
map "_type", to: :_type
|
|
61
|
+
map "type", to: :type
|
|
62
|
+
map "number", to: :number
|
|
63
|
+
map "parts", to: :parts
|
|
64
|
+
map "minor", to: :minor
|
|
65
|
+
map "version", with: { to: :version_to_kv, from: :version_from_kv }
|
|
66
|
+
map "is_edition", with: { to: :edition_to_kv, from: :edition_from_kv }
|
|
67
|
+
map "year", with: { to: :year_to_kv, from: :year_from_kv }
|
|
68
|
+
map "month", with: { to: :month_to_kv, from: :month_from_kv }
|
|
69
|
+
map "day", with: { to: :day_to_kv, from: :day_from_kv }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The composed document code, rebuilt on demand from the split columns
|
|
73
|
+
# so the renderer, the URN generator and #== keep one place to ask for
|
|
74
|
+
# the printed form ("300 175-1"). Deliberately NOT an attribute and NOT
|
|
75
|
+
# memoised: `number`/`parts` are writable (the base #exclude rebuilds
|
|
76
|
+
# through them), so a cached Code would go stale.
|
|
77
|
+
#
|
|
78
|
+
# nil when there is no number, preserving the old nil-`code` semantics
|
|
79
|
+
# the URN generator branches on.
|
|
80
|
+
def code
|
|
81
|
+
return nil if number.nil?
|
|
82
|
+
|
|
83
|
+
Pubid::Etsi::Components::Code.new(
|
|
84
|
+
number: number,
|
|
85
|
+
minor: minor,
|
|
86
|
+
parts: parts || [],
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# MR slug number segment.
|
|
91
|
+
#
|
|
92
|
+
# The base hook reads the inherited `number` and `part`; ETSI kept
|
|
93
|
+
# neither, so before the index columns landed every ETSI slug was just
|
|
94
|
+
# `etsi.<date>` — 454 distinct slugs for 24,724 documents, and
|
|
95
|
+
# `to_slug` is what consumers use as an output FILENAME.
|
|
96
|
+
#
|
|
97
|
+
# Two things the base hook cannot do for ETSI:
|
|
98
|
+
# * the parts live in the `parts` collection, not the inherited
|
|
99
|
+
# scalar `part`, so they must be appended here or every part of a
|
|
100
|
+
# document collapses onto one slug;
|
|
101
|
+
# * an ETSI number legitimately contains a SPACE ("300 175", "GSM
|
|
102
|
+
# 02.01"), which is outside the [a-z0-9.-] charset Renderers::MrString
|
|
103
|
+
# documents and guarantees. Sanitize BY CHARSET rather than by an
|
|
104
|
+
# enumerated escape list (the BIPM `mr_slug` precedent in
|
|
105
|
+
# CLAUDE.md), so a character added later cannot reach a filename.
|
|
106
|
+
# `minor` is included because it is identity-bearing everywhere else —
|
|
107
|
+
# Code#== compares it, Code#to_s renders it and the URN carries it — so
|
|
108
|
+
# omitting it here would let two distinct documents share one filename.
|
|
109
|
+
# No fixture populates it today; it is in the grammar, so it is here.
|
|
110
|
+
def mr_number_with_part
|
|
111
|
+
return nil if number.nil?
|
|
112
|
+
|
|
113
|
+
mr_sanitize([number, minor, *Array(parts)].compact.join("-"))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# ETSI's identity is type + code + version + date (see
|
|
117
|
+
# Pubid::Etsi::Identifier#==), so all four must reach the slug —
|
|
118
|
+
# CLAUDE.md's rule that an identity-bearing marker has to appear on
|
|
119
|
+
# every identity surface, not just in `==`. The base hooks find
|
|
120
|
+
# neither: `mr_type` reads `typed_stage` (ETSI has none) and
|
|
121
|
+
# `mr_edition` reads `edition.number` (ETSI models the edition as
|
|
122
|
+
# `version`). Without these, "ETSI EN 300 729 V6.1.1 (2000-04)",
|
|
123
|
+
# "…V7.1.1 (2000-04)" and "ETSI ETS 300 729 ed.2 (2000-04)" all share
|
|
124
|
+
# one slug — i.e. one output filename.
|
|
125
|
+
def mr_type
|
|
126
|
+
type&.to_s&.downcase
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def mr_edition
|
|
130
|
+
mr_sanitize(version&.version)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Segment sanitizer. Renderers::MrString joins SEGMENTS with ".", so a
|
|
134
|
+
# dot inside one would break that structure — hence "." is replaced
|
|
135
|
+
# here even though it is inside the renderer's overall charset (the
|
|
136
|
+
# BIPM `bipm.si-brochure.9e-v3-01.e` precedent in CLAUDE.md). Filtering
|
|
137
|
+
# by charset rather than by an enumerated escape list keeps a character
|
|
138
|
+
# introduced later from leaking into a filename.
|
|
139
|
+
#
|
|
140
|
+
# Public purely to keep this file's surface flat, next to the
|
|
141
|
+
# lutaml-invoked converters below — it has no external callers and
|
|
142
|
+
# would work as well private.
|
|
143
|
+
#
|
|
144
|
+
# The emptiness check is on the OUTPUT, not just the input: a value
|
|
145
|
+
# made entirely of characters outside the charset collapses to "-" and
|
|
146
|
+
# then to "", and an empty string is truthy in Ruby, so it would reach
|
|
147
|
+
# Renderers::MrString as a blank segment and produce a double dot in
|
|
148
|
+
# the joined slug. Unreachable from today's grammar, which only feeds
|
|
149
|
+
# digit/alnum captures here — but not structurally prevented.
|
|
150
|
+
def mr_sanitize(value)
|
|
151
|
+
return nil if value.nil? || value.to_s.empty?
|
|
152
|
+
|
|
153
|
+
sanitized = value.to_s.downcase
|
|
154
|
+
.gsub(/[^a-z0-9-]+/, "-").gsub(/\A-+|-+\z/, "")
|
|
155
|
+
sanitized.empty? ? nil : sanitized
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# --- Version flattened to scalar version + is_edition flag ---
|
|
159
|
+
def version_to_kv(model, doc)
|
|
160
|
+
emit_kv(doc, "version", model.version&.version)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def version_from_kv(model, value)
|
|
164
|
+
version_for(model).version = value.to_s
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def edition_to_kv(model, doc)
|
|
168
|
+
return unless model.version&.is_edition
|
|
169
|
+
|
|
170
|
+
doc.add_child(
|
|
171
|
+
Lutaml::KeyValue::DataModel::Element.new("is_edition", true),
|
|
172
|
+
)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def edition_from_kv(model, value)
|
|
176
|
+
version_for(model).is_edition = value
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# --- Date flattened to top-level year/month/day scalars ---
|
|
180
|
+
def year_to_kv(model, doc)
|
|
181
|
+
emit_kv(doc, "year", model.date&.year)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def month_to_kv(model, doc)
|
|
185
|
+
emit_kv(doc, "month", model.date&.month)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def day_to_kv(model, doc)
|
|
189
|
+
emit_kv(doc, "day", model.date&.day)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def year_from_kv(model, value)
|
|
193
|
+
date_for(model).year = value.to_s
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def month_from_kv(model, value)
|
|
197
|
+
date_for(model).month = value.to_s
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def day_from_kv(model, value)
|
|
201
|
+
date_for(model).day = value.to_s
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def emit_kv(doc, key, value)
|
|
205
|
+
return if value.nil? || value.to_s.empty?
|
|
206
|
+
|
|
207
|
+
doc.add_child(
|
|
208
|
+
Lutaml::KeyValue::DataModel::Element.new(key, value.to_s),
|
|
209
|
+
)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def version_for(model)
|
|
213
|
+
model.version ||= Pubid::Etsi::Components::Version.new
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def date_for(model)
|
|
217
|
+
model.date ||= Pubid::Components::Date.new
|
|
218
|
+
end
|
|
16
219
|
end
|
|
17
220
|
end
|
|
18
221
|
end
|
|
@@ -3,11 +3,43 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Etsi
|
|
5
5
|
module Identifiers
|
|
6
|
-
#
|
|
7
|
-
class SupplementIdentifier <
|
|
8
|
-
attribute :base, Pubid::Etsi::
|
|
6
|
+
# Identifier class for ETSI supplements (Amendment, Corrigendum)
|
|
7
|
+
class SupplementIdentifier < Identifier
|
|
8
|
+
attribute :base, Pubid::Etsi::Identifier
|
|
9
9
|
attribute :number, :integer
|
|
10
10
|
|
|
11
|
+
# Compact serialization: a supplement carries only its own ordinal
|
|
12
|
+
# `number` (A1 -> 1) and the nested base standard under the compact key
|
|
13
|
+
# `base`. type/code/version/date are delegated to `base` (methods below)
|
|
14
|
+
# and NOT re-emitted here, so the old redundant duplication is gone.
|
|
15
|
+
# This block is inherited unchanged by Amendment/Corrigendum.
|
|
16
|
+
key_value do
|
|
17
|
+
map "_type", to: :_type
|
|
18
|
+
map "number", to: :number
|
|
19
|
+
map "base", with: { to: :base_to_kv, from: :base_from_kv }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Serialize the base via its own to_hash so it collapses to the compact
|
|
23
|
+
# EtsiStandard shape.
|
|
24
|
+
def base_to_kv(model, doc)
|
|
25
|
+
return unless model.base
|
|
26
|
+
|
|
27
|
+
doc.add_child(
|
|
28
|
+
Lutaml::KeyValue::DataModel::Element.new(
|
|
29
|
+
"base", model.base.to_hash
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Re-dispatch through the flavor base so `_type` resolves to the
|
|
35
|
+
# concrete EtsiStandard; a bare polymorphic cast would rebuild a plain
|
|
36
|
+
# Identifier and lose the subclass (and its custom mappings). Mirrors JCGM.
|
|
37
|
+
def base_from_kv(model, value)
|
|
38
|
+
return unless value
|
|
39
|
+
|
|
40
|
+
model.base = Pubid::Etsi::Identifier.from_hash(value)
|
|
41
|
+
end
|
|
42
|
+
|
|
11
43
|
# Inherit attributes from base
|
|
12
44
|
def type
|
|
13
45
|
base.type
|
|
@@ -56,6 +88,16 @@ module Pubid
|
|
|
56
88
|
raise NotImplementedError
|
|
57
89
|
end
|
|
58
90
|
|
|
91
|
+
# Make Renderers::MrString recurse into `base` instead of slugging the
|
|
92
|
+
# supplement flat. Without this the flat path reads the supplement's own
|
|
93
|
+
# `number` — its ordinal, 1 — and the base document is dropped entirely,
|
|
94
|
+
# so every "/C1" corrigendum published in one month shared the slug
|
|
95
|
+
# `etsi.1.<date>`. `to_slug` is an output FILENAME, so that is an
|
|
96
|
+
# overwrite. Same fix as ITU's AnnexOfRecommendation (see CLAUDE.md).
|
|
97
|
+
def mr_supplement_suffix
|
|
98
|
+
[supplement_notation.to_s.downcase, number].compact.join(".")
|
|
99
|
+
end
|
|
100
|
+
|
|
59
101
|
def ==(other)
|
|
60
102
|
return false unless other.is_a?(SupplementIdentifier)
|
|
61
103
|
return false unless other.class == self.class
|
|
@@ -4,7 +4,6 @@ module Pubid
|
|
|
4
4
|
module Etsi
|
|
5
5
|
module Identifiers
|
|
6
6
|
autoload :Amendment, "#{__dir__}/identifiers/amendment"
|
|
7
|
-
autoload :Base, "#{__dir__}/identifiers/base"
|
|
8
7
|
autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
|
|
9
8
|
autoload :EtsiStandard, "#{__dir__}/identifiers/etsi_standard"
|
|
10
9
|
autoload :SupplementIdentifier,
|
data/lib/pubid/etsi/parser.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "parslet"
|
|
|
4
4
|
|
|
5
5
|
module Pubid
|
|
6
6
|
module Etsi
|
|
7
|
-
class Parser <
|
|
7
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
8
8
|
# Basic elements
|
|
9
9
|
rule(:digit) { match["0-9"] }
|
|
10
10
|
rule(:digits) { digit.repeat(1) }
|
|
@@ -114,13 +114,19 @@ module Pubid
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
# Main identifier
|
|
117
|
+
#
|
|
118
|
+
# The mandatory core is `etsi_prefix type number` (+ optional
|
|
119
|
+
# minor/parts/supplements), mirroring ISO. The version/edition and date
|
|
120
|
+
# suffixes are optional so a partial reference (e.g. "ETSI GS ZSM 012")
|
|
121
|
+
# parses with version/date left nil. Each `.maybe` guards its own leading
|
|
122
|
+
# space so no trailing space is demanded when the suffix is absent.
|
|
117
123
|
rule(:identifier) do
|
|
118
124
|
etsi_prefix >>
|
|
119
125
|
type >> space >>
|
|
120
126
|
number >> minor.maybe >> parts >>
|
|
121
127
|
supplements.maybe >>
|
|
122
|
-
space >> version_or_edition >>
|
|
123
|
-
space >> date_part
|
|
128
|
+
(space >> version_or_edition).maybe >>
|
|
129
|
+
(space >> date_part).maybe
|
|
124
130
|
end
|
|
125
131
|
|
|
126
132
|
rule(:root) { identifier }
|
data/lib/pubid/etsi/renderer.rb
CHANGED
|
@@ -27,7 +27,10 @@ module Pubid
|
|
|
27
27
|
|
|
28
28
|
def render_base(id)
|
|
29
29
|
result = "#{id.publisher} #{id.type} #{id.code}"
|
|
30
|
-
|
|
30
|
+
# version/date are optional on partial references; append each only when
|
|
31
|
+
# present so a partial id renders without a stray " V… ()" suffix.
|
|
32
|
+
result += " #{id.version}" if id.version
|
|
33
|
+
result += " (#{id.date.render})" if id.date
|
|
31
34
|
result
|
|
32
35
|
end
|
|
33
36
|
|
|
@@ -35,7 +38,10 @@ module Pubid
|
|
|
35
38
|
supplement_notations = id.collect_supplement_notations(id, [])
|
|
36
39
|
actual_base = id.find_actual_base(id.base)
|
|
37
40
|
code_with_supplements = "#{actual_base.code}#{supplement_notations.join}"
|
|
38
|
-
"#{actual_base.publisher} #{actual_base.type} #{code_with_supplements}
|
|
41
|
+
result = "#{actual_base.publisher} #{actual_base.type} #{code_with_supplements}"
|
|
42
|
+
result += " #{actual_base.version}" if actual_base.version
|
|
43
|
+
result += " (#{actual_base.date.render})" if actual_base.date
|
|
44
|
+
result
|
|
39
45
|
end
|
|
40
46
|
end
|
|
41
47
|
end
|
data/lib/pubid/etsi.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pubid"
|
|
3
4
|
require "lutaml/model"
|
|
4
5
|
|
|
5
6
|
module Pubid
|
|
@@ -13,7 +14,7 @@ module Pubid
|
|
|
13
14
|
|
|
14
15
|
autoload :Builder, "#{__dir__}/etsi/builder"
|
|
15
16
|
autoload :Components, "#{__dir__}/etsi/components"
|
|
16
|
-
autoload :Identifier, "#{__dir__}/etsi/
|
|
17
|
+
autoload :Identifier, "#{__dir__}/etsi/identifiers/base"
|
|
17
18
|
autoload :Identifiers, "#{__dir__}/etsi/identifiers"
|
|
18
19
|
autoload :Parser, "#{__dir__}/etsi/parser"
|
|
19
20
|
autoload :Renderer, "#{__dir__}/etsi/renderer"
|
|
@@ -25,8 +26,8 @@ module Pubid
|
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
# Per-flavor format registry: inherits global formats, overrides :human
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
|
|
30
|
+
Identifier.format_registry.register(:human, renderer: Etsi::Renderer)
|
|
30
31
|
|
|
31
32
|
# Auto-discover all identifier types from the Identifiers namespace
|
|
32
33
|
# @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
|
|
@@ -34,9 +35,9 @@ module Pubid
|
|
|
34
35
|
@identifier_types ||= Identifiers.constants
|
|
35
36
|
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
36
37
|
.select { |c| c.is_a?(Class) && c < Pubid::Identifier }
|
|
37
|
-
# Exclude the flavor base itself by identity (
|
|
38
|
+
# Exclude the flavor base itself by identity (Identifier is now an
|
|
38
39
|
# alias for Pubid::Etsi::Identifier, so name-based matching misses it).
|
|
39
|
-
.reject { |c| c ==
|
|
40
|
+
.reject { |c| c == Identifier }
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
# Build typed stage index from identifier types
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Evs
|
|
5
|
+
# Builds an EVS national adoption from the composed parse tree: the
|
|
6
|
+
# structured :adopted subtree (produced by the embedded CEN grammar) goes
|
|
7
|
+
# straight to the CEN/CENELEC builder as data — no string
|
|
8
|
+
# re-serialization anywhere.
|
|
9
|
+
class Builder < Pubid::Builder::Base
|
|
10
|
+
def self.build(parsed_data)
|
|
11
|
+
new.build(parsed_data)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def build(data)
|
|
15
|
+
data = flatten_array(data) if data.is_a?(Array)
|
|
16
|
+
|
|
17
|
+
adopted = Pubid::CenCenelec::Builder.build(data[:adopted])
|
|
18
|
+
|
|
19
|
+
Identifiers::NationalAdoption.new(
|
|
20
|
+
adopted_identifier: adopted,
|
|
21
|
+
separator: data[:evs_separator] || "-",
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Evs
|
|
5
|
+
# An EVS national adoption wraps a CEN identifier the same way BSI's
|
|
6
|
+
# AdoptedEuropeanNorm does — polymorphic `adopted_identifier` so the
|
|
7
|
+
# wrapped object stays a real Pubid::CenCenelec identifier.
|
|
8
|
+
#
|
|
9
|
+
# Examples:
|
|
10
|
+
# "EVS-EN 18216:2026" (adopted_identifier: EN 18216:2026)
|
|
11
|
+
# "EVS-EN ISO 14001:2026" (adopted_identifier: EN ISO 14001:2026)
|
|
12
|
+
# "EVS-EN ISO/IEC 27017:2026" (adopted_identifier: EN ISO/IEC 27017:2026)
|
|
13
|
+
# "EVS-EN ISO 9001:2015/A1:2024" (adopted_identifier: EN ISO 9001:2015/A1:2024)
|
|
14
|
+
class Identifier < ::Pubid::Identifier
|
|
15
|
+
attribute :adopted_identifier, ::Pubid::Identifier, polymorphic: true
|
|
16
|
+
# "-" or " " — preserves the printed separator ("EVS-EN" vs "EVS EN")
|
|
17
|
+
attribute :separator, :string, default: -> { "-" }
|
|
18
|
+
|
|
19
|
+
def to_s(**opts)
|
|
20
|
+
render(format: :human, **opts)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.parse(string)
|
|
24
|
+
unless string.is_a?(String)
|
|
25
|
+
raise Pubid::Errors::InvalidInputError,
|
|
26
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if string.length > Pubid::MAX_INPUT_LENGTH
|
|
30
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Pubid::Evs.parse(string)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|