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,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
# Human-readable renderer for EASC identifiers.
|
|
6
|
+
#
|
|
7
|
+
# Produces strings like:
|
|
8
|
+
# "ПМГ 03-2025"
|
|
9
|
+
# "ПМГ В 31-2001" (defense variant)
|
|
10
|
+
# "РМГ 151-2025"
|
|
11
|
+
#
|
|
12
|
+
# Always renders in Cyrillic — the canonical form used on
|
|
13
|
+
# mgscatalog.by. Latin transliterations (PMG, RMG, V) parse but
|
|
14
|
+
# render to Cyrillic.
|
|
15
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
16
|
+
CYRILLIC_SERIES = {
|
|
17
|
+
"PMG" => "ПМГ",
|
|
18
|
+
"RMG" => "РМГ",
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
CYRILLIC_VARIANT = "В".freeze
|
|
22
|
+
|
|
23
|
+
def render(context: nil, **_opts)
|
|
24
|
+
id = @id
|
|
25
|
+
|
|
26
|
+
if id.is_a?(Identifiers::Pmg) || id.is_a?(Identifiers::Rmg)
|
|
27
|
+
return render_standard(id)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
raise ArgumentError, "Unknown EASC identifier class: #{id.class}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def render_standard(id)
|
|
36
|
+
rendered = +"#{cyrillic_series(id.series)}"
|
|
37
|
+
rendered << " #{CYRILLIC_VARIANT}" if id.variant == "V"
|
|
38
|
+
rendered << " #{id.number}"
|
|
39
|
+
rendered << "-#{id.year}" if id.year
|
|
40
|
+
rendered
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def cyrillic_series(series)
|
|
44
|
+
CYRILLIC_SERIES.fetch(series, series)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
# Generates URN strings for EASC identifiers.
|
|
6
|
+
#
|
|
7
|
+
# Format:
|
|
8
|
+
# urn:easc:<series>[:<variant>]:<number>[:<year>]
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
# urn:easc:pmg:3:2025
|
|
12
|
+
# urn:easc:pmg:v:31:2001
|
|
13
|
+
# urn:easc:rmg:151:2025
|
|
14
|
+
class UrnGenerator
|
|
15
|
+
attr_reader :identifier
|
|
16
|
+
|
|
17
|
+
def initialize(identifier)
|
|
18
|
+
@identifier = identifier
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate
|
|
22
|
+
unless identifier.is_a?(Identifiers::Pmg) ||
|
|
23
|
+
identifier.is_a?(Identifiers::Rmg)
|
|
24
|
+
raise ArgumentError,
|
|
25
|
+
"Unknown EASC identifier class: #{identifier.class}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
parts = ["urn:easc", series_lower]
|
|
29
|
+
parts << variant_lower if identifier.variant
|
|
30
|
+
parts << identifier.number.to_s
|
|
31
|
+
parts << identifier.year.to_s if identifier.year
|
|
32
|
+
parts.join(":")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def series_lower
|
|
38
|
+
identifier.series.to_s.downcase
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def variant_lower
|
|
42
|
+
identifier.variant.to_s.downcase
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
# Parses EASC URNs back into identifiers.
|
|
6
|
+
#
|
|
7
|
+
# UrnGenerator emits:
|
|
8
|
+
# urn:easc:<series>[:<variant>]:<number>[:<year>]
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
# urn:easc:pmg:3:2025 → ПМГ 3-2025
|
|
12
|
+
# urn:easc:pmg:v:31:2001 → ПМГ В 31-2001
|
|
13
|
+
# urn:easc:rmg:151:2025 → РМГ 151-2025
|
|
14
|
+
class UrnParser < Pubid::UrnParser::Base
|
|
15
|
+
PREFIX = "urn:easc:".freeze
|
|
16
|
+
VARIANT_SEGMENT = /\Av\z/i.freeze
|
|
17
|
+
|
|
18
|
+
def parse_urn(urn)
|
|
19
|
+
body = strip_namespace(urn)
|
|
20
|
+
parts = split_parts(body)
|
|
21
|
+
series = parts.fetch(0)
|
|
22
|
+
rest = parts.drop(1)
|
|
23
|
+
|
|
24
|
+
variant = nil
|
|
25
|
+
if rest.first&.match?(VARIANT_SEGMENT)
|
|
26
|
+
variant = "V"
|
|
27
|
+
rest = rest.drop(1)
|
|
28
|
+
end
|
|
29
|
+
number = rest[0]
|
|
30
|
+
year = rest[1]
|
|
31
|
+
|
|
32
|
+
klass = Easc.identifier_klass_for_series(series) || Identifier
|
|
33
|
+
klass.new(series: series.upcase, variant: variant,
|
|
34
|
+
number: number, year: year)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def strip_namespace(urn)
|
|
40
|
+
unless urn.downcase.start_with?(PREFIX)
|
|
41
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
42
|
+
"Invalid EASC URN: #{urn.inspect}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
urn[PREFIX.length..]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def split_parts(body)
|
|
49
|
+
parts = body.split(":")
|
|
50
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
51
|
+
"EASC URN missing series: #{body.inspect}" if parts.empty?
|
|
52
|
+
|
|
53
|
+
parts
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/pubid/easc.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
extend Pubid::PrefixesSupport
|
|
6
|
+
|
|
7
|
+
# Leading identifier tokens that an EASC document id can start with.
|
|
8
|
+
# Both Cyrillic (canonical — ПМГ, РМГ) and Latin transliterations
|
|
9
|
+
# (PMG, RMG) are accepted; the canonical render is Cyrillic per
|
|
10
|
+
# mgscatalog.by convention.
|
|
11
|
+
PREFIXES = ["ПМГ", "РМГ", "PMG", "RMG"].freeze
|
|
12
|
+
|
|
13
|
+
autoload :Builder, "#{__dir__}/easc/builder"
|
|
14
|
+
autoload :Identifier, "#{__dir__}/easc/identifier"
|
|
15
|
+
autoload :Identifiers, "#{__dir__}/easc/identifiers"
|
|
16
|
+
autoload :Parser, "#{__dir__}/easc/parser"
|
|
17
|
+
autoload :Renderer, "#{__dir__}/easc/renderer"
|
|
18
|
+
autoload :UrnGenerator, "#{__dir__}/easc/urn_generator"
|
|
19
|
+
autoload :UrnParser, "#{__dir__}/easc/urn_parser"
|
|
20
|
+
|
|
21
|
+
# @param identifier [String]
|
|
22
|
+
# @return [Pubid::Easc::Identifier]
|
|
23
|
+
def self.parse(identifier)
|
|
24
|
+
Identifier.parse(identifier)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Per-flavor format registry.
|
|
28
|
+
Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
|
|
29
|
+
Identifier.format_registry.register(:human, renderer: Easc::Renderer)
|
|
30
|
+
|
|
31
|
+
# Auto-discover identifier types from the Identifiers namespace.
|
|
32
|
+
# @return [Array<Class>]
|
|
33
|
+
def self.identifier_types
|
|
34
|
+
@identifier_types ||= Identifiers.constants
|
|
35
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
36
|
+
.select { |c| c.is_a?(Class) && c < Pubid::Identifier }
|
|
37
|
+
.reject { |c| c == Identifier }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Lookup: series (ПМГ / РМГ / PMG / RMG) → identifier class
|
|
41
|
+
# @param series [String, Symbol]
|
|
42
|
+
# @return [Class<Identifier>, nil]
|
|
43
|
+
def self.identifier_klass_for_series(series)
|
|
44
|
+
@by_series ||= identifier_types.to_h do |klass|
|
|
45
|
+
[klass.type[:series].to_s, klass]
|
|
46
|
+
end
|
|
47
|
+
@by_series[series.to_s] || @by_series[series.to_s.upcase]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Pubid::Registry.register(:easc, Pubid::Easc)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
# Turns the Parslet parse tree into a concrete identifier object. The class
|
|
6
|
+
# is chosen by which number key the parser captured.
|
|
7
|
+
class Builder
|
|
8
|
+
def self.build(parsed_data)
|
|
9
|
+
new.build(parsed_data)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def build(data)
|
|
13
|
+
if data[:tr_number]
|
|
14
|
+
Identifiers::TechnicalReport.new(number: data[:tr_number].to_s)
|
|
15
|
+
elsif data[:mem_number]
|
|
16
|
+
Identifiers::Memento.new(number: data[:mem_number].to_s)
|
|
17
|
+
else
|
|
18
|
+
build_standard(data)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def build_standard(data)
|
|
25
|
+
attrs = { number: data[:number].to_s }
|
|
26
|
+
attrs[:part] = data[:part].to_s if data[:part]
|
|
27
|
+
Identifiers::Standard.new(**attrs)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
# Base class for every ECMA identifier AND the flavor's parse entry point —
|
|
6
|
+
# mirrors Pubid::Jis::Identifier. Concrete identifiers under
|
|
7
|
+
# Pubid::Ecma::Identifiers descend from this class, so a parsed ECMA id is
|
|
8
|
+
# an instance of Pubid::Ecma::Identifier. ECMA has no supplement layer.
|
|
9
|
+
class Identifier < ::Pubid::Identifier
|
|
10
|
+
# The document number as a string (preserves any leading zeros). `part`
|
|
11
|
+
# is only present for standards that split into parts (e.g. ECMA-418-1).
|
|
12
|
+
attribute :number, :string
|
|
13
|
+
attribute :part, :string
|
|
14
|
+
# Edition is separate metadata (the index stores {:id, :ed} and the YAML
|
|
15
|
+
# has edition.content); it is NOT part of the printed identifier string.
|
|
16
|
+
# Modelled as an optional string (decimal editions like "5.1" occur) that
|
|
17
|
+
# serializes in `to_hash` — so relaton preserves `:ed:` — but is omitted
|
|
18
|
+
# from `to_s`. No default, so it drops from the hash when unset.
|
|
19
|
+
attribute :edition, :string
|
|
20
|
+
|
|
21
|
+
# Polymorphic type map for lutaml::Model key_value (de)serialization:
|
|
22
|
+
# maps each subclass's polymorphic_name to its class name so a stored
|
|
23
|
+
# hash rebuilds the correct identifier type via from_hash.
|
|
24
|
+
ECMA_TYPE_MAP = {
|
|
25
|
+
"pubid:ecma:standard" => "Pubid::Ecma::Identifiers::Standard",
|
|
26
|
+
"pubid:ecma:technical-report" =>
|
|
27
|
+
"Pubid::Ecma::Identifiers::TechnicalReport",
|
|
28
|
+
"pubid:ecma:memento" => "Pubid::Ecma::Identifiers::Memento",
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
key_value do
|
|
32
|
+
map "_type", to: :_type, polymorphic_map: ECMA_TYPE_MAP
|
|
33
|
+
map "number", to: :number
|
|
34
|
+
map "part", to: :part
|
|
35
|
+
map "edition", to: :edition
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Publisher is always "ECMA". A plain constant (not a `publisher` method)
|
|
39
|
+
# so it doesn't shadow the inherited lutaml `publisher` attribute, which
|
|
40
|
+
# would otherwise fail serialization type validation.
|
|
41
|
+
PUBLISHER = "ECMA"
|
|
42
|
+
|
|
43
|
+
# Whether the last `to_s` should include the "ECMA" publisher token.
|
|
44
|
+
attr_reader :with_publisher
|
|
45
|
+
|
|
46
|
+
# Basic string representation. Delegates to renderer. `with_publisher:
|
|
47
|
+
# false` drops the ECMA token (e.g. "-411", "TR/84").
|
|
48
|
+
def to_s(with_publisher: true, **opts)
|
|
49
|
+
@with_publisher = with_publisher
|
|
50
|
+
render(format: :human, **opts)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Type token that precedes the number ("TR"/"MEM"), or nil for standards.
|
|
54
|
+
# Overridden by each concrete identifier class.
|
|
55
|
+
def type_prefix
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Parse an ECMA identifier string into an identifier object.
|
|
60
|
+
# @param identifier [String] The ECMA identifier string to parse
|
|
61
|
+
# @return [Identifier] The appropriate identifier object
|
|
62
|
+
# @raise [ArgumentError] If the input exceeds MAX_INPUT_LENGTH
|
|
63
|
+
# @raise [RuntimeError] If parsing fails
|
|
64
|
+
def self.parse(identifier)
|
|
65
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
66
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
parsed = Parser.parse(identifier)
|
|
70
|
+
Builder.build(parsed)
|
|
71
|
+
rescue Parslet::ParseFailed => e
|
|
72
|
+
raise "Failed to parse ECMA identifier '#{identifier}': #{e.message}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Memento identifier type.
|
|
7
|
+
# Format: ECMA MEM/<year>. Example: ECMA MEM/1970
|
|
8
|
+
class Memento < Identifier
|
|
9
|
+
TYPED_STAGES = [
|
|
10
|
+
Pubid::Components::TypedStage.new(
|
|
11
|
+
code: :mem,
|
|
12
|
+
stage_code: :published,
|
|
13
|
+
type_code: :ecma,
|
|
14
|
+
abbr: ["MEM"],
|
|
15
|
+
name: "Memento",
|
|
16
|
+
harmonized_stages: [],
|
|
17
|
+
),
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
def self.type
|
|
21
|
+
{ key: :mem, web: :memento, title: "Memento", short: "MEM" }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def type_prefix
|
|
25
|
+
"MEM"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Default ECMA identifier type (no type token).
|
|
7
|
+
# Examples: ECMA-411, ECMA-418-1
|
|
8
|
+
class Standard < Identifier
|
|
9
|
+
TYPED_STAGES = [
|
|
10
|
+
Pubid::Components::TypedStage.new(
|
|
11
|
+
code: :standard,
|
|
12
|
+
stage_code: :published,
|
|
13
|
+
type_code: :ecma,
|
|
14
|
+
abbr: ["ECMA"],
|
|
15
|
+
name: "Standard",
|
|
16
|
+
harmonized_stages: [],
|
|
17
|
+
),
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
def self.type
|
|
21
|
+
{ key: :standard, web: :standard, title: "Standard", short: "ECMA" }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# No type token for standards.
|
|
25
|
+
def type_prefix
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Technical Report identifier type.
|
|
7
|
+
# Format: ECMA TR/<number>. Example: ECMA TR/101
|
|
8
|
+
class TechnicalReport < Identifier
|
|
9
|
+
TYPED_STAGES = [
|
|
10
|
+
Pubid::Components::TypedStage.new(
|
|
11
|
+
code: :tr,
|
|
12
|
+
stage_code: :published,
|
|
13
|
+
type_code: :ecma,
|
|
14
|
+
abbr: ["TR"],
|
|
15
|
+
name: "Technical Report",
|
|
16
|
+
harmonized_stages: [],
|
|
17
|
+
),
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
def self.type
|
|
21
|
+
{ key: :tr, web: :technical_report, title: "Technical Report",
|
|
22
|
+
short: "TR" }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def type_prefix
|
|
26
|
+
"TR"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
module Identifiers
|
|
6
|
+
autoload :Standard, "#{__dir__}/identifiers/standard"
|
|
7
|
+
autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
|
|
8
|
+
autoload :Memento, "#{__dir__}/identifiers/memento"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parslet"
|
|
4
|
+
|
|
5
|
+
module Pubid
|
|
6
|
+
module Ecma
|
|
7
|
+
# Parslet grammar for ECMA identifiers.
|
|
8
|
+
#
|
|
9
|
+
# Four printed forms (see HANDOFFS/ecma.md):
|
|
10
|
+
# ECMA-411 standard
|
|
11
|
+
# ECMA-418-1 standard with part
|
|
12
|
+
# ECMA TR/101 technical report
|
|
13
|
+
# ECMA MEM/1970 memento
|
|
14
|
+
#
|
|
15
|
+
# Each branch captures its number under a distinct key so the builder can
|
|
16
|
+
# pick the identifier class without a separate type token. Numbers are kept
|
|
17
|
+
# as strings to preserve any leading zeros.
|
|
18
|
+
class Parser < Parslet::Parser
|
|
19
|
+
rule(:digits) { match["0-9"].repeat(1) }
|
|
20
|
+
|
|
21
|
+
rule(:prefix) { str("ECMA") }
|
|
22
|
+
|
|
23
|
+
rule(:tr) { str(" TR/") >> digits.as(:tr_number) }
|
|
24
|
+
|
|
25
|
+
rule(:mem) { str(" MEM/") >> digits.as(:mem_number) }
|
|
26
|
+
|
|
27
|
+
rule(:standard) do
|
|
28
|
+
str("-") >> digits.as(:number) >>
|
|
29
|
+
(str("-") >> digits.as(:part)).maybe
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
rule(:identifier) { prefix >> (tr | mem | standard) }
|
|
33
|
+
|
|
34
|
+
rule(:root) { identifier }
|
|
35
|
+
|
|
36
|
+
def self.parse(input)
|
|
37
|
+
new.parse(input)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
# Human-readable renderer for ECMA identifiers.
|
|
6
|
+
#
|
|
7
|
+
# Produces strings like:
|
|
8
|
+
# "ECMA-411" standard
|
|
9
|
+
# "ECMA-418-1" standard with part
|
|
10
|
+
# "ECMA TR/101" technical report
|
|
11
|
+
# "ECMA MEM/1970" memento
|
|
12
|
+
#
|
|
13
|
+
# With `with_publisher: false` the leading ECMA token is dropped, yielding
|
|
14
|
+
# "-411" / "TR/101" / "MEM/1970". The edition is never rendered — it is
|
|
15
|
+
# separate metadata carried only in `to_hash`.
|
|
16
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
17
|
+
PUBLISHER = "ECMA"
|
|
18
|
+
|
|
19
|
+
def render(context: nil, **opts)
|
|
20
|
+
id = @id
|
|
21
|
+
# Standard joins the publisher directly ("ECMA-411"); TR/MEM separate it
|
|
22
|
+
# with a space ("ECMA TR/101"). type_prefix is nil only for standards.
|
|
23
|
+
sep = id.type_prefix.nil? ? "" : " "
|
|
24
|
+
core = id.type_prefix.nil? ? standard_core(id) : typed_core(id)
|
|
25
|
+
with_publisher?(id) ? "#{PUBLISHER}#{sep}#{core}" : core
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# Standard: "-<number>[-<part>]".
|
|
31
|
+
def standard_core(id)
|
|
32
|
+
core = "-#{id.number}"
|
|
33
|
+
id.part ? "#{core}-#{id.part}" : core
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Technical Report / Memento: "<TYPE>/<number>".
|
|
37
|
+
def typed_core(id)
|
|
38
|
+
"#{id.type_prefix}/#{id.number}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def with_publisher?(id)
|
|
42
|
+
id.with_publisher != false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
# Emits `urn:ecma:<tag>:<number>[:part-<part>]` where the tag is bare for
|
|
6
|
+
# standards, "tr" for technical reports and "mem" for mementos:
|
|
7
|
+
# ECMA-411 -> urn:ecma:411
|
|
8
|
+
# ECMA-418-1 -> urn:ecma:418:part-1
|
|
9
|
+
# ECMA TR/101 -> urn:ecma:tr:101
|
|
10
|
+
# ECMA MEM/1970 -> urn:ecma:mem:1970
|
|
11
|
+
class UrnGenerator < Pubid::UrnGenerator::Base
|
|
12
|
+
def generate
|
|
13
|
+
parts = ["urn", "ecma"]
|
|
14
|
+
|
|
15
|
+
tag = identifier.type_prefix&.downcase
|
|
16
|
+
parts << tag if tag
|
|
17
|
+
|
|
18
|
+
parts << identifier.number.to_s
|
|
19
|
+
parts << "part-#{identifier.part}" if identifier.part
|
|
20
|
+
|
|
21
|
+
parts.join(":")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
# Parses ECMA URNs back into identifiers, inverting {UrnGenerator}.
|
|
6
|
+
#
|
|
7
|
+
# Examples:
|
|
8
|
+
# urn:ecma:411 -> ECMA-411
|
|
9
|
+
# urn:ecma:418:part-1 -> ECMA-418-1
|
|
10
|
+
# urn:ecma:tr:101 -> ECMA TR/101
|
|
11
|
+
# urn:ecma:mem:1970 -> ECMA MEM/1970
|
|
12
|
+
class UrnParser < Pubid::UrnParser::Base
|
|
13
|
+
def parse_urn(urn)
|
|
14
|
+
parts = split_parts(strip_namespace(urn))
|
|
15
|
+
tag = %w[tr mem].include?(parts.first) ? parts.shift : nil
|
|
16
|
+
number = parts.shift
|
|
17
|
+
part = if parts.first&.start_with?("part-")
|
|
18
|
+
parts.shift.sub("part-", "")
|
|
19
|
+
end
|
|
20
|
+
flavor_parse(reconstruct(tag, number, part))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# Rebuild the printed identifier string from the URN fields.
|
|
26
|
+
def reconstruct(tag, number, part)
|
|
27
|
+
case tag
|
|
28
|
+
when "tr" then "ECMA TR/#{number}"
|
|
29
|
+
when "mem" then "ECMA MEM/#{number}"
|
|
30
|
+
else part ? "ECMA-#{number}-#{part}" : "ECMA-#{number}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/pubid/ecma.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ecma
|
|
5
|
+
extend Pubid::PrefixesSupport
|
|
6
|
+
|
|
7
|
+
# Sole ECMA publisher token (see the parser's `prefix` rule). Document types
|
|
8
|
+
# (TR/MEM) follow the ECMA prefix as type tokens and are excluded.
|
|
9
|
+
PREFIXES = ["ECMA"].freeze
|
|
10
|
+
|
|
11
|
+
autoload :Builder, "#{__dir__}/ecma/builder"
|
|
12
|
+
autoload :Identifier, "#{__dir__}/ecma/identifier"
|
|
13
|
+
autoload :Identifiers, "#{__dir__}/ecma/identifiers"
|
|
14
|
+
autoload :Parser, "#{__dir__}/ecma/parser"
|
|
15
|
+
autoload :Renderer, "#{__dir__}/ecma/renderer"
|
|
16
|
+
autoload :UrnGenerator, "#{__dir__}/ecma/urn_generator"
|
|
17
|
+
autoload :UrnParser, "#{__dir__}/ecma/urn_parser"
|
|
18
|
+
|
|
19
|
+
# Parse an ECMA identifier string
|
|
20
|
+
def self.parse(identifier)
|
|
21
|
+
Identifier.parse(identifier)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Per-flavor format registry: inherits global formats, overrides :human
|
|
25
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
26
|
+
Identifier.format_registry.register(:human, renderer: Ecma::Renderer)
|
|
27
|
+
|
|
28
|
+
# Auto-discover all identifier types from the Identifiers namespace
|
|
29
|
+
# @return [Array<Class>] identifier classes that define a self.type Hash
|
|
30
|
+
def self.identifier_types
|
|
31
|
+
@identifier_types ||= Identifiers.constants
|
|
32
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
33
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
34
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Build typed stage index from identifier types
|
|
38
|
+
# @return [Array<Pubid::Components::TypedStage>] all typed stages
|
|
39
|
+
def self.all_typed_stages
|
|
40
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
41
|
+
if klass.const_defined?(:TYPED_STAGES)
|
|
42
|
+
klass.const_get(:TYPED_STAGES)
|
|
43
|
+
else
|
|
44
|
+
[]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Lookup: type code -> identifier class
|
|
50
|
+
# @param code [String, Symbol] the type key to find
|
|
51
|
+
# @return [Class, nil] the matching identifier class
|
|
52
|
+
def self.locate_type(code)
|
|
53
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Lookup: abbreviation -> typed stage
|
|
57
|
+
# @param abbr [String, Symbol] the abbreviation to find
|
|
58
|
+
# @return [Pubid::Components::TypedStage, nil] the matching typed stage
|
|
59
|
+
def self.locate_stage(abbr)
|
|
60
|
+
abbr_str = abbr.to_s.upcase
|
|
61
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Register ECMA flavor with the registry
|
|
67
|
+
Pubid::Registry.register(:ecma, Pubid::Ecma)
|
data/lib/pubid/etsi/builder.rb
CHANGED
|
@@ -95,19 +95,23 @@ module Pubid
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def build_version(data)
|
|
98
|
-
# Handle both version and edition
|
|
98
|
+
# Handle both version and edition. A partial reference omits both, in
|
|
99
|
+
# which case version is left nil (not defaulted) so exclude/matches?
|
|
100
|
+
# treat it as a wildcard.
|
|
99
101
|
if data[:version]
|
|
100
102
|
Components::Version.new(version: data[:version].to_s,
|
|
101
103
|
is_edition: false)
|
|
102
104
|
elsif data[:edition]
|
|
103
105
|
Components::Version.new(version: data[:edition].to_s,
|
|
104
106
|
is_edition: true)
|
|
105
|
-
else
|
|
106
|
-
Components::Version.new(version: "1.0.0", is_edition: false)
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def build_date(data)
|
|
111
|
+
# A partial reference omits the date; leave it nil rather than building
|
|
112
|
+
# an empty Date, so the canonical to_hash drops it entirely.
|
|
113
|
+
return nil unless data[:year]
|
|
114
|
+
|
|
111
115
|
Pubid::Components::Date.new(
|
|
112
116
|
year: data[:year].to_s,
|
|
113
117
|
month: data[:month].to_s,
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Pubid::Etsi::Identifier is the ETSI base class (a real Pubid::Identifier
|
|
4
|
-
# subclass); its body
|
|
5
|
-
# live in identifiers/base.rb. This file just ensures it is loaded.
|
|
6
|
-
require_relative "identifiers/base"
|
|
4
|
+
# subclass); its body and `.parse` live in identifiers/base.rb. This file just ensures it is loaded.
|