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
data/lib/pubid/csa/identifier.rb
CHANGED
|
@@ -355,12 +355,12 @@ module Pubid
|
|
|
355
355
|
end
|
|
356
356
|
|
|
357
357
|
# Parse base identifier recursively
|
|
358
|
-
|
|
359
|
-
return nil unless
|
|
358
|
+
base = base_input ? parse(base_input) : nil
|
|
359
|
+
return nil unless base
|
|
360
360
|
|
|
361
361
|
# Create PackageIdentifier
|
|
362
362
|
result = Identifiers::Package.new
|
|
363
|
-
result.
|
|
363
|
+
result.base = base
|
|
364
364
|
# Set materials if present
|
|
365
365
|
if package_materials && !package_materials.empty?
|
|
366
366
|
result.package_materials = package_materials
|
|
@@ -458,6 +458,51 @@ module Pubid
|
|
|
458
458
|
|
|
459
459
|
nil
|
|
460
460
|
end
|
|
461
|
+
|
|
462
|
+
# CSA stores the publication year in its own plain `year` string
|
|
463
|
+
# attribute (not a `Components::Date`), so the base `#exclude`'s
|
|
464
|
+
# `:year`->`:date` remap nils the unused inherited `date` and leaves
|
|
465
|
+
# `year` intact. Override to nil `year` (and its formatting metadata)
|
|
466
|
+
# when `:year`/`:date` is excluded, so a partial (year-less) CSA
|
|
467
|
+
# reference is a year wildcard under `matches?(row, ignore: [:year])`.
|
|
468
|
+
# The metadata attrs (`year_format`, `year_prefix`,
|
|
469
|
+
# `original_year_4digit`, `french`) are year-derived — a year-less
|
|
470
|
+
# parse leaves them nil/false, so they must be reset here too or `==`
|
|
471
|
+
# would still differ. `french` in particular is only ever set from a
|
|
472
|
+
# `:F` year prefix (the French-edition form `CSA B149.1:F20`), so a
|
|
473
|
+
# bare `CSA B149.1` reference must wildcard it to match both the
|
|
474
|
+
# English and French editions of a document number. `super` preserves
|
|
475
|
+
# the base recursion into nested identifiers (adoption wrappers
|
|
476
|
+
# delegate their year to an inner id and lack a `year` accessor, hence
|
|
477
|
+
# the `respond_to?` guard). Mirrors BIPM.
|
|
478
|
+
def exclude(*args)
|
|
479
|
+
result = super
|
|
480
|
+
year_keys = args & %i[year date]
|
|
481
|
+
if !year_keys.empty? && result.respond_to?(:year=)
|
|
482
|
+
result.year = nil
|
|
483
|
+
result.year_format = nil
|
|
484
|
+
result.year_prefix = nil
|
|
485
|
+
result.original_year_4digit = false
|
|
486
|
+
result.french = nil
|
|
487
|
+
end
|
|
488
|
+
result
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
# CSA encodes its identity across many shape-specific attributes
|
|
492
|
+
# (`publisher_prefix`, `code`, `no_number`, `series`, `series_prefix`,
|
|
493
|
+
# `package`, `reaffirmation`, `year` with prefix/format/French markers,
|
|
494
|
+
# etc.) that the generic MrString renderer doesn't know about. The
|
|
495
|
+
# CSA `to_s` already round-trips losslessly through the CSA parser, so
|
|
496
|
+
# MR mirrors it: ` ` → `.`, `:` → `.` (so the year never looks like
|
|
497
|
+
# another code segment), `/` → `-` (CAN/CSA- prefix), then lowercased
|
|
498
|
+
# to match the all-lowercase MR convention (issue #142).
|
|
499
|
+
def to_mr_string
|
|
500
|
+
to_s.tr(" ", ".").tr(":", ".").tr("/", "-").downcase
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def to_slug
|
|
504
|
+
to_mr_string
|
|
505
|
+
end
|
|
461
506
|
end
|
|
462
507
|
end
|
|
463
508
|
end
|
|
@@ -14,6 +14,12 @@ module Pubid
|
|
|
14
14
|
}
|
|
15
15
|
attribute :year_format, :string # Add for compatibility with identifier.rb
|
|
16
16
|
|
|
17
|
+
# CSA bundles are not Pubid::Identifier objects, so they do not inherit
|
|
18
|
+
# #root. They are their own origin for matching purposes.
|
|
19
|
+
def root
|
|
20
|
+
self
|
|
21
|
+
end
|
|
22
|
+
|
|
17
23
|
def to_s
|
|
18
24
|
# For Cec identifiers, use normalized form (code instead of cec_part + NO.)
|
|
19
25
|
# This is used for "normalized form" rendering in bundled identifiers
|
|
@@ -23,6 +23,12 @@ module Pubid
|
|
|
23
23
|
attribute :year_format, :string # Dummy for compatibility
|
|
24
24
|
attribute :separator, :string, default: -> { "/" } # "/" or ", "
|
|
25
25
|
|
|
26
|
+
# CSA combined ids are not Pubid::Identifier objects, so they do not
|
|
27
|
+
# inherit #root. They are their own origin for matching purposes.
|
|
28
|
+
def root
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
26
32
|
def to_s
|
|
27
33
|
# For comma separator, render both parts with full prefix
|
|
28
34
|
# For slash separator, second/third parts without prefix
|
|
@@ -12,7 +12,7 @@ module Pubid
|
|
|
12
12
|
# CSA C22.2 NO. 60601-1:15 PACKAGE WITH ADDENDUM
|
|
13
13
|
#
|
|
14
14
|
# This is a composite pattern where:
|
|
15
|
-
# -
|
|
15
|
+
# - base is the core CSA standard (recursively parsed)
|
|
16
16
|
# - package_materials describes what's included in the package
|
|
17
17
|
# - Package portion is metadata, not a parseable identifier
|
|
18
18
|
#
|
|
@@ -34,7 +34,7 @@ module Pubid
|
|
|
34
34
|
attribute :materials_after_keyword, :boolean, default: -> { true }
|
|
35
35
|
|
|
36
36
|
def to_s
|
|
37
|
-
result =
|
|
37
|
+
result = base.to_s
|
|
38
38
|
|
|
39
39
|
# Add package materials if present
|
|
40
40
|
if package_materials && !package_materials.empty?
|
data/lib/pubid/csa/parser.rb
CHANGED
|
@@ -179,7 +179,7 @@ module Pubid
|
|
|
179
179
|
# Optional series prefix (MH, RV, etc.) before SERIES keyword
|
|
180
180
|
(series_prefix >> space).maybe >>
|
|
181
181
|
series_keyword.as(:series_type) >>
|
|
182
|
-
(colon_year | dash_year) >>
|
|
182
|
+
(colon_year | dash_year).maybe >>
|
|
183
183
|
reaffirmation.maybe
|
|
184
184
|
end
|
|
185
185
|
|
|
@@ -194,7 +194,7 @@ module Pubid
|
|
|
194
194
|
).as(:cec_part) >>
|
|
195
195
|
no_notation >>
|
|
196
196
|
no_number >>
|
|
197
|
-
(colon_year | dash_year) >>
|
|
197
|
+
(colon_year | dash_year).maybe >>
|
|
198
198
|
reaffirmation.maybe
|
|
199
199
|
end
|
|
200
200
|
|
|
@@ -257,7 +257,7 @@ module Pubid
|
|
|
257
257
|
(space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
|
|
258
258
|
# Option 4: just year (no series, no NO.)
|
|
259
259
|
(colon_year | dash_year)
|
|
260
|
-
) >>
|
|
260
|
+
).maybe >> # trailing year optional (partial reference)
|
|
261
261
|
amendment_slash.maybe # Add amendment support here
|
|
262
262
|
end
|
|
263
263
|
|
|
@@ -274,7 +274,7 @@ module Pubid
|
|
|
274
274
|
(space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
|
|
275
275
|
# Option 4: just year
|
|
276
276
|
(colon_year | dash_year)
|
|
277
|
-
)
|
|
277
|
+
).maybe # trailing year optional (partial reference)
|
|
278
278
|
end
|
|
279
279
|
|
|
280
280
|
# Continuation code (optional CSA publisher prefix, for combined identifiers)
|
|
@@ -290,7 +290,7 @@ module Pubid
|
|
|
290
290
|
(space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
|
|
291
291
|
# Option 4: just year
|
|
292
292
|
(colon_year | dash_year)
|
|
293
|
-
) >>
|
|
293
|
+
).maybe >> # trailing year optional (partial reference)
|
|
294
294
|
amendment_slash.maybe
|
|
295
295
|
end
|
|
296
296
|
|
|
@@ -353,7 +353,7 @@ module Pubid
|
|
|
353
353
|
(space >> series_keyword.as(:series) >> (colon_year | dash_year)) |
|
|
354
354
|
# Option 3: just year
|
|
355
355
|
(colon_year | dash_year)
|
|
356
|
-
) >>
|
|
356
|
+
).maybe >> # trailing year optional (partial reference)
|
|
357
357
|
(space >> str("PACKAGE")).as(:package_portion).maybe
|
|
358
358
|
end
|
|
359
359
|
|
|
@@ -26,6 +26,23 @@ module Pubid
|
|
|
26
26
|
def to_s
|
|
27
27
|
raise NotImplementedError, "Subclasses must implement to_s method"
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
# CSA wrappers serialise through `to_s` (their distinct shape is what
|
|
31
|
+
# makes them wrappers), so MR mirrors that with ` ` → `.`, `:` → `.`,
|
|
32
|
+
# `/` → `-`, then lowercased (issue #142).
|
|
33
|
+
def to_mr_string
|
|
34
|
+
to_s.tr(" ", ".").tr(":", ".").tr("/", "-").downcase
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_slug
|
|
38
|
+
to_mr_string
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# CSA wrappers are not Pubid::Identifier objects, so they do not inherit
|
|
42
|
+
# #root. They are their own origin for matching purposes.
|
|
43
|
+
def root
|
|
44
|
+
self
|
|
45
|
+
end
|
|
29
46
|
end
|
|
30
47
|
end
|
|
31
48
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Doi
|
|
5
|
+
class Builder
|
|
6
|
+
def self.build(parsed_data)
|
|
7
|
+
new.build(parsed_data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def build(data)
|
|
11
|
+
Identifiers::Resource.new(
|
|
12
|
+
prefix: "10.#{data[:prefix]}",
|
|
13
|
+
suffix: data[:suffix].to_s,
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Doi
|
|
5
|
+
class Identifier < ::Pubid::Identifier
|
|
6
|
+
# The DOI prefix: "10." + registrar code, e.g. "10.1000", "10.6028".
|
|
7
|
+
attribute :prefix, :string
|
|
8
|
+
|
|
9
|
+
# The DOI suffix: arbitrary printable string with no whitespace. May
|
|
10
|
+
# contain slashes (e.g. "NIST.2022-04-15.001").
|
|
11
|
+
attribute :suffix, :string
|
|
12
|
+
|
|
13
|
+
DOI_TYPE_MAP = {
|
|
14
|
+
"pubid:doi:resource" => "Pubid::Doi::Identifiers::Resource",
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
key_value do
|
|
18
|
+
map "_type", to: :_type, polymorphic_map: DOI_TYPE_MAP
|
|
19
|
+
map "prefix", to: :prefix
|
|
20
|
+
map "suffix", to: :suffix
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
PUBLISHER = "DOI"
|
|
24
|
+
|
|
25
|
+
# The numeric registrar subcode (e.g. "1000" for prefix "10.1000").
|
|
26
|
+
def registrar
|
|
27
|
+
prefix.to_s.sub(/\A10\./, "") unless prefix.to_s.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_s(**opts)
|
|
31
|
+
render(format: :human, **opts)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.parse(identifier)
|
|
35
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
36
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
parsed = Parser.parse(identifier)
|
|
40
|
+
Builder.build(parsed)
|
|
41
|
+
rescue Parslet::ParseFailed => e
|
|
42
|
+
raise "Failed to parse DOI '#{identifier}': #{e.message}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Doi
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Concrete DOI identifier type.
|
|
7
|
+
#
|
|
8
|
+
# Examples:
|
|
9
|
+
# doi:10.1000/182
|
|
10
|
+
# 10.6028/NIST.2022-04-15.001
|
|
11
|
+
# https://doi.org/10.1006/jmbi.1998.2354
|
|
12
|
+
class Resource < Identifier
|
|
13
|
+
TYPED_STAGES = [
|
|
14
|
+
Pubid::Components::TypedStage.new(
|
|
15
|
+
code: :pubdoi,
|
|
16
|
+
stage_code: :published,
|
|
17
|
+
type_code: :doi,
|
|
18
|
+
abbr: ["DOI"],
|
|
19
|
+
name: "DOI",
|
|
20
|
+
harmonized_stages: [],
|
|
21
|
+
),
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
def self.type
|
|
25
|
+
{ key: :doi, web: :doi, title: "DOI", short: "DOI" }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parslet"
|
|
4
|
+
|
|
5
|
+
module Pubid
|
|
6
|
+
module Doi
|
|
7
|
+
# Parslet grammar for Digital Object Identifiers per ISO 26324.
|
|
8
|
+
#
|
|
9
|
+
# Accepts:
|
|
10
|
+
# [doi:|DOI:]10.{REGISTRAR}/{SUFFIX}
|
|
11
|
+
# https://doi.org/10.{REGISTRAR}/{SUFFIX}
|
|
12
|
+
#
|
|
13
|
+
# SUFFIX is one-or-more chars from [A-Za-z0-9._\-/()] (printable minus
|
|
14
|
+
# whitespace). The grammar is intentionally permissive on suffix chars
|
|
15
|
+
# because real DOIs cover the full printable range.
|
|
16
|
+
class Parser < Parslet::Parser
|
|
17
|
+
rule(:dot) { str(".") }
|
|
18
|
+
rule(:slash) { str("/") }
|
|
19
|
+
|
|
20
|
+
# Optional URL resolver prefix.
|
|
21
|
+
rule(:url_prefix) { (str("https://") | str("http://")).maybe >> str("doi.org").maybe }
|
|
22
|
+
|
|
23
|
+
# Optional DOI scheme prefix.
|
|
24
|
+
rule(:scheme_prefix) do
|
|
25
|
+
(str("doi:") | str("DOI:") | str("Doi:")).maybe
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Prefix: "10." then 2+ registrar digits.
|
|
29
|
+
rule(:prefix) { str("10") >> dot >> match("[0-9]").repeat(2).as(:prefix) }
|
|
30
|
+
|
|
31
|
+
# Suffix: at least one printable non-whitespace char (DOI Handbook §2.2).
|
|
32
|
+
rule(:suffix) { match("[A-Za-z0-9._\\-/()]").repeat(1).as(:suffix) }
|
|
33
|
+
|
|
34
|
+
rule(:identifier) do
|
|
35
|
+
url_prefix.maybe >>
|
|
36
|
+
scheme_prefix.maybe >>
|
|
37
|
+
slash.maybe >>
|
|
38
|
+
prefix >> slash >> suffix
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
rule(:root) { identifier }
|
|
42
|
+
|
|
43
|
+
def self.parse(input)
|
|
44
|
+
# Normalize a URL resolver form to bare form before parsing. The
|
|
45
|
+
# parser's `url_prefix.maybe >> scheme_prefix.maybe >> slash.maybe`
|
|
46
|
+
# chain also handles this in-grammar, but pre-stripping yields a
|
|
47
|
+
# cleaner error message for malformed URLs.
|
|
48
|
+
new.parse(input)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Doi
|
|
5
|
+
# Human-readable renderer for DOIs. Produces the canonical "doi:PREFIX/SUFFIX"
|
|
6
|
+
# form (RFC 5650 §2).
|
|
7
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
8
|
+
def render(**_opts)
|
|
9
|
+
"doi:#{@id.prefix}/#{@id.suffix}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/pubid/doi.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
# DOI (Digital Object Identifier) flavor.
|
|
5
|
+
#
|
|
6
|
+
# Parses the canonical DOI per ISO 26324:
|
|
7
|
+
# doi:10.{REGISTRAR}/{SUFFIX}
|
|
8
|
+
#
|
|
9
|
+
# The optional URL form `https://doi.org/10.X/Y` is accepted; the resolver
|
|
10
|
+
# host is stripped before parsing.
|
|
11
|
+
module Doi
|
|
12
|
+
extend Pubid::PrefixesSupport
|
|
13
|
+
|
|
14
|
+
# Leading tokens a DOI string can start with. The bare "10." form is the
|
|
15
|
+
# canonical prefix per ISO 26324 §4.1.
|
|
16
|
+
PREFIXES = %w[doi: DOI: 10.].freeze
|
|
17
|
+
|
|
18
|
+
autoload :Builder, "#{__dir__}/doi/builder"
|
|
19
|
+
autoload :Identifier, "#{__dir__}/doi/identifier"
|
|
20
|
+
autoload :Identifiers, "#{__dir__}/doi/identifiers"
|
|
21
|
+
autoload :Parser, "#{__dir__}/doi/parser"
|
|
22
|
+
autoload :Renderer, "#{__dir__}/doi/renderer"
|
|
23
|
+
|
|
24
|
+
def self.parse(identifier)
|
|
25
|
+
Identifier.parse(identifier)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
29
|
+
Identifier.format_registry.register(:human, renderer: Doi::Renderer)
|
|
30
|
+
|
|
31
|
+
def self.identifier_types
|
|
32
|
+
@identifier_types ||= Identifiers.constants
|
|
33
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
34
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
35
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.all_typed_stages
|
|
39
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
40
|
+
klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.locate_type(code)
|
|
45
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.locate_stage(abbr)
|
|
49
|
+
abbr_str = abbr.to_s.upcase
|
|
50
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Pubid::Registry.register(:doi, Pubid::Doi)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
# Builds an EASC identifier object from the Parslet parse tree.
|
|
6
|
+
class Builder
|
|
7
|
+
def build(parsed)
|
|
8
|
+
series_cyr = stringify(parsed[:series])&.upcase
|
|
9
|
+
canonical_series = series_to_canonical(series_cyr)
|
|
10
|
+
klass = Easc.identifier_klass_for_series(canonical_series) ||
|
|
11
|
+
Identifier
|
|
12
|
+
attrs = {
|
|
13
|
+
series: canonical_series,
|
|
14
|
+
variant: variant_to_canonical(stringify(parsed[:variant])),
|
|
15
|
+
number: stringify(parsed[:number]),
|
|
16
|
+
year: stringify(parsed[:year]),
|
|
17
|
+
}.compact
|
|
18
|
+
|
|
19
|
+
klass.new(**attrs)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.build(parsed)
|
|
23
|
+
new.build(parsed)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Map Cyrillic series to Latin canonical form (PMG/RMG). Latin
|
|
29
|
+
# input is preserved as-is (uppercased).
|
|
30
|
+
def series_to_canonical(series)
|
|
31
|
+
return nil unless series
|
|
32
|
+
|
|
33
|
+
case series
|
|
34
|
+
when "ПМГ", "PMG" then "PMG"
|
|
35
|
+
when "РМГ", "RMG" then "RMG"
|
|
36
|
+
else series
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Normalize variant marker to Latin "V" (regardless of script).
|
|
41
|
+
def variant_to_canonical(variant)
|
|
42
|
+
return nil unless variant
|
|
43
|
+
|
|
44
|
+
%w[В V].include?(variant.upcase) ? "V" : variant
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def stringify(value)
|
|
48
|
+
return nil if value.nil?
|
|
49
|
+
|
|
50
|
+
str = value.to_s
|
|
51
|
+
str.empty? ? nil : str
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
# Base class for all EASC identifiers. Canonical name
|
|
6
|
+
# Pubid::Easc::Identifier; every concrete EASC identifier
|
|
7
|
+
# (Identifiers::*) descends from it.
|
|
8
|
+
#
|
|
9
|
+
# EASC identifiers have the form:
|
|
10
|
+
# <series> [В ]<number>[-<year>]
|
|
11
|
+
#
|
|
12
|
+
# Where:
|
|
13
|
+
# * <series> identifies the document class — ПМГ (Правила
|
|
14
|
+
# межгосударственной стандартизации) or РМГ (Рекомендации по
|
|
15
|
+
# межгосударственной стандартизации). Latin forms PMG/RMG are
|
|
16
|
+
# also parsed; canonical render is Cyrillic per mgscatalog.by.
|
|
17
|
+
# * the optional "В" (Cyrillic capital V) marks a defense-related
|
|
18
|
+
# variant (e.g. "ПМГ В 31-2001"). Stored as `variant: "V"`
|
|
19
|
+
# (Latin) for cross-script consistency.
|
|
20
|
+
# * <number> is a digit run.
|
|
21
|
+
# * <year> is 2 or 4 digits, separated by ASCII hyphen OR Unicode
|
|
22
|
+
# em-dash / en-dash (Russian typographic convention).
|
|
23
|
+
#
|
|
24
|
+
# Examples:
|
|
25
|
+
# ПМГ 03-2025
|
|
26
|
+
# ПМГ В 31-2001
|
|
27
|
+
# РМГ 151-2025
|
|
28
|
+
# РМГ 29-2013
|
|
29
|
+
class Identifier < ::Pubid::Identifier
|
|
30
|
+
def self.parse(identifier)
|
|
31
|
+
parsed = Parser.parse(identifier)
|
|
32
|
+
Builder.build(parsed)
|
|
33
|
+
rescue Parslet::ParseFailed => e
|
|
34
|
+
raise "Failed to parse EASC identifier '#{identifier}': #{e.message}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attribute :publisher, :string, default: "EASC"
|
|
38
|
+
attribute :series, :string # "PMG" | "RMG" — Latin canonical
|
|
39
|
+
attribute :variant, :string # "V" | nil
|
|
40
|
+
attribute :number, :string # "151", "03", "31"
|
|
41
|
+
attribute :year, :string # "2025", "13", nil
|
|
42
|
+
|
|
43
|
+
EASC_TYPE_MAP = {
|
|
44
|
+
"pubid:easc:pmg" => "Pubid::Easc::Identifiers::Pmg",
|
|
45
|
+
"pubid:easc:rmg" => "Pubid::Easc::Identifiers::Rmg",
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
key_value do
|
|
49
|
+
map "_type", to: :_type, polymorphic_map: EASC_TYPE_MAP
|
|
50
|
+
map "series", to: :series
|
|
51
|
+
map "variant", to: :variant
|
|
52
|
+
map "number", to: :number
|
|
53
|
+
map "year", to: :year
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def to_urn
|
|
57
|
+
UrnGenerator.new(self).generate
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
module Identifiers
|
|
6
|
+
# ПМГ — Правила по межгосударственной стандартизации
|
|
7
|
+
# (Rules on interstate standardization). Issued by EASC.
|
|
8
|
+
#
|
|
9
|
+
# Examples:
|
|
10
|
+
# ПМГ 03-2025
|
|
11
|
+
# ПМГ 126-2013
|
|
12
|
+
# ПМГ В 31-2001 (defense variant)
|
|
13
|
+
class Pmg < Identifier
|
|
14
|
+
def self.type
|
|
15
|
+
{ key: :pmg, title: "Interstate Rules", series: "PMG" }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Easc
|
|
5
|
+
module Identifiers
|
|
6
|
+
# РМГ — Рекомендации по межгосударственной стандартизации
|
|
7
|
+
# (Recommendations on interstate standardization). Issued by EASC.
|
|
8
|
+
#
|
|
9
|
+
# Examples:
|
|
10
|
+
# РМГ 151-2025
|
|
11
|
+
# РМГ 29-2013
|
|
12
|
+
class Rmg < Identifier
|
|
13
|
+
def self.type
|
|
14
|
+
{ key: :rmg, title: "Interstate Recommendations", series: "RMG" }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parslet"
|
|
4
|
+
|
|
5
|
+
module Pubid
|
|
6
|
+
module Easc
|
|
7
|
+
# Parslet grammar for EASC identifiers.
|
|
8
|
+
#
|
|
9
|
+
# Accepts the Cyrillic surface forms observed in mgscatalog.by:
|
|
10
|
+
#
|
|
11
|
+
# ПМГ 03-2025
|
|
12
|
+
# ПМГ В 31-2001 (defense variant)
|
|
13
|
+
# РМГ 151-2025
|
|
14
|
+
# РМГ 29-2013
|
|
15
|
+
#
|
|
16
|
+
# Also accepts Latin transliterations (PMG, RMG, V) for
|
|
17
|
+
# round-tripping with English-language tooling. The renderer
|
|
18
|
+
# emits Cyrillic as the canonical form.
|
|
19
|
+
class Parser < Parslet::Parser
|
|
20
|
+
include ::Pubid::Parser::CommonParseRules
|
|
21
|
+
|
|
22
|
+
root :identifier
|
|
23
|
+
|
|
24
|
+
rule(:space) { str(" ") }
|
|
25
|
+
rule(:space?) { space.maybe }
|
|
26
|
+
rule(:dot) { str(".") }
|
|
27
|
+
|
|
28
|
+
# Year separator: ASCII hyphen OR Unicode em-dash / en-dash,
|
|
29
|
+
# optionally surrounded by whitespace.
|
|
30
|
+
rule(:year_sep) do
|
|
31
|
+
space?.maybe >> (str("-") | str("—") | str("–")) >> space?.maybe
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Series prefix. Captured to route to the right Identifiers::*
|
|
35
|
+
# subclass (Pmg vs Rmg). Both Cyrillic and Latin forms.
|
|
36
|
+
rule(:series_word) do
|
|
37
|
+
(str("ПМГ") | str("РМГ") | str("PMG") | str("RMG")).as(:series) >> space
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Defense variant marker — Cyrillic "В" or Latin "V".
|
|
41
|
+
rule(:variant_word) do
|
|
42
|
+
(str("В") | str("V")).as(:variant) >> space
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
rule(:prefix) do
|
|
46
|
+
series_word >> variant_word.maybe
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
rule(:digits) do
|
|
50
|
+
match("[0-9]").repeat(1)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
rule(:number) do
|
|
54
|
+
(digits >> (dot >> digits).repeat).as(:number)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
rule(:year_2digit) do
|
|
58
|
+
match("[0-9]").repeat(2, 2)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
rule(:year_4digit) do
|
|
62
|
+
match("[0-9]").repeat(4, 4)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
rule(:year) do
|
|
66
|
+
(year_4digit | year_2digit).as(:year)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
rule(:identifier) do
|
|
70
|
+
prefix >> number >> (year_sep >> year).maybe
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.parse(string)
|
|
74
|
+
raise ArgumentError, ::Pubid::INPUT_TOO_LONG_MESSAGE if string.length > ::Pubid::MAX_INPUT_LENGTH
|
|
75
|
+
|
|
76
|
+
new.parse(string.strip)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|