pubid 2.0.0.pre.alpha.2 → 2.0.0.pre.alpha.3
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 +5 -1
- data/data/nist/update_codes.yaml +25 -0
- data/lib/pubid/amca/builder.rb +2 -2
- data/lib/pubid/amca/identifier.rb +7 -39
- data/lib/pubid/amca/identifiers/base.rb +0 -26
- data/lib/pubid/amca/identifiers/interpretation.rb +0 -17
- data/lib/pubid/amca/identifiers/publication.rb +0 -13
- data/lib/pubid/amca/renderer.rb +82 -0
- data/lib/pubid/amca/single_identifier.rb +0 -23
- data/lib/pubid/amca/urn_parser.rb +28 -0
- data/lib/pubid/amca.rb +42 -1
- data/lib/pubid/ansi/builder.rb +5 -3
- data/lib/pubid/ansi/identifier.rb +1 -43
- data/lib/pubid/ansi/identifiers/american_national_standard.rb +2 -1
- data/lib/pubid/ansi/identifiers/standard.rb +2 -3
- data/lib/pubid/ansi/renderer.rb +53 -0
- data/lib/pubid/ansi/single_identifier.rb +2 -31
- data/lib/pubid/ansi/urn_generator.rb +3 -38
- data/lib/pubid/ansi/urn_parser.rb +23 -0
- data/lib/pubid/ansi.rb +38 -3
- data/lib/pubid/api/builder.rb +29 -74
- data/lib/pubid/api/identifier.rb +0 -51
- data/lib/pubid/api/identifiers/base.rb +0 -2
- data/lib/pubid/api/identifiers/bulletin.rb +0 -2
- data/lib/pubid/api/identifiers/continuous_operations_standard.rb +0 -2
- data/lib/pubid/api/identifiers/mpms.rb +1 -17
- data/lib/pubid/api/identifiers/publication.rb +0 -2
- data/lib/pubid/api/identifiers/recommended_practice.rb +0 -2
- data/lib/pubid/api/identifiers/specification.rb +0 -2
- data/lib/pubid/api/identifiers/standard.rb +0 -2
- data/lib/pubid/api/identifiers/technical_report.rb +0 -2
- data/lib/pubid/api/identifiers/typeless_standard.rb +1 -14
- data/lib/pubid/api/identifiers.rb +18 -0
- data/lib/pubid/api/renderer.rb +89 -0
- data/lib/pubid/api/single_identifier.rb +1 -13
- data/lib/pubid/api/urn_generator.rb +0 -18
- data/lib/pubid/api/urn_parser.rb +35 -0
- data/lib/pubid/api.rb +51 -5
- data/lib/pubid/ashrae/builder.rb +3 -3
- data/lib/pubid/ashrae/identifier.rb +6 -39
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +0 -10
- data/lib/pubid/ashrae/identifiers/addendum.rb +0 -19
- data/lib/pubid/ashrae/identifiers/base.rb +3 -0
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +0 -15
- data/lib/pubid/ashrae/identifiers/errata.rb +0 -10
- data/lib/pubid/ashrae/identifiers/interpretation.rb +0 -10
- data/lib/pubid/ashrae/renderer.rb +117 -0
- data/lib/pubid/ashrae/single_identifier.rb +0 -13
- data/lib/pubid/ashrae/urn_generator.rb +0 -8
- data/lib/pubid/ashrae/urn_parser.rb +27 -0
- data/lib/pubid/ashrae.rb +42 -1
- data/lib/pubid/asme/components/code.rb +10 -2
- data/lib/pubid/asme/identifier.rb +0 -46
- data/lib/pubid/asme/identifiers/base.rb +0 -60
- data/lib/pubid/asme/renderer.rb +66 -0
- data/lib/pubid/asme/urn_parser.rb +31 -0
- data/lib/pubid/asme.rb +42 -1
- data/lib/pubid/astm/components/code.rb +9 -0
- data/lib/pubid/{jis → astm}/components.rb +1 -1
- data/lib/pubid/astm/identifier.rb +0 -77
- data/lib/pubid/astm/identifiers/adjunct.rb +0 -8
- data/lib/pubid/astm/identifiers/data_series.rb +0 -14
- data/lib/pubid/astm/identifiers/iso_dual_published.rb +9 -34
- data/lib/pubid/astm/identifiers/manual.rb +0 -27
- data/lib/pubid/astm/identifiers/monograph.rb +0 -14
- data/lib/pubid/astm/identifiers/research_report.rb +0 -7
- data/lib/pubid/astm/identifiers/standard.rb +0 -39
- data/lib/pubid/astm/identifiers/technical_report.rb +0 -13
- data/lib/pubid/astm/identifiers/work_in_progress.rb +0 -11
- data/lib/pubid/astm/identifiers.rb +18 -0
- data/lib/pubid/astm/renderer.rb +172 -0
- data/lib/pubid/astm/single_identifier.rb +0 -10
- data/lib/pubid/astm/urn_parser.rb +30 -0
- data/lib/pubid/astm.rb +39 -27
- data/lib/pubid/bsi/builder.rb +21 -12
- data/lib/pubid/bsi/identifier.rb +8 -62
- data/lib/pubid/bsi/identifiers/addendum_document.rb +3 -33
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +11 -47
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +11 -38
- data/lib/pubid/bsi/identifiers/aerospace_standard.rb +3 -53
- data/lib/pubid/bsi/identifiers/amendment.rb +3 -19
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +2 -4
- data/lib/pubid/bsi/identifiers/british_standard.rb +2 -1
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +3 -84
- data/lib/pubid/bsi/identifiers/committee_document.rb +1 -14
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +3 -84
- data/lib/pubid/bsi/identifiers/corrigendum.rb +3 -7
- data/lib/pubid/bsi/identifiers/detailed_specification.rb +1 -34
- data/lib/pubid/bsi/identifiers/disc.rb +1 -27
- data/lib/pubid/bsi/identifiers/draft_document.rb +3 -44
- data/lib/pubid/bsi/identifiers/electronic_book.rb +3 -36
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +3 -15
- data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +1 -45
- data/lib/pubid/bsi/identifiers/flex.rb +1 -33
- data/lib/pubid/bsi/identifiers/handbook.rb +2 -13
- data/lib/pubid/bsi/identifiers/index.rb +1 -30
- data/lib/pubid/bsi/identifiers/method.rb +1 -39
- data/lib/pubid/bsi/identifiers/national_annex.rb +5 -27
- data/lib/pubid/bsi/identifiers/practice_guide.rb +2 -4
- data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +3 -52
- data/lib/pubid/bsi/identifiers/published_document.rb +3 -52
- data/lib/pubid/bsi/identifiers/section.rb +1 -28
- data/lib/pubid/bsi/identifiers/set.rb +3 -17
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +1 -7
- data/lib/pubid/bsi/identifiers/supplement_document.rb +3 -21
- data/lib/pubid/bsi/identifiers/supplementary_index.rb +1 -44
- data/lib/pubid/bsi/identifiers/technical_specification.rb +3 -45
- data/lib/pubid/bsi/identifiers/test_method.rb +1 -30
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +3 -14
- data/lib/pubid/bsi/identifiers.rb +0 -1
- data/lib/pubid/bsi/renderer.rb +1050 -0
- data/lib/pubid/bsi/single_identifier.rb +6 -70
- data/lib/pubid/bsi/urn_generator.rb +2 -3
- data/lib/pubid/bsi/urn_parser.rb +52 -0
- data/lib/pubid/bsi.rb +224 -1
- data/lib/pubid/builder/base.rb +57 -10
- data/lib/pubid/bundled_identifier.rb +0 -1
- data/lib/pubid/ccsds/builder.rb +4 -3
- data/lib/pubid/ccsds/identifier.rb +63 -66
- data/lib/pubid/ccsds/identifiers/base.rb +11 -61
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +7 -6
- data/lib/pubid/ccsds/parser.rb +4 -2
- data/lib/pubid/ccsds/supplement_identifier.rb +15 -11
- data/lib/pubid/ccsds/urn_generator.rb +3 -3
- data/lib/pubid/ccsds/urn_parser.rb +20 -0
- data/lib/pubid/ccsds.rb +39 -1
- data/lib/pubid/cen_cenelec/builder.rb +12 -14
- data/lib/pubid/cen_cenelec/identifier.rb +7 -38
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +13 -4
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +2 -8
- data/lib/pubid/cen_cenelec/identifiers/base.rb +5 -41
- data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +2 -25
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +2 -13
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +4 -7
- data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +2 -2
- data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +2 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +2 -1
- data/lib/pubid/cen_cenelec/renderer.rb +261 -0
- data/lib/pubid/cen_cenelec/single_identifier.rb +11 -89
- data/lib/pubid/cen_cenelec/urn_generator.rb +6 -6
- data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
- data/lib/pubid/cen_cenelec.rb +168 -1
- data/lib/pubid/cie/components/code.rb +8 -0
- data/lib/pubid/cie/identifier.rb +6 -57
- data/lib/pubid/cie/urn_parser.rb +28 -0
- data/lib/pubid/cie.rb +43 -1
- data/lib/pubid/components/adoption.rb +104 -0
- data/lib/pubid/components/code.rb +22 -8
- data/lib/pubid/components/date.rb +23 -16
- data/lib/pubid/components/edition.rb +9 -6
- data/lib/pubid/components/iteration.rb +32 -0
- data/lib/pubid/components/language.rb +6 -4
- data/lib/pubid/components/locality.rb +10 -1
- data/lib/pubid/components/publisher.rb +9 -6
- data/lib/pubid/components/relationship.rb +151 -0
- data/lib/pubid/components/stage.rb +5 -14
- data/lib/pubid/components/supplement.rb +184 -0
- data/lib/pubid/components/type.rb +5 -15
- data/lib/pubid/components/typed_stage.rb +10 -11
- data/lib/pubid/components.rb +4 -1
- data/lib/pubid/core/update_codes.rb +28 -7
- data/lib/pubid/csa/identifier.rb +0 -59
- data/lib/pubid/csa/identifiers/base.rb +2 -122
- data/lib/pubid/csa/identifiers/cec.rb +2 -101
- data/lib/pubid/csa/identifiers/series.rb +2 -102
- data/lib/pubid/csa/renderer.rb +292 -0
- data/lib/pubid/csa/urn_generator.rb +1 -1
- data/lib/pubid/csa/urn_parser.rb +33 -0
- data/lib/pubid/csa.rb +42 -1
- data/lib/pubid/etsi/components/code.rb +9 -2
- data/lib/pubid/etsi/identifier.rb +0 -43
- data/lib/pubid/etsi/identifiers/base.rb +1 -4
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +2 -9
- data/lib/pubid/etsi/renderer.rb +42 -0
- data/lib/pubid/etsi/urn_parser.rb +34 -0
- data/lib/pubid/etsi.rb +42 -1
- data/lib/pubid/export/exporter.rb +4 -46
- data/lib/pubid/export/flavor_exporter.rb +111 -278
- data/lib/pubid/export.rb +0 -6
- data/lib/pubid/identifier.rb +2 -17
- data/lib/pubid/identifier_facade.rb +114 -0
- data/lib/pubid/identifier_metadata.rb +1 -1
- data/lib/pubid/idf/builder.rb +3 -3
- data/lib/pubid/idf/identifier.rb +3 -66
- data/lib/pubid/idf/identifiers/amendment.rb +2 -1
- data/lib/pubid/idf/identifiers/corrigendum.rb +2 -1
- data/lib/pubid/idf/identifiers/international_standard.rb +2 -1
- data/lib/pubid/idf/identifiers/reviewed_method.rb +2 -1
- data/lib/pubid/idf/parser.rb +3 -2
- data/lib/pubid/idf/renderer.rb +84 -0
- data/lib/pubid/idf/supplement_identifier.rb +2 -10
- data/lib/pubid/idf/urn_generator.rb +4 -39
- data/lib/pubid/idf/urn_parser.rb +25 -0
- data/lib/pubid/idf.rb +51 -1
- data/lib/pubid/iec/builder.rb +46 -64
- data/lib/pubid/iec/components/code.rb +8 -32
- data/lib/pubid/iec/components/publisher.rb +0 -1
- data/lib/pubid/iec/components.rb +14 -0
- data/lib/pubid/iec/identifier.rb +251 -213
- data/lib/pubid/iec/identifiers/amendment.rb +2 -3
- data/lib/pubid/iec/identifiers/base.rb +8 -32
- data/lib/pubid/iec/identifiers/component_specification.rb +3 -3
- data/lib/pubid/iec/identifiers/conformity_assessment.rb +1 -2
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +27 -26
- data/lib/pubid/iec/identifiers/corrigendum.rb +2 -3
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +37 -22
- data/lib/pubid/iec/identifiers/guide.rb +0 -2
- data/lib/pubid/iec/identifiers/international_standard.rb +2 -3
- data/lib/pubid/iec/identifiers/interpretation_sheet.rb +2 -3
- data/lib/pubid/iec/identifiers/operational_document.rb +3 -3
- data/lib/pubid/iec/identifiers/publicly_available_specification.rb +2 -3
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +21 -11
- data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +3 -3
- data/lib/pubid/iec/identifiers/systems_reference_document.rb +2 -3
- data/lib/pubid/iec/identifiers/technical_report.rb +2 -3
- data/lib/pubid/iec/identifiers/technical_specification.rb +2 -3
- data/lib/pubid/iec/identifiers/technology_report.rb +1 -2
- data/lib/pubid/iec/identifiers/test_report_form.rb +5 -34
- data/lib/pubid/iec/identifiers/vap_identifier.rb +26 -19
- data/lib/pubid/iec/identifiers/white_paper.rb +3 -3
- data/lib/pubid/iec/identifiers/working_document.rb +4 -48
- data/lib/pubid/iec/identifiers.rb +30 -0
- data/lib/pubid/iec/parser.rb +13 -12
- data/lib/pubid/iec/renderer.rb +254 -0
- data/lib/pubid/iec/single_identifier.rb +6 -12
- data/lib/pubid/iec/supplement_identifier.rb +58 -54
- data/lib/pubid/iec/urn_generator.rb +3 -3
- data/lib/pubid/iec/urn_parser.rb +3 -3
- data/lib/pubid/iec.rb +40 -68
- data/lib/pubid/ieee/builder.rb +12 -12
- data/lib/pubid/ieee/components/code.rb +8 -0
- data/lib/pubid/ieee/components/draft.rb +14 -0
- data/lib/pubid/ieee/components/relationship.rb +5 -149
- data/lib/pubid/ieee/identifier.rb +6 -41
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +1 -6
- data/lib/pubid/ieee/identifiers/base.rb +101 -458
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +1 -7
- data/lib/pubid/ieee/identifiers/corrigendum.rb +1 -9
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +1 -7
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +1 -1
- data/lib/pubid/ieee/identifiers/dual_published.rb +1 -1
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +1 -6
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +1 -7
- data/lib/pubid/ieee/identifiers/joint_development.rb +2 -0
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +1 -15
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +1 -3
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +15 -0
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +1 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +1 -35
- data/lib/pubid/ieee/identifiers/standard.rb +1 -1
- data/lib/pubid/ieee/pre_parser.rb +301 -0
- data/lib/pubid/ieee/renderer.rb +307 -0
- data/lib/pubid/ieee/urn_parser.rb +34 -0
- data/lib/pubid/ieee.rb +62 -1
- data/lib/pubid/ieee_debug.rb +0 -1
- data/lib/pubid/iho/builder.rb +2 -2
- data/lib/pubid/iho/identifier.rb +8 -42
- data/lib/pubid/iho/identifiers/base.rb +49 -10
- data/lib/pubid/iho/parser.rb +3 -3
- data/lib/pubid/iho/renderer.rb +30 -0
- data/lib/pubid/iho/urn_generator.rb +2 -2
- data/lib/pubid/iho/urn_parser.rb +58 -0
- data/lib/pubid/iho.rb +50 -1
- data/lib/pubid/iso/builder.rb +55 -53
- data/lib/pubid/iso/bundled_identifier.rb +51 -0
- data/lib/pubid/iso/components/code.rb +7 -19
- data/lib/pubid/iso/components/publisher.rb +10 -8
- data/lib/pubid/iso/components.rb +2 -4
- data/lib/pubid/iso/identifier.rb +218 -252
- data/lib/pubid/iso/identifiers/addendum.rb +9 -6
- data/lib/pubid/iso/identifiers/amendment.rb +8 -4
- data/lib/pubid/iso/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/iso/identifiers/data.rb +0 -1
- data/lib/pubid/iso/identifiers/directives.rb +8 -2
- data/lib/pubid/iso/identifiers/directives_supplement.rb +43 -14
- data/lib/pubid/iso/identifiers/extract.rb +2 -2
- data/lib/pubid/iso/identifiers/guide.rb +0 -1
- data/lib/pubid/iso/identifiers/international_standard.rb +4 -4
- data/lib/pubid/iso/identifiers/international_standardized_profile.rb +4 -4
- data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +10 -4
- data/lib/pubid/iso/identifiers/pas.rb +2 -2
- data/lib/pubid/iso/identifiers/recommendation.rb +2 -2
- data/lib/pubid/iso/identifiers/supplement.rb +11 -3
- data/lib/pubid/iso/identifiers/tc_document.rb +44 -15
- data/lib/pubid/iso/identifiers/technical_report.rb +4 -4
- data/lib/pubid/iso/identifiers/technical_specification.rb +2 -2
- data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +2 -2
- data/lib/pubid/iso/identifiers.rb +0 -1
- data/lib/pubid/iso/normalizer.rb +89 -0
- data/lib/pubid/iso/parser.rb +22 -4
- data/lib/pubid/iso/supplement_identifier.rb +15 -2
- data/lib/pubid/iso/urn_generator.rb +66 -182
- data/lib/pubid/iso/urn_parser.rb +12 -7
- data/lib/pubid/iso.rb +173 -2
- data/lib/pubid/itu/builder.rb +0 -12
- data/lib/pubid/itu/components/code.rb +8 -0
- data/lib/pubid/itu/components.rb +11 -0
- data/lib/pubid/itu/identifier.rb +6 -104
- data/lib/pubid/itu/identifiers/amendment.rb +0 -2
- data/lib/pubid/itu/identifiers/annex.rb +0 -2
- data/lib/pubid/itu/identifiers/base.rb +0 -6
- data/lib/pubid/itu/identifiers/combined_identifier.rb +0 -2
- data/lib/pubid/itu/identifiers/corrigendum.rb +0 -2
- data/lib/pubid/itu/identifiers/recommendation.rb +0 -2
- data/lib/pubid/itu/identifiers/special_publication.rb +0 -2
- data/lib/pubid/itu/identifiers/supplement.rb +0 -2
- data/lib/pubid/itu/urn_parser.rb +23 -0
- data/lib/pubid/itu.rb +42 -1
- data/lib/pubid/jcgm/builder.rb +16 -8
- data/lib/pubid/jcgm/identifier.rb +0 -43
- data/lib/pubid/jcgm/identifiers/amendment.rb +2 -7
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +2 -10
- data/lib/pubid/jcgm/renderer.rb +68 -0
- data/lib/pubid/jcgm/single_identifier.rb +1 -5
- data/lib/pubid/jcgm/urn_generator.rb +4 -6
- data/lib/pubid/jcgm/urn_parser.rb +23 -0
- data/lib/pubid/jcgm.rb +43 -2
- data/lib/pubid/jis/builder.rb +44 -52
- data/lib/pubid/jis/identifier.rb +132 -46
- data/lib/pubid/jis/identifiers/amendment.rb +1 -1
- data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
- data/lib/pubid/jis/identifiers/standard.rb +2 -1
- data/lib/pubid/jis/identifiers/technical_report.rb +2 -1
- data/lib/pubid/jis/identifiers/technical_specification.rb +2 -1
- data/lib/pubid/jis/identifiers.rb +1 -1
- data/lib/pubid/jis/parser.rb +31 -5
- data/lib/pubid/jis/renderer.rb +69 -0
- data/lib/pubid/jis/single_identifier.rb +6 -12
- data/lib/pubid/jis/supplement_identifier.rb +17 -14
- data/lib/pubid/jis/urn_parser.rb +23 -0
- data/lib/pubid/jis.rb +42 -2
- data/lib/pubid/nist/builder.rb +63 -1871
- data/lib/pubid/nist/caster.rb +1272 -0
- data/lib/pubid/nist/circular_supplement_builder.rb +291 -0
- data/lib/pubid/nist/components/code.rb +9 -20
- data/lib/pubid/nist/components/supplement.rb +2 -2
- data/lib/pubid/nist/components.rb +0 -1
- data/lib/pubid/nist/identifier.rb +11 -48
- data/lib/pubid/nist/identifiers/base.rb +110 -47
- data/lib/pubid/nist/identifiers/circular.rb +7 -2
- data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -1
- data/lib/pubid/nist/identifiers/commercial_standard.rb +2 -1
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +6 -4
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +10 -3
- data/lib/pubid/nist/identifiers/crpl_report.rb +8 -8
- data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +15 -24
- data/lib/pubid/nist/identifiers/grant_contractor_report.rb +2 -1
- data/lib/pubid/nist/identifiers/handbook.rb +2 -1
- data/lib/pubid/nist/identifiers/internal_report.rb +2 -1
- data/lib/pubid/nist/identifiers/letter_circular.rb +2 -1
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +5 -4
- data/lib/pubid/nist/identifiers/monograph.rb +7 -3
- data/lib/pubid/nist/identifiers/report.rb +4 -2
- data/lib/pubid/nist/identifiers/special_publication.rb +2 -1
- data/lib/pubid/nist/identifiers/technical_note.rb +3 -2
- data/lib/pubid/nist/identifiers.rb +1 -0
- data/lib/pubid/nist/parser.rb +62 -452
- data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
- data/lib/pubid/nist/preprocessor.rb +416 -0
- data/lib/pubid/nist/renderer.rb +43 -0
- data/lib/pubid/nist/router.rb +148 -0
- data/lib/pubid/nist/series/base.rb +58 -0
- data/lib/pubid/nist/series/crpl.rb +13 -0
- data/lib/pubid/nist/series/fips.rb +14 -0
- data/lib/pubid/nist/series/ir.rb +60 -0
- data/lib/pubid/nist/series/letter_preserving.rb +15 -0
- data/lib/pubid/nist/series/mono.rb +19 -0
- data/lib/pubid/nist/series/ncstar.rb +20 -0
- data/lib/pubid/nist/series.rb +49 -0
- data/lib/pubid/nist/supplement_identifier.rb +3 -1
- data/lib/pubid/nist/urn_parser.rb +67 -0
- data/lib/pubid/nist.rb +82 -4
- data/lib/pubid/oiml/components/code.rb +10 -0
- data/lib/pubid/oiml/identifier.rb +0 -50
- data/lib/pubid/oiml/identifiers/annex.rb +3 -45
- data/lib/pubid/oiml/identifiers/base.rb +2 -17
- data/lib/pubid/oiml/renderer.rb +161 -0
- data/lib/pubid/oiml/single_identifier.rb +6 -45
- data/lib/pubid/oiml/supplement_identifier.rb +4 -19
- data/lib/pubid/oiml/urn_generator.rb +0 -8
- data/lib/pubid/oiml/urn_parser.rb +22 -0
- data/lib/pubid/oiml.rb +42 -1
- data/lib/pubid/plateau/identifier.rb +7 -41
- data/lib/pubid/plateau/identifiers/handbook.rb +1 -3
- data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
- data/lib/pubid/plateau/renderer.rb +51 -0
- data/lib/pubid/plateau/supplement_identifier.rb +1 -1
- data/lib/pubid/plateau/urn_parser.rb +43 -0
- data/lib/pubid/plateau.rb +43 -1
- data/lib/pubid/renderers/directives_renderer.rb +22 -8
- data/lib/pubid/renderers/guide_renderer.rb +4 -2
- data/lib/pubid/renderers/human_readable.rb +18 -7
- data/lib/pubid/rendering/context.rb +28 -19
- data/lib/pubid/rendering.rb +0 -3
- data/lib/pubid/sae/components/date.rb +8 -0
- data/lib/pubid/sae/components/type.rb +5 -1
- data/lib/pubid/sae/identifier.rb +0 -23
- data/lib/pubid/sae/identifiers/base.rb +2 -16
- data/lib/pubid/sae/renderer.rb +36 -0
- data/lib/pubid/sae/urn_generator.rb +2 -10
- data/lib/pubid/sae/urn_parser.rb +36 -0
- data/lib/pubid/sae.rb +42 -1
- data/lib/pubid/urn_generator/base.rb +12 -12
- data/lib/pubid/urn_parser/base.rb +81 -0
- data/lib/pubid/urn_parser/errors.rb +9 -0
- data/lib/pubid/urn_parser.rb +14 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +29 -7
- data/lib/tasks/website-data.json +1940 -1882
- metadata +75 -44
- data/lib/pubid/amca/scheme.rb +0 -16
- data/lib/pubid/ansi/scheme.rb +0 -15
- data/lib/pubid/api/scheme.rb +0 -66
- data/lib/pubid/ashrae/scheme.rb +0 -53
- data/lib/pubid/asme/scheme.rb +0 -37
- data/lib/pubid/astm/scheme.rb +0 -55
- data/lib/pubid/bsi/identifiers/base.rb +0 -11
- data/lib/pubid/bsi/scheme.rb +0 -243
- data/lib/pubid/ccsds/scheme.rb +0 -57
- data/lib/pubid/cen_cenelec/scheme.rb +0 -164
- data/lib/pubid/cie/scheme.rb +0 -64
- data/lib/pubid/components/factory.rb +0 -50
- data/lib/pubid/csa/scheme.rb +0 -44
- data/lib/pubid/etsi/scheme.rb +0 -42
- data/lib/pubid/export/data_class_exporter.rb +0 -59
- data/lib/pubid/export/ieee_exporter.rb +0 -78
- data/lib/pubid/export/itu_exporter.rb +0 -66
- data/lib/pubid/export/nist_exporter.rb +0 -64
- data/lib/pubid/export/registry_exporter.rb +0 -90
- data/lib/pubid/export/scheme_exporter.rb +0 -70
- data/lib/pubid/identifier_registry.rb +0 -198
- data/lib/pubid/idf/scheme.rb +0 -61
- data/lib/pubid/iec/scheme.rb +0 -71
- data/lib/pubid/ieee/scheme.rb +0 -90
- data/lib/pubid/iho/scheme.rb +0 -29
- data/lib/pubid/iso/identifiers/base.rb +0 -115
- data/lib/pubid/iso/scheme.rb +0 -193
- data/lib/pubid/itu/scheme.rb +0 -174
- data/lib/pubid/jcgm/scheme.rb +0 -60
- data/lib/pubid/jis/components/code.rb +0 -59
- data/lib/pubid/jis/identifiers/base.rb +0 -72
- data/lib/pubid/jis/scheme.rb +0 -49
- data/lib/pubid/nist/components/publisher.rb +0 -24
- data/lib/pubid/nist/scheme.rb +0 -199
- data/lib/pubid/oiml/scheme.rb +0 -46
- data/lib/pubid/plateau/scheme.rb +0 -45
- data/lib/pubid/rendering/base.rb +0 -73
- data/lib/pubid/rendering/common.rb +0 -211
- data/lib/pubid/rendering/format.rb +0 -25
- data/lib/pubid/sae/scheme.rb +0 -47
- data/lib/pubid/scheme.rb +0 -219
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
# Human-readable renderer for NIST identifiers.
|
|
6
|
+
#
|
|
7
|
+
# NIST supports multiple output formats (:full, :long, :abbreviated,
|
|
8
|
+
# :short, :mr). Each series class defines public style methods
|
|
9
|
+
# (to_short_style, to_mr_style, etc.) with series-specific formatting
|
|
10
|
+
# logic, so this renderer delegates to those methods rather than
|
|
11
|
+
# reimplementing them.
|
|
12
|
+
#
|
|
13
|
+
# Registered as the `:human` format in the NIST format registry and
|
|
14
|
+
# invoked via `render(format: :human, nist_format: :short)`.
|
|
15
|
+
class Renderer < ::Pubid::Renderers::Base
|
|
16
|
+
# Render the identifier in the requested NIST format.
|
|
17
|
+
#
|
|
18
|
+
# @param context [Object, nil] rendering context (unused by NIST)
|
|
19
|
+
# @param nist_format [Symbol, nil] NIST output format (:full, :long,
|
|
20
|
+
# :abbreviated, :abbrev, :short, :mr). Defaults to :short.
|
|
21
|
+
# @return [String] formatted identifier string
|
|
22
|
+
def render(context: nil, nist_format: nil, **_opts)
|
|
23
|
+
id = @id
|
|
24
|
+
|
|
25
|
+
effective_format = nist_format || :short
|
|
26
|
+
effective_format = effective_format.to_sym if effective_format.is_a?(String)
|
|
27
|
+
|
|
28
|
+
case effective_format
|
|
29
|
+
when :full, :long
|
|
30
|
+
id.public_send(:to_full_style)
|
|
31
|
+
when :abbreviated, :abbrev
|
|
32
|
+
id.public_send(:to_abbreviated_style)
|
|
33
|
+
when :short
|
|
34
|
+
id.public_send(:to_short_style)
|
|
35
|
+
when :mr
|
|
36
|
+
id.public_send(:to_mr_style)
|
|
37
|
+
else
|
|
38
|
+
id.public_send(:to_short_style)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
# Router class for NIST series-to-class mapping
|
|
6
|
+
# Single Responsibility: Resolve parsed data to the correct identifier class
|
|
7
|
+
#
|
|
8
|
+
# Delegates to Pubid::Nist.locate_stage / Pubid::Nist.locate_type
|
|
9
|
+
# for series-to-class resolution.
|
|
10
|
+
class Router
|
|
11
|
+
# All valid series codes (comprehensive list)
|
|
12
|
+
VALID_SERIES = [
|
|
13
|
+
# Major series with dedicated classes
|
|
14
|
+
"SP", "FIPS", "IR", "HB", "TN",
|
|
15
|
+
# Specialized series with dedicated classes
|
|
16
|
+
"CIRC", "CRPL", "CS", "CSM",
|
|
17
|
+
# Other series (use Base class)
|
|
18
|
+
"GCR", "AMS", "BSS", "BMS", "BH", "MONO", "MP",
|
|
19
|
+
"NCSTAR", "NSRDS", "CSWP", "VTS", "AI", "OWMWP",
|
|
20
|
+
"PC", "RPT", "SIBS", "TIBM", "TTB", "EAB",
|
|
21
|
+
"JPCRD", "JRES", "CIS", "HR", "IRPL", "IP",
|
|
22
|
+
"LC", "PS", "LCIRC",
|
|
23
|
+
# Compound series
|
|
24
|
+
"BRPD-CRPL-D", "CRPL-F-A", "CRPL-F-B", "CS-E",
|
|
25
|
+
"CSRC Building Block", "CSRC Use Case", "CSRC Book",
|
|
26
|
+
"ITL Bulletin", "NIST LC", "NIST PS", "NIST DCI",
|
|
27
|
+
"NIST Other", "NSRDS-NBS",
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
# Check if series is valid
|
|
31
|
+
# @param series_code [String] the series code
|
|
32
|
+
# @return [Boolean] true if series is valid
|
|
33
|
+
def valid_series?(series_code)
|
|
34
|
+
VALID_SERIES.include?(series_code)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Locate identifier class by series and pattern
|
|
38
|
+
# @param parsed_hash [Hash] the parsed identifier data
|
|
39
|
+
# @return [Class] the identifier class
|
|
40
|
+
def locate_identifier_klass(parsed_hash)
|
|
41
|
+
# Date-style identifier (no series) dispatches here, not via series lookup.
|
|
42
|
+
if parsed_hash[:dated_date] && parsed_hash[:dated_seq]
|
|
43
|
+
return Identifiers::DatedDocument
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
series = parsed_hash[:series]&.to_s
|
|
47
|
+
|
|
48
|
+
# Handle compound series that include publisher (both space and dot separated)
|
|
49
|
+
if series&.start_with?("NBS ")
|
|
50
|
+
simple_series = series.sub("NBS ", "")
|
|
51
|
+
|
|
52
|
+
# Check for CIRC supplement
|
|
53
|
+
if simple_series == "CIRC"
|
|
54
|
+
if has_supplement?(parsed_hash)
|
|
55
|
+
return Identifiers::CircularSupplement
|
|
56
|
+
else
|
|
57
|
+
return Identifiers::Circular
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Use simple series for lookup (TYPED_STAGES abbr handles compound forms)
|
|
62
|
+
series = simple_series
|
|
63
|
+
elsif series&.start_with?("NBS.")
|
|
64
|
+
# Handle dot-separated patterns (e.g., "NBS.LCIRC" after preprocessing)
|
|
65
|
+
simple_series = series.sub("NBS.", "")
|
|
66
|
+
|
|
67
|
+
# Check for LCIRC supplement (dot-separated variant)
|
|
68
|
+
if simple_series == "LCIRC"
|
|
69
|
+
if has_supplement?(parsed_hash)
|
|
70
|
+
return Identifiers::CircularSupplement
|
|
71
|
+
else
|
|
72
|
+
return Identifiers::LetterCircular
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Check for CIRC supplement (dot-separated variant)
|
|
77
|
+
if simple_series == "CIRC"
|
|
78
|
+
if has_supplement?(parsed_hash)
|
|
79
|
+
return Identifiers::CircularSupplement
|
|
80
|
+
else
|
|
81
|
+
return Identifiers::Circular
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Use simple series for lookup
|
|
86
|
+
series = simple_series
|
|
87
|
+
elsif series&.start_with?("NIST.")
|
|
88
|
+
# Handle dot-separated NIST patterns
|
|
89
|
+
simple_series = series.sub("NIST.", "")
|
|
90
|
+
|
|
91
|
+
# Check for LCIRC supplement (dot-separated variant)
|
|
92
|
+
if simple_series == "LCIRC"
|
|
93
|
+
if has_supplement?(parsed_hash)
|
|
94
|
+
return Identifiers::CircularSupplement
|
|
95
|
+
else
|
|
96
|
+
return Identifiers::LetterCircular
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Use simple series for lookup
|
|
101
|
+
series = simple_series
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Check for CS variants (works for both compound "NBS CS" and simple "CS")
|
|
105
|
+
if series == "CS"
|
|
106
|
+
first_num = parsed_hash[:first_number]
|
|
107
|
+
|
|
108
|
+
# Check for CSM (monthly) - v#n# pattern inside first_number hash
|
|
109
|
+
if first_num.is_a?(Hash) && first_num[:volume_number] && first_num[:issue_number]
|
|
110
|
+
return Identifiers::CommercialStandardsMonthly
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Check for CS-E (emergency) - e-prefix with 3+ digits
|
|
114
|
+
# Handle Parslet::Slice by converting to string
|
|
115
|
+
first_num_str = first_num.is_a?(String) ? first_num.to_str : first_num.to_s
|
|
116
|
+
|
|
117
|
+
# Match e104 or e104 (when "e104-43" is split into first+second)
|
|
118
|
+
if /^e\d{3,}/.match?(first_num_str)
|
|
119
|
+
return Identifiers::CommercialStandardEmergency
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Look up using TYPED_STAGES registry (replaces series_to_class_map)
|
|
124
|
+
# This handles simple series, compound series (via abbr array), and all variants
|
|
125
|
+
# Delegates to Pubid::Nist.locate_stage / Pubid::Nist.locate_type
|
|
126
|
+
# instead of an injected dependency.
|
|
127
|
+
typed_stage = Pubid::Nist.locate_stage(series)
|
|
128
|
+
if typed_stage
|
|
129
|
+
Pubid::Nist.locate_type(typed_stage.type_code) || Identifiers::Base
|
|
130
|
+
else
|
|
131
|
+
# Fallback to Base for unmapped series (e.g., "AMS", "VTS")
|
|
132
|
+
Identifiers::Base
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Check if parsed hash has supplement indicators
|
|
137
|
+
# @param parsed_hash [Hash] the parsed identifier data
|
|
138
|
+
# @return [Boolean] true if supplement indicators are present
|
|
139
|
+
def has_supplement?(parsed_hash)
|
|
140
|
+
parsed_hash[:supplement] ||
|
|
141
|
+
parsed_hash[:supplement_date_range] ||
|
|
142
|
+
parsed_hash[:supplement_date] ||
|
|
143
|
+
parsed_hash[:supplement_slash_year] ||
|
|
144
|
+
parsed_hash[:supplement_with_rev]
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# Default series behavior. All hooks return the "generic" answer so a
|
|
7
|
+
# series bug can be fixed by overriding the relevant hook in a subclass.
|
|
8
|
+
class Base
|
|
9
|
+
# Whether an uppercase letter at the end of `first_number` stays in the
|
|
10
|
+
# number (true) or is extracted as a separate Part component (false).
|
|
11
|
+
def self.preserve_letter_suffix?(parsed_hash)
|
|
12
|
+
parsed_hash[:parsed_format] == :mr
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Cast a `:letter_number` parser hash (e.g., from "800-56A").
|
|
16
|
+
# Return a cast hash, or nil to skip assignment.
|
|
17
|
+
# Default: split letter suffix into a Part component.
|
|
18
|
+
def self.cast_letter_number(value, _parsed_hash)
|
|
19
|
+
full = combine_letter_suffix(value)
|
|
20
|
+
return nil if full.nil? || full.empty?
|
|
21
|
+
|
|
22
|
+
{ part: Components::Part.new(type: "", value: full.upcase) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Whether the edition-year cast should use modern (numeric) date format
|
|
26
|
+
# instead of preserving historical month names. FIPS uses modern.
|
|
27
|
+
def self.modern_edition_date?
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Whether `part_num` alongside `second_num` becomes a Part component
|
|
32
|
+
# (true) or is folded into the compound number (false). IR uses Part.
|
|
33
|
+
def self.part_num_as_component?
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Hook: build compound number when `letter_num` is present.
|
|
38
|
+
# Return true if the series handled it; false to fall back to default.
|
|
39
|
+
def self.handle_letter_num_compound?(_identifier,
|
|
40
|
+
first_num:, letter_base:,
|
|
41
|
+
letter_suffix:)
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Hook: post-process the identifier after compound number is assigned.
|
|
46
|
+
# Override to reverse series-specific preprocessing side effects.
|
|
47
|
+
def self.finalize_identifier(_identifier, _parsed_hash); end
|
|
48
|
+
|
|
49
|
+
# Combine `:letter_suffix` and `:letter_suffix_extra` (e.g., "U" + "r").
|
|
50
|
+
def self.combine_letter_suffix(value)
|
|
51
|
+
suffix = value[:letter_suffix].to_s.strip
|
|
52
|
+
extra = value[:letter_suffix_extra].to_s.strip
|
|
53
|
+
extra.empty? ? suffix : "#{suffix}#{extra}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# CRPL series: letter suffix preserved in first_number.
|
|
7
|
+
# Range parsing ("2_3-1") is handled by the dedicated :crpl_range case
|
|
8
|
+
# in the caster; this class only carries the letter-suffix policy.
|
|
9
|
+
class Crpl < LetterPreserving
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# FIPS series: letter suffix preserved; edition dates use modern format.
|
|
7
|
+
class Fips < LetterPreserving
|
|
8
|
+
def self.modern_edition_date?
|
|
9
|
+
true
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# IR (Interagency Report) series carries the most series-specific logic:
|
|
7
|
+
#
|
|
8
|
+
# - "R" or "Ur" letter suffix becomes revision "r1" (e.g., "79-1786R").
|
|
9
|
+
# - part_num alongside second_num becomes a Part component (type "pt").
|
|
10
|
+
# - Preprocessing converts "84-2946" → "84e2946"; this class reverses
|
|
11
|
+
# that side effect so IR keeps the compound number form.
|
|
12
|
+
class Ir < LetterPreserving
|
|
13
|
+
def self.cast_letter_number(value, _parsed_hash)
|
|
14
|
+
full = combine_letter_suffix(value)
|
|
15
|
+
return nil if full.nil? || full.empty?
|
|
16
|
+
|
|
17
|
+
if ["R", "Ur"].include?(full)
|
|
18
|
+
value[:letter_suffix] = full
|
|
19
|
+
value
|
|
20
|
+
else
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.part_num_as_component?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.handle_letter_num_compound?(identifier,
|
|
30
|
+
first_num:, letter_base:,
|
|
31
|
+
letter_suffix:)
|
|
32
|
+
return false unless letter_suffix == "R"
|
|
33
|
+
|
|
34
|
+
identifier.number = Components::Code.new(
|
|
35
|
+
value: "#{first_num.value}-#{letter_base}",
|
|
36
|
+
)
|
|
37
|
+
edition_obj = Components::Edition.new(type: "r", id: "1")
|
|
38
|
+
identifier.edition = edition_obj
|
|
39
|
+
identifier.edition_component = edition_obj
|
|
40
|
+
identifier.revision = "r1"
|
|
41
|
+
true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.finalize_identifier(identifier, _parsed_hash)
|
|
45
|
+
return unless identifier.number
|
|
46
|
+
|
|
47
|
+
value = identifier.number.value.to_s
|
|
48
|
+
match = value.match(/^(\d+)e(\d{4})$/)
|
|
49
|
+
return unless match
|
|
50
|
+
|
|
51
|
+
identifier.number = Components::Code.new(
|
|
52
|
+
value: "#{match[1]}-#{match[2]}",
|
|
53
|
+
)
|
|
54
|
+
identifier.edition = nil
|
|
55
|
+
identifier.edition_component = nil
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# Series where the letter suffix on `first_number` stays in the number.
|
|
7
|
+
# Used for: RPT, MP, LC, CRPL, MONO, FIPS, IR (subclasses refine further).
|
|
8
|
+
class LetterPreserving < Base
|
|
9
|
+
def self.preserve_letter_suffix?(_parsed_hash)
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# MONO series: letter suffix preserved in first_number AND in
|
|
7
|
+
# letter_number (e.g., "NBS MONO 1A" — letter stays in the number).
|
|
8
|
+
class Mono < LetterPreserving
|
|
9
|
+
def self.cast_letter_number(value, _parsed_hash)
|
|
10
|
+
full = combine_letter_suffix(value)
|
|
11
|
+
return nil if full.nil? || full.empty?
|
|
12
|
+
|
|
13
|
+
value[:letter_suffix] = full
|
|
14
|
+
value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
module Series
|
|
6
|
+
# NCSTAR series: letter suffix in letter_number stays in the number
|
|
7
|
+
# (e.g., "NIST NCSTAR 1-1A" — "1A" remains the compound suffix).
|
|
8
|
+
# Unlike MONO, first_number letter suffix is NOT preserved.
|
|
9
|
+
class Ncstar < Base
|
|
10
|
+
def self.cast_letter_number(value, _parsed_hash)
|
|
11
|
+
full = combine_letter_suffix(value)
|
|
12
|
+
return nil if full.nil? || full.empty?
|
|
13
|
+
|
|
14
|
+
value[:letter_suffix] = full
|
|
15
|
+
value
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
# Per-series behavior policies for the NIST caster and builder.
|
|
6
|
+
#
|
|
7
|
+
# Series-specific casting decisions (letter-suffix preservation, IR revision
|
|
8
|
+
# handling, FIPS date format, etc.) live behind this interface so the
|
|
9
|
+
# caster and builder never read `parsed_hash[:series]` directly. A series
|
|
10
|
+
# bug now lives in exactly one file.
|
|
11
|
+
module Series
|
|
12
|
+
autoload :Base, "#{__dir__}/series/base"
|
|
13
|
+
autoload :LetterPreserving, "#{__dir__}/series/letter_preserving"
|
|
14
|
+
autoload :Crpl, "#{__dir__}/series/crpl"
|
|
15
|
+
autoload :Fips, "#{__dir__}/series/fips"
|
|
16
|
+
autoload :Ir, "#{__dir__}/series/ir"
|
|
17
|
+
autoload :Mono, "#{__dir__}/series/mono"
|
|
18
|
+
autoload :Ncstar, "#{__dir__}/series/ncstar"
|
|
19
|
+
|
|
20
|
+
# Order matters: longer / more-specific codes first so that substrings
|
|
21
|
+
# do not shadow them (e.g., LCIRC must be matched before IR, since
|
|
22
|
+
# "LCIRC" contains "IR").
|
|
23
|
+
REGISTRY = [
|
|
24
|
+
["LCIRC", LetterPreserving],
|
|
25
|
+
["FIPS", Fips],
|
|
26
|
+
["CRPL", Crpl],
|
|
27
|
+
["NCSTAR", Ncstar],
|
|
28
|
+
["MONO", Mono],
|
|
29
|
+
["IR", Ir],
|
|
30
|
+
["MP", LetterPreserving],
|
|
31
|
+
["RPT", LetterPreserving],
|
|
32
|
+
["LC", LetterPreserving],
|
|
33
|
+
].freeze
|
|
34
|
+
|
|
35
|
+
def self.for(parsed_hash)
|
|
36
|
+
return Base if parsed_hash.nil?
|
|
37
|
+
|
|
38
|
+
series_code = parsed_hash[:series]
|
|
39
|
+
return Base if series_code.nil?
|
|
40
|
+
|
|
41
|
+
series_str = series_code.to_s.upcase
|
|
42
|
+
REGISTRY.each do |code, klass|
|
|
43
|
+
return klass if series_str.include?(code)
|
|
44
|
+
end
|
|
45
|
+
Base
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -42,7 +42,9 @@ module Pubid
|
|
|
42
42
|
# (relaton-data-nist uses "sup" across all series).
|
|
43
43
|
is_implicit = self.class.attributes.key?(:implicit_supplement) && implicit_supplement == true
|
|
44
44
|
result += "sup" unless is_implicit
|
|
45
|
-
|
|
45
|
+
# Update#to_s emits its own leading separator (/Upd… short, -upd… mr),
|
|
46
|
+
# so append it directly instead of hardcoding the slash.
|
|
47
|
+
result += update.to_s(format)
|
|
46
48
|
return result
|
|
47
49
|
end
|
|
48
50
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Nist
|
|
5
|
+
# Parses NIST URNs back into identifiers.
|
|
6
|
+
#
|
|
7
|
+
# UrnGenerator emits:
|
|
8
|
+
# urn:nist:{type}:{code}[.{revision}].supp
|
|
9
|
+
#
|
|
10
|
+
# type is the lowercase series (sp, fips, ir, nistcir, …). code is the
|
|
11
|
+
# alphanumeric designation. revision is `r{N}` when present. The `.supp`
|
|
12
|
+
# suffix marks the series as supplementable.
|
|
13
|
+
#
|
|
14
|
+
# Examples:
|
|
15
|
+
# - urn:nist:sp:800-53.supp → NIST SP 800-53
|
|
16
|
+
# - urn:nist:sp:800-53.r5.supp → NIST SP 800-53r5
|
|
17
|
+
# - urn:nist:fips:199.supp → NIST FIPS 199
|
|
18
|
+
class UrnParser < Pubid::UrnParser::Base
|
|
19
|
+
TYPE_UPCASE = {
|
|
20
|
+
"sp" => "SP",
|
|
21
|
+
"fips" => "FIPS",
|
|
22
|
+
"ir" => "IR",
|
|
23
|
+
"nistcir" => "NISTCIR",
|
|
24
|
+
"nbs" => "NBS",
|
|
25
|
+
"nistir" => "NISTIR",
|
|
26
|
+
"csf" => "CSF",
|
|
27
|
+
"gcr" => "GCR",
|
|
28
|
+
"itl" => "ITL",
|
|
29
|
+
"jres" => "JRES",
|
|
30
|
+
"lcirc" => "LCIRC",
|
|
31
|
+
"mon" => "MONO",
|
|
32
|
+
"ms" => "MS",
|
|
33
|
+
"nsrds" => "NSRDS",
|
|
34
|
+
"tn" => "TN",
|
|
35
|
+
"wp" => "WP",
|
|
36
|
+
}.freeze
|
|
37
|
+
|
|
38
|
+
def parse_urn(urn)
|
|
39
|
+
body = strip_namespace(urn)
|
|
40
|
+
parts = split_parts(body)
|
|
41
|
+
|
|
42
|
+
type_token, payload = parts
|
|
43
|
+
code, revision = parse_payload(payload)
|
|
44
|
+
|
|
45
|
+
text = "NIST #{type_label(type_token)} #{code}"
|
|
46
|
+
text += revision if revision
|
|
47
|
+
flavor_parse(text)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def parse_payload(payload)
|
|
53
|
+
# Strip the trailing ".supp" supplement marker.
|
|
54
|
+
stripped = payload.sub(/\.supp\z/, "")
|
|
55
|
+
# Split revision suffix from code (e.g., "800-53.r5" → ["800-53", "r5"]).
|
|
56
|
+
match = stripped.match(/^(.*)\.(r\d+)$/i)
|
|
57
|
+
return [stripped, nil] unless match
|
|
58
|
+
|
|
59
|
+
[match[1], match[2]]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def type_label(token)
|
|
63
|
+
TYPE_UPCASE.fetch(token.downcase) { token.upcase }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/lib/pubid/nist.rb
CHANGED
|
@@ -3,14 +3,51 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Nist
|
|
5
5
|
autoload :Builder, "#{__dir__}/nist/builder"
|
|
6
|
+
autoload :Caster, "#{__dir__}/nist/caster"
|
|
7
|
+
autoload :CircularSupplementBuilder, "#{__dir__}/nist/circular_supplement_builder"
|
|
6
8
|
autoload :Components, "#{__dir__}/nist/components"
|
|
7
9
|
autoload :Configuration, "#{__dir__}/nist/configuration"
|
|
8
10
|
autoload :Identifier, "#{__dir__}/nist/identifier"
|
|
9
11
|
autoload :Identifiers, "#{__dir__}/nist/identifiers"
|
|
10
12
|
autoload :Parser, "#{__dir__}/nist/parser"
|
|
11
|
-
autoload :
|
|
13
|
+
autoload :ParserOutputNormalizer, "#{__dir__}/nist/parser_output_normalizer"
|
|
14
|
+
autoload :Preprocessor, "#{__dir__}/nist/preprocessor"
|
|
15
|
+
autoload :Renderer, "#{__dir__}/nist/renderer"
|
|
16
|
+
autoload :Router, "#{__dir__}/nist/router"
|
|
17
|
+
autoload :Series, "#{__dir__}/nist/series"
|
|
12
18
|
autoload :SupplementIdentifier, "#{__dir__}/nist/supplement_identifier"
|
|
13
19
|
autoload :UrnGenerator, "#{__dir__}/nist/urn_generator"
|
|
20
|
+
autoload :UrnParser, "#{__dir__}/nist/urn_parser"
|
|
21
|
+
|
|
22
|
+
# Explicit registry of NIST identifier classes.
|
|
23
|
+
#
|
|
24
|
+
# NIST identifier classes use `typed_stages` (not the `self.type` Hash
|
|
25
|
+
# pattern used by CEN/JCGM/ANSI), so they cannot be auto-discovered.
|
|
26
|
+
# Identifiers::Base is the fallback for unmapped series (e.g. AMS, VTS)
|
|
27
|
+
# and must be excluded from typed-stage aggregation.
|
|
28
|
+
IDENTIFIER_TYPES = [
|
|
29
|
+
Identifiers::SpecialPublication,
|
|
30
|
+
Identifiers::FederalInformationProcessingStandards,
|
|
31
|
+
Identifiers::InteragencyReport,
|
|
32
|
+
Identifiers::Handbook,
|
|
33
|
+
Identifiers::TechnicalNote,
|
|
34
|
+
Identifiers::Circular,
|
|
35
|
+
Identifiers::CircularSupplement,
|
|
36
|
+
Identifiers::CrplReport,
|
|
37
|
+
Identifiers::Report,
|
|
38
|
+
Identifiers::Monograph,
|
|
39
|
+
Identifiers::MiscellaneousPublication,
|
|
40
|
+
Identifiers::GrantContractorReport,
|
|
41
|
+
Identifiers::Ncstar,
|
|
42
|
+
Identifiers::Owmwp,
|
|
43
|
+
Identifiers::Nsrds,
|
|
44
|
+
Identifiers::LetterCircular,
|
|
45
|
+
Identifiers::CommercialStandard,
|
|
46
|
+
Identifiers::CommercialStandardEmergency,
|
|
47
|
+
Identifiers::CommercialStandardsMonthly,
|
|
48
|
+
Identifiers::DatedDocument,
|
|
49
|
+
Identifiers::Base, # Fallback for unmapped series
|
|
50
|
+
].freeze
|
|
14
51
|
|
|
15
52
|
# Parse a NIST identifier string
|
|
16
53
|
# @param identifier [String] the identifier string to parse
|
|
@@ -20,9 +57,8 @@ module Pubid
|
|
|
20
57
|
# Note: We call the class method directly to ensure preprocessing is applied
|
|
21
58
|
parsed = Parser.class_parse_with_preprocessing(identifier)
|
|
22
59
|
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
builder = Builder.new(Scheme)
|
|
60
|
+
# Builder is stateless — lookups go through this module (Pubid::Nist)
|
|
61
|
+
builder = Builder.new
|
|
26
62
|
builder.build(parsed)
|
|
27
63
|
end
|
|
28
64
|
|
|
@@ -31,6 +67,48 @@ module Pubid
|
|
|
31
67
|
def self.configuration
|
|
32
68
|
@configuration ||= Configuration.new
|
|
33
69
|
end
|
|
70
|
+
|
|
71
|
+
# Per-flavor format registry: inherits global formats, overrides :human
|
|
72
|
+
Identifiers::Base.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
|
|
73
|
+
Identifiers::Base.format_registry.register(:human, renderer: Nist::Renderer)
|
|
74
|
+
|
|
75
|
+
# All identifier classes for external consumption (export, website).
|
|
76
|
+
# Identifiers::Base is the fallback for unmapped series and is excluded
|
|
77
|
+
# from external type listings.
|
|
78
|
+
# @return [Array<Class>] identifier classes
|
|
79
|
+
def self.identifier_types
|
|
80
|
+
IDENTIFIER_TYPES.reject { |klass| klass == Identifiers::Base }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Aggregate TYPED_STAGES from all identifier classes.
|
|
84
|
+
# Identifiers::Base is excluded because it has no typed stages and acts
|
|
85
|
+
# as the fallback for unmapped series.
|
|
86
|
+
# @return [Array<Pubid::Components::TypedStage>] all typed stages
|
|
87
|
+
def self.all_typed_stages
|
|
88
|
+
@all_typed_stages ||= identifier_types
|
|
89
|
+
.reject { |klass| klass == Identifiers::Base }
|
|
90
|
+
.flat_map(&:typed_stages)
|
|
91
|
+
.freeze
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Lookup: type code -> identifier class.
|
|
95
|
+
# Identifiers::Base is excluded so it never gets selected by type code.
|
|
96
|
+
# @param code [String, Symbol] the type code to find
|
|
97
|
+
# @return [Class, nil] the matching identifier class, or nil
|
|
98
|
+
def self.locate_type(code)
|
|
99
|
+
type_str = code.to_s
|
|
100
|
+
identifier_types
|
|
101
|
+
.reject { |klass| klass == Identifiers::Base }
|
|
102
|
+
.find { |klass| klass.typed_stages.any? { |ts| ts.type_code.to_s == type_str } }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Lookup: abbreviation -> typed stage
|
|
106
|
+
# @param abbr [String, Symbol] the abbreviation to find
|
|
107
|
+
# @return [Pubid::Components::TypedStage, nil] the matching typed stage
|
|
108
|
+
def self.locate_stage(abbr)
|
|
109
|
+
abbr_str = abbr.to_s.upcase
|
|
110
|
+
all_typed_stages.find { |s| s.abbr.any? { |a| a.to_s.upcase == abbr_str } }
|
|
111
|
+
end
|
|
34
112
|
end
|
|
35
113
|
end
|
|
36
114
|
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Oiml
|
|
5
5
|
module Components
|
|
6
|
+
# Code component for OIML identifiers.
|
|
7
|
+
#
|
|
8
|
+
# Stays independent of Pubid::Components::Code because OIML uses
|
|
9
|
+
# +number+ as the primary field (shared Code uses +value+). The
|
|
10
|
+
# shape is otherwise compatible; a future rename of +number+ →
|
|
11
|
+
# +value+ would let this become a subclass.
|
|
6
12
|
class Code < Lutaml::Model::Serializable
|
|
7
13
|
attribute :number, :string
|
|
8
14
|
attribute :part, :string
|
|
@@ -14,6 +20,10 @@ module Pubid
|
|
|
14
20
|
result += "-#{subpart}" if subpart
|
|
15
21
|
result
|
|
16
22
|
end
|
|
23
|
+
|
|
24
|
+
def render(context: nil)
|
|
25
|
+
to_s
|
|
26
|
+
end
|
|
17
27
|
end
|
|
18
28
|
end
|
|
19
29
|
end
|