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.rb
CHANGED
|
@@ -15,6 +15,8 @@ require "pubid/lutaml/no_store_registration"
|
|
|
15
15
|
require "pubid/prefixes_support"
|
|
16
16
|
|
|
17
17
|
module Pubid
|
|
18
|
+
autoload :Schema, "pubid/schema"
|
|
19
|
+
autoload :Conformance, "pubid/conformance"
|
|
18
20
|
# Upper bound on the length of an identifier string accepted by any +parse+
|
|
19
21
|
# entry point. Real-world standards identifiers are well under 200 characters;
|
|
20
22
|
# this limit exists purely to keep pathological, attacker-controlled inputs
|
|
@@ -30,12 +32,28 @@ module Pubid
|
|
|
30
32
|
INPUT_TOO_LONG_MESSAGE =
|
|
31
33
|
"identifier string exceeds maximum length of #{MAX_INPUT_LENGTH} characters"
|
|
32
34
|
|
|
35
|
+
# Raised (as an ArgumentError) when +parse+ gets something that is not a
|
|
36
|
+
# String. Without this check the input reaches +.length+ and the caller gets a
|
|
37
|
+
# NoMethodError ("undefined method 'length' for nil"), a Ruby internal error
|
|
38
|
+
# that says nothing about the identifier contract. Every public +parse+ entry
|
|
39
|
+
# point rejects a non-String before it measures the length.
|
|
40
|
+
INPUT_NOT_A_STRING_MESSAGE = "identifier must be a String"
|
|
41
|
+
|
|
33
42
|
# Registry for tracking all loaded flavors
|
|
34
43
|
class Registry
|
|
35
44
|
@flavors = {}
|
|
36
45
|
|
|
37
46
|
class << self
|
|
38
|
-
|
|
47
|
+
# The registered flavors, always key-sorted and frozen. Sorted so
|
|
48
|
+
# no behavior can observe registration (= module load) order -
|
|
49
|
+
# hosts autoload flavor modules in any order, and order-dependent
|
|
50
|
+
# iteration once routed the same identifier to different flavors
|
|
51
|
+
# per process. Frozen so the raw table is not public mutable
|
|
52
|
+
# state; #register is the only mutator.
|
|
53
|
+
# @return [Hash{String => Module}]
|
|
54
|
+
def flavors
|
|
55
|
+
@flavors.sort.to_h.freeze
|
|
56
|
+
end
|
|
39
57
|
|
|
40
58
|
# Register a flavor with the registry
|
|
41
59
|
# @param name [String, Symbol] Flavor name (e.g., :iso, :iec)
|
|
@@ -44,6 +62,15 @@ module Pubid
|
|
|
44
62
|
@flavors[name.to_s.downcase] = flavor_module
|
|
45
63
|
end
|
|
46
64
|
|
|
65
|
+
# Remove a flavor registration. Tests that register probe flavors
|
|
66
|
+
# MUST unregister them: registry-driven specs enumerate every
|
|
67
|
+
# registered flavor, so a leaked probe fails them for everyone
|
|
68
|
+
# else in the process.
|
|
69
|
+
# @param name [String, Symbol] Flavor name
|
|
70
|
+
def unregister(name)
|
|
71
|
+
@flavors.delete(name.to_s.downcase)
|
|
72
|
+
end
|
|
73
|
+
|
|
47
74
|
# Get all registered flavor names
|
|
48
75
|
# @return [Array<String>] Array of flavor names
|
|
49
76
|
def flavor_names
|
|
@@ -57,30 +84,62 @@ module Pubid
|
|
|
57
84
|
@flavors[name.to_s.downcase]
|
|
58
85
|
end
|
|
59
86
|
|
|
87
|
+
# The canonical registered name of a module that may be registered
|
|
88
|
+
# under aliases (CenCenelec registers both cen_cenelec and cen).
|
|
89
|
+
# Canonical = the name the module's own prefix table is keyed by,
|
|
90
|
+
# so the answer cannot depend on registration or iteration order.
|
|
91
|
+
# @param flavor_module [Module]
|
|
92
|
+
# @return [String, nil]
|
|
93
|
+
def canonical_name(flavor_module)
|
|
94
|
+
if flavor_module.singleton_class.method_defined?(:prefix_flavor_key)
|
|
95
|
+
key = flavor_module.prefix_flavor_key.to_s
|
|
96
|
+
return key if @flavors[key] == flavor_module
|
|
97
|
+
end
|
|
98
|
+
@flavors.key(flavor_module)
|
|
99
|
+
end
|
|
100
|
+
|
|
60
101
|
# Check if a flavor is registered
|
|
61
102
|
# @param name [String, Symbol] Flavor name
|
|
62
103
|
# @return [Boolean]
|
|
63
104
|
def registered?(name)
|
|
64
105
|
@flavors.key?(name.to_s.downcase)
|
|
65
106
|
end
|
|
107
|
+
|
|
108
|
+
# Parse an identifier without naming its flavor.
|
|
109
|
+
#
|
|
110
|
+
# The pubid 1.x entry point, kept because consumers still call it —
|
|
111
|
+
# isodoc's +std_docid_semantic_parse+ among them. It delegates to
|
|
112
|
+
# {Pubid.parse}; it is not a second implementation.
|
|
113
|
+
#
|
|
114
|
+
# @param string [String] the identifier string
|
|
115
|
+
# @return [Pubid::Identifier]
|
|
116
|
+
# @raise [Parslet::ParseFailed] when no flavor can parse it
|
|
117
|
+
def parse(string, **opts)
|
|
118
|
+
Pubid.parse(string, **opts)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Build an identifier from its hash without naming its flavor.
|
|
122
|
+
# It delegates to {Pubid.from_hash}, as {parse} delegates to
|
|
123
|
+
# {Pubid.parse}.
|
|
124
|
+
#
|
|
125
|
+
# @param data [Hash] an identifier hash
|
|
126
|
+
# @return [Pubid::Identifier]
|
|
127
|
+
# @raise [Pubid::Errors::InvalidInputError] see {Pubid.from_hash}
|
|
128
|
+
def from_hash(data)
|
|
129
|
+
Pubid.from_hash(data)
|
|
130
|
+
end
|
|
66
131
|
end
|
|
67
132
|
end
|
|
68
133
|
|
|
69
|
-
# Canonical joint / co-publication leading tokens,
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# so co-publication symmetry can never drift. Keyed by
|
|
134
|
+
# Canonical joint / co-publication leading tokens, sourced at boot from
|
|
135
|
+
# schema/core/joint_prefixes.yaml - the single source of truth. Injected
|
|
136
|
+
# symmetrically into every participating flavor's +prefixes+ (see
|
|
137
|
+
# {PrefixesSupport}) so co-publication symmetry can never drift. Keyed by
|
|
74
138
|
# {PrefixesSupport#prefix_flavor_key}.
|
|
75
|
-
JOINT_PREFIXES =
|
|
76
|
-
|
|
77
|
-
iec: ["ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"],
|
|
78
|
-
ieee: ["ISO/IEC/IEEE"],
|
|
79
|
-
ansi: ["ANSI/ASHRAE", "ANSI/AMCA"],
|
|
80
|
-
ashrae: ["ANSI/ASHRAE"],
|
|
81
|
-
amca: ["ANSI/AMCA"],
|
|
82
|
-
}.freeze
|
|
139
|
+
JOINT_PREFIXES = Schema::Loader.joint_prefixes_map
|
|
140
|
+
.transform_keys(&:to_sym).freeze
|
|
83
141
|
|
|
142
|
+
autoload :Errors, "pubid/errors"
|
|
84
143
|
autoload :Parser, "pubid/parser"
|
|
85
144
|
autoload :Components, "pubid/components"
|
|
86
145
|
autoload :BundledIdentifier, "pubid/bundled_identifier"
|
|
@@ -97,35 +156,55 @@ module Pubid
|
|
|
97
156
|
autoload :Utils, "pubid/utils"
|
|
98
157
|
autoload :Version, "pubid/version"
|
|
99
158
|
autoload :Core, "pubid/core"
|
|
159
|
+
autoload :TypeResolver, "pubid/type_resolver"
|
|
100
160
|
|
|
101
161
|
|
|
102
162
|
# Require all flavor modules
|
|
163
|
+
autoload :Adobe, "pubid/adobe"
|
|
103
164
|
autoload :Amca, "pubid/amca"
|
|
104
165
|
autoload :Ansi, "pubid/ansi"
|
|
105
166
|
autoload :Api, "pubid/api"
|
|
106
167
|
autoload :Ashrae, "pubid/ashrae"
|
|
107
168
|
autoload :Asme, "pubid/asme"
|
|
169
|
+
autoload :Doi, "pubid/doi"
|
|
170
|
+
autoload :Easc, "pubid/easc"
|
|
108
171
|
autoload :Astm, "pubid/astm"
|
|
172
|
+
autoload :Bipm, "pubid/bipm"
|
|
109
173
|
autoload :Bsi, "pubid/bsi"
|
|
174
|
+
autoload :Calconnect, "pubid/calconnect"
|
|
110
175
|
autoload :Ccsds, "pubid/ccsds"
|
|
111
176
|
autoload :CenCenelec, "pubid/cen_cenelec"
|
|
112
177
|
autoload :Cie, "pubid/cie"
|
|
113
178
|
autoload :Csa, "pubid/csa"
|
|
179
|
+
autoload :Ecma, "pubid/ecma"
|
|
114
180
|
autoload :Etsi, "pubid/etsi"
|
|
181
|
+
autoload :Evs, "pubid/evs"
|
|
182
|
+
autoload :Gost, "pubid/gost"
|
|
183
|
+
autoload :Gb, "pubid/gb"
|
|
115
184
|
autoload :Idf, "pubid/idf"
|
|
116
185
|
autoload :Iec, "pubid/iec"
|
|
117
186
|
autoload :Ieee, "pubid/ieee"
|
|
187
|
+
autoload :Ietf, "pubid/ietf"
|
|
188
|
+
autoload :Isbn, "pubid/isbn"
|
|
118
189
|
autoload :Iala, "pubid/iala"
|
|
190
|
+
autoload :Iana, "pubid/iana"
|
|
119
191
|
autoload :Iho, "pubid/iho"
|
|
120
192
|
autoload :Iso, "pubid/iso"
|
|
121
193
|
autoload :Itu, "pubid/itu"
|
|
122
194
|
autoload :Jcgm, "pubid/jcgm"
|
|
123
195
|
autoload :Jis, "pubid/jis"
|
|
124
196
|
autoload :Nist, "pubid/nist"
|
|
197
|
+
autoload :Oasis, "pubid/oasis"
|
|
198
|
+
autoload :Ogc, "pubid/ogc"
|
|
125
199
|
autoload :Oiml, "pubid/oiml"
|
|
200
|
+
autoload :Omg, "pubid/omg"
|
|
126
201
|
autoload :Plateau, "pubid/plateau"
|
|
127
202
|
autoload :Export, "pubid/export"
|
|
128
203
|
autoload :Sae, "pubid/sae"
|
|
204
|
+
autoload :Tgpp, "pubid/tgpp"
|
|
205
|
+
autoload :Un, "pubid/un"
|
|
206
|
+
autoload :Xsf, "pubid/xsf"
|
|
207
|
+
autoload :W3c, "pubid/w3c"
|
|
129
208
|
|
|
130
209
|
# Format infrastructure (loaded eagerly so Pubid::Renderers / Pubid::Parsers are always available)
|
|
131
210
|
require "pubid/renderers/base"
|
|
@@ -142,17 +221,47 @@ module Pubid
|
|
|
142
221
|
|
|
143
222
|
# Unified parse entry point with auto-detection
|
|
144
223
|
#
|
|
224
|
+
# A human-readable string is routed to its owning flavor by leading prefix
|
|
225
|
+
# token, using the {prefix_flavors} table. This restores the pubid 1.x
|
|
226
|
+
# +Pubid::Registry.parse+ capability, which isodoc still calls; before it,
|
|
227
|
+
# this method raised +No flavor specified+ for every human-readable string,
|
|
228
|
+
# so a reference whose flavor the caller did not already know could not be
|
|
229
|
+
# parsed at all.
|
|
230
|
+
#
|
|
145
231
|
# @param string [String] The identifier string to parse
|
|
146
232
|
# @param format [Symbol] :auto, :human, :mr_string, or :urn
|
|
147
233
|
# @return [Identifier] The parsed identifier
|
|
234
|
+
# @raise [ArgumentError] for a non-String, or one over {MAX_INPUT_LENGTH}
|
|
235
|
+
# @raise [Parslet::ParseFailed] when no flavor can parse the string — the
|
|
236
|
+
# class every flavor's own +parse+ raises (see the parse-failure contract)
|
|
148
237
|
def self.parse(string, format: :auto)
|
|
149
|
-
|
|
238
|
+
unless string.is_a?(String)
|
|
239
|
+
raise Pubid::Errors::InvalidInputError,
|
|
240
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
241
|
+
end
|
|
242
|
+
if string.length > MAX_INPUT_LENGTH
|
|
243
|
+
raise Pubid::Errors::InvalidInputError,
|
|
244
|
+
Pubid::INPUT_TOO_LONG_MESSAGE
|
|
245
|
+
end
|
|
150
246
|
|
|
151
247
|
format = FormatDetector.detect(string) if format == :auto
|
|
152
248
|
|
|
153
249
|
case format
|
|
154
250
|
when :mr_string
|
|
155
|
-
|
|
251
|
+
# The MR detector is a shape heuristic (`/\A[A-Z]{2,}[.-]/`), and some
|
|
252
|
+
# human-readable identifiers have that shape — "ITU-T G.711" is the
|
|
253
|
+
# standing example. Fall through to prefix routing when the MR parse
|
|
254
|
+
# fails, rather than reporting an MR error for a string that was never
|
|
255
|
+
# an MR string. A genuine MR failure still surfaces, from the second
|
|
256
|
+
# attempt, as Parslet::ParseFailed.
|
|
257
|
+
#
|
|
258
|
+
# Narrow, for the reason spelled out on {parse_by_prefix}: only a parse
|
|
259
|
+
# failure means "wrong shape". Anything else is a defect and propagates.
|
|
260
|
+
begin
|
|
261
|
+
Parsers::MrString.parse(string)
|
|
262
|
+
rescue Parslet::ParseFailed
|
|
263
|
+
parse_by_prefix(string)
|
|
264
|
+
end
|
|
156
265
|
when :urn
|
|
157
266
|
eager_load_flavors!
|
|
158
267
|
flavor = detect_flavor_from_urn(string)
|
|
@@ -163,29 +272,255 @@ module Pubid
|
|
|
163
272
|
end
|
|
164
273
|
|
|
165
274
|
urn_parser = flavor_module.const_get(:UrnParser)
|
|
166
|
-
urn_parser.parse(string)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
275
|
+
urn_parser.parse(string)
|
|
276
|
+
else
|
|
277
|
+
parse_by_prefix(string)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Build an identifier from its serialized hash, without naming its flavor —
|
|
282
|
+
# the hash counterpart of {parse}.
|
|
283
|
+
#
|
|
284
|
+
# The hash is what {Identifier#to_hash} emits, and what a relaton-data
|
|
285
|
+
# +index-v2.yaml+ row stores under +:id+. Its +_type+ key
|
|
286
|
+
# ("pubid:<flavor>:<type>") names the concrete class, so no prefix guessing
|
|
287
|
+
# is necessary. The class is resolved by {TypeResolver}, and the class's own
|
|
288
|
+
# +from_hash+ does the rest, nested identifiers of other flavors included.
|
|
289
|
+
#
|
|
290
|
+
# @example
|
|
291
|
+
# Pubid.from_hash("_type" => "pubid:iso:international-standard",
|
|
292
|
+
# "number" => "9001", "year" => "2015").to_s
|
|
293
|
+
# # => "ISO 9001:2015"
|
|
294
|
+
#
|
|
295
|
+
# @param data [Hash] an identifier hash. String and Symbol keys are both
|
|
296
|
+
# accepted.
|
|
297
|
+
# @return [Identifier] an instance of the class that +_type+ names
|
|
298
|
+
# @raise [Pubid::Errors::InvalidInputError] when +data+ is not a Hash, has no
|
|
299
|
+
# +_type+, or has a +_type+ that no registered flavor defines. These are
|
|
300
|
+
# the only failures it translates: once +_type+ names a class, an error
|
|
301
|
+
# from that class's own +from_hash+ (a malformed field, or a bad +_type+
|
|
302
|
+
# in a NESTED hash) propagates unchanged, so a flavor defect is not
|
|
303
|
+
# disguised as bad input.
|
|
304
|
+
def self.from_hash(data)
|
|
305
|
+
unless data.is_a?(Hash)
|
|
306
|
+
raise Pubid::Errors::InvalidInputError,
|
|
307
|
+
"identifier data must be a Hash, got #{data.class}"
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
identifier_class_for(data).from_hash(data)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# The concrete class that the +_type+ of +data+ names.
|
|
314
|
+
#
|
|
315
|
+
# @param data [Hash] an identifier hash
|
|
316
|
+
# @return [Class<Identifier>]
|
|
317
|
+
# @raise [Pubid::Errors::InvalidInputError] no +_type+, or an unknown one
|
|
318
|
+
# @api private
|
|
319
|
+
def self.identifier_class_for(data)
|
|
320
|
+
type = data["_type"] || data[:_type]
|
|
321
|
+
unless type
|
|
322
|
+
raise Pubid::Errors::InvalidInputError,
|
|
323
|
+
"identifier hash has no _type key: #{data.inspect[0, 200]}"
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
TypeResolver.resolve(type) ||
|
|
327
|
+
raise(Pubid::Errors::InvalidInputError,
|
|
328
|
+
"unknown identifier _type: #{type.inspect}")
|
|
329
|
+
end
|
|
330
|
+
private_class_method :identifier_class_for
|
|
331
|
+
|
|
332
|
+
# Route a human-readable identifier to its flavor by leading prefix token.
|
|
333
|
+
#
|
|
334
|
+
# Three passes, widening each time — the pubid 1.x +Registry.parse+ shape:
|
|
335
|
+
#
|
|
336
|
+
# 1. flavors owning the longest matching prefix ("ISO/IEC" before "ISO")
|
|
337
|
+
# 2. every other flavor, in registry order
|
|
338
|
+
#
|
|
339
|
+
# A longest-match-first order matters because prefixes nest: "ISO/IEC 2131"
|
|
340
|
+
# must not be handed to the flavor that merely owns "ISO".
|
|
341
|
+
#
|
|
342
|
+
# @param string [String] a human-readable identifier
|
|
343
|
+
# @return [Identifier]
|
|
344
|
+
# @raise [Parslet::ParseFailed] when no flavor accepts the string
|
|
345
|
+
# @api private
|
|
346
|
+
def self.parse_by_prefix(string)
|
|
347
|
+
eager_load_flavors!
|
|
348
|
+
|
|
349
|
+
first_error = nil
|
|
350
|
+
fallback = nil
|
|
351
|
+
|
|
352
|
+
prefix_owners = candidates_by_prefix(string)
|
|
353
|
+
(prefix_owners + other_candidates(prefix_owners)).each do |mod|
|
|
354
|
+
begin
|
|
355
|
+
parsed = mod.parse(string)
|
|
356
|
+
rescue Parslet::ParseFailed => e
|
|
357
|
+
# ONLY a parse failure means "not this flavor's identifier". Every
|
|
358
|
+
# other exception is a defect in that flavor and must propagate.
|
|
359
|
+
#
|
|
360
|
+
# A blanket `rescue StandardError` here would swallow exactly the
|
|
361
|
+
# `ArgumentError: unknown attribute…` that the constructor contract on
|
|
362
|
+
# `Identifier` now raises — the error that turned three silent
|
|
363
|
+
# data-loss bugs (CIE `s_prefix`, IEEE `adopted_identifier`,
|
|
364
|
+
# IEEE `csa_identifier`) into visible ones. Catching it one layer up
|
|
365
|
+
# would hand it straight back its disguise: a real builder bug in any
|
|
366
|
+
# flavor would read as "this string is not an identifier".
|
|
367
|
+
first_error ||= e
|
|
368
|
+
next
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# An exact round trip is the strongest evidence the string belongs to
|
|
372
|
+
# this flavor. It matters because some grammars accept anything by
|
|
373
|
+
# design — adobe and iana take any slug — so without it the first such
|
|
374
|
+
# flavor in registry order claims every unclaimed string and invents
|
|
375
|
+
# structure that was not in the input. Same test isodoc applies before
|
|
376
|
+
# it will annotate a parsed id.
|
|
377
|
+
return parsed if parsed.to_s == string
|
|
378
|
+
|
|
379
|
+
# A non-exact parse is still usable — several flavors legitimately
|
|
380
|
+
# normalise on render, so the round trip is a preference, not a
|
|
381
|
+
# requirement (OGC prints `06-121r9` for `OGC 06-121r9`, and 32 ASHRAE /
|
|
382
|
+
# ASME / CSA / IEEE identifiers route only this way). What it must NOT
|
|
383
|
+
# come from is a flavor that accepts anything: that is how `iec.60050`
|
|
384
|
+
# came back as `IANA iec.60050`. Reporting that no flavor could be
|
|
385
|
+
# determined beats inventing one.
|
|
386
|
+
fallback ||= parsed unless accepts_anything?(mod)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
return fallback if fallback
|
|
390
|
+
raise first_error if first_error
|
|
391
|
+
|
|
392
|
+
raise Parslet::ParseFailed,
|
|
393
|
+
"no registered flavor could parse #{string.inspect}"
|
|
394
|
+
end
|
|
395
|
+
private_class_method :parse_by_prefix
|
|
396
|
+
|
|
397
|
+
# Flavor modules that own a prefix +string+ starts with, longest prefix
|
|
398
|
+
# first. Deduplicated by module identity, so an alias registration is not
|
|
399
|
+
# tried twice.
|
|
400
|
+
#
|
|
401
|
+
# These are the flavors with an actual claim on the string; a parse from one
|
|
402
|
+
# of them is trusted even when the flavor normalises on render.
|
|
403
|
+
#
|
|
404
|
+
# @param string [String] a human-readable identifier
|
|
405
|
+
# @return [Array<Module>]
|
|
406
|
+
# @api private
|
|
407
|
+
def self.candidates_by_prefix(string)
|
|
408
|
+
ordered = []
|
|
409
|
+
routing_table.each do |prefix, modules|
|
|
410
|
+
ordered.concat(modules) if prefix_match?(string, prefix)
|
|
171
411
|
end
|
|
412
|
+
ordered.compact.uniq
|
|
172
413
|
end
|
|
414
|
+
private_class_method :candidates_by_prefix
|
|
415
|
+
|
|
416
|
+
# Every other registered flavor, for the exhaustive second pass.
|
|
417
|
+
#
|
|
418
|
+
# @param exclude [Array<Module>] modules already tried
|
|
419
|
+
# @return [Array<Module>]
|
|
420
|
+
# @api private
|
|
421
|
+
def self.other_candidates(exclude)
|
|
422
|
+
ordered = []
|
|
423
|
+
each_prefix_flavor_module { |mod| ordered << mod }
|
|
424
|
+
ordered.compact.uniq - exclude
|
|
425
|
+
end
|
|
426
|
+
private_class_method :other_candidates
|
|
427
|
+
|
|
428
|
+
# A meaningless string no real identifier scheme should claim. Used to find
|
|
429
|
+
# the flavors whose grammar accepts anything.
|
|
430
|
+
ROUTING_PROBE = "zzqx-nonsense-9714"
|
|
431
|
+
private_constant :ROUTING_PROBE
|
|
432
|
+
|
|
433
|
+
# True when +mod+'s grammar accepts an arbitrary slug.
|
|
434
|
+
#
|
|
435
|
+
# `adobe` and `iana` do, by design — their identifiers genuinely are free
|
|
436
|
+
# text. That makes them unsafe as a fallback: whichever came first in
|
|
437
|
+
# registry order would claim every string no other flavor matched, and
|
|
438
|
+
# answer with structure the input never had.
|
|
439
|
+
#
|
|
440
|
+
# Detected by probing rather than by a hardcoded list, so a flavor that
|
|
441
|
+
# acquires (or loses) an anything-goes grammar is classified correctly
|
|
442
|
+
# without anyone remembering to edit a constant. Computed once per module.
|
|
443
|
+
#
|
|
444
|
+
# @param mod [Module] a flavor module
|
|
445
|
+
# @return [Boolean]
|
|
446
|
+
# @api private
|
|
447
|
+
def self.accepts_anything?(mod)
|
|
448
|
+
@accepts_anything ||= {}
|
|
449
|
+
return @accepts_anything[mod] if @accepts_anything.key?(mod)
|
|
450
|
+
|
|
451
|
+
@accepts_anything[mod] =
|
|
452
|
+
begin
|
|
453
|
+
mod.parse(ROUTING_PROBE)
|
|
454
|
+
true
|
|
455
|
+
rescue StandardError, Parslet::ParseFailed
|
|
456
|
+
false
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
private_class_method :accepts_anything?
|
|
460
|
+
|
|
461
|
+
# Prefix => flavor modules, longest prefix first, built once.
|
|
462
|
+
#
|
|
463
|
+
# {prefix_flavors} rebuilds its index on every call, iterating every
|
|
464
|
+
# registered flavor; routing consulted it twice per parse. The registry is
|
|
465
|
+
# static once +eager_load_flavors!+ has run, so the table is memoised here
|
|
466
|
+
# rather than making the public method's cost implicit.
|
|
467
|
+
#
|
|
468
|
+
# The memo is never invalidated, which is safe for every flavor shipped in
|
|
469
|
+
# this gem — they are all +Pubid+-namespace constants that
|
|
470
|
+
# +eager_load_flavors!+ loads before the first parse. A flavor registered
|
|
471
|
+
# from OUTSIDE that namespace after the first {parse} call would miss its
|
|
472
|
+
# prefix priority (it is still tried in the exhaustive second pass, so it is
|
|
473
|
+
# reachable, just not preferred). Bust the memo in +Registry.register+ if
|
|
474
|
+
# out-of-namespace flavors ever become a supported extension point.
|
|
475
|
+
#
|
|
476
|
+
# @return [Hash{String => Array<Module>}]
|
|
477
|
+
# @api private
|
|
478
|
+
def self.routing_table
|
|
479
|
+
@routing_table ||= begin
|
|
480
|
+
index = prefix_flavors
|
|
481
|
+
index.keys
|
|
482
|
+
.sort_by { |prefix| -prefix.length }
|
|
483
|
+
.to_h { |prefix| [prefix, index[prefix].map { |key| Registry.get(key) }] }
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
private_class_method :routing_table
|
|
487
|
+
|
|
488
|
+
# True when +string+ starts with +prefix+ at a token boundary, so "ISO" does
|
|
489
|
+
# not claim "ISOFIX" and "BS" does not claim "BSI".
|
|
490
|
+
# @api private
|
|
491
|
+
def self.prefix_match?(string, prefix)
|
|
492
|
+
return false unless string.start_with?(prefix)
|
|
493
|
+
|
|
494
|
+
rest = string[prefix.length]
|
|
495
|
+
rest.nil? || !/[A-Za-z0-9]/.match?(rest)
|
|
496
|
+
end
|
|
497
|
+
private_class_method :prefix_match?
|
|
173
498
|
|
|
174
499
|
def self.detect_flavor_from_urn(urn)
|
|
175
500
|
# urn:iso:std:... → "iso"
|
|
176
501
|
# urn:iec:std:... → "iec"
|
|
502
|
+
# urn:mrn:iala:pub:... → "iala": MRN URNs carry an assigning authority
|
|
503
|
+
# where ISO-style URNs carry their namespace, so routing follows the
|
|
504
|
+
# authority (works for any future MRN assignee, not only IALA).
|
|
177
505
|
parts = urn.downcase.split(":")
|
|
506
|
+
return parts[2] if parts[1] == "mrn"
|
|
507
|
+
|
|
178
508
|
parts[1] # The namespace part after "urn"
|
|
179
509
|
end
|
|
180
510
|
|
|
181
511
|
# Trigger autoloads for every declared flavor module so that
|
|
182
512
|
# Registry is populated before URN dispatch needs it. Safe to call
|
|
183
513
|
# repeatedly; no-op after the first invocation.
|
|
514
|
+
#
|
|
515
|
+
# The constant filter allows a digit inside the name (the +0-9+ in the regex)
|
|
516
|
+
# so digit-bearing flavor modules such as +W3c+ are loaded/registered too —
|
|
517
|
+
# without it +W3c+ is silently dropped from the registry enumeration and thus
|
|
518
|
+
# from every registry-driven cross-flavor spec.
|
|
184
519
|
def self.eager_load_flavors!
|
|
185
520
|
return if @flavors_loaded
|
|
186
521
|
|
|
187
522
|
constants.each do |c|
|
|
188
|
-
next unless c.to_s.match?(/\A[A-Z][a-zA-
|
|
523
|
+
next unless c.to_s.match?(/\A[A-Z][a-zA-Z0-9]+\z/)
|
|
189
524
|
|
|
190
525
|
begin
|
|
191
526
|
const_get(c)
|
|
@@ -243,4 +578,71 @@ module Pubid
|
|
|
243
578
|
yield mod
|
|
244
579
|
end
|
|
245
580
|
end
|
|
581
|
+
|
|
582
|
+
# Typed-stage lookup by abbreviation, across flavors.
|
|
583
|
+
#
|
|
584
|
+
# Each flavor module memoises +all_typed_stages+ over its own +Identifiers+
|
|
585
|
+
# namespace, so an abbreviation only one flavor uses is invisible from any
|
|
586
|
+
# other: +Pubid::Iso.locate_stage("ADTS")+ is nil while
|
|
587
|
+
# +Pubid::Iec.locate_stage("ADTS")+ finds it. A consumer that holds an
|
|
588
|
+
# abbreviation but not the owning flavor had nowhere to ask.
|
|
589
|
+
#
|
|
590
|
+
# @param abbr [String, Symbol] the stage abbreviation (case-insensitive)
|
|
591
|
+
# @param flavor [Symbol, String, nil] search this flavor only; nil searches
|
|
592
|
+
# every registered flavor and returns the first match
|
|
593
|
+
# @return [Object, nil] the flavor's typed-stage object, or nil. The class is
|
|
594
|
+
# flavor-specific: most return {Pubid::Components::TypedStage}, but IEEE
|
|
595
|
+
# has its own +Ieee::Components::TypedStage+, which is not a subclass.
|
|
596
|
+
# @raise [ArgumentError] if +flavor+ names a flavor that is not registered
|
|
597
|
+
def self.locate_stage(abbr, flavor: nil)
|
|
598
|
+
return locate_stage_in(Registry.get(flavor), abbr, flavor) if flavor
|
|
599
|
+
|
|
600
|
+
each_stage_flavor_module do |mod|
|
|
601
|
+
stage = mod.locate_stage(abbr)
|
|
602
|
+
return stage if stage
|
|
603
|
+
end
|
|
604
|
+
nil
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# Every flavor that knows +abbr+ — the diagnostic companion to
|
|
608
|
+
# {locate_stage}, for telling a consumer which module owns a stage.
|
|
609
|
+
#
|
|
610
|
+
# @param abbr [String, Symbol] the stage abbreviation (case-insensitive)
|
|
611
|
+
# @return [Array<Symbol>] registered flavor keys, sorted
|
|
612
|
+
def self.locate_stage_flavors(abbr)
|
|
613
|
+
found = []
|
|
614
|
+
each_stage_flavor_module do |mod, flavor_name|
|
|
615
|
+
found << flavor_name.to_sym if mod.locate_stage(abbr)
|
|
616
|
+
end
|
|
617
|
+
found.sort
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
# Yields each unique flavor module that implements +locate_stage+, exactly
|
|
621
|
+
# once. Three registered flavors (adobe, easc, gost) define no typed stages
|
|
622
|
+
# at all, so a cross-flavor sweep must skip them rather than raise on the
|
|
623
|
+
# first one it reaches; alias registrations are collapsed by module identity,
|
|
624
|
+
# as in {each_prefix_flavor_module}.
|
|
625
|
+
#
|
|
626
|
+
# @yieldparam mod [Module] a flavor module
|
|
627
|
+
# @yieldparam flavor_name [String] the registry key it was reached under
|
|
628
|
+
def self.each_stage_flavor_module
|
|
629
|
+
eager_load_flavors!
|
|
630
|
+
seen = {}
|
|
631
|
+
Registry.flavor_names.each do |flavor_name|
|
|
632
|
+
mod = Registry.get(flavor_name)
|
|
633
|
+
next if seen.key?(mod) || !mod.respond_to?(:locate_stage)
|
|
634
|
+
|
|
635
|
+
seen[mod] = true
|
|
636
|
+
yield mod, flavor_name
|
|
637
|
+
end
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
# @api private
|
|
641
|
+
def self.locate_stage_in(mod, abbr, flavor)
|
|
642
|
+
raise ArgumentError, "unknown flavor: #{flavor.inspect}" unless mod
|
|
643
|
+
return nil unless mod.respond_to?(:locate_stage)
|
|
644
|
+
|
|
645
|
+
mod.locate_stage(abbr)
|
|
646
|
+
end
|
|
647
|
+
private_class_method :locate_stage_in
|
|
246
648
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
namespace :conformance do
|
|
7
|
+
desc "Generate the neutral corpus from ground-truth fixtures"
|
|
8
|
+
task :generate, [:flavor] do |_t, args|
|
|
9
|
+
require "pubid"
|
|
10
|
+
require "pubid/conformance"
|
|
11
|
+
flavor = args[:flavor] || "iso"
|
|
12
|
+
tests_repo = ENV.fetch("PUBID_TESTSUITE_PATH",
|
|
13
|
+
File.expand_path("../../../pubid-testsuite",
|
|
14
|
+
__dir__))
|
|
15
|
+
output_dir = File.join(tests_repo, "tests", flavor)
|
|
16
|
+
FileUtils.mkdir_p(output_dir)
|
|
17
|
+
results = Pubid::Conformance::Generator.new(flavor)
|
|
18
|
+
.generate(output_dir: output_dir)
|
|
19
|
+
stats = results
|
|
20
|
+
puts "#{flavor}: #{stats[:files]} files, #{stats[:cases]} cases, " \
|
|
21
|
+
"#{stats[:aliases]} aliases, #{stats[:duplicates]} duplicates, " \
|
|
22
|
+
"#{stats[:reclassify]} reclassify, #{stats[:negative]} negative, " \
|
|
23
|
+
"#{stats[:debt]} debt, #{stats[:roundtrip_failures]} rt-failures"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc "Run the neutral corpus against this implementation"
|
|
27
|
+
task :run do
|
|
28
|
+
require "pubid"
|
|
29
|
+
require "pubid/conformance"
|
|
30
|
+
failures = Pubid::Conformance::Runner.new.run.flatten
|
|
31
|
+
puts "TOTAL failures: #{failures.size}"
|
|
32
|
+
exit(failures.empty? ? 0 : 1)
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/tasks/docs.rake
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# frozen_string_literal
|
|
2
|
-
|
|
3
|
-
require_relative "../../lib/pubid/core/pattern_doc_generator"
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
5
3
|
namespace :docs do
|
|
6
4
|
desc "Generate identifier pattern reference docs"
|
|
7
5
|
task :patterns do
|
|
6
|
+
require "pubid"
|
|
7
|
+
|
|
8
8
|
output_dir = File.join(__dir__, "..", "..", "docs", "identifier-patterns")
|
|
9
9
|
FileUtils.mkdir_p(output_dir)
|
|
10
10
|
|