pubid 2.0.0.pre.alpha.9 → 2.0.0.pre.alpha.11
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 +33 -11
- data/conformance/pending.yaml +4 -0
- data/lib/pubid/adobe/identifier.rb +1 -3
- data/lib/pubid/adobe/parser.rb +10 -2
- data/lib/pubid/adobe.rb +1 -0
- data/lib/pubid/amca/builder.rb +2 -2
- data/lib/pubid/amca/identifiers/base.rb +49 -27
- data/lib/pubid/amca/identifiers/interpretation.rb +17 -9
- data/lib/pubid/amca/identifiers/publication.rb +13 -9
- data/lib/pubid/amca/identifiers/standard.rb +2 -0
- data/lib/pubid/amca/parser.rb +1 -1
- data/lib/pubid/amca/renderer.rb +4 -4
- data/lib/pubid/amca/urn_generator.rb +2 -2
- data/lib/pubid/amca.rb +2 -1
- data/lib/pubid/ansi/builder.rb +2 -2
- data/lib/pubid/ansi/identifier.rb +18 -0
- data/lib/pubid/ansi/parser.rb +1 -1
- data/lib/pubid/ansi/renderer.rb +2 -2
- data/lib/pubid/ansi.rb +5 -5
- data/lib/pubid/api/builder.rb +16 -2
- data/lib/pubid/api/identifier.rb +25 -4
- data/lib/pubid/api/identifiers/mpms.rb +10 -8
- data/lib/pubid/api/parser.rb +1 -1
- data/lib/pubid/api/renderer.rb +16 -7
- data/lib/pubid/api/single_identifier.rb +5 -12
- data/lib/pubid/api.rb +1 -0
- data/lib/pubid/ashrae/builder.rb +31 -10
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +6 -0
- data/lib/pubid/ashrae/identifiers/addendum.rb +8 -0
- data/lib/pubid/ashrae/identifiers/base.rb +81 -5
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +7 -0
- data/lib/pubid/ashrae/identifiers/errata.rb +9 -0
- data/lib/pubid/ashrae/identifiers/guideline.rb +3 -0
- data/lib/pubid/ashrae/identifiers/interpretation.rb +16 -0
- data/lib/pubid/ashrae/identifiers/standard.rb +3 -0
- data/lib/pubid/ashrae/parser.rb +23 -8
- data/lib/pubid/ashrae/renderer.rb +6 -6
- data/lib/pubid/ashrae/supplement_identifier.rb +17 -2
- data/lib/pubid/ashrae/urn_generator.rb +8 -2
- data/lib/pubid/ashrae.rb +7 -1
- data/lib/pubid/asme/builder.rb +11 -2
- data/lib/pubid/asme/identifier.rb +9 -0
- data/lib/pubid/asme/identifiers/standard.rb +86 -2
- data/lib/pubid/asme/parser.rb +1 -1
- data/lib/pubid/asme/renderer.rb +3 -3
- data/lib/pubid/asme/single_identifier.rb +8 -1
- data/lib/pubid/asme/urn_generator.rb +2 -2
- data/lib/pubid/asme.rb +1 -0
- data/lib/pubid/astm/builder.rb +10 -3
- data/lib/pubid/astm/identifier.rb +9 -0
- data/lib/pubid/astm/identifiers/adjunct.rb +16 -1
- data/lib/pubid/astm/identifiers/code_number.rb +81 -0
- data/lib/pubid/astm/identifiers/data_series.rb +2 -0
- data/lib/pubid/astm/identifiers/iso_dual_published.rb +16 -0
- data/lib/pubid/astm/identifiers/manual.rb +10 -0
- data/lib/pubid/astm/identifiers/monograph.rb +2 -0
- data/lib/pubid/astm/identifiers/research_report.rb +10 -0
- data/lib/pubid/astm/identifiers/standard.rb +10 -0
- data/lib/pubid/astm/identifiers/technical_report.rb +2 -0
- data/lib/pubid/astm/identifiers/work_in_progress.rb +2 -0
- data/lib/pubid/astm/identifiers.rb +1 -0
- data/lib/pubid/astm/parser.rb +1 -1
- data/lib/pubid/astm/renderer.rb +1 -1
- data/lib/pubid/astm/single_identifier.rb +31 -1
- data/lib/pubid/astm/urn_generator.rb +7 -5
- data/lib/pubid/astm.rb +1 -0
- data/lib/pubid/bipm/builder.rb +66 -10
- data/lib/pubid/bipm/identifier.rb +134 -9
- data/lib/pubid/bipm/identifiers/committee_document.rb +12 -0
- data/lib/pubid/bipm/identifiers/guide.rb +11 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +12 -0
- data/lib/pubid/bipm/identifiers/mep.rb +12 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +24 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +13 -0
- data/lib/pubid/bipm/parser.rb +65 -12
- data/lib/pubid/bipm/renderer.rb +8 -0
- data/lib/pubid/bipm/urn_parser.rb +11 -3
- data/lib/pubid/bipm.rb +7 -1
- data/lib/pubid/bsi/builder.rb +48 -38
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +36 -7
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +7 -6
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -1
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +10 -0
- data/lib/pubid/bsi/identifiers/committee_document.rb +10 -1
- data/lib/pubid/bsi/identifiers/handbook.rb +0 -2
- data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -1
- data/lib/pubid/bsi/identifiers/set.rb +11 -0
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +10 -1
- data/lib/pubid/bsi/parser.rb +1 -1
- data/lib/pubid/bsi/renderer.rb +63 -51
- data/lib/pubid/bsi/single_identifier.rb +16 -7
- data/lib/pubid/bsi/urn_generator.rb +11 -2
- data/lib/pubid/bsi.rb +7 -1
- data/lib/pubid/builder/base.rb +18 -8
- data/lib/pubid/bundled_identifier.rb +16 -6
- data/lib/pubid/calconnect/identifier.rb +9 -5
- data/lib/pubid/calconnect/parser.rb +1 -1
- data/lib/pubid/calconnect.rb +7 -1
- data/lib/pubid/ccsds/identifier.rb +9 -2
- data/lib/pubid/ccsds/identifiers/base.rb +4 -2
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/ccsds/parser.rb +1 -1
- data/lib/pubid/ccsds/single_identifier.rb +2 -2
- data/lib/pubid/ccsds.rb +1 -0
- data/lib/pubid/cen_cenelec/builder.rb +101 -76
- data/lib/pubid/cen_cenelec/identifier.rb +115 -3
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +27 -16
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +46 -6
- data/lib/pubid/cen_cenelec/identifiers/base.rb +8 -9
- data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +29 -20
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +27 -2
- data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +15 -5
- data/lib/pubid/cen_cenelec/identifiers/guide.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +1 -1
- data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +1 -1
- data/lib/pubid/cen_cenelec/parser.rb +1 -1
- data/lib/pubid/cen_cenelec/renderer.rb +55 -60
- data/lib/pubid/cen_cenelec/single_identifier.rb +20 -2
- data/lib/pubid/cen_cenelec/urn_generator.rb +66 -44
- data/lib/pubid/cen_cenelec.rb +28 -10
- data/lib/pubid/cie/builder.rb +10 -0
- data/lib/pubid/cie/identifier.rb +6 -1
- data/lib/pubid/cie/identifiers/bundle.rb +4 -2
- data/lib/pubid/cie/identifiers/conference.rb +2 -2
- data/lib/pubid/cie/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/cie/identifiers/dual_published.rb +2 -2
- data/lib/pubid/cie/identifiers/identical.rb +2 -2
- data/lib/pubid/cie/identifiers/joint_published.rb +2 -2
- data/lib/pubid/cie/identifiers/proceedings.rb +8 -6
- data/lib/pubid/cie/identifiers/standard.rb +22 -13
- data/lib/pubid/cie/identifiers/supplement.rb +2 -2
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +2 -2
- data/lib/pubid/cie/parser.rb +1 -1
- data/lib/pubid/cie.rb +7 -1
- data/lib/pubid/conformance/checks.rb +72 -0
- data/lib/pubid/conformance/corpus/case.rb +55 -0
- data/lib/pubid/conformance/corpus.rb +36 -0
- data/lib/pubid/conformance/generator.rb +212 -0
- data/lib/pubid/conformance/pending.rb +63 -0
- data/lib/pubid/conformance/runner.rb +153 -0
- data/lib/pubid/conformance.rb +55 -0
- data/lib/pubid/core.rb +2 -0
- data/lib/pubid/csa/builder.rb +47 -47
- data/lib/pubid/csa/composite_identifier.rb +14 -19
- data/lib/pubid/csa/identifier.rb +143 -81
- data/lib/pubid/csa/identifiers/bundled.rb +23 -13
- data/lib/pubid/csa/identifiers/canadian_adopted.rb +13 -13
- data/lib/pubid/csa/identifiers/cec.rb +44 -4
- data/lib/pubid/csa/identifiers/combined.rb +95 -73
- data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
- data/lib/pubid/csa/identifiers/package.rb +2 -2
- data/lib/pubid/csa/parser.rb +6 -2
- data/lib/pubid/csa/renderer.rb +13 -5
- data/lib/pubid/csa/single_identifier.rb +93 -4
- data/lib/pubid/csa/urn_generator.rb +9 -2
- data/lib/pubid/csa/wrapper_identifier.rb +39 -23
- data/lib/pubid/csa.rb +7 -1
- data/lib/pubid/doi/identifier.rb +6 -3
- data/lib/pubid/doi/parser.rb +1 -1
- data/lib/pubid/doi.rb +1 -0
- data/lib/pubid/easc/identifier.rb +0 -2
- data/lib/pubid/easc/parser.rb +10 -2
- data/lib/pubid/easc.rb +1 -0
- data/lib/pubid/ecma/builder.rb +23 -9
- data/lib/pubid/ecma/identifier.rb +81 -10
- data/lib/pubid/ecma/parser.rb +39 -4
- data/lib/pubid/ecma/renderer.rb +29 -8
- data/lib/pubid/ecma/urn_generator.rb +34 -13
- data/lib/pubid/ecma/urn_parser.rb +30 -14
- data/lib/pubid/ecma.rb +1 -0
- data/lib/pubid/errors.rb +80 -0
- data/lib/pubid/etsi/builder.rb +6 -1
- data/lib/pubid/etsi/identifiers/base.rb +34 -20
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +120 -41
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +10 -0
- data/lib/pubid/etsi/parser.rb +1 -1
- data/lib/pubid/etsi.rb +1 -0
- data/lib/pubid/evs/builder.rb +26 -0
- data/lib/pubid/evs/identifier.rb +37 -0
- data/lib/pubid/evs/identifiers/national_adoption.rb +17 -0
- data/lib/pubid/evs/identifiers.rb +9 -0
- data/lib/pubid/evs/parser.rb +27 -0
- data/lib/pubid/evs/renderer.rb +30 -0
- data/lib/pubid/evs/urn_generator.rb +30 -0
- data/lib/pubid/evs/urn_parser.rb +80 -0
- data/lib/pubid/evs.rb +90 -0
- data/lib/pubid/export.rb +1 -0
- data/lib/pubid/format_detector.rb +1 -0
- data/lib/pubid/gb/identifier.rb +6 -3
- data/lib/pubid/gb/parser.rb +1 -1
- data/lib/pubid/gb.rb +1 -0
- data/lib/pubid/gost/builder.rb +46 -9
- data/lib/pubid/gost/identifier.rb +0 -2
- data/lib/pubid/gost/identifiers/foreign_reference.rb +1 -1
- data/lib/pubid/gost/parser.rb +10 -2
- data/lib/pubid/gost.rb +1 -0
- data/lib/pubid/iala/identifier.rb +9 -6
- data/lib/pubid/iala/parser.rb +10 -2
- data/lib/pubid/iala/urn_parser.rb +6 -2
- data/lib/pubid/iala.rb +1 -0
- data/lib/pubid/iana/builder.rb +3 -1
- data/lib/pubid/iana/identifier.rb +74 -6
- data/lib/pubid/iana/identifiers/registry.rb +36 -0
- data/lib/pubid/iana/parser.rb +1 -1
- data/lib/pubid/iana/renderer.rb +3 -0
- data/lib/pubid/iana/urn_generator.rb +5 -1
- data/lib/pubid/iana.rb +1 -0
- data/lib/pubid/identifier.rb +594 -10
- data/lib/pubid/identifier_metadata.rb +1 -0
- data/lib/pubid/idf/builder.rb +3 -3
- data/lib/pubid/idf/identifier.rb +18 -9
- data/lib/pubid/idf/parser.rb +1 -1
- data/lib/pubid/idf/renderer.rb +4 -4
- data/lib/pubid/idf/urn_generator.rb +1 -1
- data/lib/pubid/idf.rb +7 -1
- data/lib/pubid/iec/builder.rb +14 -7
- data/lib/pubid/iec/components.rb +0 -1
- data/lib/pubid/iec/identifier.rb +73 -83
- data/lib/pubid/iec/identifiers/amendment.rb +6 -2
- data/lib/pubid/iec/identifiers/component_specification.rb +0 -10
- data/lib/pubid/iec/identifiers/conformity_assessment.rb +0 -10
- data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +2 -4
- data/lib/pubid/iec/identifiers/guide.rb +0 -16
- data/lib/pubid/iec/identifiers/international_standard.rb +15 -2
- data/lib/pubid/iec/identifiers/operational_document.rb +0 -10
- data/lib/pubid/iec/identifiers/publicly_available_specification.rb +0 -12
- data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +0 -10
- data/lib/pubid/iec/identifiers/systems_reference_document.rb +0 -10
- data/lib/pubid/iec/identifiers/technical_report.rb +0 -17
- data/lib/pubid/iec/identifiers/technical_specification.rb +0 -17
- data/lib/pubid/iec/identifiers/technology_report.rb +0 -10
- data/lib/pubid/iec/identifiers/test_report_form.rb +0 -11
- data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
- data/lib/pubid/iec/identifiers/working_document.rb +24 -10
- data/lib/pubid/iec/parser.rb +2 -18
- data/lib/pubid/iec/renderer.rb +13 -10
- data/lib/pubid/iec/single_identifier.rb +33 -10
- data/lib/pubid/iec/urn_generator.rb +227 -61
- data/lib/pubid/iec/urn_parser.rb +42 -4
- data/lib/pubid/iec.rb +1 -0
- data/lib/pubid/ieee/aiee/identifier.rb +2 -2
- data/lib/pubid/ieee/aiee/parser.rb +1 -1
- data/lib/pubid/ieee/builder.rb +45 -1
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +32 -0
- data/lib/pubid/ieee/identifiers/base.rb +42 -5
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +21 -0
- data/lib/pubid/ieee/identifiers/dual_published.rb +55 -0
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +23 -0
- data/lib/pubid/ieee/identifiers/joint_development.rb +11 -7
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +57 -5
- data/lib/pubid/ieee/identifiers/nesc/base.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +2 -2
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +2 -2
- data/lib/pubid/ieee/ire/identifier.rb +2 -2
- data/lib/pubid/ieee/ire/parser.rb +1 -1
- data/lib/pubid/ieee/nesc/parser.rb +1 -1
- data/lib/pubid/ieee/parser.rb +1 -1
- data/lib/pubid/ieee/renderer.rb +5 -1
- data/lib/pubid/ieee/urn_generator.rb +32 -3
- data/lib/pubid/ieee.rb +7 -1
- data/lib/pubid/ieee_debug.rb +1 -0
- data/lib/pubid/ietf/builder.rb +24 -8
- data/lib/pubid/ietf/identifiers/base.rb +25 -28
- data/lib/pubid/ietf/identifiers/bcp.rb +11 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +11 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +18 -2
- data/lib/pubid/ietf/identifiers/rfc.rb +2 -0
- data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
- data/lib/pubid/ietf/identifiers/std.rb +11 -0
- data/lib/pubid/ietf/identifiers.rb +1 -0
- data/lib/pubid/ietf/parser.rb +27 -9
- data/lib/pubid/ietf/renderer.rb +44 -6
- data/lib/pubid/ietf/urn_generator.rb +20 -6
- data/lib/pubid/ietf/urn_parser.rb +10 -2
- data/lib/pubid/ietf.rb +12 -2
- data/lib/pubid/iho/identifiers/base.rb +10 -3
- data/lib/pubid/iho/parser.rb +1 -1
- data/lib/pubid/iho.rb +1 -0
- data/lib/pubid/isbn/identifier.rb +25 -7
- data/lib/pubid/isbn/parser.rb +1 -1
- data/lib/pubid/isbn.rb +1 -0
- data/lib/pubid/iso/bundled_identifier.rb +5 -3
- data/lib/pubid/iso/combined_identifier.rb +5 -3
- data/lib/pubid/iso/identifier.rb +12 -7
- data/lib/pubid/iso/identifiers/directives_supplement.rb +4 -4
- data/lib/pubid/iso/parser.rb +1 -1
- data/lib/pubid/iso.rb +7 -1
- data/lib/pubid/itu/identifiers/addendum.rb +2 -2
- data/lib/pubid/itu/identifiers/amendment.rb +2 -2
- data/lib/pubid/itu/identifiers/base.rb +19 -5
- data/lib/pubid/itu/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/itu/identifiers/errata.rb +2 -2
- data/lib/pubid/itu/identifiers/supplement.rb +2 -2
- data/lib/pubid/itu/parser.rb +1 -1
- data/lib/pubid/itu.rb +1 -0
- data/lib/pubid/jcgm/builder.rb +1 -1
- data/lib/pubid/jcgm/identifier.rb +10 -0
- data/lib/pubid/jcgm/identifiers/meeting.rb +1 -1
- data/lib/pubid/jcgm/parser.rb +10 -3
- data/lib/pubid/jcgm/renderer.rb +10 -3
- data/lib/pubid/jcgm/single_identifier.rb +24 -15
- data/lib/pubid/jcgm/urn_generator.rb +1 -1
- data/lib/pubid/jcgm/urn_parser.rb +156 -14
- data/lib/pubid/jcgm.rb +10 -0
- data/lib/pubid/jis/identifier.rb +10 -3
- data/lib/pubid/jis/parser.rb +1 -1
- data/lib/pubid/jis.rb +1 -0
- data/lib/pubid/nist/components/stage.rb +2 -2
- data/lib/pubid/nist/configuration.rb +6 -8
- data/lib/pubid/nist/identifiers/base.rb +12 -2
- data/lib/pubid/nist/identifiers/circular.rb +9 -2
- data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +7 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +7 -1
- data/lib/pubid/nist/identifiers/handbook.rb +9 -2
- data/lib/pubid/nist/identifiers/internal_report.rb +12 -5
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +14 -6
- data/lib/pubid/nist/identifiers/monograph.rb +14 -7
- data/lib/pubid/nist/identifiers/report.rb +14 -6
- data/lib/pubid/nist/parser.rb +1 -1
- data/lib/pubid/nist/supplement_identifier.rb +16 -1
- data/lib/pubid/nist.rb +7 -1
- data/lib/pubid/oasis/builder.rb +12 -10
- data/lib/pubid/oasis/identifier.rb +89 -11
- data/lib/pubid/oasis/parser.rb +1 -1
- data/lib/pubid/oasis.rb +7 -1
- data/lib/pubid/ogc/identifier.rb +9 -5
- data/lib/pubid/ogc/parser.rb +1 -1
- data/lib/pubid/ogc.rb +1 -0
- data/lib/pubid/oiml/builder.rb +5 -1
- data/lib/pubid/oiml/identifiers/basic_publication.rb +2 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +36 -0
- data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
- data/lib/pubid/oiml/identifiers/document.rb +2 -0
- data/lib/pubid/oiml/identifiers/expert_report.rb +2 -0
- data/lib/pubid/oiml/identifiers/guide.rb +2 -0
- data/lib/pubid/oiml/identifiers/recommendation.rb +2 -0
- data/lib/pubid/oiml/identifiers/seminar_report.rb +2 -0
- data/lib/pubid/oiml/identifiers/vocabulary.rb +2 -0
- data/lib/pubid/oiml/identifiers.rb +1 -0
- data/lib/pubid/oiml/parser.rb +1 -1
- data/lib/pubid/oiml/single_identifier.rb +26 -42
- data/lib/pubid/oiml/supplement_identifier.rb +27 -0
- data/lib/pubid/oiml.rb +7 -1
- data/lib/pubid/omg/builder.rb +1 -0
- data/lib/pubid/omg/identifier.rb +20 -3
- data/lib/pubid/omg/parser.rb +64 -11
- data/lib/pubid/omg/renderer.rb +13 -1
- data/lib/pubid/omg.rb +2 -1
- data/lib/pubid/parser/grammar.rb +74 -0
- data/lib/pubid/parser.rb +2 -0
- data/lib/pubid/parsers/mr_string.rb +19 -0
- data/lib/pubid/plateau/parser.rb +1 -1
- data/lib/pubid/plateau.rb +10 -0
- data/lib/pubid/prefixes_support.rb +1 -0
- data/lib/pubid/renderers/annotator.rb +233 -0
- data/lib/pubid/renderers/base.rb +13 -0
- data/lib/pubid/renderers/directives_renderer.rb +3 -3
- data/lib/pubid/renderers/human_readable.rb +3 -3
- data/lib/pubid/renderers/mr_string.rb +15 -9
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/rendering/numbering.rb +25 -7
- data/lib/pubid/rendering.rb +1 -0
- data/lib/pubid/sae/identifiers/base.rb +9 -2
- data/lib/pubid/sae/parser.rb +1 -1
- data/lib/pubid/sae.rb +1 -0
- data/lib/pubid/schema/declaration.rb +33 -0
- data/lib/pubid/schema/error.rb +14 -0
- data/lib/pubid/schema/identifier_type.rb +23 -0
- data/lib/pubid/schema/loader.rb +117 -0
- data/lib/pubid/schema/typed_stage.rb +24 -0
- data/lib/pubid/schema.rb +25 -0
- data/lib/pubid/tgpp/builder.rb +1 -1
- data/lib/pubid/tgpp/identifier.rb +21 -5
- data/lib/pubid/tgpp/identifiers/technical_report.rb +2 -2
- data/lib/pubid/tgpp/identifiers/technical_specification.rb +2 -2
- data/lib/pubid/tgpp/parser.rb +22 -6
- data/lib/pubid/tgpp/renderer.rb +21 -5
- data/lib/pubid/tgpp/urn_generator.rb +27 -8
- data/lib/pubid/tgpp/urn_parser.rb +8 -6
- data/lib/pubid/tgpp.rb +7 -1
- data/lib/pubid/type_resolver.rb +16 -1
- data/lib/pubid/un/identifier.rb +6 -3
- data/lib/pubid/un/parser.rb +1 -1
- data/lib/pubid/un.rb +1 -0
- data/lib/pubid/urn_parser/errors.rb +8 -1
- data/lib/pubid/urn_parser.rb +1 -0
- data/lib/pubid/utils.rb +1 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/builder.rb +5 -5
- data/lib/pubid/w3c/identifier.rb +38 -9
- data/lib/pubid/w3c/parser.rb +1 -1
- data/lib/pubid/w3c/renderer.rb +1 -1
- data/lib/pubid/w3c/urn_generator.rb +2 -2
- data/lib/pubid/w3c.rb +1 -0
- data/lib/pubid/xsf/identifier.rb +9 -5
- data/lib/pubid/xsf/parser.rb +17 -4
- data/lib/pubid/xsf.rb +7 -1
- data/lib/pubid.rb +399 -21
- data/lib/tasks/conformance.rake +34 -0
- data/lib/tasks/docs.rake +3 -3
- data/lib/tasks/schema.rake +88 -0
- data/schema/core/joint_prefixes.yaml +24 -0
- data/schema/iec.yaml +1017 -0
- data/schema/iso.yaml +1586 -0
- data/schema/schema.schema.yaml +96 -0
- metadata +38 -17
- data/archived-gems/pubid-ccsds/update_codes.yaml +0 -1
- data/archived-gems/pubid-iec/stages.yaml +0 -129
- data/archived-gems/pubid-iec/update_codes.yaml +0 -67
- data/archived-gems/pubid-ieee/update_codes.yaml +0 -104
- data/archived-gems/pubid-iso/stages.yaml +0 -106
- data/archived-gems/pubid-iso/update_codes.yaml +0 -4
- data/archived-gems/pubid-itu/i18n.yaml +0 -13
- data/archived-gems/pubid-itu/series.yaml +0 -42
- data/archived-gems/pubid-nist/publishers.yaml +0 -6
- data/archived-gems/pubid-nist/series.yaml +0 -121
- data/archived-gems/pubid-nist/update_codes.yaml +0 -93
- data/archived-gems/pubid-plateau/update_codes.yaml +0 -6
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +0 -48
- data/lib/pubid/iec/components/code.rb +0 -36
- /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
|
@@ -4,31 +4,173 @@ module Pubid
|
|
|
4
4
|
module Jcgm
|
|
5
5
|
# Parses JCGM URNs back into identifiers.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
7
|
+
# Identifiers are rebuilt **directly from the URN segments** rather than
|
|
8
|
+
# rendered to a human-readable string and re-parsed (the BIPM UrnParser
|
|
9
|
+
# pattern). Round-tripping through the grammar flattened the segments into
|
|
10
|
+
# one string and silently lost everything the string form could not carry:
|
|
11
|
+
# a GUM guide (`urn:jcgm:gum.6:2020`) raised, and the language and
|
|
12
|
+
# supplement segments were dropped, so a corrigendum read back as the
|
|
13
|
+
# standard it amends — a different document, with no error.
|
|
9
14
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
15
|
+
# Shapes emitted by UrnGenerator, and read back here:
|
|
16
|
+
# urn:jcgm:200:2008 → JCGM 200:2008
|
|
17
|
+
# urn:jcgm:100:2008:en → JCGM 100:2008(E)
|
|
18
|
+
# urn:jcgm:200:2012:en,fr → JCGM 200:2012(E/F)
|
|
19
|
+
# urn:jcgm:GUM → JCGM GUM
|
|
20
|
+
# urn:jcgm:gum.6:2020 → JCGM GUM-6:2020
|
|
21
|
+
# urn:jcgm:200:2008:corrigendum → JCGM 200:2008 Corrigendum
|
|
22
|
+
# urn:jcgm:101:2008:corrigendum:1:2009 → JCGM 101:2008/Cor 1:2009
|
|
23
|
+
# urn:jcgm:100:2008:amendment:1:2023 → JCGM 100:2008/Amd 1:2023
|
|
24
|
+
# urn:jcgm:meeting:17:2012 → JCGM 17th Meeting (2012)
|
|
25
|
+
# urn:jcgm:meeting:11 → JCGM 11st Meeting
|
|
26
|
+
#
|
|
27
|
+
# KNOWN GAP, on the generator side and unchanged here: a full date is
|
|
28
|
+
# rendered as its year alone (`JCGM GUM-1:2022-11-28` →
|
|
29
|
+
# `urn:jcgm:gum.1:2022`), so a URN cannot restore the month and day.
|
|
30
|
+
# Widening it would change already-published URNs.
|
|
14
31
|
class UrnParser < Pubid::UrnParser::Base
|
|
32
|
+
MEETING_MARKER = "meeting"
|
|
33
|
+
|
|
34
|
+
# The GUM-guide number is written "gum.<n>" by UrnGenerator.
|
|
35
|
+
GUM_PREFIX = "gum."
|
|
36
|
+
|
|
37
|
+
# The supplement marker UrnGenerator writes is the typed stage's
|
|
38
|
+
# `type_code`; the abbreviation is what `Jcgm.locate_stage` matches on.
|
|
39
|
+
SUPPLEMENT_ABBRS = {
|
|
40
|
+
"corrigendum" => "Cor",
|
|
41
|
+
"amendment" => "Amd",
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
MEETING_ABBR = "Meeting"
|
|
45
|
+
|
|
46
|
+
# Mirrors `year_digits` in the shared parser rules.
|
|
47
|
+
YEAR_PATTERN = /\A(?:19|20)\d{2}\z/
|
|
48
|
+
|
|
49
|
+
# A language segment is one or more comma-joined ISO codes.
|
|
50
|
+
LANGUAGES_PATTERN = /\A[a-z]{2}(?:,[a-z]{2})*\z/
|
|
51
|
+
|
|
52
|
+
# Language codes back to the single-letter form the identifier prints;
|
|
53
|
+
# the builder maps the other way when parsing "(E)" / "(E/F)".
|
|
54
|
+
LANGUAGE_LETTERS = Pubid::Builder::Base::LANG_CHAR_MAP.invert.freeze
|
|
55
|
+
|
|
15
56
|
def parse_urn(urn)
|
|
16
57
|
parts = split_parts(strip_namespace(urn))
|
|
17
|
-
return parse_meeting_urn(parts) if parts.first ==
|
|
58
|
+
return parse_meeting_urn(parts) if parts.first == MEETING_MARKER
|
|
18
59
|
|
|
19
|
-
|
|
20
|
-
text = "JCGM #{number}"
|
|
21
|
-
text += ":#{year}" if year
|
|
22
|
-
flavor_parse(text)
|
|
60
|
+
parse_document_urn(parts)
|
|
23
61
|
end
|
|
24
62
|
|
|
25
63
|
private
|
|
26
64
|
|
|
27
|
-
# urn:jcgm:meeting:<number
|
|
65
|
+
# urn:jcgm:meeting:<number>[:<year>] -> Identifiers::Meeting
|
|
66
|
+
#
|
|
67
|
+
# The reconstruction must agree with a parsed identifier attribute for
|
|
68
|
+
# attribute, so `typed_stage` comes from the same registry lookup
|
|
69
|
+
# `Builder#locate_typed_stage` uses. (The attribute default now agrees
|
|
70
|
+
# too — it no longer sets `original_abbr` — so this mirrors the builder
|
|
71
|
+
# for clarity rather than out of necessity.)
|
|
28
72
|
def parse_meeting_urn(parts)
|
|
29
73
|
_, number, year = parts
|
|
30
|
-
|
|
31
|
-
|
|
74
|
+
|
|
75
|
+
Identifiers::Meeting.new(
|
|
76
|
+
number: meeting_number(number),
|
|
77
|
+
date: urn_date(year),
|
|
78
|
+
typed_stage: Jcgm.locate_stage(MEETING_ABBR),
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# A guide, a GUM guide, or a supplement wrapping one of those. The
|
|
83
|
+
# supplement marker splits the segments: everything before it describes
|
|
84
|
+
# the base document, everything after is the supplement's own number and
|
|
85
|
+
# date.
|
|
86
|
+
def parse_document_urn(parts)
|
|
87
|
+
marker_at = parts.index { |segment| SUPPLEMENT_ABBRS.key?(segment) }
|
|
88
|
+
return build_document(parts) unless marker_at
|
|
89
|
+
|
|
90
|
+
build_supplement(
|
|
91
|
+
parts[marker_at],
|
|
92
|
+
build_document(parts[0...marker_at]),
|
|
93
|
+
parts[(marker_at + 1)..] || [],
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The class comes from the same registry the builder uses, so a URN and a
|
|
98
|
+
# parsed reference resolve to one class and one typed_stage.
|
|
99
|
+
def build_supplement(marker, base, tail)
|
|
100
|
+
typed_stage = Jcgm.locate_stage(SUPPLEMENT_ABBRS.fetch(marker))
|
|
101
|
+
number, year = tail
|
|
102
|
+
|
|
103
|
+
Jcgm.locate_type(typed_stage.type_code).new(
|
|
104
|
+
base: base,
|
|
105
|
+
number: (number.nil? || number.empty? ? nil : number.to_s),
|
|
106
|
+
date: urn_date(year),
|
|
107
|
+
typed_stage: typed_stage,
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# <number>[:<year>][:<languages>] — the number segment carries the
|
|
112
|
+
# "gum." prefix for a GUM guide, which is what selects the class.
|
|
113
|
+
#
|
|
114
|
+
# Guide and GumGuide deliberately take their `typed_stage` from the
|
|
115
|
+
# attribute default: the grammar emits no type token for them, so
|
|
116
|
+
# `Builder#build` fills it from `published_typed_stage` too, and both
|
|
117
|
+
# paths agree.
|
|
118
|
+
def build_document(parts)
|
|
119
|
+
number, *rest = parts
|
|
120
|
+
require_number!(number)
|
|
121
|
+
gum = number.start_with?(GUM_PREFIX)
|
|
122
|
+
|
|
123
|
+
(gum ? Identifiers::GumGuide : Identifiers::Guide).new(
|
|
124
|
+
number: (gum ? number.delete_prefix(GUM_PREFIX) : number).to_s,
|
|
125
|
+
date: urn_date(segment_matching(rest, YEAR_PATTERN)),
|
|
126
|
+
languages: urn_languages(segment_matching(rest, LANGUAGES_PATTERN)),
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def require_number!(segment)
|
|
131
|
+
return unless segment.nil? || segment.empty?
|
|
132
|
+
|
|
133
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
134
|
+
"JCGM URN has no document number"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def segment_matching(segments, pattern)
|
|
138
|
+
segments.find { |segment| segment.match?(pattern) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# The ordinal, normalized the way `Identifiers::Meeting.ordinal` does it
|
|
142
|
+
# (`number.to_i`), so "011" reads back as "11" and a missing or
|
|
143
|
+
# non-numeric segment as "0" — the behaviour of the previous
|
|
144
|
+
# render-and-re-parse implementation.
|
|
145
|
+
def meeting_number(segment)
|
|
146
|
+
segment.to_i.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# nil for an absent year; a Date for a well-formed one. The grammar
|
|
150
|
+
# accepts only a 19xx/20xx year, so anything else is a malformed URN and
|
|
151
|
+
# must still be rejected now that no re-parse validates it.
|
|
152
|
+
def urn_date(segment)
|
|
153
|
+
return nil if segment.nil? || segment.empty?
|
|
154
|
+
|
|
155
|
+
unless segment.match?(YEAR_PATTERN)
|
|
156
|
+
raise Pubid::UrnParser::Errors::ParseError,
|
|
157
|
+
"Invalid year in JCGM URN: #{segment.inspect}"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
Pubid::Components::Date.new(year: segment)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# "en" -> (E), "en,fr" -> (E/F). `original_code` is what the renderer
|
|
164
|
+
# prints, so it is restored from the code rather than left nil.
|
|
165
|
+
def urn_languages(segment)
|
|
166
|
+
return nil if segment.nil? || segment.empty?
|
|
167
|
+
|
|
168
|
+
segment.split(",").map do |code|
|
|
169
|
+
Pubid::Components::Language.new(
|
|
170
|
+
code: code,
|
|
171
|
+
original_code: LANGUAGE_LETTERS.fetch(code, code),
|
|
172
|
+
)
|
|
173
|
+
end
|
|
32
174
|
end
|
|
33
175
|
end
|
|
34
176
|
end
|
data/lib/pubid/jcgm.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pubid"
|
|
3
4
|
module Pubid
|
|
4
5
|
module Jcgm
|
|
5
6
|
extend Pubid::PrefixesSupport
|
|
@@ -22,6 +23,15 @@ module Pubid
|
|
|
22
23
|
# @param identifier [String] the identifier string to parse
|
|
23
24
|
# @return [Identifier] the parsed identifier
|
|
24
25
|
def self.parse(identifier)
|
|
26
|
+
unless identifier.is_a?(String)
|
|
27
|
+
raise Pubid::Errors::InvalidInputError,
|
|
28
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
32
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
33
|
+
end
|
|
34
|
+
|
|
25
35
|
parser = Parser.new
|
|
26
36
|
builder = Builder.new
|
|
27
37
|
|
data/lib/pubid/jis/identifier.rb
CHANGED
|
@@ -175,12 +175,19 @@ module Pubid
|
|
|
175
175
|
# Parse a JIS identifier string into an identifier object
|
|
176
176
|
# @param identifier [String] The JIS identifier string to parse
|
|
177
177
|
# @return [Identifier] The appropriate identifier object
|
|
178
|
-
# @raise [
|
|
178
|
+
# @raise [Pubid::Errors::ParseError] If parsing fails
|
|
179
179
|
def self.parse(identifier)
|
|
180
|
+
unless identifier.is_a?(String)
|
|
181
|
+
raise Pubid::Errors::InvalidInputError,
|
|
182
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
186
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
187
|
+
end
|
|
188
|
+
|
|
180
189
|
parsed = Parser.parse(identifier)
|
|
181
190
|
Builder.build(parsed)
|
|
182
|
-
rescue Parslet::ParseFailed => e
|
|
183
|
-
raise "Failed to parse JIS identifier '#{identifier}': #{e.message}"
|
|
184
191
|
end
|
|
185
192
|
end
|
|
186
193
|
end
|
data/lib/pubid/jis/parser.rb
CHANGED
data/lib/pubid/jis.rb
CHANGED
|
@@ -16,10 +16,10 @@ module Pubid
|
|
|
16
16
|
attribute :id, :string # i, f, 1-9
|
|
17
17
|
attribute :type, :string # pd, wd, prd
|
|
18
18
|
|
|
19
|
-
# Load stages from
|
|
19
|
+
# Load stages from data/nist/stages.yaml
|
|
20
20
|
STAGES = YAML.load_file(
|
|
21
21
|
File.join(File.dirname(__FILE__),
|
|
22
|
-
"../../../../
|
|
22
|
+
"../../../../data/nist/stages.yaml"),
|
|
23
23
|
).freeze
|
|
24
24
|
|
|
25
25
|
# Render stage in specified format
|
|
@@ -58,13 +58,7 @@ module Pubid
|
|
|
58
58
|
private
|
|
59
59
|
|
|
60
60
|
def default_series_path
|
|
61
|
-
|
|
62
|
-
# fall back to archived-gems/pubid-nist/series.yaml for backward
|
|
63
|
-
# compat with the v1 layout.
|
|
64
|
-
monorepo = File.join(__dir__, "../../../data/nist/series.yaml")
|
|
65
|
-
return monorepo if File.exist?(monorepo)
|
|
66
|
-
|
|
67
|
-
File.join(__dir__, "../../../archived-gems/pubid-nist/series.yaml")
|
|
61
|
+
File.join(__dir__, "../../../data/nist/series.yaml")
|
|
68
62
|
end
|
|
69
63
|
|
|
70
64
|
def load_series
|
|
@@ -78,6 +72,10 @@ module Pubid
|
|
|
78
72
|
end
|
|
79
73
|
end
|
|
80
74
|
|
|
81
|
-
|
|
75
|
+
# Raised when the NIST series YAML cannot be loaded. Included in the
|
|
76
|
+
# marker module so `rescue Pubid::Errors::Error` stays exhaustive.
|
|
77
|
+
class ConfigurationError < StandardError
|
|
78
|
+
include ::Pubid::Errors::Error
|
|
79
|
+
end
|
|
82
80
|
end
|
|
83
81
|
end
|
|
@@ -170,6 +170,10 @@ module Pubid
|
|
|
170
170
|
end
|
|
171
171
|
|
|
172
172
|
def initialize(**attributes)
|
|
173
|
+
# This override calls `super()` with no attributes and assigns through
|
|
174
|
+
# setters instead, so it bypasses the base constructor's coercion and
|
|
175
|
+
# unknown-key check. Apply them here to keep the cross-flavor contract.
|
|
176
|
+
attributes = self.class.normalize_init_attributes(attributes)
|
|
173
177
|
super()
|
|
174
178
|
|
|
175
179
|
attrs = self.class.attributes
|
|
@@ -304,13 +308,19 @@ module Pubid
|
|
|
304
308
|
# @param format [:full, :long, :abbreviated, :short, :mr] output format
|
|
305
309
|
def to_s(format = nil)
|
|
306
310
|
# Handle both keyword argument (hash) and positional argument (symbol/string)
|
|
311
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
307
312
|
format = format[:format] if format.is_a?(Hash)
|
|
308
313
|
|
|
309
314
|
# Default to parsed_format if available (preserves input format on round-trip)
|
|
310
315
|
# Falls back to :short format for output (normalization)
|
|
311
316
|
# Explicit format parameter always overrides parsed_format
|
|
312
|
-
render(format: :human,
|
|
313
|
-
|
|
317
|
+
rendered = render(format: :human,
|
|
318
|
+
nist_format: format || parsed_format&.to_sym || :short)
|
|
319
|
+
|
|
320
|
+
# NIST's `to_s` takes a POSITIONAL format and its `render` override
|
|
321
|
+
# builds no rendering context, so neither the flag nor the context
|
|
322
|
+
# reaches the shared hook. Apply the annotation fallback here.
|
|
323
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
314
324
|
end
|
|
315
325
|
|
|
316
326
|
# NIST has its own defined MR format (to_mr_style) used by relaton-nist
|
|
@@ -53,7 +53,14 @@ module Pubid
|
|
|
53
53
|
# Override to_s for CIRC-specific edition+year rendering
|
|
54
54
|
# CIRC uses dot notation: "NBS CIRC 11e2.1915" instead of "NBS CIRC 11e2-1915"
|
|
55
55
|
def to_s(format = nil)
|
|
56
|
-
|
|
56
|
+
# The rewrite below is `$`-anchored, so it has to run on the PLAIN
|
|
57
|
+
# string: with the flag set, `super` returns a string ending in
|
|
58
|
+
# "</span>" and the anchor no longer matches. Render plain, rewrite,
|
|
59
|
+
# then annotate.
|
|
60
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
61
|
+
format = format[:format] if format.is_a?(Hash)
|
|
62
|
+
|
|
63
|
+
result = super(format)
|
|
57
64
|
|
|
58
65
|
# For CIRC edition patterns with additional_text (year), render with dot notation
|
|
59
66
|
# "11e2-1915" format: edition.id="2", additional_text="1915" → render as "11e2.1915"
|
|
@@ -65,7 +72,7 @@ module Pubid
|
|
|
65
72
|
"e#{edition.id || '?'}.#{edition.additional_text}")
|
|
66
73
|
end
|
|
67
74
|
|
|
68
|
-
result
|
|
75
|
+
annotate_plain_render(result, annotated: annotated)
|
|
69
76
|
end
|
|
70
77
|
end
|
|
71
78
|
end
|
|
@@ -37,13 +37,22 @@ module Pubid
|
|
|
37
37
|
attribute :implicit_supplement, :boolean # true for implicit supplements (e.g., "145r11/1925")
|
|
38
38
|
|
|
39
39
|
def to_s(format = :short)
|
|
40
|
+
# A caller passing `annotated:` reaches this positional parameter as a
|
|
41
|
+
# Hash. Normalise it away before `super`, so the annotation is applied
|
|
42
|
+
# once, here, and covers the date-range branch too — that branch
|
|
43
|
+
# returns a hand-composed string and never reached `super` at all.
|
|
44
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
45
|
+
format = format[:format] || :short if format.is_a?(Hash)
|
|
46
|
+
|
|
40
47
|
# Handle date range supplements (no base identifier)
|
|
41
|
-
if supplement_date_range_start && supplement_date_range_end
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
result = if supplement_date_range_start && supplement_date_range_end
|
|
49
|
+
"NBS CIRC sup#{supplement_date_range_start}-#{supplement_date_range_end}"
|
|
50
|
+
else
|
|
51
|
+
# Use parent's rendering for base + supplement
|
|
52
|
+
super(format)
|
|
53
|
+
end
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
super
|
|
55
|
+
annotate_plain_render(result, annotated: annotated)
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
58
|
end
|
|
@@ -41,6 +41,12 @@ module Pubid
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def to_s(format = nil)
|
|
44
|
+
# A caller passing `annotated:` reaches this positional parameter as
|
|
45
|
+
# a Hash — Ruby converts keywords for a method that accepts none.
|
|
46
|
+
# The same idiom `Identifiers::Base#to_s` uses. This renderer
|
|
47
|
+
# ignores `format`, so only the flag is read.
|
|
48
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
49
|
+
|
|
44
50
|
result = "#{publisher} #{series}"
|
|
45
51
|
|
|
46
52
|
# Proper Volume and Part components
|
|
@@ -55,7 +61,7 @@ module Pubid
|
|
|
55
61
|
result += " #{vol_str}n#{issue_number.number}"
|
|
56
62
|
end
|
|
57
63
|
|
|
58
|
-
result
|
|
64
|
+
annotate_plain_render(result, annotated: annotated)
|
|
59
65
|
end
|
|
60
66
|
end
|
|
61
67
|
end
|
|
@@ -88,6 +88,12 @@ module Pubid
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
def to_s(format = nil)
|
|
91
|
+
# A caller passing `annotated:` reaches this positional parameter as
|
|
92
|
+
# a Hash — Ruby converts keywords for a method that accepts none.
|
|
93
|
+
# The same idiom `Identifiers::Base#to_s` uses. This renderer
|
|
94
|
+
# ignores `format`, so only the flag is read.
|
|
95
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
96
|
+
|
|
91
97
|
# Use actual series attribute if it contains subseries (e.g., "CRPL-F-B")
|
|
92
98
|
# Otherwise use default series_code ("CRPL")
|
|
93
99
|
series_to_render = if series&.value&.include?("CRPL-F-")
|
|
@@ -124,7 +130,7 @@ module Pubid
|
|
|
124
130
|
result += append_short_components
|
|
125
131
|
|
|
126
132
|
result += range_notation if range_notation
|
|
127
|
-
result
|
|
133
|
+
annotate_plain_render(result, annotated: annotated)
|
|
128
134
|
end
|
|
129
135
|
end
|
|
130
136
|
end
|
|
@@ -34,8 +34,15 @@ module Pubid
|
|
|
34
34
|
# Override to_s to handle edition+year pattern with dash instead of dot
|
|
35
35
|
# Pattern: "44e2-1955" (dash separator) not "44e2.1955" (dot separator)
|
|
36
36
|
def to_s(format = nil)
|
|
37
|
+
# The rewrite below is `$`-anchored, so it has to run on the PLAIN
|
|
38
|
+
# string: with the flag set, `super` returns a string ending in
|
|
39
|
+
# "</span>" and the anchor no longer matches. Render plain, rewrite,
|
|
40
|
+
# then annotate.
|
|
41
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
42
|
+
format = format[:format] if format.is_a?(Hash)
|
|
43
|
+
|
|
37
44
|
# Use the base to_s method first
|
|
38
|
-
result = super
|
|
45
|
+
result = super(format)
|
|
39
46
|
|
|
40
47
|
# If edition has additional_text (year), replace dot with dash
|
|
41
48
|
if edition&.additional_text && !edition.additional_text.empty?
|
|
@@ -43,7 +50,7 @@ module Pubid
|
|
|
43
50
|
"#{edition.type}#{edition.id}-#{edition.additional_text}")
|
|
44
51
|
end
|
|
45
52
|
|
|
46
|
-
result
|
|
53
|
+
annotate_plain_render(result, annotated: annotated)
|
|
47
54
|
end
|
|
48
55
|
end
|
|
49
56
|
end
|
|
@@ -37,6 +37,11 @@ module Pubid
|
|
|
37
37
|
# @param format [Symbol, Hash, nil] output format
|
|
38
38
|
# @return [String] formatted identifier
|
|
39
39
|
def to_s(format = nil)
|
|
40
|
+
# `super` is handed a SYMBOL below, so the base's annotation hook
|
|
41
|
+
# never sees the flag. Capture it here and wrap what comes back —
|
|
42
|
+
# exactly once, because the base returned plain text.
|
|
43
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
44
|
+
|
|
40
45
|
# Handle both keyword argument (hash) and positional argument (symbol/string)
|
|
41
46
|
effective_format = if format.is_a?(Hash)
|
|
42
47
|
format[:format]
|
|
@@ -45,11 +50,13 @@ module Pubid
|
|
|
45
50
|
end
|
|
46
51
|
|
|
47
52
|
# If explicit format is specified, use it. Otherwise, default to short.
|
|
48
|
-
if effective_format.nil?
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
rendered = if effective_format.nil?
|
|
54
|
+
super(:short)
|
|
55
|
+
else
|
|
56
|
+
super(effective_format)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
end
|
|
@@ -36,13 +36,21 @@ module Pubid
|
|
|
36
36
|
"MP"
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
# A caller passing `annotated:` reaches this positional parameter as a
|
|
40
|
+
# Hash — Ruby converts keywords for a method that accepts none. The same
|
|
41
|
+
# idiom `Identifiers::Base#to_s` uses.
|
|
39
42
|
def to_s(format = :short)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
44
|
+
format = format[:format] || :short if format.is_a?(Hash)
|
|
45
|
+
|
|
46
|
+
rendered = case format
|
|
47
|
+
when :mr
|
|
48
|
+
to_mr_style
|
|
49
|
+
else
|
|
50
|
+
to_short_style
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
46
54
|
end
|
|
47
55
|
|
|
48
56
|
public
|
|
@@ -35,6 +35,11 @@ module Pubid
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def to_s(format = nil)
|
|
38
|
+
# `super` is handed a SYMBOL below, so the base's annotation hook
|
|
39
|
+
# never sees the flag. Capture it here and wrap what comes back —
|
|
40
|
+
# exactly once, because the base returned plain text.
|
|
41
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
42
|
+
|
|
38
43
|
# Handle both keyword argument (hash) and positional argument (symbol/string)
|
|
39
44
|
effective_format = if format.is_a?(Hash)
|
|
40
45
|
format[:format]
|
|
@@ -43,13 +48,15 @@ module Pubid
|
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
# If explicit format is specified, use it. Otherwise, default to short.
|
|
46
|
-
if effective_format.nil?
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
rendered = if effective_format.nil?
|
|
52
|
+
super(:short)
|
|
53
|
+
elsif effective_format == :mr
|
|
54
|
+
to_mr_style
|
|
55
|
+
else
|
|
56
|
+
super(effective_format)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
53
60
|
end
|
|
54
61
|
|
|
55
62
|
private
|
|
@@ -39,13 +39,21 @@ module Pubid
|
|
|
39
39
|
"RPT"
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# A caller passing `annotated:` reaches this positional parameter as a
|
|
43
|
+
# Hash — Ruby converts keywords for a method that accepts none. The same
|
|
44
|
+
# idiom `Identifiers::Base#to_s` uses.
|
|
42
45
|
def to_s(format = :short)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
47
|
+
format = format[:format] || :short if format.is_a?(Hash)
|
|
48
|
+
|
|
49
|
+
rendered = case format
|
|
50
|
+
when :mr
|
|
51
|
+
to_mr_style
|
|
52
|
+
else
|
|
53
|
+
to_short_style
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
49
57
|
end
|
|
50
58
|
|
|
51
59
|
private
|
data/lib/pubid/nist/parser.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Pubid
|
|
|
6
6
|
module Nist
|
|
7
7
|
# Parser class for NIST identifiers
|
|
8
8
|
# Single Responsibility: Parsing NIST identifier syntax
|
|
9
|
-
class Parser <
|
|
9
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
10
10
|
|
|
11
11
|
# Class-level parse method with preprocessing.
|
|
12
12
|
# Delegates all string normalization to Nist::Preprocessor, then
|
|
@@ -25,13 +25,28 @@ module Pubid
|
|
|
25
25
|
base&.series
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# Four exits — a date range, a base-less delegation, an update form and
|
|
29
|
+
# the canonical one — so the composition stays whole in its own method
|
|
30
|
+
# and `to_s` wraps its single result. `super` is not reachable from a
|
|
31
|
+
# private method, so it is handed in as a block.
|
|
28
32
|
def to_s(format = :short)
|
|
33
|
+
annotated = format.is_a?(Hash) ? format[:annotated] : nil
|
|
34
|
+
format = format[:format] || :short if format.is_a?(Hash)
|
|
35
|
+
|
|
36
|
+
rendered = render_plain(format) { super(format) }
|
|
37
|
+
|
|
38
|
+
annotate_plain_render(rendered, annotated: annotated)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def render_plain(format)
|
|
29
44
|
# Handle date range supplements (no base identifier)
|
|
30
45
|
if supplement_date_range_start && supplement_date_range_end
|
|
31
46
|
return "NBS CIRC sup#{supplement_date_range_start}-#{supplement_date_range_end}"
|
|
32
47
|
end
|
|
33
48
|
|
|
34
|
-
return
|
|
49
|
+
return yield unless base
|
|
35
50
|
|
|
36
51
|
result = base.to_s(format)
|
|
37
52
|
|
data/lib/pubid/nist.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pubid"
|
|
3
4
|
module Pubid
|
|
4
5
|
module Nist
|
|
5
6
|
extend Pubid::PrefixesSupport
|
|
@@ -67,8 +68,13 @@ module Pubid
|
|
|
67
68
|
# @param identifier [String] the identifier string to parse
|
|
68
69
|
# @return [Identifier] the parsed identifier
|
|
69
70
|
def self.parse(identifier)
|
|
71
|
+
unless identifier.is_a?(String)
|
|
72
|
+
raise Pubid::Errors::InvalidInputError,
|
|
73
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
74
|
+
end
|
|
75
|
+
|
|
70
76
|
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
71
|
-
raise
|
|
77
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
72
78
|
end
|
|
73
79
|
|
|
74
80
|
# Use the Parser class's preprocessing method
|