pubid 2.0.0.pre.alpha.8 → 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/data/bipm/update_codes.yaml +9 -0
- data/data/iec/update_codes.yaml +3 -0
- data/data/ieee/update_codes.yaml +107 -1
- data/{archived-gems/pubid-nist → data/nist}/series.yaml +34 -0
- data/data/nist/update_codes.yaml +8 -0
- data/lib/pubid/adobe/builder.rb +52 -0
- data/lib/pubid/adobe/identifier.rb +47 -0
- data/lib/pubid/adobe/identifiers/publication.rb +31 -0
- data/lib/pubid/adobe/identifiers/tech_note.rb +32 -0
- data/lib/pubid/adobe/identifiers.rb +10 -0
- data/lib/pubid/adobe/parser.rb +136 -0
- data/lib/pubid/adobe/renderer.rb +39 -0
- data/lib/pubid/adobe/urn_generator.rb +42 -0
- data/lib/pubid/adobe/urn_parser.rb +69 -0
- data/lib/pubid/adobe.rb +61 -0
- data/lib/pubid/amca/builder.rb +4 -4
- data/lib/pubid/amca/identifier.rb +1 -3
- data/lib/pubid/amca/identifiers/base.rb +50 -33
- data/lib/pubid/amca/identifiers/interpretation.rb +18 -10
- data/lib/pubid/amca/identifiers/publication.rb +14 -10
- data/lib/pubid/amca/identifiers/standard.rb +3 -1
- data/lib/pubid/amca/identifiers.rb +0 -1
- data/lib/pubid/amca/parser.rb +1 -1
- data/lib/pubid/amca/renderer.rb +4 -4
- data/lib/pubid/amca/single_identifier.rb +1 -1
- data/lib/pubid/amca/urn_generator.rb +2 -2
- data/lib/pubid/amca.rb +5 -4
- 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 +53 -32
- data/lib/pubid/ashrae/identifier.rb +3 -4
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +7 -1
- data/lib/pubid/ashrae/identifiers/addendum.rb +9 -1
- data/lib/pubid/ashrae/identifiers/base.rb +94 -12
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +8 -1
- 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/identifiers.rb +0 -1
- data/lib/pubid/ashrae/parser.rb +37 -17
- data/lib/pubid/ashrae/renderer.rb +20 -20
- data/lib/pubid/ashrae/single_identifier.rb +1 -1
- data/lib/pubid/ashrae/supplement_identifier.rb +21 -6
- data/lib/pubid/ashrae/urn_generator.rb +8 -2
- data/lib/pubid/ashrae.rb +10 -4
- 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 +163 -0
- data/lib/pubid/bipm/identifier.rb +285 -0
- data/lib/pubid/bipm/identifiers/committee_document.rb +36 -0
- data/lib/pubid/bipm/identifiers/guide.rb +35 -0
- data/lib/pubid/bipm/identifiers/meeting.rb +53 -0
- data/lib/pubid/bipm/identifiers/mep.rb +33 -0
- data/lib/pubid/bipm/identifiers/metrologia_article.rb +48 -0
- data/lib/pubid/bipm/identifiers/si_brochure.rb +33 -0
- data/lib/pubid/bipm/identifiers.rb +15 -0
- data/lib/pubid/bipm/parser.rb +237 -0
- data/lib/pubid/bipm/renderer.rb +118 -0
- data/lib/pubid/bipm/urn_generator.rb +58 -0
- data/lib/pubid/bipm/urn_parser.rb +60 -0
- data/lib/pubid/bipm.rb +92 -0
- data/lib/pubid/bsi/builder.rb +62 -52
- data/lib/pubid/bsi/identifier.rb +0 -1
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -2
- 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/amendment.rb +4 -4
- 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/consolidated_identifier.rb +6 -0
- data/lib/pubid/bsi/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +5 -5
- data/lib/pubid/bsi/identifiers/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/identifiers/supplement_document.rb +2 -2
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +6 -6
- data/lib/pubid/bsi/parser.rb +1 -1
- data/lib/pubid/bsi/renderer.rb +71 -59
- data/lib/pubid/bsi/single_identifier.rb +64 -7
- data/lib/pubid/bsi/urn_generator.rb +11 -2
- data/lib/pubid/bsi.rb +7 -1
- data/lib/pubid/builder/base.rb +23 -11
- data/lib/pubid/bundled_identifier.rb +19 -9
- data/lib/pubid/calconnect/builder.rb +38 -0
- data/lib/pubid/calconnect/identifier.rb +121 -0
- data/lib/pubid/calconnect/identifiers/standard.rb +29 -0
- data/lib/pubid/calconnect/identifiers.rb +9 -0
- data/lib/pubid/calconnect/parser.rb +54 -0
- data/lib/pubid/calconnect/renderer.rb +36 -0
- data/lib/pubid/calconnect/urn_generator.rb +33 -0
- data/lib/pubid/calconnect/urn_parser.rb +34 -0
- data/lib/pubid/calconnect.rb +83 -0
- data/lib/pubid/ccsds/builder.rb +1 -1
- data/lib/pubid/ccsds/identifier.rb +10 -3
- data/lib/pubid/ccsds/identifiers/base.rb +4 -2
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +4 -4
- data/lib/pubid/ccsds/parser.rb +1 -1
- data/lib/pubid/ccsds/single_identifier.rb +2 -2
- data/lib/pubid/ccsds/supplement_identifier.rb +6 -6
- data/lib/pubid/ccsds/urn_generator.rb +3 -3
- data/lib/pubid/ccsds.rb +1 -0
- data/lib/pubid/cen_cenelec/builder.rb +131 -72
- 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 -14
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +47 -8
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +60 -3
- 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 +104 -82
- data/lib/pubid/cie/builder.rb +149 -24
- data/lib/pubid/cie/identifier.rb +13 -4
- data/lib/pubid/cie/identifiers/bundle.rb +35 -5
- data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
- data/lib/pubid/cie/identifiers/conference.rb +11 -6
- data/lib/pubid/cie/identifiers/corrigendum.rb +17 -23
- data/lib/pubid/cie/identifiers/dual_published.rb +6 -6
- data/lib/pubid/cie/identifiers/identical.rb +9 -9
- data/lib/pubid/cie/identifiers/joint_published.rb +10 -10
- data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
- data/lib/pubid/cie/identifiers/standard.rb +43 -8
- data/lib/pubid/cie/identifiers/supplement.rb +27 -25
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +7 -3
- data/lib/pubid/cie/identifiers.rb +2 -0
- data/lib/pubid/cie/parser.rb +55 -6
- data/lib/pubid/cie/single_identifier.rb +40 -1
- data/lib/pubid/cie/supplement_identifier.rb +29 -16
- data/lib/pubid/cie/urn_generator.rb +11 -8
- data/lib/pubid/cie.rb +7 -2
- data/lib/pubid/components/date.rb +21 -5
- 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 +48 -48
- data/lib/pubid/csa/composite_identifier.rb +18 -7
- data/lib/pubid/csa/identifier.rb +187 -80
- data/lib/pubid/csa/identifiers/bundled.rb +25 -9
- 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 +97 -69
- data/lib/pubid/csa/identifiers/csa_adopted.rb +4 -4
- data/lib/pubid/csa/identifiers/package.rb +4 -4
- data/lib/pubid/csa/parser.rb +12 -8
- 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 +43 -10
- data/lib/pubid/csa.rb +7 -1
- data/lib/pubid/doi/builder.rb +18 -0
- data/lib/pubid/doi/identifier.rb +49 -0
- data/lib/pubid/doi/identifiers/resource.rb +30 -0
- data/lib/pubid/doi/identifiers.rb +9 -0
- data/lib/pubid/doi/parser.rb +52 -0
- data/lib/pubid/doi/renderer.rb +13 -0
- data/lib/pubid/doi.rb +56 -0
- data/lib/pubid/easc/builder.rb +55 -0
- data/lib/pubid/easc/identifier.rb +59 -0
- data/lib/pubid/easc/identifiers/pmg.rb +20 -0
- data/lib/pubid/easc/identifiers/rmg.rb +19 -0
- data/lib/pubid/easc/identifiers.rb +10 -0
- data/lib/pubid/easc/parser.rb +88 -0
- data/lib/pubid/easc/renderer.rb +48 -0
- data/lib/pubid/easc/urn_generator.rb +46 -0
- data/lib/pubid/easc/urn_parser.rb +57 -0
- data/lib/pubid/easc.rb +53 -0
- data/lib/pubid/ecma/builder.rb +45 -0
- data/lib/pubid/ecma/identifier.rb +147 -0
- data/lib/pubid/ecma/identifiers/memento.rb +30 -0
- data/lib/pubid/ecma/identifiers/standard.rb +31 -0
- data/lib/pubid/ecma/identifiers/technical_report.rb +31 -0
- data/lib/pubid/ecma/identifiers.rb +11 -0
- data/lib/pubid/ecma/parser.rb +76 -0
- data/lib/pubid/ecma/renderer.rb +67 -0
- data/lib/pubid/ecma/urn_generator.rb +46 -0
- data/lib/pubid/ecma/urn_parser.rb +51 -0
- data/lib/pubid/ecma.rb +68 -0
- data/lib/pubid/errors.rb +80 -0
- data/lib/pubid/etsi/builder.rb +13 -4
- data/lib/pubid/etsi/identifier.rb +1 -3
- data/lib/pubid/etsi/identifiers/base.rb +43 -11
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +207 -4
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +45 -3
- data/lib/pubid/etsi/identifiers.rb +0 -1
- data/lib/pubid/etsi/parser.rb +9 -3
- data/lib/pubid/etsi/renderer.rb +8 -2
- data/lib/pubid/etsi.rb +6 -5
- 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/exporter.rb +2 -1
- data/lib/pubid/export/flavor_exporter.rb +18 -3
- data/lib/pubid/export.rb +1 -0
- data/lib/pubid/format_detector.rb +1 -0
- data/lib/pubid/gb/builder.rb +45 -0
- data/lib/pubid/gb/identifier.rb +67 -0
- data/lib/pubid/gb/identifiers/standard.rb +34 -0
- data/lib/pubid/gb/identifiers.rb +9 -0
- data/lib/pubid/gb/parser.rb +63 -0
- data/lib/pubid/gb/renderer.rb +35 -0
- data/lib/pubid/gb.rb +88 -0
- data/lib/pubid/gost/builder.rb +185 -0
- data/lib/pubid/gost/identifier.rb +47 -0
- data/lib/pubid/gost/identifiers/foreign_reference.rb +25 -0
- data/lib/pubid/gost/identifiers/harmonized.rb +39 -0
- data/lib/pubid/gost/identifiers/identical_adoption.rb +39 -0
- data/lib/pubid/gost/identifiers/interstate_standard.rb +20 -0
- data/lib/pubid/gost/identifiers/national_standard.rb +19 -0
- data/lib/pubid/gost/identifiers.rb +13 -0
- data/lib/pubid/gost/parser.rb +105 -0
- data/lib/pubid/gost/renderer.rb +48 -0
- data/lib/pubid/gost/urn_generator.rb +46 -0
- data/lib/pubid/gost/urn_parser.rb +52 -0
- data/lib/pubid/gost.rb +50 -0
- data/lib/pubid/iala/builder.rb +22 -27
- data/lib/pubid/iala/identifier.rb +36 -8
- data/lib/pubid/iala/identifiers/advice.rb +1 -1
- data/lib/pubid/iala/identifiers/annex.rb +10 -10
- data/lib/pubid/iala/identifiers/general_assembly.rb +5 -2
- data/lib/pubid/iala/identifiers/guideline.rb +3 -1
- data/lib/pubid/iala/identifiers/letter.rb +1 -1
- data/lib/pubid/iala/identifiers/manual.rb +3 -1
- data/lib/pubid/iala/identifiers/model_course.rb +3 -1
- data/lib/pubid/iala/identifiers/recommendation.rb +3 -1
- data/lib/pubid/iala/identifiers/report.rb +1 -1
- data/lib/pubid/iala/identifiers/resolution.rb +1 -1
- data/lib/pubid/iala/identifiers/standard.rb +3 -1
- data/lib/pubid/iala/identifiers.rb +0 -1
- data/lib/pubid/iala/parser.rb +10 -2
- data/lib/pubid/iala/renderer.rb +1 -1
- data/lib/pubid/iala/urn_generator.rb +1 -1
- data/lib/pubid/iala/urn_parser.rb +24 -3
- data/lib/pubid/iala.rb +5 -4
- data/lib/pubid/iana/builder.rb +22 -0
- data/lib/pubid/iana/identifier.rb +140 -0
- data/lib/pubid/iana/identifiers/registry.rb +69 -0
- data/lib/pubid/iana/identifiers.rb +9 -0
- data/lib/pubid/iana/parser.rb +38 -0
- data/lib/pubid/iana/renderer.rb +32 -0
- data/lib/pubid/iana/urn_generator.rb +19 -0
- data/lib/pubid/iana/urn_parser.rb +24 -0
- data/lib/pubid/iana.rb +70 -0
- data/lib/pubid/identifier.rb +797 -26
- data/lib/pubid/identifier_metadata.rb +1 -0
- data/lib/pubid/idf/builder.rb +4 -4
- data/lib/pubid/idf/identifier.rb +18 -9
- data/lib/pubid/idf/parser.rb +3 -3
- data/lib/pubid/idf/renderer.rb +5 -5
- data/lib/pubid/idf/supplement_identifier.rb +3 -3
- data/lib/pubid/idf/urn_generator.rb +1 -1
- data/lib/pubid/idf.rb +7 -1
- data/lib/pubid/iec/builder.rb +49 -32
- data/lib/pubid/iec/components.rb +0 -1
- data/lib/pubid/iec/identifier.rb +112 -77
- data/lib/pubid/iec/identifiers/amendment.rb +6 -2
- data/lib/pubid/iec/identifiers/base.rb +2 -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/consolidated_identifier.rb +6 -0
- data/lib/pubid/iec/identifiers/corrigendum.rb +2 -2
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +13 -15
- data/lib/pubid/iec/identifiers/guide.rb +0 -16
- data/lib/pubid/iec/identifiers/international_standard.rb +22 -6
- 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/sheet_identifier.rb +12 -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_group.rb +30 -0
- data/lib/pubid/iec/identifiers/technical_report.rb +1 -18
- data/lib/pubid/iec/identifiers/technical_specification.rb +1 -18
- 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/vap_identifier.rb +12 -12
- data/lib/pubid/iec/identifiers/white_paper.rb +0 -10
- data/lib/pubid/iec/identifiers/working_document.rb +24 -10
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/parser.rb +53 -28
- data/lib/pubid/iec/renderer.rb +31 -18
- data/lib/pubid/iec/single_identifier.rb +34 -11
- data/lib/pubid/iec/supplement_identifier.rb +32 -19
- data/lib/pubid/iec/urn_generator.rb +227 -61
- data/lib/pubid/iec/urn_parser.rb +42 -4
- data/lib/pubid/iec.rb +2 -6
- data/lib/pubid/ieee/aiee/builder.rb +17 -3
- data/lib/pubid/ieee/aiee/identifier.rb +46 -62
- data/lib/pubid/ieee/aiee/parser.rb +1 -1
- data/lib/pubid/ieee/builder.rb +386 -69
- data/lib/pubid/ieee/compaction.rb +121 -0
- data/lib/pubid/ieee/components/draft.rb +47 -7
- data/lib/pubid/ieee/identifier.rb +1 -3
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +62 -5
- data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
- data/lib/pubid/ieee/identifiers/base.rb +148 -18
- data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +6 -2
- data/lib/pubid/ieee/identifiers/corrigendum.rb +17 -2
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +24 -3
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/dual_published.rb +58 -3
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +102 -5
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +25 -1
- data/lib/pubid/ieee/identifiers/joint_development.rb +64 -15
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +58 -6
- data/lib/pubid/ieee/identifiers/nesc/base.rb +90 -19
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +20 -5
- data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +16 -5
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +11 -2
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +18 -3
- data/lib/pubid/ieee/identifiers/nesc.rb +1 -0
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +3 -3
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +14 -6
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +4 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/standard.rb +4 -1
- data/lib/pubid/ieee/identifiers/supplement_identifier.rb +26 -7
- data/lib/pubid/ieee/identifiers.rb +2 -1
- data/lib/pubid/ieee/ire/builder.rb +7 -6
- data/lib/pubid/ieee/ire/identifier.rb +48 -33
- data/lib/pubid/ieee/ire/parser.rb +1 -1
- data/lib/pubid/ieee/nesc/builder.rb +33 -20
- data/lib/pubid/ieee/nesc/parser.rb +16 -15
- data/lib/pubid/ieee/parser.rb +462 -44
- data/lib/pubid/ieee/pre_parser.rb +1 -1
- data/lib/pubid/ieee/renderer.rb +158 -57
- data/lib/pubid/ieee/typed_stages.rb +12 -1
- data/lib/pubid/ieee/urn_generator.rb +35 -8
- data/lib/pubid/ieee.rb +63 -4
- data/lib/pubid/ieee_debug.rb +1 -0
- data/lib/pubid/ietf/builder.rb +78 -0
- data/lib/pubid/ietf/identifier.rb +5 -0
- data/lib/pubid/ietf/identifiers/base.rb +72 -0
- data/lib/pubid/ietf/identifiers/bcp.rb +36 -0
- data/lib/pubid/ietf/identifiers/fyi.rb +36 -0
- data/lib/pubid/ietf/identifiers/internet_draft.rb +45 -0
- data/lib/pubid/ietf/identifiers/rfc.rb +27 -0
- data/lib/pubid/ietf/identifiers/serialization.rb +51 -0
- data/lib/pubid/ietf/identifiers/std.rb +36 -0
- data/lib/pubid/ietf/identifiers.rb +14 -0
- data/lib/pubid/ietf/parser.rb +61 -0
- data/lib/pubid/ietf/renderer.rb +64 -0
- data/lib/pubid/ietf/urn_generator.rb +37 -0
- data/lib/pubid/ietf/urn_parser.rb +43 -0
- data/lib/pubid/ietf.rb +86 -0
- data/lib/pubid/iho/identifier.rb +1 -3
- data/lib/pubid/iho/identifiers/base.rb +11 -10
- data/lib/pubid/iho/identifiers/bibliographic.rb +1 -1
- data/lib/pubid/iho/identifiers/circular_letter.rb +1 -1
- data/lib/pubid/iho/identifiers/miscellaneous.rb +1 -1
- data/lib/pubid/iho/identifiers/publication.rb +1 -1
- data/lib/pubid/iho/identifiers/standard.rb +1 -1
- data/lib/pubid/iho/identifiers.rb +0 -1
- data/lib/pubid/iho/parser.rb +1 -1
- data/lib/pubid/iho.rb +8 -7
- data/lib/pubid/isbn/builder.rb +44 -0
- data/lib/pubid/isbn/check_digit.rb +53 -0
- data/lib/pubid/isbn/identifier.rb +81 -0
- data/lib/pubid/isbn/identifiers/book.rb +30 -0
- data/lib/pubid/isbn/identifiers.rb +9 -0
- data/lib/pubid/isbn/parser.rb +45 -0
- data/lib/pubid/isbn/renderer.rb +16 -0
- data/lib/pubid/isbn.rb +53 -0
- data/lib/pubid/iso/builder.rb +9 -4
- data/lib/pubid/iso/bundled_identifier.rb +5 -3
- data/lib/pubid/iso/combined_identifier.rb +6 -4
- data/lib/pubid/iso/identifier.rb +29 -8
- data/lib/pubid/iso/identifiers/directives_supplement.rb +12 -12
- data/lib/pubid/iso/normalizer.rb +2 -2
- data/lib/pubid/iso/parser.rb +17 -13
- data/lib/pubid/iso/supplement_identifier.rb +19 -6
- data/lib/pubid/iso/urn_generator.rb +4 -1
- data/lib/pubid/iso/urn_parser.rb +1 -1
- data/lib/pubid/iso.rb +7 -1
- data/lib/pubid/itu/builder.rb +230 -29
- data/lib/pubid/itu/components/code.rb +48 -5
- data/lib/pubid/itu/components/designation.rb +35 -0
- data/lib/pubid/itu/components.rb +1 -0
- data/lib/pubid/itu/identifier.rb +1 -3
- data/lib/pubid/itu/identifiers/addendum.rb +15 -0
- data/lib/pubid/itu/identifiers/amendment.rb +7 -29
- data/lib/pubid/itu/identifiers/annex.rb +13 -2
- data/lib/pubid/itu/identifiers/annex_of_recommendation.rb +87 -0
- data/lib/pubid/itu/identifiers/appendix_of_recommendation.rb +92 -0
- data/lib/pubid/itu/identifiers/base.rb +357 -25
- data/lib/pubid/itu/identifiers/combined_identifier.rb +99 -23
- data/lib/pubid/itu/identifiers/corrigendum.rb +16 -23
- data/lib/pubid/itu/identifiers/errata.rb +15 -0
- data/lib/pubid/itu/identifiers/handbook.rb +38 -0
- data/lib/pubid/itu/identifiers/question.rb +63 -0
- data/lib/pubid/itu/identifiers/recommendation.rb +3 -2
- data/lib/pubid/itu/identifiers/report.rb +39 -0
- data/lib/pubid/itu/identifiers/special_publication.rb +3 -1
- data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
- data/lib/pubid/itu/identifiers/supplement.rb +119 -14
- data/lib/pubid/itu/identifiers.rb +10 -1
- data/lib/pubid/itu/model.rb +1 -1
- data/lib/pubid/itu/parser.rb +481 -27
- data/lib/pubid/itu/urn_generator.rb +36 -6
- data/lib/pubid/itu/urn_parser.rb +8 -0
- data/lib/pubid/itu.rb +12 -3
- data/lib/pubid/jcgm/builder.rb +24 -14
- data/lib/pubid/jcgm/identifier.rb +10 -0
- data/lib/pubid/jcgm/identifiers/amendment.rb +0 -2
- data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +3 -3
- data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
- data/lib/pubid/jcgm/identifiers.rb +2 -0
- data/lib/pubid/jcgm/parser.rb +74 -7
- data/lib/pubid/jcgm/renderer.rb +33 -12
- data/lib/pubid/jcgm/single_identifier.rb +84 -6
- data/lib/pubid/jcgm/supplement_identifier.rb +39 -4
- data/lib/pubid/jcgm/urn_generator.rb +21 -13
- data/lib/pubid/jcgm/urn_parser.rb +164 -10
- data/lib/pubid/jcgm.rb +10 -0
- data/lib/pubid/jis/identifier.rb +62 -3
- data/lib/pubid/jis/parser.rb +1 -1
- data/lib/pubid/jis.rb +1 -0
- data/lib/pubid/nist/builder.rb +29 -9
- data/lib/pubid/nist/caster.rb +7 -45
- data/lib/pubid/nist/circular_supplement_builder.rb +7 -5
- data/lib/pubid/nist/components/stage.rb +2 -2
- data/lib/pubid/nist/components/supplement.rb +5 -2
- data/lib/pubid/nist/configuration.rb +6 -2
- data/lib/pubid/nist/identifier.rb +1 -3
- data/lib/pubid/nist/identifiers/base.rb +133 -39
- data/lib/pubid/nist/identifiers/circular.rb +10 -3
- data/lib/pubid/nist/identifiers/circular_supplement.rb +14 -5
- data/lib/pubid/nist/identifiers/commercial_standard.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +8 -2
- data/lib/pubid/nist/identifiers/crpl_report.rb +8 -2
- data/lib/pubid/nist/identifiers/dated_document.rb +1 -1
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +1 -1
- data/lib/pubid/nist/identifiers/grant_contractor_report.rb +1 -1
- data/lib/pubid/nist/identifiers/handbook.rb +10 -3
- data/lib/pubid/nist/identifiers/internal_report.rb +13 -6
- data/lib/pubid/nist/identifiers/letter_circular.rb +1 -1
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +15 -7
- data/lib/pubid/nist/identifiers/monograph.rb +15 -8
- data/lib/pubid/nist/identifiers/ncstar.rb +2 -2
- data/lib/pubid/nist/identifiers/nsrds.rb +1 -1
- data/lib/pubid/nist/identifiers/owmwp.rb +1 -1
- data/lib/pubid/nist/identifiers/report.rb +15 -7
- data/lib/pubid/nist/identifiers/special_publication.rb +10 -1
- data/lib/pubid/nist/identifiers/technical_note.rb +1 -1
- data/lib/pubid/nist/identifiers.rb +0 -1
- data/lib/pubid/nist/parser.rb +27 -4
- data/lib/pubid/nist/preprocessor.rb +15 -0
- data/lib/pubid/nist/router.rb +2 -2
- data/lib/pubid/nist/series/ir.rb +0 -3
- data/lib/pubid/nist/supplement_identifier.rb +24 -9
- data/lib/pubid/nist.rb +19 -13
- data/lib/pubid/oasis/builder.rb +79 -0
- data/lib/pubid/oasis/identifier.rb +160 -0
- data/lib/pubid/oasis/identifiers/standard.rb +29 -0
- data/lib/pubid/oasis/identifiers.rb +9 -0
- data/lib/pubid/oasis/parser.rb +34 -0
- data/lib/pubid/oasis/renderer.rb +29 -0
- data/lib/pubid/oasis/urn_generator.rb +25 -0
- data/lib/pubid/oasis/urn_parser.rb +22 -0
- data/lib/pubid/oasis.rb +80 -0
- data/lib/pubid/ogc/builder.rb +33 -0
- data/lib/pubid/ogc/identifier.rb +81 -0
- data/lib/pubid/ogc/identifiers/document.rb +26 -0
- data/lib/pubid/ogc/identifiers.rb +10 -0
- data/lib/pubid/ogc/parser.rb +40 -0
- data/lib/pubid/ogc/renderer.rb +33 -0
- data/lib/pubid/ogc/urn_generator.rb +14 -0
- data/lib/pubid/ogc/urn_parser.rb +22 -0
- data/lib/pubid/ogc.rb +72 -0
- data/lib/pubid/oiml/builder.rb +36 -8
- data/lib/pubid/oiml/identifier.rb +9 -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 +12 -13
- data/lib/pubid/oiml/renderer.rb +13 -13
- data/lib/pubid/oiml/single_identifier.rb +41 -37
- data/lib/pubid/oiml/supplement_identifier.rb +36 -9
- data/lib/pubid/oiml/urn_parser.rb +23 -6
- data/lib/pubid/oiml.rb +10 -0
- data/lib/pubid/omg/builder.rb +20 -0
- data/lib/pubid/omg/identifier.rb +61 -0
- data/lib/pubid/omg/identifiers/specification.rb +32 -0
- data/lib/pubid/omg/identifiers.rb +9 -0
- data/lib/pubid/omg/parser.rb +93 -0
- data/lib/pubid/omg/renderer.rb +31 -0
- data/lib/pubid/omg.rb +52 -0
- data/lib/pubid/parser/grammar.rb +74 -0
- data/lib/pubid/parser.rb +2 -0
- data/lib/pubid/parsers/mr_string.rb +120 -7
- data/lib/pubid/plateau/builder.rb +8 -4
- data/lib/pubid/plateau/identifier.rb +1 -3
- data/lib/pubid/plateau/identifiers/base.rb +1 -6
- data/lib/pubid/plateau/identifiers/handbook.rb +1 -1
- data/lib/pubid/plateau/identifiers/technical_report.rb +1 -1
- data/lib/pubid/plateau/identifiers.rb +0 -1
- data/lib/pubid/plateau/parser.rb +16 -6
- data/lib/pubid/plateau/renderer.rb +1 -1
- data/lib/pubid/plateau/supplement_identifier.rb +11 -11
- data/lib/pubid/plateau.rb +14 -4
- 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 +6 -4
- data/lib/pubid/renderers/mr_string.rb +54 -6
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/rendering/numbering.rb +25 -7
- data/lib/pubid/rendering/supplement.rb +4 -4
- data/lib/pubid/rendering.rb +1 -0
- data/lib/pubid/sae/builder.rb +1 -1
- data/lib/pubid/sae/identifier.rb +1 -3
- data/lib/pubid/sae/identifiers/base.rb +19 -9
- data/lib/pubid/sae/identifiers.rb +0 -1
- data/lib/pubid/sae/parser.rb +1 -1
- data/lib/pubid/sae.rb +4 -3
- 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 +41 -0
- data/lib/pubid/tgpp/identifier.rb +107 -0
- data/lib/pubid/tgpp/identifiers/technical_report.rb +32 -0
- data/lib/pubid/tgpp/identifiers/technical_specification.rb +33 -0
- data/lib/pubid/tgpp/identifiers.rb +11 -0
- data/lib/pubid/tgpp/parser.rb +78 -0
- data/lib/pubid/tgpp/renderer.rb +52 -0
- data/lib/pubid/tgpp/urn_generator.rb +39 -0
- data/lib/pubid/tgpp/urn_parser.rb +30 -0
- data/lib/pubid/tgpp.rb +84 -0
- data/lib/pubid/type_resolver.rb +74 -0
- data/lib/pubid/un/builder.rb +42 -0
- data/lib/pubid/un/identifier.rb +40 -0
- data/lib/pubid/un/identifiers/document.rb +24 -0
- data/lib/pubid/un/identifiers.rb +9 -0
- data/lib/pubid/un/parser.rb +25 -0
- data/lib/pubid/un/renderer.rb +11 -0
- data/lib/pubid/un.rb +47 -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 +55 -0
- data/lib/pubid/w3c/identifier.rb +130 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/candidate_recommendation_draft.rb +31 -0
- data/lib/pubid/w3c/identifiers/draft_note.rb +31 -0
- data/lib/pubid/w3c/identifiers/note.rb +30 -0
- data/lib/pubid/w3c/identifiers/obsolete_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_edited_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/proposed_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/standard.rb +12 -0
- data/lib/pubid/w3c/identifiers/superseded_recommendation.rb +31 -0
- data/lib/pubid/w3c/identifiers/working_draft.rb +30 -0
- data/lib/pubid/w3c/identifiers.rb +25 -0
- data/lib/pubid/w3c/parser.rb +43 -0
- data/lib/pubid/w3c/renderer.rb +35 -0
- data/lib/pubid/w3c/urn_generator.rb +18 -0
- data/lib/pubid/w3c/urn_parser.rb +36 -0
- data/lib/pubid/w3c.rb +68 -0
- data/lib/pubid/xsf/builder.rb +17 -0
- data/lib/pubid/xsf/identifier.rb +66 -0
- data/lib/pubid/xsf/identifiers/xep.rb +31 -0
- data/lib/pubid/xsf/identifiers.rb +9 -0
- data/lib/pubid/xsf/parser.rb +38 -0
- data/lib/pubid/xsf/renderer.rb +23 -0
- data/lib/pubid/xsf/urn_generator.rb +13 -0
- data/lib/pubid/xsf/urn_parser.rb +18 -0
- data/lib/pubid/xsf.rb +82 -0
- data/lib/pubid.rb +424 -22
- 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 +241 -19
- 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/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/cie/components/code.rb +0 -80
- data/lib/pubid/iala/identifiers/base.rb +0 -14
- data/lib/pubid/iec/components/code.rb +0 -36
- /data/{archived-gems/pubid-nist → data/nist}/stages.yaml +0 -0
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Parsers
|
|
5
|
+
# Parses a machine-readable (MR) identifier string back into an Identifier.
|
|
6
|
+
#
|
|
7
|
+
# The MR format produced by `Renderers::MrString` mirrors the human form,
|
|
8
|
+
# lowercased and filename-safe:
|
|
9
|
+
#
|
|
10
|
+
# iso.9001.2015 → ISO 9001:2015
|
|
11
|
+
# iso-iec.17031-1.2020 → ISO/IEC 17031-1:2020
|
|
12
|
+
# iso.1234-1-2-3.2020 → ISO 1234-1-2-3:2020
|
|
13
|
+
# iso.tr.14627.2017 → ISO/TR 14627:2017
|
|
14
|
+
# iso.16634.-- → ISO 16634:--
|
|
15
|
+
# iso.9001.2015_amd.1.2020 → ISO 9001:2015/Amd 1:2020
|
|
16
|
+
# iso-iec.13818-1.2015_amd.3.2016_cor.1.2017 → ISO/IEC 13818-1:2015/Amd 3:2016/Cor 1:2017
|
|
17
|
+
#
|
|
18
|
+
# Copublishers join with `-` (`iso-iec`), supplements append with `_`
|
|
19
|
+
# (`iso.9001.2015_amd.1.2020`). Both round-trip back to `/` here. The
|
|
20
|
+
# flavor's own parser is case-insensitive on the type/publisher tokens
|
|
21
|
+
# we emit, so the lowercased slug re-parses cleanly.
|
|
22
|
+
#
|
|
23
|
+
# Note: NIST, CSA, IEEE, JIS, and SAE emit their own MR shapes that this
|
|
24
|
+
# parser does not attempt to reverse (their `to_s` already round-trips
|
|
25
|
+
# through the flavor's own parser, so callers should use that path for
|
|
26
|
+
# those flavors).
|
|
5
27
|
class MrString < Base
|
|
6
28
|
FLAVOR_MAP = {
|
|
7
29
|
"ISO" => :iso,
|
|
@@ -59,6 +81,14 @@ module Pubid
|
|
|
59
81
|
ccsds: :Ccsds,
|
|
60
82
|
}.freeze
|
|
61
83
|
|
|
84
|
+
# Lower-case type codes the renderer emits as a separate MR segment
|
|
85
|
+
# (e.g. `iso.tr.14627`). When the parser sees one of these in the
|
|
86
|
+
# second position, it splits it back out as `/TYPE`.
|
|
87
|
+
TYPE_CODES = %w[
|
|
88
|
+
tr ts pas is amd cor suppl add ext guide spec
|
|
89
|
+
standard corrigendum amendment
|
|
90
|
+
].freeze
|
|
91
|
+
|
|
62
92
|
def self.parse(mr_string)
|
|
63
93
|
flavor = detect_flavor(mr_string)
|
|
64
94
|
|
|
@@ -71,23 +101,106 @@ module Pubid
|
|
|
71
101
|
raise ArgumentError, "Unknown flavor: #{flavor}" unless flavor_module
|
|
72
102
|
|
|
73
103
|
identifier_string = convert_to_human_readable(mr_string)
|
|
104
|
+
|
|
105
|
+
# Refuse to hand the flavor a string this parser did not change.
|
|
106
|
+
#
|
|
107
|
+
# `detect_flavor` falls back to `:iso` for any publisher it does not
|
|
108
|
+
# know, and `Pubid::Iso.parse` sends an MR-shaped string straight back
|
|
109
|
+
# here — so a string that survives conversion unchanged recurses
|
|
110
|
+
# forever. `ECMA-426 ed1` is the standing example: "ECMA" is absent
|
|
111
|
+
# from FLAVOR_MAP, the string matches the MR shape heuristic
|
|
112
|
+
# (`/\A[A-Z]{2,}[.-]/`), and conversion is a fixed point.
|
|
113
|
+
# `Pubid::Iso.parse("ECMA-426 ed1")` raised SystemStackError.
|
|
114
|
+
#
|
|
115
|
+
# A fixed point means "this was never an MR string", which is a parse
|
|
116
|
+
# failure — the class the cross-flavor contract requires, and the one
|
|
117
|
+
# `Pubid.parse` treats as "try the next flavor".
|
|
118
|
+
if identifier_string == mr_string && flavor_module == Pubid::Iso
|
|
119
|
+
raise Parslet::ParseFailed,
|
|
120
|
+
"#{mr_string.inspect} is not an MR string"
|
|
121
|
+
end
|
|
122
|
+
|
|
74
123
|
flavor_module.parse(identifier_string)
|
|
75
124
|
end
|
|
76
125
|
|
|
77
126
|
def self.detect_flavor(mr_string)
|
|
78
|
-
publisher = mr_string.split(
|
|
127
|
+
publisher = mr_string.split(/[._-]/).first.to_s.upcase
|
|
79
128
|
FLAVOR_MAP[publisher] || :iso
|
|
80
129
|
end
|
|
81
130
|
|
|
131
|
+
# Convert the MR slug back to a human-readable identifier string the
|
|
132
|
+
# flavor's own parser will accept. Splits on `_` first so each segment
|
|
133
|
+
# (head + each supplement) is converted independently, then re-joined
|
|
134
|
+
# with `/`. Within the head, the copublisher separator `-` (first
|
|
135
|
+
# segment only) is restored to `/`.
|
|
82
136
|
def self.convert_to_human_readable(mr_string)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
137
|
+
head, *supplements = mr_string.split("_")
|
|
138
|
+
human = convert_head(head)
|
|
139
|
+
return human if supplements.empty?
|
|
140
|
+
|
|
141
|
+
supplements.inject(human) do |acc, supp|
|
|
142
|
+
"#{acc}/#{convert_supplement(supp)}"
|
|
89
143
|
end
|
|
90
144
|
end
|
|
145
|
+
|
|
146
|
+
# Converts a head segment like `iso-iec.13818-1.2015` to
|
|
147
|
+
# `ISO/IEC 13818-1:2015`.
|
|
148
|
+
def self.convert_head(head)
|
|
149
|
+
parts = head.split(".")
|
|
150
|
+
return parts.join(" ").upcase if parts.length <= 1
|
|
151
|
+
|
|
152
|
+
publisher, *rest = parts
|
|
153
|
+
|
|
154
|
+
# Optional type code segment (iso.tr.14627.2017 → ISO/TR 14627:2017).
|
|
155
|
+
type_segment = nil
|
|
156
|
+
if rest.first && TYPE_CODES.include?(rest.first.downcase)
|
|
157
|
+
type_segment = rest.shift.upcase
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Trailing language segment — bare language code(s) with no parens.
|
|
161
|
+
# Detect by length <= 5 and all-alpha (en, fr, en-fr, ru).
|
|
162
|
+
language_segment = nil
|
|
163
|
+
if rest.last&.match?(/\A[a-z]{2}(-[a-z]{2})*\z/)
|
|
164
|
+
language_segment = rest.pop
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Trailing year segment (may be `--` for undated, or YYYY[-MM[-DD]]).
|
|
168
|
+
year_segment = nil
|
|
169
|
+
if rest.any? && rest.last.match?(/\A(?:\d{4}(?:-\d{2}){0,2}|--)\z/)
|
|
170
|
+
year_segment = rest.pop
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Copublishers in the first segment: `iso-iec` → `ISO/IEC`. Multi-word
|
|
174
|
+
# publisher bodies (e.g. `cen-cenelec`) round-trip the same way.
|
|
175
|
+
publisher_part = publisher.split("-").map(&:upcase).join("/")
|
|
176
|
+
publisher_part = "#{publisher_part}/#{type_segment}" if type_segment
|
|
177
|
+
|
|
178
|
+
number_part = rest.join(" ")
|
|
179
|
+
result = publisher_part
|
|
180
|
+
result += " #{number_part}" unless number_part.empty?
|
|
181
|
+
result += ":#{year_segment}" if year_segment
|
|
182
|
+
if language_segment
|
|
183
|
+
langs = language_segment.split("-").join(",")
|
|
184
|
+
result += "(#{langs})"
|
|
185
|
+
end
|
|
186
|
+
result
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Converts a supplement segment like `amd.1.2020` to `Amd 1:2020`.
|
|
190
|
+
# The first token is the lowercase type code; remaining tokens are
|
|
191
|
+
# number and optional year.
|
|
192
|
+
def self.convert_supplement(supp)
|
|
193
|
+
tokens = supp.split(".")
|
|
194
|
+
type = tokens.shift&.upcase
|
|
195
|
+
year = tokens.last&.match?(/\A\d{4}\z/) ? tokens.pop : nil
|
|
196
|
+
number = tokens.join(" ")
|
|
197
|
+
|
|
198
|
+
result = type.to_s
|
|
199
|
+
result += " #{number}" unless number.empty?
|
|
200
|
+
result += ":#{year}" if year
|
|
201
|
+
result
|
|
202
|
+
end
|
|
91
203
|
end
|
|
92
204
|
end
|
|
93
205
|
end
|
|
206
|
+
|
|
@@ -9,7 +9,7 @@ module Pubid
|
|
|
9
9
|
|
|
10
10
|
def build(parsed)
|
|
11
11
|
# Check for annex supplement first
|
|
12
|
-
if parsed[:
|
|
12
|
+
if parsed[:base] && parsed[:annex_letter]
|
|
13
13
|
return build_annex(parsed)
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -29,7 +29,11 @@ module Pubid
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
params[:annex] = parsed[:annex].to_s.to_i if parsed[:annex]
|
|
32
|
-
|
|
32
|
+
# Only Handbook carries an edition; a legacy Latin TR captures the
|
|
33
|
+
# edition slice via the shared handbook rule, so drop it here.
|
|
34
|
+
if parsed[:edition] && klass == Identifiers::Handbook
|
|
35
|
+
params[:edition] = parsed[:edition].to_s
|
|
36
|
+
end
|
|
33
37
|
|
|
34
38
|
klass.new(**params)
|
|
35
39
|
end
|
|
@@ -38,10 +42,10 @@ module Pubid
|
|
|
38
42
|
|
|
39
43
|
def build_annex(parsed)
|
|
40
44
|
# Recursively parse base identifier
|
|
41
|
-
base = build(parsed[:
|
|
45
|
+
base = build(parsed[:base])
|
|
42
46
|
|
|
43
47
|
Identifiers::Annex.new(
|
|
44
|
-
|
|
48
|
+
base: base,
|
|
45
49
|
letter: parsed[:annex_letter].to_s,
|
|
46
50
|
)
|
|
47
51
|
end
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Pubid::Plateau::Identifier is the PLATEAU base class (a real Pubid::Identifier
|
|
4
|
-
# subclass); its body
|
|
5
|
-
# live in identifiers/base.rb. This file just ensures it is loaded.
|
|
6
|
-
require_relative "identifiers/base"
|
|
4
|
+
# subclass); its body and `.parse` live in identifiers/base.rb. This file just ensures it is loaded.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Plateau
|
|
5
5
|
# Base class for all PLATEAU identifiers. Canonical name
|
|
6
|
-
# Pubid::Plateau::Identifier
|
|
6
|
+
# Pubid::Plateau::Identifier.
|
|
7
7
|
class Identifier < ::Pubid::Identifier
|
|
8
8
|
# Delegate to the flavor module so callers can use
|
|
9
9
|
# `Pubid::Plateau::Identifier.parse` consistently with other flavors.
|
|
@@ -51,10 +51,5 @@ module Pubid
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
module Identifiers
|
|
55
|
-
# Backward-compatible alias: PLATEAU's base class used to be
|
|
56
|
-
# Pubid::Plateau::Identifiers::Base. It is now Pubid::Plateau::Identifier.
|
|
57
|
-
Base = Pubid::Plateau::Identifier
|
|
58
|
-
end
|
|
59
54
|
end
|
|
60
55
|
end
|
|
@@ -4,7 +4,6 @@ module Pubid
|
|
|
4
4
|
module Plateau
|
|
5
5
|
module Identifiers
|
|
6
6
|
autoload :Annex, "#{__dir__}/identifiers/annex"
|
|
7
|
-
autoload :Base, "#{__dir__}/identifiers/base"
|
|
8
7
|
autoload :Handbook, "#{__dir__}/identifiers/handbook"
|
|
9
8
|
autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
|
|
10
9
|
end
|
data/lib/pubid/plateau/parser.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Plateau
|
|
5
|
-
class Parser <
|
|
5
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
6
6
|
rule(:space) { str(" ") }
|
|
7
7
|
rule(:dash) { str("-") }
|
|
8
8
|
rule(:hash) { str("#") }
|
|
@@ -21,17 +21,23 @@ module Pubid
|
|
|
21
21
|
# Number: #00, #01, #46, etc.
|
|
22
22
|
rule(:number) { hash >> digits.as(:number) }
|
|
23
23
|
|
|
24
|
-
# Annex: -1, -2, etc.
|
|
25
|
-
|
|
24
|
+
# Annex: -1, -2, etc. Legacy Latin references use "_" as the sub-number
|
|
25
|
+
# separator (e.g. "#46_1"); both render as the canonical dash.
|
|
26
|
+
rule(:annex) { (dash | str("_")) >> digits.as(:annex) }
|
|
26
27
|
|
|
27
|
-
# Edition
|
|
28
|
+
# Edition (Handbook only). Canonical form is 第X.Y版; legacy Latin
|
|
29
|
+
# references write the bare X.Y (e.g. "PLATEAU Handbook #00 1.0"). Both
|
|
30
|
+
# capture the same numeric :edition slice, so they build the same object
|
|
31
|
+
# and render to the canonical 第X.Y版.
|
|
28
32
|
rule(:edition_part) do
|
|
29
33
|
str("第") >>
|
|
30
34
|
(digits >> str(".") >> digits).as(:edition) >>
|
|
31
35
|
str("版")
|
|
32
36
|
end
|
|
33
37
|
|
|
34
|
-
rule(:
|
|
38
|
+
rule(:edition_latin) { (digits >> str(".") >> digits).as(:edition) }
|
|
39
|
+
|
|
40
|
+
rule(:edition) { space >> (edition_part | edition_latin) }
|
|
35
41
|
|
|
36
42
|
# Annex supplement: "Annex A", "Annex B", etc.
|
|
37
43
|
rule(:annex_letter) { match["A-Z"].as(:annex_letter) }
|
|
@@ -45,6 +51,10 @@ module Pubid
|
|
|
45
51
|
number >> annex.maybe >> edition.maybe
|
|
46
52
|
end
|
|
47
53
|
|
|
54
|
+
# Technical Report has no edition. A legacy Latin TR reference carrying a
|
|
55
|
+
# trailing edition (e.g. "#00 1.0") is matched by the `handbook` rule
|
|
56
|
+
# (doc_type matches either keyword, tried first); the builder dispatches
|
|
57
|
+
# on :type and drops the captured edition for Technical Report.
|
|
48
58
|
rule(:technical_report) do
|
|
49
59
|
publisher >> space >> doc_type >> space >>
|
|
50
60
|
number >> annex.maybe
|
|
@@ -52,7 +62,7 @@ module Pubid
|
|
|
52
62
|
|
|
53
63
|
# Annex identifier (supplement)
|
|
54
64
|
rule(:annex_identifier) do
|
|
55
|
-
(handbook | technical_report).as(:
|
|
65
|
+
(handbook | technical_report).as(:base) >> annex_supplement
|
|
56
66
|
end
|
|
57
67
|
|
|
58
68
|
rule(:identifier) { annex_identifier | handbook | technical_report }
|
|
@@ -7,7 +7,7 @@ module Pubid
|
|
|
7
7
|
# Base class for PLATEAU supplements (Annex)
|
|
8
8
|
# Supplements reference a base identifier
|
|
9
9
|
class SupplementIdentifier < Pubid::Identifier
|
|
10
|
-
attribute :
|
|
10
|
+
attribute :base, Identifier
|
|
11
11
|
attribute :letter, :string, default: -> {}
|
|
12
12
|
|
|
13
13
|
def publisher
|
|
@@ -19,20 +19,20 @@ module Pubid
|
|
|
19
19
|
raise NotImplementedError, "Subclasses must implement supplement_string"
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# Override base_hash to extract edition, type, and annex from
|
|
22
|
+
# Override base_hash to extract edition, type, and annex from base
|
|
23
23
|
def base_hash
|
|
24
24
|
hash = super
|
|
25
25
|
# For Plateau supplements, edition comes from the base identifier
|
|
26
|
-
if
|
|
27
|
-
hash[:edition] =
|
|
26
|
+
if base.class.attributes.key?(:edition) && base.edition
|
|
27
|
+
hash[:edition] = base.edition
|
|
28
28
|
end
|
|
29
|
-
# Include type from
|
|
30
|
-
if
|
|
31
|
-
hash[:type] =
|
|
29
|
+
# Include type from base
|
|
30
|
+
if base.class.attributes.key?(:type_string) && base.type_string
|
|
31
|
+
hash[:type] = base.type_string
|
|
32
32
|
end
|
|
33
|
-
# Include annex from
|
|
34
|
-
if
|
|
35
|
-
hash[:annex] =
|
|
33
|
+
# Include annex from base
|
|
34
|
+
if base.class.attributes.key?(:annex) && base.annex
|
|
35
|
+
hash[:annex] = base.annex
|
|
36
36
|
end
|
|
37
37
|
hash
|
|
38
38
|
end
|
|
@@ -60,7 +60,7 @@ module Pubid
|
|
|
60
60
|
def ==(other)
|
|
61
61
|
return false unless other.class == self.class
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
base == other.base &&
|
|
64
64
|
letter == other.letter
|
|
65
65
|
end
|
|
66
66
|
end
|
data/lib/pubid/plateau.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pubid"
|
|
3
4
|
require "parslet"
|
|
4
5
|
|
|
5
6
|
module Pubid
|
|
@@ -10,7 +11,7 @@ module Pubid
|
|
|
10
11
|
PREFIXES = ["PLATEAU"].freeze
|
|
11
12
|
|
|
12
13
|
autoload :Builder, "#{__dir__}/plateau/builder"
|
|
13
|
-
autoload :Identifier, "#{__dir__}/plateau/
|
|
14
|
+
autoload :Identifier, "#{__dir__}/plateau/identifiers/base"
|
|
14
15
|
autoload :Identifiers, "#{__dir__}/plateau/identifiers"
|
|
15
16
|
autoload :Parser, "#{__dir__}/plateau/parser"
|
|
16
17
|
autoload :Renderer, "#{__dir__}/plateau/renderer"
|
|
@@ -19,6 +20,15 @@ module Pubid
|
|
|
19
20
|
autoload :UrnParser, "#{__dir__}/plateau/urn_parser"
|
|
20
21
|
|
|
21
22
|
def self.parse(input)
|
|
23
|
+
unless input.is_a?(String)
|
|
24
|
+
raise Pubid::Errors::InvalidInputError,
|
|
25
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if input.length > Pubid::MAX_INPUT_LENGTH
|
|
29
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
30
|
+
end
|
|
31
|
+
|
|
22
32
|
# Apply legacy update_codes normalization first
|
|
23
33
|
normalized = Core::UpdateCodes.apply(input, :plateau)
|
|
24
34
|
parser = Parser.new
|
|
@@ -27,9 +37,9 @@ module Pubid
|
|
|
27
37
|
end
|
|
28
38
|
|
|
29
39
|
# Per-flavor format registry: inherits global formats, overrides :human
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
SupplementIdentifier.format_registry =
|
|
40
|
+
Identifier.format_registry = FormatRegistry.new(parent: ::Pubid::Identifier.format_registry)
|
|
41
|
+
Identifier.format_registry.register(:human, renderer: Plateau::Renderer)
|
|
42
|
+
SupplementIdentifier.format_registry = Identifier.format_registry
|
|
33
43
|
|
|
34
44
|
# Auto-discover all identifier types from the Identifiers namespace
|
|
35
45
|
# @return [Array<Class>] identifier classes that define a self.type Hash
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Renderers
|
|
5
|
+
# Adds semantic <span class="..."> markers to an already-rendered
|
|
6
|
+
# identifier string.
|
|
7
|
+
#
|
|
8
|
+
# In pubid 1.x annotation was applied in ONE place — `prerender_params`
|
|
9
|
+
# wrapped every value in the param hash — so all 40-odd flavors got it for
|
|
10
|
+
# free. pubid 2 replaced that hash with typed components and per-flavor
|
|
11
|
+
# renderers, and the annotation went with it: `Renderers::Base#annotate`
|
|
12
|
+
# exists, but only the HumanReadable family calls it. All 39 flavor
|
|
13
|
+
# renderers receive `context.annotated` and ignore it, so
|
|
14
|
+
# `to_s(annotated: true)` returned plain text for every flavor but ISO.
|
|
15
|
+
#
|
|
16
|
+
# Re-annotating inside 39 renderers would mean 39 chances to drift. This
|
|
17
|
+
# class recovers the markup from the OUTSIDE instead: it asks the
|
|
18
|
+
# identifier for its own component values and wraps each one where it
|
|
19
|
+
# appears in the rendered string. That is one implementation, and a flavor
|
|
20
|
+
# added tomorrow is covered without touching its renderer.
|
|
21
|
+
#
|
|
22
|
+
# It is a fallback, not a replacement. `Identifier#render` uses it only
|
|
23
|
+
# when the renderer produced no span of its own, so ISO's exact,
|
|
24
|
+
# render-time placement still wins.
|
|
25
|
+
#
|
|
26
|
+
# Deliberate limits:
|
|
27
|
+
#
|
|
28
|
+
# * A token that does not appear verbatim in the output is skipped. A
|
|
29
|
+
# renderer may transform a value (abbreviate it, change its case), and a
|
|
30
|
+
# missing span is a far better outcome than a wrong one or a crash.
|
|
31
|
+
# * Matching walks left to right behind a cursor, so a later token can
|
|
32
|
+
# never match text an earlier one already claimed — that is what stops
|
|
33
|
+
# the part "1" of `ISO 1234-1` from matching inside "1234".
|
|
34
|
+
class Annotator
|
|
35
|
+
# Semantic class for each token, in the order tokens appear in a printed
|
|
36
|
+
# identifier. Order matters: it is the sequence the cursor walks.
|
|
37
|
+
TOKENS = [
|
|
38
|
+
[:publisher, "publisher"],
|
|
39
|
+
[:copublishers, "publisher"],
|
|
40
|
+
%i[typed_stage typed_stage_css],
|
|
41
|
+
[:type, "doctype"],
|
|
42
|
+
[:stage, "stage"],
|
|
43
|
+
[:number, "docnumber"],
|
|
44
|
+
[:part, "part"],
|
|
45
|
+
[:subpart, "part"],
|
|
46
|
+
[:stage_iteration, "iteration"],
|
|
47
|
+
[:year, "year"],
|
|
48
|
+
[:edition, "edition"],
|
|
49
|
+
[:languages, "language"],
|
|
50
|
+
].freeze
|
|
51
|
+
|
|
52
|
+
# Characters that may not sit directly against a match, so a token never
|
|
53
|
+
# binds to the middle of a longer run of the same character class.
|
|
54
|
+
WORD_CHAR = /[A-Za-z0-9]/
|
|
55
|
+
|
|
56
|
+
# How deep to follow nested identifiers. A wrapper around a wrapper is
|
|
57
|
+
# real (BSI adopts a CEN prestandard that adopts an ISO standard); four
|
|
58
|
+
# levels is past anything the corpus holds, and the cap is here so a
|
|
59
|
+
# cyclic `base` cannot hang a rendering call.
|
|
60
|
+
MAX_NESTING = 4
|
|
61
|
+
|
|
62
|
+
def initialize(identifier, context = nil)
|
|
63
|
+
@id = identifier
|
|
64
|
+
@context = context
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param rendered [String] the plain rendering of {@id}
|
|
68
|
+
# @return [String] the same string with semantic spans inserted
|
|
69
|
+
def annotate(rendered)
|
|
70
|
+
return rendered unless rendered.is_a?(String) && !rendered.empty?
|
|
71
|
+
|
|
72
|
+
cursor = 0
|
|
73
|
+
result = +""
|
|
74
|
+
|
|
75
|
+
ordered_tokens(rendered).each do |text, css_class|
|
|
76
|
+
index = find_token(rendered, text, cursor)
|
|
77
|
+
next if index.nil?
|
|
78
|
+
|
|
79
|
+
result << rendered[cursor...index]
|
|
80
|
+
result << %(<span class="#{css_class}">#{text}</span>)
|
|
81
|
+
cursor = index + text.length
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
result << rendered[cursor..]
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
# Tokens sorted by where they actually appear, not by the order
|
|
91
|
+
# {TOKENS} lists them.
|
|
92
|
+
#
|
|
93
|
+
# Flavors disagree about layout: ISO prints the number before the type
|
|
94
|
+
# ("ISO/IEC TR 2131"), CCSDS prints it after ("CCSDS 121.0-B-2"). Walking
|
|
95
|
+
# in declaration order pushed the cursor past the number for CCSDS, so
|
|
96
|
+
# "121" was never annotated. Sorting by first occurrence makes the walk
|
|
97
|
+
# follow the printed identifier instead of a fixed idea of one.
|
|
98
|
+
def ordered_tokens(rendered)
|
|
99
|
+
tokens = []
|
|
100
|
+
each_token { |text, css_class| tokens << [text, css_class] }
|
|
101
|
+
|
|
102
|
+
decorated = tokens.each_with_index.map do |token, i|
|
|
103
|
+
position = find_token(rendered, token.first, 0) || rendered.length
|
|
104
|
+
[position, i, token]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
decorated.sort_by { |position, i, _| [position, i] }.map(&:last)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Yields [text, css_class] for every annotatable token this identifier
|
|
111
|
+
# actually carries, then every one its nested identifiers carry.
|
|
112
|
+
def each_token(&)
|
|
113
|
+
emit_tokens(@id, 0, &)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# A wrapper — an adoption, a supplement, a bundle — carries no number of
|
|
117
|
+
# its own and prints the document it wraps, so the annotatable tokens in
|
|
118
|
+
# its string belong to `base`. Reading only the wrapper's own attributes
|
|
119
|
+
# is why every CSA container and CIE's supplement rendered plain while
|
|
120
|
+
# accepting the flag.
|
|
121
|
+
#
|
|
122
|
+
# Order does not matter here: `ordered_tokens` sorts by first occurrence,
|
|
123
|
+
# so a nested token lands where it actually appears in the string.
|
|
124
|
+
def emit_tokens(id, depth, &)
|
|
125
|
+
return if depth > MAX_NESTING
|
|
126
|
+
|
|
127
|
+
tokens_for(id).each do |attr_name, css_class|
|
|
128
|
+
Array(token_values(id, attr_name)).each do |value|
|
|
129
|
+
text = token_text(value)
|
|
130
|
+
next if text.nil? || text.empty?
|
|
131
|
+
|
|
132
|
+
yield text, resolve_class(css_class, value)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
nested_identifiers(id).each { |nested| emit_tokens(nested, depth + 1, &) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# {TOKENS} unless the identifier names more of its own — see
|
|
140
|
+
# `Pubid::Identifier#annotation_tokens`.
|
|
141
|
+
def tokens_for(id)
|
|
142
|
+
id.respond_to?(:annotation_tokens) ? id.annotation_tokens : TOKENS
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The identifiers this one wraps, under any of the four names the gem
|
|
146
|
+
# uses: `base` (the uniform parent accessor), the `ids` / `identifiers`
|
|
147
|
+
# collections that bundles and consolidated identifiers hold instead, and
|
|
148
|
+
# CSA `Bundled`'s `bundled_with` — which holds the amendments a
|
|
149
|
+
# consolidation prints, and whose values it composes into the string from
|
|
150
|
+
# their components rather than from their own `to_s`.
|
|
151
|
+
def nested_identifiers(id)
|
|
152
|
+
%i[base ids identifiers bundled_with].flat_map do |name|
|
|
153
|
+
next [] unless id.respond_to?(name)
|
|
154
|
+
|
|
155
|
+
begin
|
|
156
|
+
Array(id.public_send(name))
|
|
157
|
+
rescue StandardError
|
|
158
|
+
[]
|
|
159
|
+
end
|
|
160
|
+
end.grep(::Pubid::Identifier)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def token_values(id, attr_name)
|
|
164
|
+
return nil unless id.respond_to?(attr_name)
|
|
165
|
+
|
|
166
|
+
id.public_send(attr_name)
|
|
167
|
+
rescue StandardError
|
|
168
|
+
# A derived reader may assume state a partial identifier lacks. A
|
|
169
|
+
# missing span is not worth an exception on a rendering path.
|
|
170
|
+
nil
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# The printed form of one component. Components render themselves through
|
|
174
|
+
# the context; a bare scalar is already its own text.
|
|
175
|
+
def token_text(value)
|
|
176
|
+
return nil if value.nil?
|
|
177
|
+
|
|
178
|
+
text = if value.respond_to?(:render)
|
|
179
|
+
value.render(context: @context)
|
|
180
|
+
else
|
|
181
|
+
value
|
|
182
|
+
end
|
|
183
|
+
text.to_s.strip
|
|
184
|
+
rescue StandardError
|
|
185
|
+
nil
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def resolve_class(css_class, value)
|
|
189
|
+
return css_class unless css_class == :typed_stage_css
|
|
190
|
+
|
|
191
|
+
TypedStageClass.for(value)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# First occurrence of +text+ at or after +cursor+ that is not embedded in
|
|
195
|
+
# a longer word — so "1" matches the part in "ISO 1234-1", never the "1"
|
|
196
|
+
# inside "1234".
|
|
197
|
+
def find_token(rendered, text, cursor)
|
|
198
|
+
at = cursor
|
|
199
|
+
while (index = rendered.index(text, at))
|
|
200
|
+
return index if standalone?(rendered, index, text.length)
|
|
201
|
+
|
|
202
|
+
at = index + 1
|
|
203
|
+
end
|
|
204
|
+
nil
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def standalone?(rendered, index, length)
|
|
208
|
+
before = index.zero? ? nil : rendered[index - 1]
|
|
209
|
+
after = rendered[index + length]
|
|
210
|
+
|
|
211
|
+
!WORD_CHAR.match?(before.to_s) && !WORD_CHAR.match?(after.to_s)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# The typed-stage class depends on the stage's type code, the same
|
|
215
|
+
# mapping `Renderers::Base#typed_stage_css` applies. Kept here rather
|
|
216
|
+
# than reached for through a private method on another object.
|
|
217
|
+
module TypedStageClass
|
|
218
|
+
MAP = {
|
|
219
|
+
"amd" => "amendment",
|
|
220
|
+
"cor" => "corrigendum",
|
|
221
|
+
"add" => "addendum",
|
|
222
|
+
}.freeze
|
|
223
|
+
|
|
224
|
+
def self.for(typed_stage)
|
|
225
|
+
code = typed_stage.respond_to?(:type_code) ? typed_stage.type_code.to_s : ""
|
|
226
|
+
return "stage" if code.empty? || code == "is"
|
|
227
|
+
|
|
228
|
+
MAP[code] || "doctype"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
data/lib/pubid/renderers/base.rb
CHANGED
|
@@ -41,6 +41,19 @@ module Pubid
|
|
|
41
41
|
%(#{lead}<span class="#{css_class}">#{core}</span>#{trail})
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Render a value that may be a component or a bare scalar.
|
|
45
|
+
#
|
|
46
|
+
# `number`, `part` and `subpart` are `Components::Code` on
|
|
47
|
+
# ::Pubid::Identifier but a plain `:string` in a growing number of
|
|
48
|
+
# flavors, so a shared renderer cannot assume the format-aware
|
|
49
|
+
# `#render(context:)` seam is there. This keeps both shapes working while
|
|
50
|
+
# the flavors convert one tranche at a time.
|
|
51
|
+
def render_component(value, context)
|
|
52
|
+
return nil if value.nil?
|
|
53
|
+
|
|
54
|
+
value.respond_to?(:render) ? value.render(context: context) : value.to_s
|
|
55
|
+
end
|
|
56
|
+
|
|
44
57
|
# Choose between "stage" and a type/supplement class for a typed stage.
|
|
45
58
|
def typed_stage_css(typed_stage)
|
|
46
59
|
code = typed_stage&.type_code.to_s
|