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,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
module Identifiers
|
|
6
|
+
# An FYI (For Your Information) sub-series id, e.g. "FYI 1".
|
|
7
|
+
class Fyi < Identifier
|
|
8
|
+
TYPED_STAGES = [
|
|
9
|
+
Pubid::Components::TypedStage.new(
|
|
10
|
+
code: :fyi,
|
|
11
|
+
stage_code: :published,
|
|
12
|
+
type_code: :fyi,
|
|
13
|
+
abbr: ["FYI"],
|
|
14
|
+
name: "For Your Information",
|
|
15
|
+
harmonized_stages: [],
|
|
16
|
+
),
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def self.type
|
|
20
|
+
{ key: :fyi, web: :fyi, title: "For Your Information", short: "FYI" }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
module Identifiers
|
|
6
|
+
# An Internet-Draft, e.g. "draft-giuliano-treedn-02" (versioned) or
|
|
7
|
+
# "draft-giuliano-treedn" (the unversioned "latest" sibling). The full
|
|
8
|
+
# slug (including the leading "draft-") is stored in `name`; the optional
|
|
9
|
+
# trailing two-digit version in `version`.
|
|
10
|
+
class InternetDraft < Identifier
|
|
11
|
+
TYPED_STAGES = [
|
|
12
|
+
Pubid::Components::TypedStage.new(
|
|
13
|
+
code: :internet_draft,
|
|
14
|
+
stage_code: :draft,
|
|
15
|
+
type_code: :internet_draft,
|
|
16
|
+
abbr: ["I-D", "Internet-Draft"],
|
|
17
|
+
name: "Internet-Draft",
|
|
18
|
+
harmonized_stages: [],
|
|
19
|
+
),
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
22
|
+
def self.type
|
|
23
|
+
{ key: :internet_draft, web: :internet_draft,
|
|
24
|
+
title: "Internet-Draft", short: "I-D" }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
module Identifiers
|
|
6
|
+
# An RFC (Request for Comments), e.g. "RFC 2119".
|
|
7
|
+
class Rfc < Identifier
|
|
8
|
+
TYPED_STAGES = [
|
|
9
|
+
Pubid::Components::TypedStage.new(
|
|
10
|
+
code: :rfc,
|
|
11
|
+
stage_code: :published,
|
|
12
|
+
type_code: :rfc,
|
|
13
|
+
abbr: ["RFC"],
|
|
14
|
+
name: "Request for Comments",
|
|
15
|
+
harmonized_stages: [],
|
|
16
|
+
),
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def self.type
|
|
20
|
+
{ key: :rfc, web: :rfc, title: "Request for Comments", short: "RFC" }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
module Identifiers
|
|
6
|
+
# An STD (Internet Standard) sub-series id, e.g. "STD 66".
|
|
7
|
+
class Std < Identifier
|
|
8
|
+
TYPED_STAGES = [
|
|
9
|
+
Pubid::Components::TypedStage.new(
|
|
10
|
+
code: :std,
|
|
11
|
+
stage_code: :published,
|
|
12
|
+
type_code: :std,
|
|
13
|
+
abbr: ["STD"],
|
|
14
|
+
name: "Internet Standard",
|
|
15
|
+
harmonized_stages: [],
|
|
16
|
+
),
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def self.type
|
|
20
|
+
{ key: :std, web: :std, title: "Internet Standard", short: "STD" }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
module Identifiers
|
|
6
|
+
autoload :Rfc, "#{__dir__}/identifiers/rfc"
|
|
7
|
+
autoload :Bcp, "#{__dir__}/identifiers/bcp"
|
|
8
|
+
autoload :Std, "#{__dir__}/identifiers/std"
|
|
9
|
+
autoload :Fyi, "#{__dir__}/identifiers/fyi"
|
|
10
|
+
autoload :InternetDraft, "#{__dir__}/identifiers/internet_draft"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parslet"
|
|
4
|
+
|
|
5
|
+
module Pubid
|
|
6
|
+
module Ietf
|
|
7
|
+
# Parslet grammar for the three IETF families. The top-level alternation is
|
|
8
|
+
# keyed by leading token, and each alternative captures the raw fields the
|
|
9
|
+
# Builder needs:
|
|
10
|
+
# * RFC -> { number: }
|
|
11
|
+
# * sub-series -> { series:, number: }
|
|
12
|
+
# * draft -> { draft_rest: } (everything after "draft-"; the version
|
|
13
|
+
# split is done in the Builder to keep the digit-tail
|
|
14
|
+
# heuristic in one place)
|
|
15
|
+
class Parser < Parslet::Parser
|
|
16
|
+
rule(:space) { str(" ") }
|
|
17
|
+
rule(:digit) { match["0-9"] }
|
|
18
|
+
rule(:digits) { digit.repeat(1) }
|
|
19
|
+
|
|
20
|
+
# "RFC 2119"
|
|
21
|
+
rule(:rfc) { str("RFC") >> space >> digits.as(:number) }
|
|
22
|
+
|
|
23
|
+
# "BCP 3" / "STD 66" / "FYI 1"
|
|
24
|
+
rule(:subseries) do
|
|
25
|
+
(str("BCP") | str("STD") | str("FYI")).as(:series) >>
|
|
26
|
+
space >> digits.as(:number)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Internet-Draft slug characters (lowercase, digits, and the "-", "+", "_"
|
|
30
|
+
# separators seen in the corpus). The whole remainder after "draft-" is
|
|
31
|
+
# captured; the Builder anchors the optional trailing "-NN" version.
|
|
32
|
+
rule(:draft_rest) { match['a-z0-9+_\-'].repeat(1).as(:draft_rest) }
|
|
33
|
+
rule(:draft) { str("draft-") >> draft_rest }
|
|
34
|
+
|
|
35
|
+
rule(:identifier) { rfc | subseries | draft }
|
|
36
|
+
rule(:root) { identifier }
|
|
37
|
+
|
|
38
|
+
def self.parse(input)
|
|
39
|
+
new.parse(input)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
# Human-readable renderer for IETF identifiers.
|
|
6
|
+
#
|
|
7
|
+
# Produces strings like:
|
|
8
|
+
# "RFC 2119"
|
|
9
|
+
# "BCP 3" / "STD 66" / "FYI 1"
|
|
10
|
+
# "draft-giuliano-treedn-02" / "draft-giuliano-treedn"
|
|
11
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
12
|
+
def render(context: nil, **_opts)
|
|
13
|
+
id = @id
|
|
14
|
+
|
|
15
|
+
case id
|
|
16
|
+
when Identifiers::Rfc
|
|
17
|
+
"RFC #{id.number}"
|
|
18
|
+
when Identifiers::InternetDraft
|
|
19
|
+
id.version ? "#{id.name}-#{id.version}" : id.name
|
|
20
|
+
else # Bcp/Std/Fyi sub-series
|
|
21
|
+
"#{id.series} #{id.number}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
# Emits the canonical IETF URNs:
|
|
6
|
+
# RFC -> urn:ietf:rfc:2119
|
|
7
|
+
# BCP/STD/FYI -> urn:ietf:bcp:3 / urn:ietf:std:66 / urn:ietf:fyi:1
|
|
8
|
+
# Internet-Draft -> urn:ietf:id:draft-giuliano-treedn[:02]
|
|
9
|
+
class UrnGenerator < Pubid::UrnGenerator::Base
|
|
10
|
+
def generate
|
|
11
|
+
case identifier
|
|
12
|
+
when Identifiers::Rfc
|
|
13
|
+
"urn:ietf:rfc:#{identifier.number}"
|
|
14
|
+
when Identifiers::InternetDraft
|
|
15
|
+
base = "urn:ietf:id:#{identifier.name}"
|
|
16
|
+
identifier.version ? "#{base}:#{identifier.version}" : base
|
|
17
|
+
else # Bcp/Std/Fyi sub-series
|
|
18
|
+
"urn:ietf:#{identifier.series.downcase}:#{identifier.number}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
# Parses IETF URNs back into identifiers by reconstructing the printed form
|
|
6
|
+
# and delegating to the flavor's text parser. Inverts UrnGenerator:
|
|
7
|
+
# urn:ietf:rfc:2119 -> "RFC 2119"
|
|
8
|
+
# urn:ietf:bcp:3 -> "BCP 3"
|
|
9
|
+
# urn:ietf:id:draft-giuliano-treedn:02 -> "draft-giuliano-treedn-02"
|
|
10
|
+
# urn:ietf:id:draft-giuliano-treedn -> "draft-giuliano-treedn"
|
|
11
|
+
class UrnParser < Pubid::UrnParser::Base
|
|
12
|
+
def parse_urn(urn)
|
|
13
|
+
parts = split_parts(strip_namespace(urn))
|
|
14
|
+
flavor_parse(human_text(parts.shift, parts))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def human_text(type, parts)
|
|
20
|
+
case type
|
|
21
|
+
when "rfc" then "RFC #{parts[0]}"
|
|
22
|
+
when "bcp", "std", "fyi" then "#{type.upcase} #{parts[0]}"
|
|
23
|
+
when "id" then draft_text(parts)
|
|
24
|
+
else
|
|
25
|
+
raise Errors::ParseError, "Invalid IETF URN type: #{type.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def draft_text(parts)
|
|
30
|
+
name, version = parts
|
|
31
|
+
version ? "#{name}-#{version}" : name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/pubid/ietf.rb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
# IETF flavor: one module covering the three IETF document families that share
|
|
5
|
+
# the IETF publisher and the `urn:ietf:` namespace —
|
|
6
|
+
# * RFC (e.g. "RFC 2119") -> Identifiers::Rfc
|
|
7
|
+
# * RFC sub-series (BCP/STD/FYI) -> Identifiers::Bcp/Std/Fyi
|
|
8
|
+
# * Internet-Drafts (e.g. "draft-...-02") -> Identifiers::InternetDraft
|
|
9
|
+
module Ietf
|
|
10
|
+
extend Pubid::PrefixesSupport
|
|
11
|
+
|
|
12
|
+
# Leading tokens a printed IETF id can begin with. "draft" covers the
|
|
13
|
+
# "draft-<slug>" Internet-Draft form. No joint/co-publication prefixes.
|
|
14
|
+
PREFIXES = ["RFC", "BCP", "STD", "FYI", "draft"].freeze
|
|
15
|
+
|
|
16
|
+
autoload :Builder, "#{__dir__}/ietf/builder"
|
|
17
|
+
autoload :Identifier, "#{__dir__}/ietf/identifiers/base"
|
|
18
|
+
autoload :Identifiers, "#{__dir__}/ietf/identifiers"
|
|
19
|
+
autoload :Parser, "#{__dir__}/ietf/parser"
|
|
20
|
+
autoload :Renderer, "#{__dir__}/ietf/renderer"
|
|
21
|
+
autoload :UrnGenerator, "#{__dir__}/ietf/urn_generator"
|
|
22
|
+
autoload :UrnParser, "#{__dir__}/ietf/urn_parser"
|
|
23
|
+
|
|
24
|
+
# Parse an IETF identifier string
|
|
25
|
+
def self.parse(identifier)
|
|
26
|
+
# Inline length guard (CodeQL rb/polynomial-redos barrier) before the
|
|
27
|
+
# normalization/parse path — must be the first statement.
|
|
28
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
29
|
+
|
|
30
|
+
Identifier.parse(identifier)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Per-flavor format registry: inherits global formats, overrides :human
|
|
34
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
35
|
+
Identifier.format_registry.register(:human, renderer: Ietf::Renderer)
|
|
36
|
+
|
|
37
|
+
# Auto-discover all identifier types from the Identifiers namespace
|
|
38
|
+
# @return [Array<Class>] identifier classes that define a self.type Hash
|
|
39
|
+
def self.identifier_types
|
|
40
|
+
@identifier_types ||= Identifiers.constants
|
|
41
|
+
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
42
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
43
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Build typed stage index from identifier types
|
|
47
|
+
# @return [Array<Pubid::Components::TypedStage>] all typed stages
|
|
48
|
+
def self.all_typed_stages
|
|
49
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
50
|
+
if klass.const_defined?(:TYPED_STAGES)
|
|
51
|
+
klass.const_get(:TYPED_STAGES)
|
|
52
|
+
else
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Lookup: type code -> identifier class
|
|
59
|
+
# @param code [String, Symbol] the type key to find
|
|
60
|
+
# @return [Class, nil] the matching identifier class
|
|
61
|
+
def self.locate_type(code)
|
|
62
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Lookup: abbreviation -> typed stage
|
|
66
|
+
# @param abbr [String, Symbol] the abbreviation to find
|
|
67
|
+
# @return [Pubid::Components::TypedStage, nil] the matching typed stage
|
|
68
|
+
def self.locate_stage(abbr)
|
|
69
|
+
abbr_str = abbr.to_s.upcase
|
|
70
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Register IETF flavor with the registry
|
|
76
|
+
Pubid::Registry.register(:ietf, Pubid::Ietf)
|
data/lib/pubid/iho/identifier.rb
CHANGED
|
@@ -3,7 +3,5 @@
|
|
|
3
3
|
# The IHO flavor base class is Pubid::Iho::Identifier — a real Pubid::Identifier
|
|
4
4
|
# subclass that every concrete IHO identifier descends from, so `is_a?` identity
|
|
5
5
|
# and the shared polymorphic `from_hash` work natively (no facade needed). Its
|
|
6
|
-
# body
|
|
7
|
-
# identifiers/base.rb; this file just ensures it is loaded when a consumer
|
|
6
|
+
# body and `.parse` live in identifiers/base.rb; this file just ensures it is loaded when a consumer
|
|
8
7
|
# references Pubid::Iho::Identifier directly.
|
|
9
|
-
require_relative "identifiers/base"
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Iho
|
|
5
5
|
# Base class for all IHO identifiers. Canonical name Pubid::Iho::Identifier;
|
|
6
|
-
# every concrete IHO identifier (Identifiers::*) descends from it
|
|
7
|
-
# Identifiers::Base — aliased at the foot of this file — points back to it.
|
|
6
|
+
# every concrete IHO identifier (Identifiers::*) descends from it.
|
|
8
7
|
#
|
|
9
8
|
# IHO identifiers have the form:
|
|
10
9
|
# IHO {S|P|M|B|C}-{number}[ Ap. {appendix}][ Part {part}][ Annex {annex}][ Suppl {supplement}][ {version}]
|
|
@@ -65,10 +64,5 @@ module Pubid
|
|
|
65
64
|
# IHO_TYPE_MAP remains as the key_value polymorphic_map.
|
|
66
65
|
end
|
|
67
66
|
|
|
68
|
-
module Identifiers
|
|
69
|
-
# Backward-compatible alias: IHO's base class used to be
|
|
70
|
-
# Pubid::Iho::Identifiers::Base. It is now Pubid::Iho::Identifier.
|
|
71
|
-
Base = Pubid::Iho::Identifier
|
|
72
|
-
end
|
|
73
67
|
end
|
|
74
68
|
end
|
|
@@ -5,7 +5,7 @@ module Pubid
|
|
|
5
5
|
module Identifiers
|
|
6
6
|
# IHO Bibliographic Publication (B series).
|
|
7
7
|
# Example: IHO B-4 2.19.0.
|
|
8
|
-
class Bibliographic <
|
|
8
|
+
class Bibliographic < Identifier
|
|
9
9
|
def self.type
|
|
10
10
|
{ key: :bibliographic, title: "Bibliographic Publication",
|
|
11
11
|
short: "B" }
|
|
@@ -5,7 +5,7 @@ module Pubid
|
|
|
5
5
|
module Identifiers
|
|
6
6
|
# IHO Publication (P series).
|
|
7
7
|
# Examples: IHO P-1 1.0.0, IHO P-1/21 1.0.0, IHO P-6-3 1.0.0.
|
|
8
|
-
class Publication <
|
|
8
|
+
class Publication < Identifier
|
|
9
9
|
def self.type
|
|
10
10
|
{ key: :publication, title: "Publication", short: "P" }
|
|
11
11
|
end
|
|
@@ -5,7 +5,7 @@ module Pubid
|
|
|
5
5
|
module Identifiers
|
|
6
6
|
# IHO Standards and Specifications (S series).
|
|
7
7
|
# Examples: IHO S-44 5.0.0, IHO S-100 Part 4a 1.0.0, IHO S-65 Ap. A 1.0.0.
|
|
8
|
-
class Standard <
|
|
8
|
+
class Standard < Identifier
|
|
9
9
|
def self.type
|
|
10
10
|
{ key: :standard, title: "Standards and Specifications", short: "S" }
|
|
11
11
|
end
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Iho
|
|
5
5
|
module Identifiers
|
|
6
|
-
autoload :Base, "#{__dir__}/identifiers/base"
|
|
7
6
|
autoload :Bibliographic, "#{__dir__}/identifiers/bibliographic"
|
|
8
7
|
autoload :CircularLetter, "#{__dir__}/identifiers/circular_letter"
|
|
9
8
|
autoload :Miscellaneous, "#{__dir__}/identifiers/miscellaneous"
|
data/lib/pubid/iho.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Pubid
|
|
|
8
8
|
PREFIXES = ["IHO"].freeze
|
|
9
9
|
|
|
10
10
|
autoload :Builder, "#{__dir__}/iho/builder"
|
|
11
|
-
autoload :Identifier,
|
|
11
|
+
autoload :Identifier, "#{__dir__}/iho/identifiers/base"
|
|
12
12
|
autoload :Identifiers, "#{__dir__}/iho/identifiers"
|
|
13
13
|
autoload :Parser, "#{__dir__}/iho/parser"
|
|
14
14
|
autoload :Renderer, "#{__dir__}/iho/renderer"
|
|
@@ -17,14 +17,14 @@ module Pubid
|
|
|
17
17
|
|
|
18
18
|
# Parse an IHO identifier string into an identifier object
|
|
19
19
|
# @param identifier [String] The IHO identifier string to parse
|
|
20
|
-
# @return [Pubid::Iho::
|
|
20
|
+
# @return [Pubid::Iho::Identifier] The appropriate identifier object
|
|
21
21
|
def self.parse(identifier)
|
|
22
22
|
Identifier.parse(identifier)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
# Per-flavor format registry: inherits global formats, overrides :human
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
|
|
27
|
+
Identifier.format_registry.register(:human, renderer: Iho::Renderer)
|
|
28
28
|
|
|
29
29
|
# Auto-discover all identifier types from the Identifiers namespace.
|
|
30
30
|
# @return [Array<Class>] identifier classes (Pubid::Identifier subclasses)
|
|
@@ -32,9 +32,9 @@ module Pubid
|
|
|
32
32
|
@identifier_types ||= Identifiers.constants
|
|
33
33
|
.filter_map { |c| begin; Identifiers.const_get(c); rescue NameError; nil; end }
|
|
34
34
|
.select { |c| c.is_a?(Class) && c < Pubid::Identifier }
|
|
35
|
-
# Exclude the flavor base itself by identity (
|
|
35
|
+
# Exclude the flavor base itself by identity (Identifier is now an
|
|
36
36
|
# alias for Pubid::Iho::Identifier, so name-based matching misses it).
|
|
37
|
-
.reject { |c| c ==
|
|
37
|
+
.reject { |c| c == Identifier }
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Build typed stage index from identifier types
|
|
@@ -66,7 +66,7 @@ module Pubid
|
|
|
66
66
|
|
|
67
67
|
# Look up an identifier class by its IHO series letter (S/P/M/B/C).
|
|
68
68
|
# @param letter [String]
|
|
69
|
-
# @return [Class<
|
|
69
|
+
# @return [Class<Identifier>]
|
|
70
70
|
def self.identifier_klass_for_type_letter(letter)
|
|
71
71
|
@by_letter ||= identifier_types.to_h { |klass| [klass.type[:short], klass] }
|
|
72
72
|
@by_letter.fetch(letter.to_s)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Isbn
|
|
5
|
+
# Builds a Pubid::Isbn::Identifier from a parse tree.
|
|
6
|
+
#
|
|
7
|
+
# Validates the check digit; raises if invalid. Stores both the
|
|
8
|
+
# hyphenated form (for round-trip rendering) and the bare digits
|
|
9
|
+
# (for queries).
|
|
10
|
+
class Builder
|
|
11
|
+
INVALID_LENGTH = /^(?:\d{9}[\dX]|\d{13})$/.freeze
|
|
12
|
+
|
|
13
|
+
def self.build(parsed_data)
|
|
14
|
+
new.build(parsed_data)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def build(data)
|
|
18
|
+
hyphenated = data[:body].to_s
|
|
19
|
+
raw = hyphenated.delete("-")
|
|
20
|
+
|
|
21
|
+
validate_length!(raw)
|
|
22
|
+
validate_check_digit!(raw)
|
|
23
|
+
|
|
24
|
+
Identifiers::Book.new(raw: raw, hyphenated: hyphenated.include?("-") ? hyphenated : nil)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def validate_length!(raw)
|
|
30
|
+
return if raw.match?(INVALID_LENGTH)
|
|
31
|
+
|
|
32
|
+
raise ArgumentError,
|
|
33
|
+
"ISBN must be 10 or 13 digits (got #{raw.length})"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def validate_check_digit!(raw)
|
|
37
|
+
return if CheckDigit.valid?(raw)
|
|
38
|
+
|
|
39
|
+
raise ArgumentError,
|
|
40
|
+
"ISBN check digit invalid for #{raw}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Isbn
|
|
5
|
+
# Pure-functional check digit math for ISBN-10 and ISBN-13 per ISO 2108.
|
|
6
|
+
#
|
|
7
|
+
# ISBN-10: weighted sum with weights 10..1, mod 11. Check digit 10 is
|
|
8
|
+
# rendered as "X".
|
|
9
|
+
# ISBN-13: weighted sum with alternating weights 1/3, mod 10. Check digit
|
|
10
|
+
# is 0-9.
|
|
11
|
+
class CheckDigit
|
|
12
|
+
# Compute the correct ISBN-10 check digit for a 9-digit payload.
|
|
13
|
+
# @return [String] "0".."9" or "X"
|
|
14
|
+
def self.compute_isbn10(payload)
|
|
15
|
+
raise ArgumentError, "ISBN-10 payload must be 9 digits" unless payload.to_s.match?(/\A\d{9}\z/)
|
|
16
|
+
|
|
17
|
+
sum = payload.to_s.each_char.with_index.sum { |c, i| c.to_i * (10 - i) }
|
|
18
|
+
digit = (11 - sum % 11) % 11
|
|
19
|
+
digit == 10 ? "X" : digit.to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Compute the correct ISBN-13 check digit for a 12-digit payload.
|
|
23
|
+
# @return [String] "0".."9"
|
|
24
|
+
def self.compute_isbn13(payload)
|
|
25
|
+
raise ArgumentError, "ISBN-13 payload must be 12 digits" unless payload.to_s.match?(/\A\d{12}\z/)
|
|
26
|
+
|
|
27
|
+
sum = payload.to_s.each_char.with_index.sum do |c, i|
|
|
28
|
+
c.to_i * (i.even? ? 1 : 3)
|
|
29
|
+
end
|
|
30
|
+
((10 - sum % 10) % 10).to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Verify the check digit on a full 10- or 13-digit ISBN string.
|
|
34
|
+
# @param full [String] 10 or 13 chars; ISBN-10 may end with X.
|
|
35
|
+
# @return [Boolean]
|
|
36
|
+
def self.valid?(full)
|
|
37
|
+
digits = full.to_s.upcase.delete("^0-9X")
|
|
38
|
+
case digits.length
|
|
39
|
+
when 10
|
|
40
|
+
payload = digits[0, 9]
|
|
41
|
+
actual = digits[9]
|
|
42
|
+
compute_isbn10(payload) == actual
|
|
43
|
+
when 13
|
|
44
|
+
payload = digits[0, 12]
|
|
45
|
+
actual = digits[12]
|
|
46
|
+
compute_isbn13(payload) == actual
|
|
47
|
+
else
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Isbn
|
|
5
|
+
class Identifier < ::Pubid::Identifier
|
|
6
|
+
# The digits-only ISBN (no hyphens), including check digit. 10 or 13 chars.
|
|
7
|
+
attribute :raw, :string
|
|
8
|
+
|
|
9
|
+
# Original hyphenated form (may be nil when the input had no hyphens).
|
|
10
|
+
# Preserved for round-trip rendering; not queryable semantics.
|
|
11
|
+
attribute :hyphenated, :string
|
|
12
|
+
|
|
13
|
+
ISBN_TYPE_MAP = {
|
|
14
|
+
"pubid:isbn:book" => "Pubid::Isbn::Identifiers::Book",
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
key_value do
|
|
18
|
+
map "_type", to: :_type, polymorphic_map: ISBN_TYPE_MAP
|
|
19
|
+
map "raw", to: :raw
|
|
20
|
+
map "hyphenated", to: :hyphenated
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
PUBLISHER = "ISBN"
|
|
24
|
+
|
|
25
|
+
# Returns :isbn10 or :isbn13.
|
|
26
|
+
def form
|
|
27
|
+
case raw.to_s.length
|
|
28
|
+
when 10 then :isbn10
|
|
29
|
+
when 13 then :isbn13
|
|
30
|
+
else raise "Invalid ISBN length: #{raw.inspect}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def check_digit
|
|
35
|
+
raw.to_s[-1]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def valid?
|
|
39
|
+
CheckDigit.valid?(raw)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_s(**opts)
|
|
43
|
+
render(format: :human, **opts)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.parse(identifier)
|
|
47
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
48
|
+
raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
parsed = Parser.parse(identifier)
|
|
52
|
+
Builder.build(parsed)
|
|
53
|
+
rescue Parslet::ParseFailed => e
|
|
54
|
+
raise "Failed to parse ISBN '#{identifier}': #{e.message}"
|
|
55
|
+
rescue ArgumentError => e
|
|
56
|
+
# Builder validates length/check-digit; surface as a parse error so
|
|
57
|
+
# the error contract matches other flavors (always raises a string
|
|
58
|
+
# beginning with "Failed to parse").
|
|
59
|
+
raise "Failed to parse ISBN '#{identifier}': #{e.message}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Isbn
|
|
5
|
+
module Identifiers
|
|
6
|
+
# ISBN book identifier — supports both ISBN-10 and ISBN-13.
|
|
7
|
+
#
|
|
8
|
+
# Examples:
|
|
9
|
+
# ISBN 978-3-16-148410-0
|
|
10
|
+
# ISBN 0-306-40615-2
|
|
11
|
+
# 9783161484100
|
|
12
|
+
class Book < Identifier
|
|
13
|
+
TYPED_STAGES = [
|
|
14
|
+
Pubid::Components::TypedStage.new(
|
|
15
|
+
code: :pubisbn,
|
|
16
|
+
stage_code: :published,
|
|
17
|
+
type_code: :isbn,
|
|
18
|
+
abbr: ["ISBN"],
|
|
19
|
+
name: "ISBN",
|
|
20
|
+
harmonized_stages: [],
|
|
21
|
+
),
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
def self.type
|
|
25
|
+
{ key: :isbn, web: :book, title: "ISBN", short: "ISBN" }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|