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
|
@@ -82,18 +82,6 @@ module Pubid
|
|
|
82
82
|
web: :publicly_available_specification, title: "Publicly Available Specification", short: "PAS" }
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
# Override publisher_portion to add PAS or DPAS stage
|
|
86
|
-
def publisher_portion
|
|
87
|
-
result = publisher.to_s
|
|
88
|
-
|
|
89
|
-
if typed_stage
|
|
90
|
-
abbr = typed_stage.abbreviation
|
|
91
|
-
# PAS uses space for all stages
|
|
92
|
-
result += " #{abbr}" unless abbr.empty?
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
result
|
|
96
|
-
end
|
|
97
85
|
end
|
|
98
86
|
end
|
|
99
87
|
end
|
|
@@ -24,16 +24,6 @@ module Pubid
|
|
|
24
24
|
short: "Trend Report" }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# Override publisher_portion to add Trend Report
|
|
28
|
-
def publisher_portion
|
|
29
|
-
result = publisher.to_s
|
|
30
|
-
|
|
31
|
-
if typed_stage && typed_stage.abbreviation == "Trend Report"
|
|
32
|
-
result += " Trend Report"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
result
|
|
36
|
-
end
|
|
37
27
|
end
|
|
38
28
|
end
|
|
39
29
|
end
|
|
@@ -23,16 +23,6 @@ module Pubid
|
|
|
23
23
|
web: :systems_reference_document, title: "Systems Reference Document", short: "SRD" }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Override publisher_portion to add SRD
|
|
27
|
-
def publisher_portion
|
|
28
|
-
result = publisher.to_s
|
|
29
|
-
|
|
30
|
-
if typed_stage && typed_stage.abbreviation == "SRD"
|
|
31
|
-
result += " SRD"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
result
|
|
35
|
-
end
|
|
36
26
|
end
|
|
37
27
|
end
|
|
38
28
|
end
|
|
@@ -108,23 +108,6 @@ module Pubid
|
|
|
108
108
|
web: :technical_report, title: "Technical Report", short: "TR" }
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
# Override publisher_portion to handle TR formatting
|
|
112
|
-
# If copublishers exist, use parent implementation
|
|
113
|
-
def publisher_portion
|
|
114
|
-
# If copublishers, delegate to parent (SingleIdentifier) which handles them
|
|
115
|
-
return super if copublishers&.any?
|
|
116
|
-
|
|
117
|
-
# No copublishers: simple TR formatting
|
|
118
|
-
result = publisher.to_s
|
|
119
|
-
|
|
120
|
-
if typed_stage
|
|
121
|
-
abbr = typed_stage.abbreviation
|
|
122
|
-
# For TR: always use space (IEC convention for ALL publishers)
|
|
123
|
-
result += " #{abbr}" unless abbr.empty?
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
result
|
|
127
|
-
end
|
|
128
111
|
end
|
|
129
112
|
end
|
|
130
113
|
end
|
|
@@ -108,23 +108,6 @@ module Pubid
|
|
|
108
108
|
web: :technical_specification, title: "Technical Specification", short: "TS" }
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
# Override publisher_portion to handle TS formatting
|
|
112
|
-
# If copublishers exist, use parent implementation
|
|
113
|
-
def publisher_portion
|
|
114
|
-
# If copublishers, delegate to parent (SingleIdentifier) which handles them
|
|
115
|
-
return super if copublishers&.any?
|
|
116
|
-
|
|
117
|
-
# No copublishers: simple TS formatting
|
|
118
|
-
result = publisher.to_s
|
|
119
|
-
|
|
120
|
-
if typed_stage
|
|
121
|
-
abbr = typed_stage.abbreviation
|
|
122
|
-
# TS uses space for all stages
|
|
123
|
-
result += " #{abbr}" unless abbr.empty?
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
result
|
|
127
|
-
end
|
|
128
111
|
end
|
|
129
112
|
end
|
|
130
113
|
end
|
|
@@ -22,16 +22,6 @@ module Pubid
|
|
|
22
22
|
{ key: :tec, title: "Technology Report", short: "Technology Report" }
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
# Override publisher_portion to add Technology Report
|
|
26
|
-
def publisher_portion
|
|
27
|
-
result = publisher.to_s
|
|
28
|
-
|
|
29
|
-
if typed_stage && typed_stage.abbreviation == "Technology Report"
|
|
30
|
-
result += " Technology Report"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
result
|
|
34
|
-
end
|
|
35
25
|
end
|
|
36
26
|
end
|
|
37
27
|
end
|
|
@@ -28,17 +28,6 @@ module Pubid
|
|
|
28
28
|
web: :test_report_form, title: "Test Report Form", short: "TRF" }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
# Override publisher_portion to add TRF with space
|
|
32
|
-
def publisher_portion
|
|
33
|
-
result = publisher.to_s
|
|
34
|
-
|
|
35
|
-
if typed_stage && typed_stage.abbreviation == "TRF"
|
|
36
|
-
result += " TRF"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
result
|
|
40
|
-
end
|
|
41
|
-
|
|
42
31
|
# TRF uses special rendering via the Renderer
|
|
43
32
|
end
|
|
44
33
|
end
|
|
@@ -23,16 +23,6 @@ module Pubid
|
|
|
23
23
|
web: :white_paper, title: "White Paper", short: "White Paper" }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Override publisher_portion to add White Paper
|
|
27
|
-
def publisher_portion
|
|
28
|
-
result = publisher.to_s
|
|
29
|
-
|
|
30
|
-
if typed_stage && typed_stage.abbreviation == "White Paper"
|
|
31
|
-
result += " White Paper"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
result
|
|
35
|
-
end
|
|
36
26
|
end
|
|
37
27
|
end
|
|
38
28
|
end
|
|
@@ -28,19 +28,33 @@ module Pubid
|
|
|
28
28
|
web: :working_document, title: "Working Document", short: "WD" }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
#
|
|
31
|
+
# A working document prints its committee, number, language and stage —
|
|
32
|
+
# `1/2457(F)/FDIS` — and none of those is the `number` the shared token
|
|
33
|
+
# table looks for, so it had no annotatable token. `wd_stage` is the
|
|
34
|
+
# printed stage token ("FDIS"); the derived `#stage` reader covers only
|
|
35
|
+
# the PWI/PNW work-programme form and is nil here.
|
|
36
|
+
def annotation_tokens
|
|
37
|
+
super + [
|
|
38
|
+
[:technical_committee, "docnumber"],
|
|
39
|
+
[:wd_number, "docnumber"],
|
|
40
|
+
[:wd_language, "language"],
|
|
41
|
+
[:wd_stage, "stage"],
|
|
42
|
+
[:wp_stage, "stage"],
|
|
43
|
+
[:wp_type, "doctype"],
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Return stage object for the PWI/PNW work-programme stage.
|
|
48
|
+
#
|
|
49
|
+
# This used to build a bare Stage from a hand-written abbreviation map,
|
|
50
|
+
# so the stage carried no harmonized code and "pnw" existed as a stage
|
|
51
|
+
# code nowhere else in the registry. It now resolves through the shared
|
|
52
|
+
# registry, so PWI carries 00.* and PNW carries 10.20 — which is what
|
|
53
|
+
# the URN generator reads.
|
|
32
54
|
def stage
|
|
33
55
|
return nil unless wp_stage
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
stage_map = {
|
|
37
|
-
"PWI" => "pwi",
|
|
38
|
-
"PNW" => "pnw",
|
|
39
|
-
}
|
|
40
|
-
stage_code = stage_map[wp_stage]
|
|
41
|
-
return nil unless stage_code
|
|
42
|
-
|
|
43
|
-
@stage ||= ::Pubid::Components::Stage.new(stage_code: stage_code)
|
|
57
|
+
@stage ||= Pubid::Iec.locate_stage(wp_stage)&.to_stage
|
|
44
58
|
end
|
|
45
59
|
end
|
|
46
60
|
end
|
data/lib/pubid/iec/parser.rb
CHANGED
|
@@ -3,7 +3,7 @@ require "parslet"
|
|
|
3
3
|
|
|
4
4
|
module Pubid
|
|
5
5
|
module Iec
|
|
6
|
-
class Parser <
|
|
6
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
7
7
|
include ::Pubid::Parser::CommonParseRules
|
|
8
8
|
include ::Pubid::Parser::CommonParseMethods
|
|
9
9
|
|
|
@@ -17,8 +17,7 @@ module Pubid
|
|
|
17
17
|
root :identifier
|
|
18
18
|
|
|
19
19
|
rule(:identifier) do
|
|
20
|
-
|
|
21
|
-
working_programme |
|
|
20
|
+
working_programme |
|
|
22
21
|
technical_group |
|
|
23
22
|
working_document |
|
|
24
23
|
sheet_supplement_identifier |
|
|
@@ -81,21 +80,6 @@ module Pubid
|
|
|
81
80
|
(space >> edition).maybe
|
|
82
81
|
end
|
|
83
82
|
|
|
84
|
-
# Working Programme with publisher prefix: IEC/PWI [TR] number edition
|
|
85
|
-
# Examples: "IEC/PWI 60038", "ISO/IEC/PWI TR 100-36 ED1"
|
|
86
|
-
rule(:working_programme_with_publisher) do
|
|
87
|
-
prefix_with_copublishers >> str("/") >>
|
|
88
|
-
(str("PWI") | str("PNW")).as(:wp_stage) >>
|
|
89
|
-
space >>
|
|
90
|
-
(
|
|
91
|
-
(str("TR") >> space) |
|
|
92
|
-
(str("TS") >> space) |
|
|
93
|
-
(str("SRD") >> space)
|
|
94
|
-
).maybe.as(:wp_type) >>
|
|
95
|
-
wp_number >>
|
|
96
|
-
(space >> edition).maybe
|
|
97
|
-
end
|
|
98
|
-
|
|
99
83
|
# Working programme numbers can be digits or TC names
|
|
100
84
|
rule(:wp_number) do
|
|
101
85
|
# TC-style: SYCSMARTENERGY-1, SyCLVDC-125
|
data/lib/pubid/iec/renderer.rb
CHANGED
|
@@ -89,13 +89,18 @@ module Pubid
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def render_supplement_standalone(id, context)
|
|
92
|
+
# This is a second, independent publisher/stage join that
|
|
93
|
+
# SingleIdentifier#publisher_portion never reaches. It follows the same
|
|
94
|
+
# house style: the slash separates copublishers, and a SPACE separates
|
|
95
|
+
# the publisher from the stage abbreviation. See issue #360 item 2.
|
|
92
96
|
parts = []
|
|
93
97
|
|
|
94
98
|
if id.publisher
|
|
95
|
-
|
|
99
|
+
publishers = [id.publisher.render(context:)]
|
|
96
100
|
if id.copublishers&.any?
|
|
97
|
-
|
|
101
|
+
publishers += id.copublishers.map { |c| c.render(context:) }
|
|
98
102
|
end
|
|
103
|
+
parts << publishers.join("/")
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
abbr = id.typed_stage.abbr.first
|
|
@@ -104,7 +109,7 @@ module Pubid
|
|
|
104
109
|
number_str += "-#{id.subpart}" if id.subpart
|
|
105
110
|
parts << "#{abbr} #{number_str}"
|
|
106
111
|
|
|
107
|
-
result = parts.join("
|
|
112
|
+
result = parts.join(" ")
|
|
108
113
|
result += ":#{id.date.render(context:)}" if id.date
|
|
109
114
|
result += " #{id.edition.render(context:)}" if id.edition&.number
|
|
110
115
|
result
|
|
@@ -197,14 +202,12 @@ module Pubid
|
|
|
197
202
|
|
|
198
203
|
def render_working_document(id, context)
|
|
199
204
|
if id.wp_stage
|
|
205
|
+
# A work-programme registration renders bare, as it is written:
|
|
206
|
+
# "PNW 65-915 ED1", not "IEC/PNW 65-915 ED1". Its number is
|
|
207
|
+
# TC-scoped, not an IEC document number, and prefixing "IEC " would
|
|
208
|
+
# break idempotence — "IEC PNW 65-915 ED1" re-parses as an
|
|
209
|
+
# International Standard, so rendering would not be a fixed point.
|
|
200
210
|
parts = []
|
|
201
|
-
if id.publisher
|
|
202
|
-
parts << id.publisher.render(context:)
|
|
203
|
-
if id.copublishers&.any?
|
|
204
|
-
parts << "/#{id.copublishers.map { |c| c.render(context:) }.join('/')}"
|
|
205
|
-
end
|
|
206
|
-
parts << "/"
|
|
207
|
-
end
|
|
208
211
|
parts << id.wp_stage
|
|
209
212
|
if id.wp_type && !id.wp_type.strip.empty?
|
|
210
213
|
parts << " #{id.wp_type.strip}"
|
|
@@ -8,6 +8,31 @@ module Pubid
|
|
|
8
8
|
attribute :typed_stage, ::Pubid::Components::TypedStage,
|
|
9
9
|
default: -> { self.class.published_typed_stage }
|
|
10
10
|
|
|
11
|
+
# number/part/subpart are mapped HERE, not on Iec::Identifier, and the
|
|
12
|
+
# placement is the whole design.
|
|
13
|
+
#
|
|
14
|
+
# The four wrapper identifiers — FragmentIdentifier,
|
|
15
|
+
# ConsolidatedIdentifier, VapIdentifier and SheetIdentifier — inherit
|
|
16
|
+
# from Iec::Identifier DIRECTLY and override `number`/`part`/`subpart` as
|
|
17
|
+
# readers that delegate to what they wrap. A map on the shared parent
|
|
18
|
+
# would therefore serialize
|
|
19
|
+
# the delegated value twice: once at the wrapper's top level and again
|
|
20
|
+
# inside "base"/"identifiers". SingleIdentifier is the seam that excludes
|
|
21
|
+
# exactly those four while covering both classes that own a number of
|
|
22
|
+
# their own (Identifiers::Base and SupplementIdentifier).
|
|
23
|
+
#
|
|
24
|
+
# That is a structural exclusion, not a denylist of no-op converters that
|
|
25
|
+
# a later key can be forgotten from — which is how `month`/`day` came to
|
|
26
|
+
# leak (see DelegatedFieldSuppression).
|
|
27
|
+
#
|
|
28
|
+
# The values are plain strings, so no converter is needed: lutaml writes
|
|
29
|
+
# the scalar, and ::Pubid::Identifier#to_hash drops a nil.
|
|
30
|
+
key_value do
|
|
31
|
+
map "number", to: :number
|
|
32
|
+
map "part", to: :part
|
|
33
|
+
map "subpart", to: :subpart
|
|
34
|
+
end
|
|
35
|
+
|
|
11
36
|
# Generate URN for this identifier
|
|
12
37
|
#
|
|
13
38
|
# @return [String] URN representation
|
|
@@ -28,16 +53,14 @@ module Pubid
|
|
|
28
53
|
publisher.body
|
|
29
54
|
end
|
|
30
55
|
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
end
|
|
56
|
+
# IEC house style separates the publisher from the typed-stage
|
|
57
|
+
# abbreviation with a SPACE, for every type and whether or not there
|
|
58
|
+
# are copublishers: "IEC CD 60038", "IEC PNW 1000-1:2023". The slash
|
|
59
|
+
# stays the copublisher separator only. The slash input spelling
|
|
60
|
+
# ("IEC/CD 60038") is still accepted by the parser; only rendering
|
|
61
|
+
# normalises. See issue #360 item 2.
|
|
62
|
+
abbr = typed_stage&.abbreviation.to_s
|
|
63
|
+
pub_string += " #{abbr}" unless abbr.empty?
|
|
41
64
|
|
|
42
65
|
pub_string
|
|
43
66
|
end
|
|
@@ -2,77 +2,243 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Iec
|
|
5
|
-
# Generates IEC URNs in the
|
|
6
|
-
#
|
|
5
|
+
# Generates IEC URNs in the positional format used as ground truth by
|
|
6
|
+
# relaton-data-iec:
|
|
7
7
|
#
|
|
8
|
-
# urn:iec:std:{
|
|
8
|
+
# urn:iec:std:{authority}:{number}[-{part}[-{subpart}]]
|
|
9
|
+
# :{date}:{stage-or-type}:{deliverable}:{language}{adjuncts}
|
|
9
10
|
#
|
|
10
|
-
# e.g. +urn:iec:std:iec:60050-102:2007
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
11
|
+
# e.g. +urn:iec:std:iec:60050-102:2007:::+. Absent trailing slots are
|
|
12
|
+
# emitted as empty fields. The all-parts series URN is the one exception:
|
|
13
|
+
# a bare series omits the language slot (8 fields).
|
|
14
|
+
#
|
|
15
|
+
# This used to be a port of relaton-iec's +code_to_urn+, which regex-scraped
|
|
16
|
+
# +identifier.to_s+. Three defects followed from reading the printed form:
|
|
17
|
+
# the stage was folded into the authority slot (+urn:iec:std:iec-np:...+),
|
|
18
|
+
# the edition was never emitted, and the regex was unanchored, so any type
|
|
19
|
+
# token outside its hard-coded list consumed the publisher instead
|
|
20
|
+
# (+IEC/DTS 62271-1+ became +urn:iec:std:dts:62271-1::::+, and every
|
|
21
|
+
# +IECEE TRF ...+ keyed +urn:iec:std:trf:...+). The generator now reads the
|
|
22
|
+
# identifier's own components. The slot ORDER is unchanged, because the
|
|
23
|
+
# published corpus uses it. See issue #360 item 4.
|
|
15
24
|
class UrnGenerator < Pubid::UrnGenerator::Base
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
URN_CONTEXT = Rendering::RenderingContext.urn.freeze
|
|
26
|
+
private_constant :URN_CONTEXT
|
|
27
|
+
|
|
28
|
+
# Type codes that occupy the type slot. `is` and `trf` render empty
|
|
29
|
+
# there, as they always have. `tec` and `wp` never appear in the corpus
|
|
30
|
+
# but the legacy grammar accepted them, so they stay recognised.
|
|
31
|
+
TYPE_SLOT_CODES = %w[tr ts pas srd guide tec wp].freeze
|
|
32
|
+
|
|
33
|
+
# Deliverable markers occupying the deliverable slot. "ser" reaches this
|
|
34
|
+
# list as a spelled-out VAP code ("IEC 60034:2026 SER"), which is not the
|
|
35
|
+
# same thing as the `all_parts` series form handled below.
|
|
36
|
+
DELIVERABLES = %w[cmv csv exv prv rlv ser].freeze
|
|
37
|
+
|
|
38
|
+
# Supplement classes that contribute an adjunct, and the token each one
|
|
39
|
+
# writes into it.
|
|
40
|
+
ADJUNCT_TOKENS = {
|
|
41
|
+
"Amendment" => "amd",
|
|
42
|
+
"Corrigendum" => "cor",
|
|
43
|
+
"InterpretationSheet" => "ish",
|
|
44
|
+
}.freeze
|
|
18
45
|
|
|
19
46
|
def generate
|
|
20
|
-
|
|
47
|
+
doc = document
|
|
48
|
+
return nil if doc.nil?
|
|
21
49
|
|
|
22
|
-
|
|
50
|
+
num = number_segment(doc)
|
|
51
|
+
return nil if num.nil? || num.empty?
|
|
52
|
+
|
|
53
|
+
slots = ["urn", "iec", "std", authority(doc), num,
|
|
54
|
+
date_slot(doc), stage_or_type_slot(doc), deliverable_slot]
|
|
55
|
+
adjuncts = adjunct_slots(identifier)
|
|
56
|
+
language = language_slot
|
|
57
|
+
slots << language unless bare_series?(slots, adjuncts, language)
|
|
58
|
+
|
|
59
|
+
(slots + adjuncts).join(":").downcase
|
|
23
60
|
end
|
|
24
61
|
|
|
25
62
|
private
|
|
26
63
|
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
# The document the URN names: the origin standard, with every amendment,
|
|
65
|
+
# corrigendum, consolidation, VAP and fragment layer peeled off. Those
|
|
66
|
+
# layers are what the adjunct and deliverable slots record.
|
|
67
|
+
#
|
|
68
|
+
# A CISPR test report form carries no number of its own — the document it
|
|
69
|
+
# reports on sits in `cispr_identifier`, and that is what the URN has
|
|
70
|
+
# always named.
|
|
71
|
+
def document
|
|
72
|
+
doc = identifier.respond_to?(:root) ? identifier.root : identifier
|
|
73
|
+
return doc if doc.nil? || number_segment(doc)
|
|
74
|
+
|
|
75
|
+
maybe_of(doc, :cispr_identifier) || doc
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# A publisher body may carry a space ("IEC CA", "IECQ CS", "IECQ OD").
|
|
79
|
+
# The published corpus records only the last token for those
|
|
80
|
+
# (+urn:iec:std:ca:01:2017:::+), which is what the old whitespace-
|
|
81
|
+
# splitting regex produced. Keeping that spelling is what keeps those
|
|
82
|
+
# rows byte-identical; correcting it to "iec-ca" would need a data
|
|
83
|
+
# migration first.
|
|
84
|
+
def authority(doc)
|
|
85
|
+
publishers = [doc.publisher] + Array(doc.copublishers)
|
|
86
|
+
publishers.compact.map { |p| p.body.to_s.split(/\s+/).last.to_s }
|
|
87
|
+
.reject(&:empty?).join("-")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def number_segment(doc)
|
|
91
|
+
return nil unless doc.respond_to?(:number) && doc.number
|
|
92
|
+
|
|
93
|
+
segment = [doc.number, maybe_of(doc, :part), maybe_of(doc, :subpart)]
|
|
94
|
+
.compact.map(&:to_s).reject(&:empty?).join("-")
|
|
95
|
+
return nil if segment.empty?
|
|
96
|
+
|
|
97
|
+
# A few document numbers are multi-word ("DIR 1 IEC SUP"). A URN
|
|
98
|
+
# carries no spaces, so they become hyphens.
|
|
99
|
+
segment.gsub(/\s+/, "-")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# `Components::Date#render` under a URN context deliberately drops the
|
|
103
|
+
# month, which is the ISO convention. IEC keeps the precision it was
|
|
104
|
+
# given ("IEC CA 01:2025-10" keys ...:2025-10:...), so this reads the
|
|
105
|
+
# printed form.
|
|
106
|
+
def date_slot(doc)
|
|
107
|
+
maybe_of(doc, :date).to_s
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# The stage slot and the type slot are the same slot, and a draft of a
|
|
111
|
+
# typed document has both. Both are kept, type first
|
|
112
|
+
# ("ts-stage-50.00"), because the harmonized codes are shared across
|
|
113
|
+
# types: dropping the type would make a draft TS, a draft TR and a draft
|
|
114
|
+
# International Standard collide, and `parse_urn` would resolve every one
|
|
115
|
+
# of them to an International Standard.
|
|
116
|
+
def stage_or_type_slot(doc)
|
|
117
|
+
type = type_token(doc)
|
|
118
|
+
stage = stage_token(doc)
|
|
119
|
+
|
|
120
|
+
return type if stage.nil?
|
|
121
|
+
|
|
122
|
+
[type, stage].reject { |t| t.nil? || t.empty? }.join("-")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def type_token(doc)
|
|
126
|
+
ts = maybe_of(doc, :typed_stage)
|
|
127
|
+
code = ts&.type_code.to_s.downcase
|
|
128
|
+
TYPE_SLOT_CODES.include?(code) ? code : ""
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# nil when the document is published (or carries no stage at all), so the
|
|
132
|
+
# slot keeps holding the bare type token for every published row.
|
|
133
|
+
def stage_token(doc)
|
|
134
|
+
stage = maybe_of(doc, :typed_stage)&.to_stage || maybe_of(doc, :stage)
|
|
135
|
+
harmonized = stage&.harmonized_stages&.first.to_s
|
|
136
|
+
return nil if harmonized.empty?
|
|
137
|
+
return nil if published_stage?(stage)
|
|
138
|
+
|
|
139
|
+
"stage-#{harmonized}"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def published_stage?(stage)
|
|
143
|
+
stage.stage_code.to_s == "published"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# A deliverable code owns the slot; the edition takes it only when there
|
|
147
|
+
# is none.
|
|
148
|
+
def deliverable_slot
|
|
149
|
+
return "ser" if maybe_of(identifier, :all_parts)
|
|
150
|
+
|
|
151
|
+
vap = vap_codes
|
|
152
|
+
return vap unless vap.empty?
|
|
153
|
+
|
|
154
|
+
edition = maybe_of(identifier, :edition)
|
|
155
|
+
return "" unless edition&.number
|
|
156
|
+
|
|
157
|
+
edition.render(context: URN_CONTEXT).to_s
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# A deliverable sits on the VAP layer, which is not always the outermost
|
|
161
|
+
# one: "IEC 60079-10-1:2020 CMV/COR1:2021" is a corrigendum wrapping the
|
|
162
|
+
# CMV, so the codes have to be looked for down the chain.
|
|
163
|
+
def vap_codes
|
|
164
|
+
codes = find_down(:vap)
|
|
165
|
+
return "" unless codes
|
|
166
|
+
|
|
167
|
+
Array(codes).map { |c| c.to_s.downcase }
|
|
168
|
+
.select { |c| DELIVERABLES.include?(c) }.join("-")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# First non-empty value of `attribute` from the outermost identifier
|
|
172
|
+
# inwards.
|
|
173
|
+
def find_down(attribute)
|
|
174
|
+
id = identifier
|
|
175
|
+
while id
|
|
176
|
+
value = maybe_of(id, attribute)
|
|
177
|
+
return value unless value.nil? ||
|
|
178
|
+
(value.respond_to?(:empty?) && value.empty?)
|
|
179
|
+
|
|
180
|
+
id = maybe_of(id, :base) ||
|
|
181
|
+
Array(maybe_of(id, :identifiers)).first
|
|
182
|
+
end
|
|
183
|
+
nil
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def language_slot
|
|
187
|
+
langs = maybe_of(identifier, :languages)
|
|
188
|
+
return "" unless langs&.any?
|
|
189
|
+
|
|
190
|
+
langs.map { |l| l.code.to_s }.join("-")
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# A bare, undated, stage- and language-less all-parts series drops the
|
|
194
|
+
# trailing empty language slot, matching the canonical relaton-data-iec
|
|
195
|
+
# form urn:iec:std:iec:80000:::ser. A dated series, or one carrying a
|
|
196
|
+
# stage, keeps the slot.
|
|
197
|
+
def bare_series?(slots, adjuncts, language)
|
|
198
|
+
slots.last == "ser" && slots[5, 2].all? { |s| s.to_s.empty? } &&
|
|
199
|
+
adjuncts.empty? && language.empty?
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Walks the identifier tree for the amendment / corrigendum /
|
|
203
|
+
# interpretation-sheet layers, innermost first. A member of a
|
|
204
|
+
# consolidated identifier carries the "plus" relation marker, which the
|
|
205
|
+
# printed form spells "+".
|
|
206
|
+
def adjunct_slots(id)
|
|
207
|
+
return [] if id.nil?
|
|
208
|
+
|
|
209
|
+
case id.class.name.split("::").last
|
|
210
|
+
when "ConsolidatedIdentifier"
|
|
211
|
+
members = Array(id.identifiers)
|
|
212
|
+
adjunct_slots(members.first) +
|
|
213
|
+
members.drop(1).flat_map { |m| adjunct_fields(m, plus: true) }
|
|
214
|
+
when *ADJUNCT_TOKENS.keys
|
|
215
|
+
adjunct_slots(id.base) + adjunct_fields(id, plus: false)
|
|
216
|
+
else
|
|
217
|
+
adjunct_slots(id.respond_to?(:base) ? id.base : nil)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def adjunct_fields(id, plus:)
|
|
222
|
+
token = ADJUNCT_TOKENS[id.class.name.split("::").last]
|
|
223
|
+
return adjunct_slots(id.respond_to?(:base) ? id.base : nil) unless token
|
|
224
|
+
|
|
225
|
+
[plus ? "plus" : "", token, id.number.to_s,
|
|
226
|
+
maybe_of(id, :date)&.render(context: URN_CONTEXT).to_s]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Not every IEC class declares every attribute, and a wrapper may not
|
|
230
|
+
# declare one its base does. The `respond_to?` guard covers the missing
|
|
231
|
+
# attribute; the rescue covers an attribute that exists but nil-chases
|
|
232
|
+
# while resolving — `SupplementIdentifier#number` runs `ensure_base` and
|
|
233
|
+
# reads through a base that may not be built yet. It is deliberately
|
|
234
|
+
# narrow: a broader rescue would swallow a real bug into a silently
|
|
235
|
+
# empty URN slot instead of failing loudly.
|
|
236
|
+
def maybe_of(id, attribute)
|
|
237
|
+
return nil unless id.respond_to?(attribute)
|
|
238
|
+
|
|
239
|
+
id.public_send(attribute)
|
|
240
|
+
rescue NoMethodError
|
|
241
|
+
nil
|
|
76
242
|
end
|
|
77
243
|
end
|
|
78
244
|
end
|