pubid 2.0.0.pre.alpha.9 → 2.0.0.pre.alpha.12
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/lib/pubid/adobe/identifier.rb +1 -3
- data/lib/pubid/adobe/parser.rb +10 -2
- data/lib/pubid/adobe.rb +1 -0
- data/lib/pubid/amca/builder.rb +2 -2
- data/lib/pubid/amca/identifiers/base.rb +49 -27
- data/lib/pubid/amca/identifiers/interpretation.rb +17 -9
- data/lib/pubid/amca/identifiers/publication.rb +13 -9
- data/lib/pubid/amca/identifiers/standard.rb +2 -0
- data/lib/pubid/amca/parser.rb +1 -1
- data/lib/pubid/amca/renderer.rb +4 -4
- data/lib/pubid/amca/urn_generator.rb +2 -2
- data/lib/pubid/amca.rb +2 -1
- 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 +31 -10
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +6 -0
- data/lib/pubid/ashrae/identifiers/addendum.rb +8 -0
- data/lib/pubid/ashrae/identifiers/base.rb +81 -5
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +7 -0
- 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/parser.rb +23 -8
- data/lib/pubid/ashrae/renderer.rb +6 -6
- data/lib/pubid/ashrae/supplement_identifier.rb +17 -2
- data/lib/pubid/ashrae/urn_generator.rb +8 -2
- data/lib/pubid/ashrae.rb +7 -1
- 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 +66 -10
- data/lib/pubid/bipm/identifier.rb +134 -9
- data/lib/pubid/bipm/identifiers/committee_document.rb +12 -0
- data/lib/pubid/bipm/identifiers/guide.rb +11 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +12 -0
- data/lib/pubid/bipm/identifiers/mep.rb +12 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +13 -0
- data/lib/pubid/bipm/parser.rb +65 -12
- data/lib/pubid/bipm/renderer.rb +8 -0
- data/lib/pubid/bipm/urn_parser.rb +11 -3
- data/lib/pubid/bipm.rb +7 -1
- data/lib/pubid/bsi/builder.rb +48 -38
- data/lib/pubid/bsi/components/date.rb +10 -4
- 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/british_industrial_practice.rb +1 -2
- 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/handbook.rb +1 -3
- data/lib/pubid/bsi/identifiers/practice_guide.rb +1 -2
- data/lib/pubid/bsi/identifiers/set.rb +11 -0
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
- data/lib/pubid/bsi/parser.rb +1 -1
- data/lib/pubid/bsi/renderer.rb +63 -51
- data/lib/pubid/bsi/single_identifier.rb +27 -9
- data/lib/pubid/bsi/urn_generator.rb +11 -2
- data/lib/pubid/bsi.rb +7 -1
- data/lib/pubid/builder/base.rb +18 -8
- data/lib/pubid/bundled_identifier.rb +16 -6
- data/lib/pubid/calconnect/identifier.rb +9 -5
- data/lib/pubid/calconnect/parser.rb +1 -1
- data/lib/pubid/calconnect.rb +7 -1
- data/lib/pubid/ccsds/identifier.rb +13 -2
- data/lib/pubid/ccsds/identifiers/base.rb +4 -2
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/ccsds/parser.rb +1 -1
- data/lib/pubid/ccsds/single_identifier.rb +16 -12
- data/lib/pubid/ccsds.rb +1 -0
- data/lib/pubid/cen_cenelec/builder.rb +101 -76
- 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 -20
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
- 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 +28 -10
- data/lib/pubid/cie/builder.rb +10 -0
- data/lib/pubid/cie/identifier.rb +6 -1
- data/lib/pubid/cie/identifiers/bundle.rb +4 -2
- data/lib/pubid/cie/identifiers/conference.rb +2 -2
- data/lib/pubid/cie/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/cie/identifiers/dual_published.rb +2 -2
- data/lib/pubid/cie/identifiers/identical.rb +2 -2
- data/lib/pubid/cie/identifiers/joint_published.rb +2 -2
- data/lib/pubid/cie/identifiers/proceedings.rb +8 -6
- data/lib/pubid/cie/identifiers/standard.rb +22 -13
- data/lib/pubid/cie/identifiers/supplement.rb +2 -2
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +2 -2
- data/lib/pubid/cie/parser.rb +1 -1
- data/lib/pubid/cie.rb +7 -1
- 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 +47 -47
- data/lib/pubid/csa/composite_identifier.rb +14 -19
- data/lib/pubid/csa/identifier.rb +143 -81
- data/lib/pubid/csa/identifiers/bundled.rb +23 -13
- 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 +95 -73
- data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
- data/lib/pubid/csa/identifiers/package.rb +2 -2
- data/lib/pubid/csa/parser.rb +6 -2
- 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 +39 -23
- data/lib/pubid/csa.rb +7 -1
- data/lib/pubid/doi/identifier.rb +6 -3
- data/lib/pubid/doi/parser.rb +1 -1
- data/lib/pubid/doi.rb +1 -0
- data/lib/pubid/easc/identifier.rb +0 -2
- data/lib/pubid/easc/parser.rb +10 -2
- data/lib/pubid/easc.rb +1 -0
- data/lib/pubid/ecma/builder.rb +23 -9
- data/lib/pubid/ecma/identifier.rb +81 -10
- data/lib/pubid/ecma/parser.rb +39 -4
- data/lib/pubid/ecma/renderer.rb +29 -8
- data/lib/pubid/ecma/urn_generator.rb +34 -13
- data/lib/pubid/ecma/urn_parser.rb +30 -14
- data/lib/pubid/ecma.rb +1 -0
- data/lib/pubid/errors.rb +80 -0
- data/lib/pubid/etsi/builder.rb +6 -1
- data/lib/pubid/etsi/identifiers/base.rb +34 -20
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +120 -41
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +10 -0
- data/lib/pubid/etsi/parser.rb +1 -1
- data/lib/pubid/etsi.rb +1 -0
- data/lib/pubid/evs/builder.rb +26 -0
- data/lib/pubid/evs/identifier.rb +37 -0
- data/lib/pubid/evs/identifiers/national_adoption.rb +22 -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.rb +1 -0
- data/lib/pubid/format_detector.rb +1 -0
- data/lib/pubid/gb/builder.rb +14 -9
- data/lib/pubid/gb/identifier.rb +29 -7
- data/lib/pubid/gb/parser.rb +5 -1
- data/lib/pubid/gb/renderer.rb +4 -3
- data/lib/pubid/gb.rb +2 -0
- data/lib/pubid/gost/builder.rb +46 -9
- data/lib/pubid/gost/identifier.rb +0 -2
- data/lib/pubid/gost/identifiers/foreign_reference.rb +1 -1
- data/lib/pubid/gost/parser.rb +10 -2
- data/lib/pubid/gost.rb +1 -0
- data/lib/pubid/iala/identifier.rb +9 -6
- data/lib/pubid/iala/parser.rb +10 -2
- data/lib/pubid/iala/urn_parser.rb +6 -2
- data/lib/pubid/iala.rb +1 -0
- data/lib/pubid/iana/builder.rb +3 -1
- data/lib/pubid/iana/identifier.rb +74 -6
- data/lib/pubid/iana/identifiers/registry.rb +36 -0
- data/lib/pubid/iana/parser.rb +1 -1
- data/lib/pubid/iana/renderer.rb +3 -0
- data/lib/pubid/iana/urn_generator.rb +5 -1
- data/lib/pubid/iana.rb +1 -0
- data/lib/pubid/identifier.rb +605 -13
- data/lib/pubid/identifier_metadata.rb +1 -0
- data/lib/pubid/idf/builder.rb +3 -3
- data/lib/pubid/idf/identifier.rb +25 -9
- data/lib/pubid/idf/identifiers/amendment.rb +1 -1
- data/lib/pubid/idf/identifiers/corrigendum.rb +1 -1
- data/lib/pubid/idf/identifiers/international_standard.rb +1 -1
- data/lib/pubid/idf/identifiers/reviewed_method.rb +1 -1
- data/lib/pubid/idf/parser.rb +1 -1
- data/lib/pubid/idf/renderer.rb +4 -4
- data/lib/pubid/idf/single_identifier.rb +1 -1
- data/lib/pubid/idf/urn_generator.rb +1 -1
- data/lib/pubid/idf.rb +7 -1
- data/lib/pubid/iec/builder.rb +14 -7
- data/lib/pubid/iec/components.rb +0 -1
- data/lib/pubid/iec/identifier.rb +73 -83
- data/lib/pubid/iec/identifiers/amendment.rb +6 -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/corrigendum.rb +2 -2
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +2 -4
- data/lib/pubid/iec/identifiers/guide.rb +0 -16
- data/lib/pubid/iec/identifiers/international_standard.rb +15 -2
- 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/societal_technology_trend_report.rb +0 -10
- data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
- data/lib/pubid/iec/identifiers/technical_report.rb +0 -17
- data/lib/pubid/iec/identifiers/technical_specification.rb +0 -17
- 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/white_paper.rb +0 -10
- data/lib/pubid/iec/identifiers/working_document.rb +24 -10
- data/lib/pubid/iec/parser.rb +2 -18
- data/lib/pubid/iec/renderer.rb +13 -10
- data/lib/pubid/iec/single_identifier.rb +33 -10
- data/lib/pubid/iec/urn_generator.rb +227 -61
- data/lib/pubid/iec/urn_parser.rb +42 -4
- data/lib/pubid/iec.rb +1 -0
- data/lib/pubid/ieee/aiee/identifier.rb +2 -2
- data/lib/pubid/ieee/aiee/parser.rb +1 -1
- data/lib/pubid/ieee/builder.rb +87 -3
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +32 -0
- data/lib/pubid/ieee/identifiers/base.rb +42 -5
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +21 -0
- data/lib/pubid/ieee/identifiers/dual_published.rb +55 -0
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +23 -0
- data/lib/pubid/ieee/identifiers/joint_development.rb +11 -7
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +57 -5
- data/lib/pubid/ieee/identifiers/nesc/base.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +2 -2
- data/lib/pubid/ieee/identifiers/si_standard.rb +5 -2
- data/lib/pubid/ieee/ire/identifier.rb +2 -2
- data/lib/pubid/ieee/ire/parser.rb +20 -2
- data/lib/pubid/ieee/nesc/parser.rb +1 -1
- data/lib/pubid/ieee/parser.rb +208 -33
- data/lib/pubid/ieee/project_renderer.rb +46 -0
- data/lib/pubid/ieee/renderer.rb +11 -8
- data/lib/pubid/ieee/urn_generator.rb +32 -3
- data/lib/pubid/ieee.rb +9 -1
- data/lib/pubid/ieee_debug.rb +1 -0
- data/lib/pubid/ietf/builder.rb +24 -8
- data/lib/pubid/ietf/identifiers/base.rb +25 -28
- data/lib/pubid/ietf/identifiers/bcp.rb +11 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +11 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +18 -2
- data/lib/pubid/ietf/identifiers/rfc.rb +2 -0
- data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
- data/lib/pubid/ietf/identifiers/std.rb +11 -0
- data/lib/pubid/ietf/identifiers.rb +1 -0
- data/lib/pubid/ietf/parser.rb +27 -9
- data/lib/pubid/ietf/renderer.rb +44 -6
- data/lib/pubid/ietf/urn_generator.rb +20 -6
- data/lib/pubid/ietf/urn_parser.rb +10 -2
- data/lib/pubid/ietf.rb +12 -2
- data/lib/pubid/iho/identifiers/base.rb +10 -3
- data/lib/pubid/iho/parser.rb +1 -1
- data/lib/pubid/iho.rb +1 -0
- data/lib/pubid/isbn/identifier.rb +25 -7
- data/lib/pubid/isbn/parser.rb +1 -1
- data/lib/pubid/isbn.rb +1 -0
- data/lib/pubid/iso/builder.rb +10 -11
- data/lib/pubid/iso/bundled_identifier.rb +5 -3
- data/lib/pubid/iso/combined_identifier.rb +5 -3
- data/lib/pubid/iso/components.rb +0 -1
- data/lib/pubid/iso/identifier.rb +23 -11
- data/lib/pubid/iso/identifiers/directives.rb +7 -4
- data/lib/pubid/iso/identifiers/directives_supplement.rb +4 -4
- data/lib/pubid/iso/identifiers/tc_document.rb +31 -46
- data/lib/pubid/iso/normalizer.rb +1 -1
- data/lib/pubid/iso/parser.rb +1 -1
- data/lib/pubid/iso/urn_generator.rb +10 -10
- data/lib/pubid/iso.rb +12 -5
- data/lib/pubid/itu/builder.rb +10 -0
- data/lib/pubid/itu/identifiers/addendum.rb +2 -2
- data/lib/pubid/itu/identifiers/amendment.rb +2 -2
- data/lib/pubid/itu/identifiers/base.rb +29 -5
- data/lib/pubid/itu/identifiers/contribution.rb +31 -0
- data/lib/pubid/itu/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/itu/identifiers/errata.rb +2 -2
- data/lib/pubid/itu/identifiers/supplement.rb +2 -2
- data/lib/pubid/itu/identifiers.rb +1 -0
- data/lib/pubid/itu/parser.rb +20 -3
- data/lib/pubid/itu.rb +1 -0
- data/lib/pubid/jcgm/builder.rb +1 -1
- data/lib/pubid/jcgm/identifier.rb +10 -0
- data/lib/pubid/jcgm/identifiers/meeting.rb +1 -1
- data/lib/pubid/jcgm/parser.rb +10 -3
- data/lib/pubid/jcgm/renderer.rb +10 -3
- data/lib/pubid/jcgm/single_identifier.rb +24 -15
- data/lib/pubid/jcgm/urn_generator.rb +1 -1
- data/lib/pubid/jcgm/urn_parser.rb +156 -14
- data/lib/pubid/jcgm.rb +10 -0
- data/lib/pubid/jis/identifier.rb +10 -3
- data/lib/pubid/jis/parser.rb +1 -1
- data/lib/pubid/jis.rb +1 -0
- data/lib/pubid/nist/builder.rb +12 -12
- data/lib/pubid/nist/components/stage.rb +2 -2
- data/lib/pubid/nist/configuration.rb +6 -8
- data/lib/pubid/nist/identifiers/base.rb +22 -5
- data/lib/pubid/nist/identifiers/circular.rb +9 -2
- data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +7 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +12 -7
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +2 -2
- data/lib/pubid/nist/identifiers/handbook.rb +9 -2
- data/lib/pubid/nist/identifiers/internal_report.rb +12 -5
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +16 -8
- data/lib/pubid/nist/identifiers/monograph.rb +14 -7
- data/lib/pubid/nist/identifiers/report.rb +14 -6
- data/lib/pubid/nist/parser.rb +1 -1
- data/lib/pubid/nist/series/ir.rb +3 -7
- data/lib/pubid/nist/supplement_identifier.rb +16 -1
- data/lib/pubid/nist.rb +7 -1
- data/lib/pubid/oasis/builder.rb +12 -10
- data/lib/pubid/oasis/identifier.rb +89 -11
- data/lib/pubid/oasis/parser.rb +1 -1
- data/lib/pubid/oasis.rb +7 -1
- data/lib/pubid/ogc/identifier.rb +9 -5
- data/lib/pubid/ogc/parser.rb +1 -1
- data/lib/pubid/ogc.rb +1 -0
- data/lib/pubid/oiml/builder.rb +7 -3
- data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +40 -10
- 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 +8 -3
- data/lib/pubid/oiml/renderer.rb +3 -3
- data/lib/pubid/oiml/single_identifier.rb +26 -42
- data/lib/pubid/oiml/supplement_identifier.rb +27 -0
- data/lib/pubid/oiml/urn_generator.rb +4 -4
- data/lib/pubid/oiml.rb +7 -1
- data/lib/pubid/omg/builder.rb +1 -0
- data/lib/pubid/omg/identifier.rb +20 -3
- data/lib/pubid/omg/parser.rb +64 -11
- data/lib/pubid/omg/renderer.rb +13 -1
- data/lib/pubid/omg.rb +2 -1
- data/lib/pubid/parser/grammar.rb +74 -0
- data/lib/pubid/parser.rb +2 -0
- data/lib/pubid/parsers/mr_string.rb +19 -0
- data/lib/pubid/plateau/parser.rb +1 -1
- data/lib/pubid/plateau.rb +10 -0
- 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 +6 -4
- data/lib/pubid/renderers/human_readable.rb +3 -3
- data/lib/pubid/renderers/mr_string.rb +15 -9
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/rendering/numbering.rb +25 -7
- data/lib/pubid/rendering.rb +1 -0
- data/lib/pubid/sae/builder.rb +1 -1
- data/lib/pubid/sae/identifiers/base.rb +13 -3
- data/lib/pubid/sae/parser.rb +1 -1
- data/lib/pubid/sae/urn_generator.rb +1 -1
- data/lib/pubid/sae.rb +1 -0
- 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 +1 -1
- data/lib/pubid/tgpp/identifier.rb +21 -5
- data/lib/pubid/tgpp/identifiers/technical_report.rb +2 -2
- data/lib/pubid/tgpp/identifiers/technical_specification.rb +2 -2
- data/lib/pubid/tgpp/parser.rb +22 -6
- data/lib/pubid/tgpp/renderer.rb +21 -5
- data/lib/pubid/tgpp/urn_generator.rb +27 -8
- data/lib/pubid/tgpp/urn_parser.rb +8 -6
- data/lib/pubid/tgpp.rb +7 -1
- data/lib/pubid/type_resolver.rb +16 -1
- data/lib/pubid/un/identifier.rb +6 -3
- data/lib/pubid/un/parser.rb +1 -1
- data/lib/pubid/un.rb +1 -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 +5 -5
- data/lib/pubid/w3c/identifier.rb +38 -9
- data/lib/pubid/w3c/parser.rb +1 -1
- data/lib/pubid/w3c/renderer.rb +1 -1
- data/lib/pubid/w3c/urn_generator.rb +2 -2
- data/lib/pubid/w3c.rb +1 -0
- data/lib/pubid/xsf/identifier.rb +9 -5
- data/lib/pubid/xsf/parser.rb +17 -4
- data/lib/pubid/xsf.rb +7 -1
- data/lib/pubid.rb +399 -21
- data/lib/tasks/conformance.rake +34 -0
- data/lib/tasks/docs.rake +16 -14
- 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 +40 -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/series.yaml +0 -121
- data/archived-gems/pubid-nist/update_codes.yaml +0 -93
- data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
- data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +0 -70
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
- data/lib/pubid/iec/components/code.rb +0 -36
- data/lib/pubid/iso/components/code.rb +0 -24
- /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
|
@@ -6,8 +6,8 @@ module Pubid
|
|
|
6
6
|
# Errata identifier (Err.)
|
|
7
7
|
# Pattern: "ITU-T G.9701 (2014) Err. 1 (07/2016)"
|
|
8
8
|
class Errata < Supplement
|
|
9
|
-
def to_s
|
|
10
|
-
render_supplement("Err.")
|
|
9
|
+
def to_s(**opts)
|
|
10
|
+
annotate_plain_render(render_supplement("Err."), **opts)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -11,6 +11,7 @@ module Pubid
|
|
|
11
11
|
autoload :AppendixOfRecommendation,
|
|
12
12
|
"#{__dir__}/identifiers/appendix_of_recommendation"
|
|
13
13
|
autoload :CombinedIdentifier, "#{__dir__}/identifiers/combined_identifier"
|
|
14
|
+
autoload :Contribution, "#{__dir__}/identifiers/contribution"
|
|
14
15
|
autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
|
|
15
16
|
autoload :Errata, "#{__dir__}/identifiers/errata"
|
|
16
17
|
autoload :Handbook, "#{__dir__}/identifiers/handbook"
|
data/lib/pubid/itu/parser.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "parslet"
|
|
|
4
4
|
|
|
5
5
|
module Pubid
|
|
6
6
|
module Itu
|
|
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) }
|
|
@@ -323,6 +323,22 @@ module Pubid
|
|
|
323
323
|
(digits | letter.repeat(1)).as(:number) >> parts
|
|
324
324
|
end
|
|
325
325
|
|
|
326
|
+
# ITU Contribution (Temporary Document) — "ITU-R SG17-C1000" (pubid#340).
|
|
327
|
+
# The "-C" marker before the number distinguishes it from every
|
|
328
|
+
# neighbouring shape: a series-code document's post-dash number starts
|
|
329
|
+
# with digits or is all letters (never "C"+digits), and with_series
|
|
330
|
+
# requires a dot after the series.
|
|
331
|
+
rule(:contribution) do
|
|
332
|
+
itu_prefix >>
|
|
333
|
+
sector >>
|
|
334
|
+
space >>
|
|
335
|
+
series >>
|
|
336
|
+
str("-C").as(:contribution_marker) >>
|
|
337
|
+
number >>
|
|
338
|
+
parts >>
|
|
339
|
+
language.maybe
|
|
340
|
+
end
|
|
341
|
+
|
|
326
342
|
rule(:base_series_code) do
|
|
327
343
|
itu_prefix >>
|
|
328
344
|
sector >>
|
|
@@ -656,9 +672,10 @@ module Pubid
|
|
|
656
672
|
numeric_question |
|
|
657
673
|
letter_question |
|
|
658
674
|
with_series |
|
|
675
|
+
contribution |
|
|
659
676
|
# Unreachable earlier: special_publication needs the literal "OB",
|
|
660
|
-
# handbook/numeric_question need leading digits,
|
|
661
|
-
# needs series >> dot
|
|
677
|
+
# handbook/numeric_question need leading digits, letter_question
|
|
678
|
+
# needs series >> dot, and contribution needs "-C" after the series.
|
|
662
679
|
series_code_identifier |
|
|
663
680
|
without_series
|
|
664
681
|
end
|
data/lib/pubid/itu.rb
CHANGED
data/lib/pubid/jcgm/builder.rb
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Jcgm
|
|
5
5
|
class Identifier < ::Pubid::Identifier
|
|
6
|
+
# `number`/`part`/`subpart` are declared here rather than inherited as a
|
|
7
|
+
# Components::Code: JCGM stores a bare string in `number` and uses neither
|
|
8
|
+
# of the other two. Declaring on this class is safe because its body lives
|
|
9
|
+
# in this one file and is never reopened, so every subclass body opens
|
|
10
|
+
# after it has run (lutaml deep-dups the parent attribute table at
|
|
11
|
+
# class-definition time).
|
|
12
|
+
attribute :number, :string
|
|
13
|
+
attribute :part, :string
|
|
14
|
+
attribute :subpart, :string
|
|
15
|
+
|
|
6
16
|
def self.parse(string)
|
|
7
17
|
Pubid::Jcgm.parse(string)
|
|
8
18
|
end
|
data/lib/pubid/jcgm/parser.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "parslet"
|
|
|
4
4
|
|
|
5
5
|
module Pubid
|
|
6
6
|
module Jcgm
|
|
7
|
-
class Parser <
|
|
7
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
8
8
|
include ::Pubid::Parser::CommonParseRules
|
|
9
9
|
include ::Pubid::Parser::CommonParseMethods
|
|
10
10
|
|
|
@@ -53,10 +53,17 @@ module Pubid
|
|
|
53
53
|
# wants the ordinal suffix), so ordered choice is unambiguous. Emits the
|
|
54
54
|
# same tokens as a guide plus type_with_stage "Meeting", so the generic
|
|
55
55
|
# builder path resolves it to Identifiers::Meeting (like "Amd").
|
|
56
|
+
#
|
|
57
|
+
# The trailing " (YYYY)" group is optional, so the partial reference
|
|
58
|
+
# "JCGM 11st Meeting" parses with `date` left nil. JCGM numbers its
|
|
59
|
+
# meetings in one sequence, so the ordinal alone names the event and the
|
|
60
|
+
# year is redundant detail. The whole group is `.maybe` (not the year
|
|
61
|
+
# inside it), so a dangling "(" or a truncated year still fails —
|
|
62
|
+
# the same shape as `date_portion.maybe` in `rule(:base)`.
|
|
56
63
|
rule(:meeting_identifier) do
|
|
57
64
|
publisher >> space >> digits.as(:number) >> ordinal_suffix >>
|
|
58
|
-
space >> str("Meeting").as(:type_with_stage) >>
|
|
59
|
-
str("(") >> year_digits.as(:date) >> str(")")
|
|
65
|
+
space >> str("Meeting").as(:type_with_stage) >>
|
|
66
|
+
(space >> str("(") >> year_digits.as(:date) >> str(")")).maybe
|
|
60
67
|
end
|
|
61
68
|
|
|
62
69
|
rule(:ordinal_suffix) do
|
data/lib/pubid/jcgm/renderer.rb
CHANGED
|
@@ -37,8 +37,15 @@ module Pubid
|
|
|
37
37
|
id.date ? ":#{id.date}" : ""
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
# Two surface forms:
|
|
41
|
+
# "JCGM 17th Meeting (2012)" — date present (published records)
|
|
42
|
+
# "JCGM 17th Meeting" — date absent (partial reference)
|
|
43
|
+
# The ordinal alone names the meeting, so the dateless form is a valid
|
|
44
|
+
# identifier and must stay re-parseable (the parser makes the " (YYYY)"
|
|
45
|
+
# group optional to match).
|
|
40
46
|
def render_meeting(id)
|
|
41
|
-
"JCGM #{id.ordinal} Meeting
|
|
47
|
+
base = "JCGM #{id.ordinal} Meeting"
|
|
48
|
+
id.date ? "#{base} (#{id.date.year})" : base
|
|
42
49
|
end
|
|
43
50
|
|
|
44
51
|
def render_single(id)
|
|
@@ -52,7 +59,7 @@ module Pubid
|
|
|
52
59
|
def render_amendment(id, context)
|
|
53
60
|
result = id.base.to_s if id.base
|
|
54
61
|
result += "/Amd"
|
|
55
|
-
result += " #{id.number
|
|
62
|
+
result += " #{id.number}" if id.number
|
|
56
63
|
result += ":#{id.date}" if id.date
|
|
57
64
|
result
|
|
58
65
|
end
|
|
@@ -60,7 +67,7 @@ module Pubid
|
|
|
60
67
|
def render_gum_guide(id, context)
|
|
61
68
|
parts = []
|
|
62
69
|
parts << id.publisher.publisher if id.publisher
|
|
63
|
-
parts << "GUM-#{id.number
|
|
70
|
+
parts << "GUM-#{id.number}" if id.number
|
|
64
71
|
|
|
65
72
|
result = parts.join(" ")
|
|
66
73
|
result += ":#{id.date}" if id.date
|
|
@@ -7,7 +7,6 @@ module Pubid
|
|
|
7
7
|
default: -> { self.class.default_publisher }
|
|
8
8
|
attribute :typed_stage, Pubid::Components::TypedStage,
|
|
9
9
|
default: -> { self.class.published_typed_stage }
|
|
10
|
-
attribute :number, Pubid::Components::Code
|
|
11
10
|
attribute :date, Pubid::Components::Date
|
|
12
11
|
attribute :languages, Pubid::Components::Language, collection: true
|
|
13
12
|
attribute :stage, Pubid::Components::Stage
|
|
@@ -18,7 +17,7 @@ module Pubid
|
|
|
18
17
|
# (fully determined by the class, i.e. `_type`) are intentionally NOT
|
|
19
18
|
# mapped — they are reconstructed from the class on load via the
|
|
20
19
|
# attribute defaults above. Components collapse to bare scalars:
|
|
21
|
-
# number
|
|
20
|
+
# number is already a bare :string; date -> year/month/day scalars.
|
|
22
21
|
# Mirrors ISO (lib/pubid/iso/identifier.rb) and OIML.
|
|
23
22
|
key_value do
|
|
24
23
|
map "_type", to: :_type
|
|
@@ -37,15 +36,29 @@ module Pubid
|
|
|
37
36
|
# The class's published typed_stage (canonical surface form). Each JCGM
|
|
38
37
|
# class registers exactly one, all :published; `_type` fixes the class,
|
|
39
38
|
# so an omitted typed_stage reconstructs deterministically on from_hash.
|
|
39
|
+
#
|
|
40
|
+
# `original_abbr` is deliberately LEFT NIL. It records the spelling the
|
|
41
|
+
# input used and is not serialized, so it cannot survive a round trip —
|
|
42
|
+
# and this method is one of the two paths that fill `typed_stage`. The
|
|
43
|
+
# other is the parse path (`Builder#locate_typed_stage` ->
|
|
44
|
+
# `Jcgm.locate_stage`), which returns the registry entry untouched.
|
|
45
|
+
# Setting it here made the two disagree, so `from_hash(to_hash) != parse`
|
|
46
|
+
# for every type the grammar tags (Meeting, Corrigendum, Amendment) —
|
|
47
|
+
# and because `#matches?` is `exclude(...) == other.exclude(...)`, a
|
|
48
|
+
# relaton index lookup then silently matched nothing. Nothing in JCGM
|
|
49
|
+
# reads the field: the renderer hardcodes its surface words, the URN
|
|
50
|
+
# generator reads only `type_code`, and `TypedStage#abbreviation` chooses
|
|
51
|
+
# among long_abbr/short_abbr/abbr.first. Recording the *matched* token
|
|
52
|
+
# instead would not work either — "/Cor 1" would store "Cor" where
|
|
53
|
+
# from_hash rebuilds "Corrigendum".
|
|
40
54
|
def self.published_typed_stage
|
|
41
55
|
return nil unless const_defined?(:TYPED_STAGES)
|
|
42
56
|
|
|
43
57
|
ts = self::TYPED_STAGES.find { |t| t.stage_code.to_s == "published" }
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
ts
|
|
48
|
-
ts
|
|
58
|
+
# dup: locate_stage hands out the shared object from the frozen
|
|
59
|
+
# TYPED_STAGES array (the array is frozen, its elements are not), so a
|
|
60
|
+
# future in-place mutation would otherwise leak globally.
|
|
61
|
+
ts&.dup
|
|
49
62
|
end
|
|
50
63
|
|
|
51
64
|
# type and stage are derived from typed_stage, never stored — so the
|
|
@@ -58,13 +71,9 @@ module Pubid
|
|
|
58
71
|
typed_stage&.to_stage
|
|
59
72
|
end
|
|
60
73
|
|
|
61
|
-
# --- number
|
|
62
|
-
def number_to_kv(model, doc) = emit_kv(doc, "number", model.number
|
|
63
|
-
def number_from_kv(model, value) = model.number =
|
|
64
|
-
|
|
65
|
-
def build_code(value)
|
|
66
|
-
Pubid::Components::Code.new(value: value.to_s)
|
|
67
|
-
end
|
|
74
|
+
# --- number ---
|
|
75
|
+
def number_to_kv(model, doc) = emit_kv(doc, "number", model.number)
|
|
76
|
+
def number_from_kv(model, value) = model.number = value.to_s
|
|
68
77
|
|
|
69
78
|
# --- date flattened to top-level year/month/day scalars ---
|
|
70
79
|
def year_to_kv(model, doc) = emit_kv(doc, "year", model.date&.year)
|
|
@@ -90,7 +99,7 @@ module Pubid
|
|
|
90
99
|
|
|
91
100
|
def number_portion
|
|
92
101
|
parts = []
|
|
93
|
-
parts << number
|
|
102
|
+
parts << number if number
|
|
94
103
|
parts << ":#{date.year}" if date
|
|
95
104
|
parts.join
|
|
96
105
|
end
|
|
@@ -18,7 +18,7 @@ module Pubid
|
|
|
18
18
|
# urn:jcgm:meeting:<number>:<year>, e.g. urn:jcgm:meeting:17:2012
|
|
19
19
|
def generate_meeting_urn
|
|
20
20
|
parts = ["urn", "jcgm", "meeting"]
|
|
21
|
-
parts << identifier.number
|
|
21
|
+
parts << identifier.number if identifier.number
|
|
22
22
|
parts << identifier.date.year if identifier.date
|
|
23
23
|
parts.join(":")
|
|
24
24
|
end
|
|
@@ -4,31 +4,173 @@ module Pubid
|
|
|
4
4
|
module Jcgm
|
|
5
5
|
# Parses JCGM URNs back into identifiers.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
7
|
+
# Identifiers are rebuilt **directly from the URN segments** rather than
|
|
8
|
+
# rendered to a human-readable string and re-parsed (the BIPM UrnParser
|
|
9
|
+
# pattern). Round-tripping through the grammar flattened the segments into
|
|
10
|
+
# one string and silently lost everything the string form could not carry:
|
|
11
|
+
# a GUM guide (`urn:jcgm:gum.6:2020`) raised, and the language and
|
|
12
|
+
# supplement segments were dropped, so a corrigendum read back as the
|
|
13
|
+
# standard it amends — a different document, with no error.
|
|
9
14
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
15
|
+
# Shapes emitted by UrnGenerator, and read back here:
|
|
16
|
+
# urn:jcgm:200:2008 → JCGM 200:2008
|
|
17
|
+
# urn:jcgm:100:2008:en → JCGM 100:2008(E)
|
|
18
|
+
# urn:jcgm:200:2012:en,fr → JCGM 200:2012(E/F)
|
|
19
|
+
# urn:jcgm:GUM → JCGM GUM
|
|
20
|
+
# urn:jcgm:gum.6:2020 → JCGM GUM-6:2020
|
|
21
|
+
# urn:jcgm:200:2008:corrigendum → JCGM 200:2008 Corrigendum
|
|
22
|
+
# urn:jcgm:101:2008:corrigendum:1:2009 → JCGM 101:2008/Cor 1:2009
|
|
23
|
+
# urn:jcgm:100:2008:amendment:1:2023 → JCGM 100:2008/Amd 1:2023
|
|
24
|
+
# urn:jcgm:meeting:17:2012 → JCGM 17th Meeting (2012)
|
|
25
|
+
# urn:jcgm:meeting:11 → JCGM 11st Meeting
|
|
26
|
+
#
|
|
27
|
+
# KNOWN GAP, on the generator side and unchanged here: a full date is
|
|
28
|
+
# rendered as its year alone (`JCGM GUM-1:2022-11-28` →
|
|
29
|
+
# `urn:jcgm:gum.1:2022`), so a URN cannot restore the month and day.
|
|
30
|
+
# Widening it would change already-published URNs.
|
|
14
31
|
class UrnParser < Pubid::UrnParser::Base
|
|
32
|
+
MEETING_MARKER = "meeting"
|
|
33
|
+
|
|
34
|
+
# The GUM-guide number is written "gum.<n>" by UrnGenerator.
|
|
35
|
+
GUM_PREFIX = "gum."
|
|
36
|
+
|
|
37
|
+
# The supplement marker UrnGenerator writes is the typed stage's
|
|
38
|
+
# `type_code`; the abbreviation is what `Jcgm.locate_stage` matches on.
|
|
39
|
+
SUPPLEMENT_ABBRS = {
|
|
40
|
+
"corrigendum" => "Cor",
|
|
41
|
+
"amendment" => "Amd",
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
MEETING_ABBR = "Meeting"
|
|
45
|
+
|
|
46
|
+
# Mirrors `year_digits` in the shared parser rules.
|
|
47
|
+
YEAR_PATTERN = /\A(?:19|20)\d{2}\z/
|
|
48
|
+
|
|
49
|
+
# A language segment is one or more comma-joined ISO codes.
|
|
50
|
+
LANGUAGES_PATTERN = /\A[a-z]{2}(?:,[a-z]{2})*\z/
|
|
51
|
+
|
|
52
|
+
# Language codes back to the single-letter form the identifier prints;
|
|
53
|
+
# the builder maps the other way when parsing "(E)" / "(E/F)".
|
|
54
|
+
LANGUAGE_LETTERS = Pubid::Builder::Base::LANG_CHAR_MAP.invert.freeze
|
|
55
|
+
|
|
15
56
|
def parse_urn(urn)
|
|
16
57
|
parts = split_parts(strip_namespace(urn))
|
|
17
|
-
return parse_meeting_urn(parts) if parts.first ==
|
|
58
|
+
return parse_meeting_urn(parts) if parts.first == MEETING_MARKER
|
|
18
59
|
|
|
19
|
-
|
|
20
|
-
text = "JCGM #{number}"
|
|
21
|
-
text += ":#{year}" if year
|
|
22
|
-
flavor_parse(text)
|
|
60
|
+
parse_document_urn(parts)
|
|
23
61
|
end
|
|
24
62
|
|
|
25
63
|
private
|
|
26
64
|
|
|
27
|
-
# urn:jcgm:meeting:<number
|
|
65
|
+
# urn:jcgm:meeting:<number>[:<year>] -> Identifiers::Meeting
|
|
66
|
+
#
|
|
67
|
+
# The reconstruction must agree with a parsed identifier attribute for
|
|
68
|
+
# attribute, so `typed_stage` comes from the same registry lookup
|
|
69
|
+
# `Builder#locate_typed_stage` uses. (The attribute default now agrees
|
|
70
|
+
# too — it no longer sets `original_abbr` — so this mirrors the builder
|
|
71
|
+
# for clarity rather than out of necessity.)
|
|
28
72
|
def parse_meeting_urn(parts)
|
|
29
73
|
_, number, year = parts
|
|
30
|
-
|
|
31
|
-
|
|
74
|
+
|
|
75
|
+
Identifiers::Meeting.new(
|
|
76
|
+
number: meeting_number(number),
|
|
77
|
+
date: urn_date(year),
|
|
78
|
+
typed_stage: Jcgm.locate_stage(MEETING_ABBR),
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# A guide, a GUM guide, or a supplement wrapping one of those. The
|
|
83
|
+
# supplement marker splits the segments: everything before it describes
|
|
84
|
+
# the base document, everything after is the supplement's own number and
|
|
85
|
+
# date.
|
|
86
|
+
def parse_document_urn(parts)
|
|
87
|
+
marker_at = parts.index { |segment| SUPPLEMENT_ABBRS.key?(segment) }
|
|
88
|
+
return build_document(parts) unless marker_at
|
|
89
|
+
|
|
90
|
+
build_supplement(
|
|
91
|
+
parts[marker_at],
|
|
92
|
+
build_document(parts[0...marker_at]),
|
|
93
|
+
parts[(marker_at + 1)..] || [],
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The class comes from the same registry the builder uses, so a URN and a
|
|
98
|
+
# parsed reference resolve to one class and one typed_stage.
|
|
99
|
+
def build_supplement(marker, base, tail)
|
|
100
|
+
typed_stage = Jcgm.locate_stage(SUPPLEMENT_ABBRS.fetch(marker))
|
|
101
|
+
number, year = tail
|
|
102
|
+
|
|
103
|
+
Jcgm.locate_type(typed_stage.type_code).new(
|
|
104
|
+
base: base,
|
|
105
|
+
number: (number.nil? || number.empty? ? nil : number.to_s),
|
|
106
|
+
date: urn_date(year),
|
|
107
|
+
typed_stage: typed_stage,
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# <number>[:<year>][:<languages>] — the number segment carries the
|
|
112
|
+
# "gum." prefix for a GUM guide, which is what selects the class.
|
|
113
|
+
#
|
|
114
|
+
# Guide and GumGuide deliberately take their `typed_stage` from the
|
|
115
|
+
# attribute default: the grammar emits no type token for them, so
|
|
116
|
+
# `Builder#build` fills it from `published_typed_stage` too, and both
|
|
117
|
+
# paths agree.
|
|
118
|
+
def build_document(parts)
|
|
119
|
+
number, *rest = parts
|
|
120
|
+
require_number!(number)
|
|
121
|
+
gum = number.start_with?(GUM_PREFIX)
|
|
122
|
+
|
|
123
|
+
(gum ? Identifiers::GumGuide : Identifiers::Guide).new(
|
|
124
|
+
number: (gum ? number.delete_prefix(GUM_PREFIX) : number).to_s,
|
|
125
|
+
date: urn_date(segment_matching(rest, YEAR_PATTERN)),
|
|
126
|
+
languages: urn_languages(segment_matching(rest, LANGUAGES_PATTERN)),
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def require_number!(segment)
|
|
131
|
+
return unless segment.nil? || segment.empty?
|
|
132
|
+
|
|
133
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
134
|
+
"JCGM URN has no document number"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def segment_matching(segments, pattern)
|
|
138
|
+
segments.find { |segment| segment.match?(pattern) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# The ordinal, normalized the way `Identifiers::Meeting.ordinal` does it
|
|
142
|
+
# (`number.to_i`), so "011" reads back as "11" and a missing or
|
|
143
|
+
# non-numeric segment as "0" — the behaviour of the previous
|
|
144
|
+
# render-and-re-parse implementation.
|
|
145
|
+
def meeting_number(segment)
|
|
146
|
+
segment.to_i.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# nil for an absent year; a Date for a well-formed one. The grammar
|
|
150
|
+
# accepts only a 19xx/20xx year, so anything else is a malformed URN and
|
|
151
|
+
# must still be rejected now that no re-parse validates it.
|
|
152
|
+
def urn_date(segment)
|
|
153
|
+
return nil if segment.nil? || segment.empty?
|
|
154
|
+
|
|
155
|
+
unless segment.match?(YEAR_PATTERN)
|
|
156
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
157
|
+
"Invalid year in JCGM URN: #{segment.inspect}"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
Pubid::Components::Date.new(year: segment)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# "en" -> (E), "en,fr" -> (E/F). `original_code` is what the renderer
|
|
164
|
+
# prints, so it is restored from the code rather than left nil.
|
|
165
|
+
def urn_languages(segment)
|
|
166
|
+
return nil if segment.nil? || segment.empty?
|
|
167
|
+
|
|
168
|
+
segment.split(",").map do |code|
|
|
169
|
+
Pubid::Components::Language.new(
|
|
170
|
+
code: code,
|
|
171
|
+
original_code: LANGUAGE_LETTERS.fetch(code, code),
|
|
172
|
+
)
|
|
173
|
+
end
|
|
32
174
|
end
|
|
33
175
|
end
|
|
34
176
|
end
|
data/lib/pubid/jcgm.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pubid"
|
|
3
4
|
module Pubid
|
|
4
5
|
module Jcgm
|
|
5
6
|
extend Pubid::PrefixesSupport
|
|
@@ -22,6 +23,15 @@ module Pubid
|
|
|
22
23
|
# @param identifier [String] the identifier string to parse
|
|
23
24
|
# @return [Identifier] the parsed identifier
|
|
24
25
|
def self.parse(identifier)
|
|
26
|
+
unless identifier.is_a?(String)
|
|
27
|
+
raise Pubid::Errors::InvalidInputError,
|
|
28
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
32
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
33
|
+
end
|
|
34
|
+
|
|
25
35
|
parser = Parser.new
|
|
26
36
|
builder = Builder.new
|
|
27
37
|
|
data/lib/pubid/jis/identifier.rb
CHANGED
|
@@ -175,12 +175,19 @@ module Pubid
|
|
|
175
175
|
# Parse a JIS identifier string into an identifier object
|
|
176
176
|
# @param identifier [String] The JIS identifier string to parse
|
|
177
177
|
# @return [Identifier] The appropriate identifier object
|
|
178
|
-
# @raise [
|
|
178
|
+
# @raise [Pubid::Errors::ParseError] If parsing fails
|
|
179
179
|
def self.parse(identifier)
|
|
180
|
+
unless identifier.is_a?(String)
|
|
181
|
+
raise Pubid::Errors::InvalidInputError,
|
|
182
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
186
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
187
|
+
end
|
|
188
|
+
|
|
180
189
|
parsed = Parser.parse(identifier)
|
|
181
190
|
Builder.build(parsed)
|
|
182
|
-
rescue Parslet::ParseFailed => e
|
|
183
|
-
raise "Failed to parse JIS identifier '#{identifier}': #{e.message}"
|
|
184
191
|
end
|
|
185
192
|
end
|
|
186
193
|
end
|
data/lib/pubid/jis/parser.rb
CHANGED
data/lib/pubid/jis.rb
CHANGED
data/lib/pubid/nist/builder.rb
CHANGED
|
@@ -253,7 +253,7 @@ module Pubid
|
|
|
253
253
|
elsif decimal_num
|
|
254
254
|
decimal_base = decimal_num[:decimal_base].to_s
|
|
255
255
|
decimal_suffix = decimal_num[:decimal_suffix].to_s
|
|
256
|
-
identifier.number =
|
|
256
|
+
identifier.number = "#{first_num.value}-#{decimal_base}.#{decimal_suffix}"
|
|
257
257
|
# NEW: Handle letter number pattern (e.g., 1-1A, 1-3B for NCSTAR identifiers)
|
|
258
258
|
# letter_num is {:letter_base => "1", :letter_suffix => "A"}
|
|
259
259
|
# Also handles IR series "R" suffix: "79-1786R" -> "79-1786r1"
|
|
@@ -268,10 +268,10 @@ module Pubid
|
|
|
268
268
|
# Series-specific handler took ownership (e.g., IR "R" → r1)
|
|
269
269
|
elsif identifier.part
|
|
270
270
|
# SpecialPublication pattern: letter_suffix is separate Part component
|
|
271
|
-
identifier.number =
|
|
271
|
+
identifier.number = "#{first_num.value}-#{letter_base}"
|
|
272
272
|
else
|
|
273
273
|
# NCSTAR pattern: letter_suffix is part of the number
|
|
274
|
-
identifier.number =
|
|
274
|
+
identifier.number = "#{first_num.value}-#{letter_base}#{letter_suffix}"
|
|
275
275
|
end
|
|
276
276
|
elsif second_num
|
|
277
277
|
# Check for special patterns first
|
|
@@ -285,7 +285,7 @@ module Pubid
|
|
|
285
285
|
# Create Edition component
|
|
286
286
|
edition_obj = Components::Edition.new(type: "r", id: edition_id)
|
|
287
287
|
|
|
288
|
-
identifier.number =
|
|
288
|
+
identifier.number = "#{first_num.value}-#{number_part}"
|
|
289
289
|
identifier.edition = edition_obj
|
|
290
290
|
# CS Emergency pattern: e104-43 -> number=104, edition_year=1943
|
|
291
291
|
# Logic: e104-43 means "emergency 104 from 1943" (43 = 1943)
|
|
@@ -300,7 +300,7 @@ module Pubid
|
|
|
300
300
|
# Create Edition component
|
|
301
301
|
edition_obj = Components::Edition.new(type: "e", id: edition_year)
|
|
302
302
|
|
|
303
|
-
identifier.number =
|
|
303
|
+
identifier.number = number_part
|
|
304
304
|
identifier.edition = edition_obj
|
|
305
305
|
elsif first_num.value.to_s.match?(/^(\d+)e(\d+)$/) &&
|
|
306
306
|
second_num.value.to_s.match?(/^\d{2,4}$/)
|
|
@@ -314,7 +314,7 @@ module Pubid
|
|
|
314
314
|
# Expand 2-digit year to 4-digit (50 -> 1950)
|
|
315
315
|
year_part = "19#{year_part}" if year_part.length == 2
|
|
316
316
|
|
|
317
|
-
identifier.number =
|
|
317
|
+
identifier.number = number_part
|
|
318
318
|
|
|
319
319
|
# For edition+year patterns, handling depends on identifier type:
|
|
320
320
|
# - CIRC: edition number + year as additional_text, rendered with dot ("11e2-1915" -> "11e2.1915")
|
|
@@ -329,7 +329,7 @@ module Pubid
|
|
|
329
329
|
number_part = first_num.value.to_s.match(/^(\d+)supp?$/)[1]
|
|
330
330
|
year_part = second_num.value.to_s
|
|
331
331
|
|
|
332
|
-
identifier.number =
|
|
332
|
+
identifier.number = number_part
|
|
333
333
|
supp[:value] = year_part
|
|
334
334
|
supp[:present] = true
|
|
335
335
|
elsif second_num.value.to_s.match?(/^(\d+)supp?$/)
|
|
@@ -337,14 +337,14 @@ module Pubid
|
|
|
337
337
|
# second number. Strip it and isolate as supplement="" (single-p).
|
|
338
338
|
second_part = second_num.value.to_s.match(/^(\d+)supp?$/)[1]
|
|
339
339
|
compound = "#{first_num.value}-#{second_part}"
|
|
340
|
-
identifier.number =
|
|
340
|
+
identifier.number = compound
|
|
341
341
|
supp[:value] = ""
|
|
342
342
|
supp[:present] = true
|
|
343
343
|
elsif identifier.is_a?(Identifiers::TechnicalNote) &&
|
|
344
344
|
second_num.value.to_s.match?(/^(19|20)\d{2}$/)
|
|
345
345
|
# SPECIAL CASE FOR TN: second_num is edition year
|
|
346
346
|
# Following "date IS edition" rule: -1993 becomes Edition(type: "e", id: "1993")
|
|
347
|
-
identifier.number = first_num
|
|
347
|
+
identifier.number = first_num.value.to_s
|
|
348
348
|
edition_obj = Components::Edition.new(type: "e",
|
|
349
349
|
id: second_num.value.to_s)
|
|
350
350
|
identifier.edition = edition_obj
|
|
@@ -354,16 +354,16 @@ module Pubid
|
|
|
354
354
|
# not folded into the compound number.
|
|
355
355
|
identifier.part = Components::Part.new(type: "pt",
|
|
356
356
|
value: part_num)
|
|
357
|
-
identifier.number =
|
|
357
|
+
identifier.number = "#{first_num.value}-#{second_num.value}"
|
|
358
358
|
else
|
|
359
359
|
# For GCR and others, include part number in compound number
|
|
360
360
|
compound_value = "#{first_num.value}-#{second_num.value}"
|
|
361
361
|
compound_value += "-#{part_num}" if part_num
|
|
362
|
-
identifier.number =
|
|
362
|
+
identifier.number = compound_value
|
|
363
363
|
end
|
|
364
364
|
else
|
|
365
365
|
# No second_num, use first_num directly
|
|
366
|
-
identifier.number = first_num
|
|
366
|
+
identifier.number = first_num.value.to_s
|
|
367
367
|
end
|
|
368
368
|
end
|
|
369
369
|
|
|
@@ -16,10 +16,10 @@ module Pubid
|
|
|
16
16
|
attribute :id, :string # i, f, 1-9
|
|
17
17
|
attribute :type, :string # pd, wd, prd
|
|
18
18
|
|
|
19
|
-
# Load stages from
|
|
19
|
+
# Load stages from data/nist/stages.yaml
|
|
20
20
|
STAGES = YAML.load_file(
|
|
21
21
|
File.join(File.dirname(__FILE__),
|
|
22
|
-
"../../../../
|
|
22
|
+
"../../../../data/nist/stages.yaml"),
|
|
23
23
|
).freeze
|
|
24
24
|
|
|
25
25
|
# Render stage in specified format
|