pubid 2.0.0.pre.alpha.7 → 2.0.0.pre.alpha.9
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 +9 -50
- data/data/bipm/update_codes.yaml +9 -0
- data/data/iec/update_codes.yaml +3 -0
- data/data/ieee/update_codes.yaml +107 -1
- data/data/nist/series.yaml +155 -0
- data/data/nist/update_codes.yaml +8 -0
- data/lib/pubid/adobe/builder.rb +52 -0
- data/lib/pubid/adobe/identifier.rb +49 -0
- data/lib/pubid/adobe/identifiers/publication.rb +31 -0
- data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
- data/lib/pubid/adobe/identifiers.rb +10 -0
- data/lib/pubid/adobe/parser.rb +128 -0
- data/lib/pubid/adobe/renderer.rb +39 -0
- data/lib/pubid/adobe/urn_generator.rb +42 -0
- data/lib/pubid/adobe/urn_parser.rb +69 -0
- data/lib/pubid/adobe.rb +60 -0
- data/lib/pubid/amca/builder.rb +2 -2
- data/lib/pubid/amca/identifier.rb +1 -3
- data/lib/pubid/amca/identifiers/base.rb +1 -6
- data/lib/pubid/amca/identifiers/interpretation.rb +1 -1
- data/lib/pubid/amca/identifiers/publication.rb +1 -1
- data/lib/pubid/amca/identifiers/standard.rb +1 -1
- data/lib/pubid/amca/identifiers.rb +0 -1
- data/lib/pubid/amca/single_identifier.rb +1 -1
- data/lib/pubid/amca.rb +3 -3
- data/lib/pubid/ashrae/builder.rb +22 -22
- data/lib/pubid/ashrae/identifier.rb +3 -4
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +1 -1
- data/lib/pubid/ashrae/identifiers/addendum.rb +1 -1
- data/lib/pubid/ashrae/identifiers/base.rb +14 -8
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +1 -1
- data/lib/pubid/ashrae/identifiers.rb +0 -1
- data/lib/pubid/ashrae/parser.rb +14 -9
- data/lib/pubid/ashrae/renderer.rb +19 -19
- data/lib/pubid/ashrae/single_identifier.rb +1 -1
- data/lib/pubid/ashrae/supplement_identifier.rb +6 -6
- data/lib/pubid/ashrae.rb +3 -3
- data/lib/pubid/bipm/builder.rb +107 -0
- data/lib/pubid/bipm/identifier.rb +160 -0
- data/lib/pubid/bipm/identifiers/committee_document.rb +24 -0
- data/lib/pubid/bipm/identifiers/guide.rb +24 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +41 -0
- data/lib/pubid/bipm/identifiers/mep.rb +21 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +20 -0
- data/lib/pubid/bipm/identifiers.rb +15 -0
- data/lib/pubid/bipm/parser.rb +184 -0
- data/lib/pubid/bipm/renderer.rb +110 -0
- data/lib/pubid/bipm/urn_generator.rb +58 -0
- data/lib/pubid/bipm/urn_parser.rb +52 -0
- data/lib/pubid/bipm.rb +86 -0
- data/lib/pubid/bsi/builder.rb +14 -14
- data/lib/pubid/bsi/identifier.rb +0 -1
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/amendment.rb +4 -4
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
- data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
- data/lib/pubid/bsi/renderer.rb +8 -8
- data/lib/pubid/bsi/single_identifier.rb +48 -0
- data/lib/pubid/builder/base.rb +5 -3
- data/lib/pubid/bundled_identifier.rb +3 -3
- data/lib/pubid/calconnect/builder.rb +38 -0
- data/lib/pubid/calconnect/identifier.rb +117 -0
- data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
- data/lib/pubid/calconnect/identifiers.rb +9 -0
- data/lib/pubid/calconnect/parser.rb +54 -0
- data/lib/pubid/calconnect/renderer.rb +36 -0
- data/lib/pubid/calconnect/urn_generator.rb +33 -0
- data/lib/pubid/calconnect/urn_parser.rb +34 -0
- data/lib/pubid/calconnect.rb +77 -0
- data/lib/pubid/ccsds/builder.rb +1 -1
- data/lib/pubid/ccsds/identifier.rb +1 -1
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
- data/lib/pubid/ccsds/urn_generator.rb +3 -3
- data/lib/pubid/cen_cenelec/builder.rb +46 -12
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -2
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
- data/lib/pubid/cen_cenelec/renderer.rb +5 -5
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +5 -5
- data/lib/pubid/cen_cenelec/urn_generator.rb +1 -1
- data/lib/pubid/cen_cenelec.rb +76 -72
- data/lib/pubid/cie/builder.rb +139 -24
- data/lib/pubid/cie/identifier.rb +7 -3
- data/lib/pubid/cie/identifiers/bundle.rb +32 -4
- data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
- data/lib/pubid/cie/identifiers/conference.rb +9 -4
- data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
- data/lib/pubid/cie/identifiers/dual_published.rb +4 -4
- data/lib/pubid/cie/identifiers/identical.rb +7 -7
- data/lib/pubid/cie/identifiers/joint_published.rb +8 -8
- data/lib/pubid/cie/identifiers/proceedings.rb +39 -0
- data/lib/pubid/cie/identifiers/standard.rb +33 -7
- data/lib/pubid/cie/identifiers/supplement.rb +24 -22
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +6 -2
- data/lib/pubid/cie/identifiers.rb +2 -0
- data/lib/pubid/cie/parser.rb +54 -5
- data/lib/pubid/cie/single_identifier.rb +40 -1
- data/lib/pubid/cie/supplement_identifier.rb +29 -16
- data/lib/pubid/cie/urn_generator.rb +11 -8
- data/lib/pubid/cie.rb +0 -1
- data/lib/pubid/components/date.rb +21 -5
- data/lib/pubid/csa/builder.rb +1 -1
- data/lib/pubid/csa/composite_identifier.rb +17 -1
- data/lib/pubid/csa/identifier.rb +48 -3
- data/lib/pubid/csa/identifiers/bundled.rb +6 -0
- data/lib/pubid/csa/identifiers/combined.rb +6 -0
- data/lib/pubid/csa/identifiers/package.rb +2 -2
- data/lib/pubid/csa/parser.rb +6 -6
- data/lib/pubid/csa/wrapper_identifier.rb +17 -0
- data/lib/pubid/doi/builder.rb +18 -0
- data/lib/pubid/doi/identifier.rb +46 -0
- data/lib/pubid/doi/identifiers/resource.rb +30 -0
- data/lib/pubid/doi/identifiers.rb +9 -0
- data/lib/pubid/doi/parser.rb +52 -0
- data/lib/pubid/doi/renderer.rb +13 -0
- data/lib/pubid/doi.rb +55 -0
- data/lib/pubid/easc/builder.rb +55 -0
- data/lib/pubid/easc/identifier.rb +61 -0
- data/lib/pubid/easc/identifiers/pmg.rb +20 -0
- data/lib/pubid/easc/identifiers/rmg.rb +19 -0
- data/lib/pubid/easc/identifiers.rb +10 -0
- data/lib/pubid/easc/parser.rb +80 -0
- data/lib/pubid/easc/renderer.rb +48 -0
- data/lib/pubid/easc/urn_generator.rb +46 -0
- data/lib/pubid/easc/urn_parser.rb +57 -0
- data/lib/pubid/easc.rb +52 -0
- data/lib/pubid/ecma/builder.rb +31 -0
- data/lib/pubid/ecma/identifier.rb +76 -0
- data/lib/pubid/ecma/identifiers/memento.rb +30 -0
- data/lib/pubid/ecma/identifiers/standard.rb +31 -0
- data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
- data/lib/pubid/ecma/identifiers.rb +11 -0
- data/lib/pubid/ecma/parser.rb +41 -0
- data/lib/pubid/ecma/renderer.rb +46 -0
- data/lib/pubid/ecma/urn_generator.rb +25 -0
- data/lib/pubid/ecma/urn_parser.rb +35 -0
- data/lib/pubid/ecma.rb +67 -0
- data/lib/pubid/etsi/builder.rb +7 -3
- data/lib/pubid/etsi/identifier.rb +1 -3
- data/lib/pubid/etsi/identifiers/base.rb +28 -10
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +128 -4
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +35 -3
- data/lib/pubid/etsi/identifiers.rb +0 -1
- data/lib/pubid/etsi/parser.rb +8 -2
- data/lib/pubid/etsi/renderer.rb +8 -2
- data/lib/pubid/etsi.rb +5 -5
- data/lib/pubid/export/exporter.rb +2 -1
- data/lib/pubid/export/flavor_exporter.rb +18 -3
- data/lib/pubid/gb/builder.rb +45 -0
- data/lib/pubid/gb/identifier.rb +64 -0
- data/lib/pubid/gb/identifiers/standard.rb +34 -0
- data/lib/pubid/gb/identifiers.rb +9 -0
- data/lib/pubid/gb/parser.rb +63 -0
- data/lib/pubid/gb/renderer.rb +35 -0
- data/lib/pubid/gb.rb +87 -0
- data/lib/pubid/gost/builder.rb +148 -0
- data/lib/pubid/gost/identifier.rb +49 -0
- data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
- data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
- data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
- data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
- data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
- data/lib/pubid/gost/identifiers.rb +13 -0
- data/lib/pubid/gost/parser.rb +97 -0
- data/lib/pubid/gost/renderer.rb +48 -0
- data/lib/pubid/gost/urn_generator.rb +46 -0
- data/lib/pubid/gost/urn_parser.rb +52 -0
- data/lib/pubid/gost.rb +49 -0
- data/lib/pubid/iala/builder.rb +22 -27
- data/lib/pubid/iala/identifier.rb +27 -2
- data/lib/pubid/iala/identifiers/advice.rb +1 -1
- data/lib/pubid/iala/identifiers/annex.rb +14 -12
- data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
- data/lib/pubid/iala/identifiers/guideline.rb +3 -1
- data/lib/pubid/iala/identifiers/letter.rb +1 -1
- data/lib/pubid/iala/identifiers/manual.rb +3 -1
- data/lib/pubid/iala/identifiers/model_course.rb +3 -1
- data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
- data/lib/pubid/iala/identifiers/report.rb +1 -1
- data/lib/pubid/iala/identifiers/resolution.rb +1 -1
- data/lib/pubid/iala/identifiers/standard.rb +3 -1
- data/lib/pubid/iala/identifiers.rb +0 -1
- data/lib/pubid/iala/renderer.rb +1 -1
- data/lib/pubid/iala/urn_generator.rb +1 -1
- data/lib/pubid/iala/urn_parser.rb +19 -2
- data/lib/pubid/iala.rb +4 -4
- data/lib/pubid/iana/builder.rb +20 -0
- data/lib/pubid/iana/identifier.rb +72 -0
- data/lib/pubid/iana/identifiers/registry.rb +33 -0
- data/lib/pubid/iana/identifiers.rb +9 -0
- data/lib/pubid/iana/parser.rb +38 -0
- data/lib/pubid/iana/renderer.rb +29 -0
- data/lib/pubid/iana/urn_generator.rb +15 -0
- data/lib/pubid/iana/urn_parser.rb +24 -0
- data/lib/pubid/iana.rb +69 -0
- data/lib/pubid/identifier.rb +210 -23
- data/lib/pubid/idf/builder.rb +1 -1
- data/lib/pubid/idf/parser.rb +2 -2
- data/lib/pubid/idf/renderer.rb +1 -1
- data/lib/pubid/idf/supplement_identifier.rb +3 -3
- data/lib/pubid/iec/builder.rb +35 -25
- data/lib/pubid/iec/identifier.rb +47 -2
- data/lib/pubid/iec/identifiers/base.rb +2 -2
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +6 -0
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +11 -11
- data/lib/pubid/iec/identifiers/international_standard.rb +8 -5
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
- data/lib/pubid/iec/identifiers/technical_report.rb +1 -1
- data/lib/pubid/iec/identifiers/technical_specification.rb +1 -1
- data/lib/pubid/iec/identifiers/vap_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/parser.rb +51 -10
- data/lib/pubid/iec/renderer.rb +18 -8
- data/lib/pubid/iec/single_identifier.rb +1 -1
- data/lib/pubid/iec/supplement_identifier.rb +32 -19
- data/lib/pubid/iec.rb +1 -6
- data/lib/pubid/ieee/aiee/builder.rb +17 -3
- data/lib/pubid/ieee/aiee/identifier.rb +45 -61
- data/lib/pubid/ieee/builder.rb +341 -68
- data/lib/pubid/ieee/compaction.rb +121 -0
- data/lib/pubid/ieee/components/draft.rb +47 -7
- data/lib/pubid/ieee/identifier.rb +1 -3
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +30 -5
- data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
- data/lib/pubid/ieee/identifiers/base.rb +106 -13
- data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
- data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_published.rb +3 -3
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +2 -1
- data/lib/pubid/ieee/identifiers/joint_development.rb +56 -11
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -1
- data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
- data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
- data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
- data/lib/pubid/ieee/identifiers.rb +2 -1
- data/lib/pubid/ieee/ire/builder.rb +7 -6
- data/lib/pubid/ieee/ire/identifier.rb +48 -33
- data/lib/pubid/ieee/nesc/builder.rb +33 -20
- data/lib/pubid/ieee/nesc/parser.rb +15 -14
- data/lib/pubid/ieee/parser.rb +461 -43
- data/lib/pubid/ieee/pre_parser.rb +1 -1
- data/lib/pubid/ieee/renderer.rb +154 -57
- data/lib/pubid/ieee/typed_stages.rb +12 -1
- data/lib/pubid/ieee/urn_generator.rb +3 -5
- data/lib/pubid/ieee.rb +56 -3
- data/lib/pubid/ietf/builder.rb +62 -0
- data/lib/pubid/ietf/identifier.rb +5 -0
- data/lib/pubid/ietf/identifiers/base.rb +75 -0
- data/lib/pubid/ietf/identifiers/bcp.rb +25 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +25 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +29 -0
- data/lib/pubid/ietf/identifiers/rfc.rb +25 -0
- data/lib/pubid/ietf/identifiers/std.rb +25 -0
- data/lib/pubid/ietf/identifiers.rb +13 -0
- data/lib/pubid/ietf/parser.rb +43 -0
- data/lib/pubid/ietf/renderer.rb +26 -0
- data/lib/pubid/ietf/urn_generator.rb +23 -0
- data/lib/pubid/ietf/urn_parser.rb +35 -0
- data/lib/pubid/ietf.rb +76 -0
- data/lib/pubid/iho/identifier.rb +1 -3
- data/lib/pubid/iho/identifiers/base.rb +1 -7
- data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
- data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
- data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
- data/lib/pubid/iho/identifiers/publication.rb +1 -1
- data/lib/pubid/iho/identifiers/standard.rb +1 -1
- data/lib/pubid/iho/identifiers.rb +0 -1
- data/lib/pubid/iho.rb +7 -7
- data/lib/pubid/isbn/builder.rb +44 -0
- data/lib/pubid/isbn/check_digit.rb +53 -0
- data/lib/pubid/isbn/identifier.rb +63 -0
- data/lib/pubid/isbn/identifiers/book.rb +30 -0
- data/lib/pubid/isbn/identifiers.rb +9 -0
- data/lib/pubid/isbn/parser.rb +45 -0
- data/lib/pubid/isbn/renderer.rb +16 -0
- data/lib/pubid/isbn.rb +52 -0
- data/lib/pubid/iso/builder.rb +9 -4
- data/lib/pubid/iso/combined_identifier.rb +2 -2
- data/lib/pubid/iso/identifier.rb +17 -1
- data/lib/pubid/iso/identifiers/directives_supplement.rb +8 -8
- data/lib/pubid/iso/normalizer.rb +2 -2
- data/lib/pubid/iso/parser.rb +16 -12
- data/lib/pubid/iso/supplement_identifier.rb +19 -6
- data/lib/pubid/iso/urn_generator.rb +4 -1
- data/lib/pubid/iso/urn_parser.rb +1 -1
- data/lib/pubid/itu/builder.rb +230 -29
- data/lib/pubid/itu/components/code.rb +48 -5
- data/lib/pubid/itu/components/designation.rb +35 -0
- data/lib/pubid/itu/components.rb +1 -0
- data/lib/pubid/itu/identifier.rb +1 -3
- data/lib/pubid/itu/identifiers/addendum.rb +15 -0
- data/lib/pubid/itu/identifiers/amendment.rb +6 -28
- data/lib/pubid/itu/identifiers/annex.rb +13 -2
- data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
- data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
- data/lib/pubid/itu/identifiers/base.rb +341 -23
- data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
- data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
- data/lib/pubid/itu/identifiers/errata.rb +15 -0
- data/lib/pubid/itu/identifiers/handbook.rb +38 -0
- data/lib/pubid/itu/identifiers/question.rb +63 -0
- data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
- data/lib/pubid/itu/identifiers/report.rb +39 -0
- data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
- data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
- data/lib/pubid/itu/identifiers/supplement.rb +119 -14
- data/lib/pubid/itu/identifiers.rb +10 -1
- data/lib/pubid/itu/model.rb +1 -1
- data/lib/pubid/itu/parser.rb +480 -26
- data/lib/pubid/itu/urn_generator.rb +36 -6
- data/lib/pubid/itu/urn_parser.rb +8 -0
- data/lib/pubid/itu.rb +11 -3
- data/lib/pubid/jcgm/builder.rb +23 -13
- data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
- data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
- data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
- data/lib/pubid/jcgm/identifiers.rb +2 -0
- data/lib/pubid/jcgm/parser.rb +66 -6
- data/lib/pubid/jcgm/renderer.rb +26 -12
- data/lib/pubid/jcgm/single_identifier.rb +74 -5
- data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
- data/lib/pubid/jcgm/urn_generator.rb +21 -13
- data/lib/pubid/jcgm/urn_parser.rb +15 -3
- data/lib/pubid/jis/identifier.rb +52 -0
- data/lib/pubid/nist/builder.rb +29 -9
- data/lib/pubid/nist/caster.rb +7 -45
- data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
- data/lib/pubid/nist/components/supplement.rb +5 -2
- data/lib/pubid/nist/configuration.rb +7 -1
- data/lib/pubid/nist/identifier.rb +1 -3
- data/lib/pubid/nist/identifiers/base.rb +121 -37
- data/lib/pubid/nist/identifiers/circular.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +1 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +1 -1
- data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
- data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
- data/lib/pubid/nist/identifiers/handbook.rb +1 -1
- data/lib/pubid/nist/identifiers/internal_report.rb +1 -1
- data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +1 -1
- data/lib/pubid/nist/identifiers/monograph.rb +1 -1
- data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
- data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
- data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
- data/lib/pubid/nist/identifiers/report.rb +1 -1
- data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
- data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
- data/lib/pubid/nist/identifiers.rb +0 -1
- data/lib/pubid/nist/parser.rb +29 -4
- data/lib/pubid/nist/preprocessor.rb +15 -0
- data/lib/pubid/nist/router.rb +3 -2
- data/lib/pubid/nist/series/ir.rb +0 -3
- data/lib/pubid/nist/supplement_identifier.rb +9 -9
- data/lib/pubid/nist.rb +13 -12
- data/lib/pubid/oasis/builder.rb +77 -0
- data/lib/pubid/oasis/identifier.rb +82 -0
- data/lib/pubid/oasis/identifiers/standard.rb +29 -0
- data/lib/pubid/oasis/identifiers.rb +9 -0
- data/lib/pubid/oasis/parser.rb +34 -0
- data/lib/pubid/oasis/renderer.rb +29 -0
- data/lib/pubid/oasis/urn_generator.rb +25 -0
- data/lib/pubid/oasis/urn_parser.rb +22 -0
- data/lib/pubid/oasis.rb +74 -0
- data/lib/pubid/ogc/builder.rb +33 -0
- data/lib/pubid/ogc/identifier.rb +77 -0
- data/lib/pubid/ogc/identifiers/document.rb +26 -0
- data/lib/pubid/ogc/identifiers.rb +10 -0
- data/lib/pubid/ogc/parser.rb +40 -0
- data/lib/pubid/ogc/renderer.rb +33 -0
- data/lib/pubid/ogc/urn_generator.rb +14 -0
- data/lib/pubid/ogc/urn_parser.rb +22 -0
- data/lib/pubid/ogc.rb +71 -0
- data/lib/pubid/oiml/builder.rb +31 -7
- data/lib/pubid/oiml/identifier.rb +9 -1
- data/lib/pubid/oiml/parser.rb +11 -12
- data/lib/pubid/oiml/renderer.rb +13 -13
- data/lib/pubid/oiml/single_identifier.rb +20 -0
- data/lib/pubid/oiml/supplement_identifier.rb +9 -9
- data/lib/pubid/oiml/urn_parser.rb +23 -6
- data/lib/pubid/oiml.rb +4 -0
- data/lib/pubid/omg/builder.rb +19 -0
- data/lib/pubid/omg/identifier.rb +44 -0
- data/lib/pubid/omg/identifiers/specification.rb +32 -0
- data/lib/pubid/omg/identifiers.rb +9 -0
- data/lib/pubid/omg/parser.rb +40 -0
- data/lib/pubid/omg/renderer.rb +19 -0
- data/lib/pubid/omg.rb +51 -0
- data/lib/pubid/parsers/mr_string.rb +101 -7
- data/lib/pubid/plateau/builder.rb +8 -4
- data/lib/pubid/plateau/identifier.rb +1 -3
- data/lib/pubid/plateau/identifiers/base.rb +1 -6
- data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
- data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
- data/lib/pubid/plateau/identifiers.rb +0 -1
- data/lib/pubid/plateau/parser.rb +15 -5
- data/lib/pubid/plateau/renderer.rb +1 -1
- data/lib/pubid/plateau/supplement_identifier.rb +11 -11
- data/lib/pubid/plateau.rb +4 -4
- data/lib/pubid/renderers/human_readable.rb +3 -1
- data/lib/pubid/renderers/mr_string.rb +46 -4
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/rendering/supplement.rb +4 -4
- data/lib/pubid/sae/builder.rb +1 -1
- data/lib/pubid/sae/identifier.rb +1 -3
- data/lib/pubid/sae/identifiers/base.rb +10 -7
- data/lib/pubid/sae/identifiers.rb +0 -1
- data/lib/pubid/sae.rb +3 -3
- data/lib/pubid/tgpp/builder.rb +41 -0
- data/lib/pubid/tgpp/identifier.rb +91 -0
- data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
- data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
- data/lib/pubid/tgpp/identifiers.rb +11 -0
- data/lib/pubid/tgpp/parser.rb +62 -0
- data/lib/pubid/tgpp/renderer.rb +36 -0
- data/lib/pubid/tgpp/urn_generator.rb +20 -0
- data/lib/pubid/tgpp/urn_parser.rb +28 -0
- data/lib/pubid/tgpp.rb +78 -0
- data/lib/pubid/type_resolver.rb +59 -0
- data/lib/pubid/un/builder.rb +42 -0
- data/lib/pubid/un/identifier.rb +37 -0
- data/lib/pubid/un/identifiers/document.rb +24 -0
- data/lib/pubid/un/identifiers.rb +9 -0
- data/lib/pubid/un/parser.rb +25 -0
- data/lib/pubid/un/renderer.rb +11 -0
- data/lib/pubid/un.rb +46 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/builder.rb +55 -0
- data/lib/pubid/w3c/identifier.rb +101 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
- data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
- data/lib/pubid/w3c/identifiers/note.rb +30 -0
- data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/standard.rb +12 -0
- data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
- data/lib/pubid/w3c/identifiers.rb +25 -0
- data/lib/pubid/w3c/parser.rb +43 -0
- data/lib/pubid/w3c/renderer.rb +35 -0
- data/lib/pubid/w3c/urn_generator.rb +18 -0
- data/lib/pubid/w3c/urn_parser.rb +36 -0
- data/lib/pubid/w3c.rb +67 -0
- data/lib/pubid/xsf/builder.rb +17 -0
- data/lib/pubid/xsf/identifier.rb +62 -0
- data/lib/pubid/xsf/identifiers/xep.rb +31 -0
- data/lib/pubid/xsf/identifiers.rb +9 -0
- data/lib/pubid/xsf/parser.rb +25 -0
- data/lib/pubid/xsf/renderer.rb +23 -0
- data/lib/pubid/xsf/urn_generator.rb +13 -0
- data/lib/pubid/xsf/urn_parser.rb +18 -0
- data/lib/pubid/xsf.rb +76 -0
- data/lib/pubid.rb +25 -1
- metadata +205 -4
- data/lib/pubid/cie/components/code.rb +0 -80
- data/lib/pubid/iala/identifiers/base.rb +0 -14
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Itu
|
|
5
|
+
module Identifiers
|
|
6
|
+
# A labelled appendix of a Recommendation — "ITU-T G.101 App. I
|
|
7
|
+
# (05/2000)", "ITU-T G.722 (1988) App. IV (11/2006)".
|
|
8
|
+
#
|
|
9
|
+
# Structurally the twin of AnnexOfRecommendation: an appendix is
|
|
10
|
+
# published and dated separately from the Recommendation it appends, and
|
|
11
|
+
# may itself carry an amendment/errata ("ITU-T G.729 App. I (2002)
|
|
12
|
+
# Amd. 1"). The label is a Roman numeral rather than a series letter.
|
|
13
|
+
class AppendixOfRecommendation < Identifier
|
|
14
|
+
attribute :base, Identifier, polymorphic: true
|
|
15
|
+
# The appendix label ("I", "II", "IV"). Named `number` for symmetry
|
|
16
|
+
# with Supplement's ordinal and AnnexOfRecommendation's label; it
|
|
17
|
+
# shadows Identifier#number (code&.number), which is nil here anyway —
|
|
18
|
+
# the document number is reached via #root.
|
|
19
|
+
attribute :number, :string
|
|
20
|
+
# The companion artefact published under the appendix's designation:
|
|
21
|
+
# "test vectors" or "Software". Its own catalogue record, so it must
|
|
22
|
+
# stay distinct from the appendix itself.
|
|
23
|
+
attribute :material, :string
|
|
24
|
+
|
|
25
|
+
# Compact serialization: the nested (itself-flat) base plus this
|
|
26
|
+
# document's own label, date and language. sector/series/code belong to
|
|
27
|
+
# the base and are deliberately not re-emitted.
|
|
28
|
+
key_value do
|
|
29
|
+
map "_type", to: :_type
|
|
30
|
+
map "number", to: :number
|
|
31
|
+
map "material", to: :material
|
|
32
|
+
map "year", with: { to: :year_to_kv, from: :year_from_kv }
|
|
33
|
+
map "month", with: { to: :month_to_kv, from: :month_from_kv }
|
|
34
|
+
map "base", with: { to: :base_to_kv, from: :base_from_kv }
|
|
35
|
+
map "language", to: :language
|
|
36
|
+
map "common_text_twin",
|
|
37
|
+
with: { to: :common_text_twin_to_kv,
|
|
38
|
+
from: :common_text_twin_from_kv }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# "<base urn>:appendix:<label>[:<date>]" — the appendix's own date must
|
|
42
|
+
# be there, or two editions of one appendix share a URN (the base's
|
|
43
|
+
# date rides inside base_urn, so omitting this one would be asymmetric).
|
|
44
|
+
def to_urn
|
|
45
|
+
segments = [base&.to_urn || "urn:itu", "appendix", number&.downcase]
|
|
46
|
+
# Without this the test-vector record and the appendix itself would
|
|
47
|
+
# share a URN.
|
|
48
|
+
segments << material.downcase.gsub(/[^a-z0-9]/, "") if material
|
|
49
|
+
segments << urn_date_segment
|
|
50
|
+
segments.compact.join(":")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def render_base(**opts)
|
|
54
|
+
result = base ? base.render_base(**opts) : "#{publisher}-#{sector}"
|
|
55
|
+
|
|
56
|
+
result += " App. #{number}"
|
|
57
|
+
result += " #{material}" if material
|
|
58
|
+
result + render_date_suffix
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# MR: recurse into the appendixed document and append
|
|
62
|
+
# "app.<label>[.year]" (the documented supplement-suffix hook), so the
|
|
63
|
+
# slug stays distinct per appendix. Without it the wrapper's own nil
|
|
64
|
+
# sector/series/code would collapse every appendix onto "itu.<year>".
|
|
65
|
+
def mr_supplement_suffix
|
|
66
|
+
label = "#{number}#{material}".downcase.gsub(/[^a-z0-9]/, "")
|
|
67
|
+
|
|
68
|
+
["app", label.empty? ? nil : label, date&.year].compact.join(".")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def ==(other)
|
|
72
|
+
return false unless other.instance_of?(self.class)
|
|
73
|
+
|
|
74
|
+
base == other.base &&
|
|
75
|
+
number == other.number &&
|
|
76
|
+
material == other.material &&
|
|
77
|
+
date == other.date &&
|
|
78
|
+
language == other.language &&
|
|
79
|
+
common_text_twin == other.common_text_twin
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def urn_date_segment
|
|
85
|
+
return nil unless date
|
|
86
|
+
|
|
87
|
+
date.month ? "#{date.month}/#{date.year}" : date.year.to_s
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -2,17 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Itu
|
|
5
|
-
# Base class for all ITU identifiers. Canonical name Pubid::Itu::Identifier
|
|
6
|
-
# (Identifiers::Base is a back-compat alias).
|
|
5
|
+
# Base class for all ITU identifiers. Canonical name Pubid::Itu::Identifier.
|
|
7
6
|
class Identifier < ::Pubid::Identifier
|
|
8
7
|
# Parse an ITU identifier string into an identifier object.
|
|
9
8
|
def self.parse(identifier)
|
|
10
|
-
parsed = Parser.parse(identifier)
|
|
9
|
+
parsed = Parser.parse(normalize_whitespace(identifier))
|
|
11
10
|
Builder.build(parsed)
|
|
12
11
|
rescue Parslet::ParseFailed => e
|
|
13
12
|
raise "Failed to parse ITU identifier '#{identifier}': #{e.message}"
|
|
14
13
|
end
|
|
15
14
|
|
|
15
|
+
# ITU's own listings occasionally carry a doubled space
|
|
16
|
+
# ("ITU-T D.271 (10/2016)"). Whitespace is never significant in an ITU
|
|
17
|
+
# identifier, so collapse runs of it rather than teaching every rule to
|
|
18
|
+
# tolerate them. Any string over the shared input-length guard is left
|
|
19
|
+
# untouched — `Pubid.parse` rejects it before this point, and the guard
|
|
20
|
+
# exists precisely to keep long inputs away from regexes.
|
|
21
|
+
def self.normalize_whitespace(identifier)
|
|
22
|
+
return identifier unless identifier.is_a?(String)
|
|
23
|
+
return identifier if identifier.length > ::Pubid::MAX_INPUT_LENGTH
|
|
24
|
+
|
|
25
|
+
identifier.gsub(/[[:space:]]+/, " ").strip
|
|
26
|
+
end
|
|
27
|
+
private_class_method :normalize_whitespace
|
|
28
|
+
|
|
16
29
|
# Long-form ↔ ITU single-letter language code map. The parser produces
|
|
17
30
|
# single-letter codes (E/F/S/R/A/C); API callers (e.g. metanorma-itu)
|
|
18
31
|
# pass long-form (en/fr/es/ru/ar/zh). Storage is normalized to the
|
|
@@ -30,6 +43,36 @@ module Pubid
|
|
|
30
43
|
attribute :code, Pubid::Itu::Components::Code
|
|
31
44
|
attribute :date, Pubid::Components::Date
|
|
32
45
|
attribute :language, :string
|
|
46
|
+
# "(V14)" of "ITU-T H.264 (V14) (08/2021)" — an ITU-T revision marker
|
|
47
|
+
# distinct from the publication date. Declared here (not on the leaves)
|
|
48
|
+
# because `render_base` lives here and the parser feeds it to both plain
|
|
49
|
+
# and combined recommendations, and to the nested base of a supplement.
|
|
50
|
+
# Safe from the number/stage redefinition landmine: ::Pubid::Identifier
|
|
51
|
+
# declares no `version` attribute, so this is a new one, not a retype.
|
|
52
|
+
attribute :version, :string
|
|
53
|
+
# The literal word "series" of "ITU-T E-100 series Suppl. 1" and
|
|
54
|
+
# "ITU-T E.1100 series Suppl. 1" — the document is the series group, not
|
|
55
|
+
# one Recommendation within it. It cannot live inside `series` itself
|
|
56
|
+
# because it also follows a *dotted* code, where folding it into the
|
|
57
|
+
# series token would corrupt the value every index row is keyed on.
|
|
58
|
+
# Named so the common case is the `false` default and stays out of
|
|
59
|
+
# `to_hash`.
|
|
60
|
+
attribute :series_word, :boolean, default: -> { false }
|
|
61
|
+
# A series-code document joins its mnemonic series to its number with a
|
|
62
|
+
# dash rather than a dot ("ITU-T EMC-5", "ITU-T SEC-QKD"). Keeping the
|
|
63
|
+
# two halves split — rather than storing "EMC-5" in `series` — is what
|
|
64
|
+
# keeps `root.number` non-empty for relaton-index. Named for the rare
|
|
65
|
+
# form, so the dotted majority stays out of `to_hash`.
|
|
66
|
+
attribute :series_dash, :boolean, default: -> { false }
|
|
67
|
+
# "ITU-T H.350 attachment (08/2003)" — the machine-readable attachment
|
|
68
|
+
# of a Recommendation, catalogued as its own record.
|
|
69
|
+
attribute :attachment, :boolean, default: -> { false }
|
|
70
|
+
# The upper bound of a Recommendation range published as one document —
|
|
71
|
+
# "ITU-T Q.120-Q.139 (11/1988)", where this holds "Q.139". A plain string
|
|
72
|
+
# rather than a structured designation: five legacy records, and the
|
|
73
|
+
# printed form is the whole of their identity.
|
|
74
|
+
attribute :range_end, :string
|
|
75
|
+
attribute :common_text_twin, ::Pubid::Identifier
|
|
33
76
|
|
|
34
77
|
def initialize(**kwargs)
|
|
35
78
|
if kwargs[:language]
|
|
@@ -41,10 +84,91 @@ module Pubid
|
|
|
41
84
|
validate_ob_no_sector!
|
|
42
85
|
end
|
|
43
86
|
|
|
87
|
+
# The document number lives on the `code` component for ITU; surface it at
|
|
88
|
+
# the identifier root so consumers that key on `#number` — e.g.
|
|
89
|
+
# Relaton::Index's sort/bsearch narrowing on `id.root.number.to_s` — work
|
|
90
|
+
# without special-casing ITU. Returns the `code.number` string (e.g.
|
|
91
|
+
# "530"); serialization is unaffected because the flat key_value block
|
|
92
|
+
# maps "number" via `number_to_kv`/`number_from_kv`, which read/write
|
|
93
|
+
# `code.number` directly and never touch the inherited `number` attribute.
|
|
94
|
+
# Supplement/Amendment/Corrigendum/Errata declare their own `:string`
|
|
95
|
+
# `number` (the ordinal), which overrides this reader; their base document
|
|
96
|
+
# number is still reachable via `root.number`.
|
|
97
|
+
def number
|
|
98
|
+
code&.number
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# ITU keeps the document number and its edition/part together inside one
|
|
102
|
+
# Code component (like ETSI, unlike ISO's separate `part` attribute), so a
|
|
103
|
+
# top-level exclude(:part) can't reach the part. Handle it during the
|
|
104
|
+
# nested-exclusion pass: when :part/:parts is excluded, return a copy of
|
|
105
|
+
# the Code with its parts cleared while keeping number/series/subseries.
|
|
106
|
+
# This lets a part-less reference (e.g. `ITU-R P.838`) match every edition
|
|
107
|
+
# (`ITU-R P.838-3`) via matches?(other, ignore: [:parts]). Any non-Code
|
|
108
|
+
# value falls through to super, so nested identifiers (common_text_twin,
|
|
109
|
+
# supplement `base`, combined `Designation`s) still recurse.
|
|
110
|
+
def exclude_from_nested(value, args)
|
|
111
|
+
part_keys = args & %i[part parts]
|
|
112
|
+
if value.is_a?(Pubid::Itu::Components::Code) && !part_keys.empty?
|
|
113
|
+
return Pubid::Itu::Components::Code.new(
|
|
114
|
+
imp_marker: value.imp_marker,
|
|
115
|
+
number: value.number,
|
|
116
|
+
series_suffix: value.series_suffix,
|
|
117
|
+
series_suffix_spaced: value.series_suffix_spaced,
|
|
118
|
+
subseries: value.subseries,
|
|
119
|
+
parts: [],
|
|
120
|
+
qualifier: value.qualifier,
|
|
121
|
+
qualifier_glued: value.qualifier_glued,
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
super
|
|
126
|
+
end
|
|
127
|
+
|
|
44
128
|
# Generate URN for this identifier
|
|
45
129
|
#
|
|
46
130
|
# @return [String] URN representation
|
|
47
131
|
|
|
132
|
+
# ITU encodes identity across `sector` (T/R/CD), `series` (G/H/J…), and
|
|
133
|
+
# `code` (number with optional part), not in the inherited `number`/
|
|
134
|
+
# `typed_stage`. The generic MrString renderer would otherwise drop all
|
|
135
|
+
# three and emit just `ITU`. Losslessness for issue #142 requires the
|
|
136
|
+
# sector letter, series letter, and document number to appear in MR.
|
|
137
|
+
# Lowercased to match the all-lowercase MR convention.
|
|
138
|
+
def mr_publisher
|
|
139
|
+
publisher&.to_s&.downcase
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def mr_type
|
|
143
|
+
sector&.sector&.to_s&.downcase
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def mr_number_with_part
|
|
147
|
+
segments = []
|
|
148
|
+
segments << series&.series&.to_s&.downcase if series&.series
|
|
149
|
+
# The edition word and the qualifier letter are part of the document's
|
|
150
|
+
# identity, so they must reach the slug: without them "D.200" and
|
|
151
|
+
# "D.200 R" — and, worse, "Q.2931 B" and "Q.2931 C" — collapse onto
|
|
152
|
+
# one MR string. They are glued to the number rather than given their
|
|
153
|
+
# own "-" segment so they read as part of it ("x-50bis", "d-200r").
|
|
154
|
+
number = code&.number&.to_s
|
|
155
|
+
if number
|
|
156
|
+
number += code.series_suffix.to_s if code.series_suffix
|
|
157
|
+
number += code.qualifier.to_s.downcase if code.qualifier
|
|
158
|
+
segments << number
|
|
159
|
+
end
|
|
160
|
+
segments << code&.subseries&.to_s if code&.subseries
|
|
161
|
+
segments.concat(code&.parts&.map(&:to_s) || [])
|
|
162
|
+
# Same reasoning as the suffixes above, and as the URN generator: these
|
|
163
|
+
# three distinguish documents that otherwise slug identically.
|
|
164
|
+
segments << "series" if series_word
|
|
165
|
+
segments << "attachment" if attachment
|
|
166
|
+
segments << "to-#{range_end.to_s.downcase.tr('.', '-')}" if range_end
|
|
167
|
+
return nil if segments.empty?
|
|
168
|
+
|
|
169
|
+
segments.join("-")
|
|
170
|
+
end
|
|
171
|
+
|
|
48
172
|
# Stored as a plain string (always "ITU") so it round-trips through
|
|
49
173
|
# to_hash/from_hash. Was a `def publisher` method, which made lutaml
|
|
50
174
|
# serialize a String against the Components::Publisher attribute.
|
|
@@ -61,29 +185,43 @@ module Pubid
|
|
|
61
185
|
# identifiers, otherwise the default short form.
|
|
62
186
|
def to_s(**opts)
|
|
63
187
|
opts = self.class.normalize_to_s_opts(opts)
|
|
64
|
-
render_base(**opts) + render_language_suffix
|
|
188
|
+
result = render_base(**opts) + render_language_suffix
|
|
189
|
+
result += " | #{common_text_twin}" if common_text_twin
|
|
190
|
+
result
|
|
65
191
|
end
|
|
66
192
|
|
|
67
193
|
def render_base(**_opts)
|
|
68
194
|
result = "#{publisher}-#{sector}"
|
|
69
195
|
|
|
70
|
-
# Add series and code
|
|
71
|
-
|
|
72
|
-
|
|
196
|
+
# Add series and code. A series with no code is a series GROUP
|
|
197
|
+
# ("ITU-T G-100 series"); without this branch it rendered a dangling
|
|
198
|
+
# trailing dot.
|
|
199
|
+
result += if series && code
|
|
200
|
+
" #{series}#{series_dash ? '-' : '.'}#{code}"
|
|
201
|
+
elsif series
|
|
202
|
+
" #{series}"
|
|
73
203
|
else
|
|
74
204
|
" #{code}"
|
|
75
205
|
end
|
|
76
206
|
|
|
77
|
-
|
|
78
|
-
if
|
|
79
|
-
|
|
80
|
-
" (#{date.month}/#{date.year})"
|
|
81
|
-
else
|
|
82
|
-
" (#{date.year})"
|
|
83
|
-
end
|
|
84
|
-
end
|
|
207
|
+
result += "-#{range_end}" if range_end
|
|
208
|
+
result += " series" if series_word
|
|
209
|
+
result += " attachment" if attachment
|
|
85
210
|
|
|
86
|
-
|
|
211
|
+
# Add version marker if present — always between code and date
|
|
212
|
+
result += " (V#{version})" if version
|
|
213
|
+
|
|
214
|
+
result + render_date_suffix
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# " (MM/YYYY)", or " (YYYY)" when the month is unknown; "" when undated.
|
|
218
|
+
# Shared by every type that prints its date this way (Supplement and its
|
|
219
|
+
# subclasses, CombinedIdentifier, AnnexOfRecommendation). NOT used by
|
|
220
|
+
# SpecialPublication, which zero-pads its month.
|
|
221
|
+
def render_date_suffix
|
|
222
|
+
return "" unless date
|
|
223
|
+
|
|
224
|
+
date.month ? " (#{date.month}/#{date.year})" : " (#{date.year})"
|
|
87
225
|
end
|
|
88
226
|
|
|
89
227
|
def render_language_suffix
|
|
@@ -109,14 +247,199 @@ module Pubid
|
|
|
109
247
|
opts
|
|
110
248
|
end
|
|
111
249
|
|
|
250
|
+
# Class-strict, like Supplement#== — the ITU *type* is part of the
|
|
251
|
+
# identity, not just the sector/series/number. Report ITU-R BT.2020-1 and
|
|
252
|
+
# Recommendation ITU-R BT.2020-1 are two different, both-current
|
|
253
|
+
# documents; an `is_a?` guard would make them equal (and `#matches?`
|
|
254
|
+
# resolve one to the other). Using `self.class` rather than a hard-coded
|
|
255
|
+
# class keeps the comparison symmetric in both directions, and closes the
|
|
256
|
+
# same one-way holes that existed against CombinedIdentifier and
|
|
257
|
+
# SpecialPublication.
|
|
112
258
|
def ==(other)
|
|
113
|
-
return false unless other.
|
|
259
|
+
return false unless other.instance_of?(self.class)
|
|
114
260
|
|
|
115
261
|
sector == other.sector &&
|
|
116
262
|
series == other.series &&
|
|
117
263
|
code == other.code &&
|
|
118
264
|
date == other.date &&
|
|
119
|
-
|
|
265
|
+
version == other.version &&
|
|
266
|
+
# "the E.1100 series" is not Recommendation E.1100.
|
|
267
|
+
series_word == other.series_word &&
|
|
268
|
+
series_dash == other.series_dash &&
|
|
269
|
+
attachment == other.attachment &&
|
|
270
|
+
range_end == other.range_end &&
|
|
271
|
+
language == other.language &&
|
|
272
|
+
common_text_twin == other.common_text_twin
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# --- Compact flat key_value converters (shared) --------------------
|
|
276
|
+
# Collapse the identity components (Sector/Series/Code/Date) to bare
|
|
277
|
+
# top-level scalars so the serialized hash is flat and index-friendly,
|
|
278
|
+
# mirroring ISO/ETSI/JCGM/OIML. Used by the per-leaf key_value blocks
|
|
279
|
+
# (see StandardSerialization) and by the Supplement/Annex/Combined
|
|
280
|
+
# blocks. `publisher` ("ITU") is intentionally never mapped — it is
|
|
281
|
+
# reconstructed from its attribute default.
|
|
282
|
+
|
|
283
|
+
def sector_to_kv(model, doc)
|
|
284
|
+
emit_kv(doc, "sector", model.sector&.sector)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def sector_from_kv(model, value)
|
|
288
|
+
model.sector = Components::Sector.new(sector: value.to_s)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def series_to_kv(model, doc)
|
|
292
|
+
emit_kv(doc, "series", model.series&.series)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def series_from_kv(model, value)
|
|
296
|
+
model.series = Components::Series.new(series: value.to_s)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def imp_marker_to_kv(model, doc)
|
|
300
|
+
emit_kv(doc, "imp_marker", model.code&.imp_marker)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def imp_marker_from_kv(model, value)
|
|
304
|
+
code_for(model).imp_marker = value.to_s
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def number_to_kv(model, doc)
|
|
308
|
+
emit_kv(doc, "number", model.code&.number)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def number_from_kv(model, value)
|
|
312
|
+
code_for(model).number = value.to_s
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def series_suffix_to_kv(model, doc)
|
|
316
|
+
emit_kv(doc, "series_suffix", model.code&.series_suffix)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def series_suffix_from_kv(model, value)
|
|
320
|
+
code_for(model).series_suffix = value.to_s
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# The three spelling/qualifier fields of Components::Code. The two
|
|
324
|
+
# booleans emit only when true, so no already-published index row gains
|
|
325
|
+
# a key; `qualifier` emits only when present.
|
|
326
|
+
def series_suffix_spaced_to_kv(model, doc)
|
|
327
|
+
return unless model.code&.series_suffix_spaced
|
|
328
|
+
|
|
329
|
+
doc["series_suffix_spaced"] = true
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def series_suffix_spaced_from_kv(model, value)
|
|
333
|
+
code_for(model).series_suffix_spaced = value
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def qualifier_to_kv(model, doc)
|
|
337
|
+
emit_kv(doc, "qualifier", model.code&.qualifier)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def qualifier_from_kv(model, value)
|
|
341
|
+
code_for(model).qualifier = value.to_s
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def qualifier_glued_to_kv(model, doc)
|
|
345
|
+
return unless model.code&.qualifier_glued
|
|
346
|
+
|
|
347
|
+
doc["qualifier_glued"] = true
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def qualifier_glued_from_kv(model, value)
|
|
351
|
+
code_for(model).qualifier_glued = value
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def subseries_to_kv(model, doc)
|
|
355
|
+
emit_kv(doc, "subseries", model.code&.subseries)
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def subseries_from_kv(model, value)
|
|
359
|
+
code_for(model).subseries = value.to_s
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def parts_to_kv(model, doc)
|
|
363
|
+
parts = model.code&.parts
|
|
364
|
+
return if parts.nil? || parts.empty?
|
|
365
|
+
|
|
366
|
+
doc.add_child(
|
|
367
|
+
Lutaml::KeyValue::DataModel::Element.new("parts", parts.map(&:to_s)),
|
|
368
|
+
)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def parts_from_kv(model, value)
|
|
372
|
+
code_for(model).parts = Array(value).map(&:to_s)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def year_to_kv(model, doc)
|
|
376
|
+
emit_kv(doc, "year", model.date&.year)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def year_from_kv(model, value)
|
|
380
|
+
date_for(model).year = value.to_s
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def month_to_kv(model, doc)
|
|
384
|
+
emit_kv(doc, "month", model.date&.month)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def month_from_kv(model, value)
|
|
388
|
+
date_for(model).month = value.to_s
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# Serialize a nested `base` identifier via its own to_hash so it collapses
|
|
392
|
+
# to the compact shape, and re-dispatch through the flavor base on load so
|
|
393
|
+
# `_type` resolves to the concrete subclass (a bare polymorphic cast would
|
|
394
|
+
# rebuild a plain Identifier and lose the subclass). Mirrors ETSI/JCGM.
|
|
395
|
+
def base_to_kv(model, doc)
|
|
396
|
+
return unless model.base
|
|
397
|
+
|
|
398
|
+
doc.add_child(
|
|
399
|
+
Lutaml::KeyValue::DataModel::Element.new("base", model.base.to_hash),
|
|
400
|
+
)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def base_from_kv(model, value)
|
|
404
|
+
return unless value
|
|
405
|
+
|
|
406
|
+
model.base = Pubid::Itu::Identifier.from_hash(value)
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# The common-text twin ("| ISO/IEC 13818-1:2022") is another flavor's
|
|
410
|
+
# identifier (ISO/IEC …); serialize it via its own flat to_hash and
|
|
411
|
+
# reconstruct it cross-flavor through the top-level polymorphic router so
|
|
412
|
+
# its concrete class (and custom mappings) are restored by `_type`.
|
|
413
|
+
def common_text_twin_to_kv(model, doc)
|
|
414
|
+
return unless model.common_text_twin
|
|
415
|
+
|
|
416
|
+
doc.add_child(
|
|
417
|
+
Lutaml::KeyValue::DataModel::Element.new(
|
|
418
|
+
"common_text_twin", model.common_text_twin.to_hash
|
|
419
|
+
),
|
|
420
|
+
)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def common_text_twin_from_kv(model, value)
|
|
424
|
+
return unless value
|
|
425
|
+
|
|
426
|
+
model.common_text_twin = ::Pubid::Identifier.from_hash(value)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def emit_kv(doc, key, value)
|
|
430
|
+
return if value.nil? || value.to_s.empty?
|
|
431
|
+
|
|
432
|
+
doc.add_child(
|
|
433
|
+
Lutaml::KeyValue::DataModel::Element.new(key, value.to_s),
|
|
434
|
+
)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def code_for(model)
|
|
438
|
+
model.code ||= Components::Code.new
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def date_for(model)
|
|
442
|
+
model.date ||= Pubid::Components::Date.new
|
|
120
443
|
end
|
|
121
444
|
|
|
122
445
|
private
|
|
@@ -141,10 +464,5 @@ module Pubid
|
|
|
141
464
|
end
|
|
142
465
|
end
|
|
143
466
|
|
|
144
|
-
module Identifiers
|
|
145
|
-
# Backward-compatible alias: ITU's base class used to be
|
|
146
|
-
# Pubid::Itu::Identifiers::Base. It is now Pubid::Itu::Identifier.
|
|
147
|
-
Base = Pubid::Itu::Identifier
|
|
148
|
-
end
|
|
149
467
|
end
|
|
150
468
|
end
|
|
@@ -3,41 +3,117 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Itu
|
|
5
5
|
module Identifiers
|
|
6
|
-
# Combined
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
# Combined (joint) recommendation — a single document published under two
|
|
7
|
+
# or more series/number designations at once.
|
|
8
|
+
# Format: ITU-T G.780/Y.1351 (dual)
|
|
9
|
+
# ITU-T G.780/Y.1351/Z.1362 (triple)
|
|
10
|
+
#
|
|
11
|
+
# The primary designation lives on the base `series`/`code`; every
|
|
12
|
+
# additional designation is a Components::Designation in `combined`
|
|
13
|
+
# (one for a dual form, two+ for triple).
|
|
14
|
+
class CombinedIdentifier < Identifier
|
|
15
|
+
include StandardSerialization
|
|
16
|
+
|
|
17
|
+
attribute :combined, Pubid::Itu::Components::Designation,
|
|
18
|
+
collection: true, default: -> { [] }
|
|
19
|
+
|
|
20
|
+
# Extra map merged on top of StandardSerialization: the additional
|
|
21
|
+
# designations as a flat list of { series, number, subseries?, parts? }.
|
|
22
|
+
key_value do
|
|
23
|
+
map "combined",
|
|
24
|
+
with: { to: :combined_to_kv, from: :combined_from_kv }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def combined_to_kv(model, doc)
|
|
28
|
+
designations = model.combined
|
|
29
|
+
return if designations.nil? || designations.empty?
|
|
30
|
+
|
|
31
|
+
rows = designations.map do |d|
|
|
32
|
+
row = { "series" => d.series&.series.to_s,
|
|
33
|
+
"number" => d.code&.number.to_s }
|
|
34
|
+
row["subseries"] = d.code.subseries.to_s if d.code&.subseries
|
|
35
|
+
row["parts"] = d.code.parts.map(&:to_s) if d.code&.parts&.any?
|
|
36
|
+
# Each emitted only when set, so an ordinary joint designation's
|
|
37
|
+
# row keeps its existing two-key shape.
|
|
38
|
+
if d.code&.series_suffix
|
|
39
|
+
row["series_suffix"] = d.code.series_suffix.to_s
|
|
40
|
+
row["series_suffix_spaced"] = true if d.code.series_suffix_spaced
|
|
41
|
+
end
|
|
42
|
+
if d.code&.qualifier
|
|
43
|
+
row["qualifier"] = d.code.qualifier.to_s
|
|
44
|
+
row["qualifier_glued"] = true if d.code.qualifier_glued
|
|
45
|
+
end
|
|
46
|
+
row
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
doc.add_child(
|
|
50
|
+
Lutaml::KeyValue::DataModel::Element.new("combined", rows),
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def combined_from_kv(model, value)
|
|
55
|
+
model.combined = Array(value).map do |row|
|
|
56
|
+
row = row.transform_keys(&:to_s)
|
|
57
|
+
Components::Designation.new(
|
|
58
|
+
series: Components::Series.new(series: row["series"].to_s),
|
|
59
|
+
code: Components::Code.new(
|
|
60
|
+
number: row["number"].to_s,
|
|
61
|
+
series_suffix: row["series_suffix"]&.to_s,
|
|
62
|
+
series_suffix_spaced: !!row["series_suffix_spaced"],
|
|
63
|
+
subseries: row["subseries"]&.to_s,
|
|
64
|
+
parts: Array(row["parts"]).map(&:to_s),
|
|
65
|
+
qualifier: row["qualifier"]&.to_s,
|
|
66
|
+
qualifier_glued: !!row["qualifier_glued"],
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Rendering hooks into `render_base` (not `to_s`) so that any wrapper
|
|
73
|
+
# composing this identifier — AnnexOfRecommendation, which renders
|
|
74
|
+
# "<base.render_base> Annex <label>" — keeps the co-designations.
|
|
75
|
+
# Overriding `to_s` instead silently dropped the "/Y.1351" half.
|
|
76
|
+
# The inherited `to_s` adds the language suffix and common-text twin.
|
|
77
|
+
def render_base(**_opts)
|
|
14
78
|
result = "#{publisher}-#{sector}"
|
|
15
79
|
|
|
16
80
|
# Add primary series and code
|
|
17
81
|
result += if series
|
|
18
|
-
" #{series}
|
|
82
|
+
" #{series}#{series_dash ? '-' : '.'}#{code}"
|
|
19
83
|
else
|
|
20
84
|
" #{code}"
|
|
21
85
|
end
|
|
22
86
|
|
|
23
|
-
|
|
24
|
-
if combined_series && combined_code
|
|
25
|
-
result += "/#{combined_series}.#{combined_code}"
|
|
26
|
-
end
|
|
87
|
+
result += "-#{range_end}" if range_end
|
|
27
88
|
|
|
28
|
-
# Add
|
|
29
|
-
if
|
|
30
|
-
result +=
|
|
31
|
-
" (#{date.month}/#{date.year})"
|
|
32
|
-
else
|
|
33
|
-
" (#{date.year})"
|
|
34
|
-
end
|
|
89
|
+
# Add additional designations
|
|
90
|
+
if combined&.any?
|
|
91
|
+
result += "/#{combined.join('/')}"
|
|
35
92
|
end
|
|
36
93
|
|
|
37
|
-
|
|
38
|
-
result += "
|
|
94
|
+
result += " series" if series_word
|
|
95
|
+
result += " attachment" if attachment
|
|
96
|
+
|
|
97
|
+
# Add version marker if present — always between code and date
|
|
98
|
+
result += " (V#{version})" if version
|
|
99
|
+
|
|
100
|
+
result + render_date_suffix
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def ==(other)
|
|
104
|
+
return false unless other.is_a?(CombinedIdentifier)
|
|
39
105
|
|
|
40
|
-
|
|
106
|
+
sector == other.sector &&
|
|
107
|
+
series == other.series &&
|
|
108
|
+
code == other.code &&
|
|
109
|
+
combined == other.combined &&
|
|
110
|
+
date == other.date &&
|
|
111
|
+
version == other.version &&
|
|
112
|
+
series_word == other.series_word &&
|
|
113
|
+
series_dash == other.series_dash &&
|
|
114
|
+
attachment == other.attachment &&
|
|
115
|
+
range_end == other.range_end &&
|
|
116
|
+
language == other.language
|
|
41
117
|
end
|
|
42
118
|
end
|
|
43
119
|
end
|