pubid 1.15.21 → 2.0.0.alpha.10
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/LICENSE.txt +1 -1
- data/README.adoc +2044 -53
- data/archived-gems/pubid-ccsds/update_codes.yaml +1 -0
- data/archived-gems/pubid-iec/stages.yaml +129 -0
- data/archived-gems/pubid-iec/update_codes.yaml +67 -0
- data/archived-gems/pubid-ieee/update_codes.yaml +104 -0
- data/archived-gems/pubid-iso/stages.yaml +106 -0
- data/archived-gems/pubid-iso/update_codes.yaml +4 -0
- data/archived-gems/pubid-itu/i18n.yaml +13 -0
- data/archived-gems/pubid-itu/series.yaml +42 -0
- data/archived-gems/pubid-nist/publishers.yaml +6 -0
- data/archived-gems/pubid-nist/series.yaml +121 -0
- data/archived-gems/pubid-nist/stages.yaml +16 -0
- data/archived-gems/pubid-nist/update_codes.yaml +93 -0
- data/archived-gems/pubid-plateau/update_codes.yaml +6 -0
- data/data/bipm/update_codes.yaml +9 -0
- data/data/ccsds/update_codes.yaml +1 -0
- data/data/iec/update_codes.yaml +70 -0
- data/data/ieee/update_codes.yaml +210 -0
- data/data/iso/update_codes.yaml +21 -0
- data/data/nist/series.yaml +155 -0
- data/data/nist/update_codes.yaml +122 -0
- data/data/plateau/update_codes.yaml +6 -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 +60 -0
- data/lib/pubid/amca/builder.rb +176 -0
- data/lib/pubid/amca/identifier.rb +4 -0
- data/lib/pubid/amca/identifiers/base.rb +92 -0
- data/lib/pubid/amca/identifiers/interpretation.rb +38 -0
- data/lib/pubid/amca/identifiers/publication.rb +34 -0
- data/lib/pubid/amca/identifiers/standard.rb +20 -0
- data/lib/pubid/amca/identifiers.rb +11 -0
- data/lib/pubid/amca/parser.rb +153 -0
- data/lib/pubid/amca/renderer.rb +82 -0
- data/lib/pubid/amca/single_identifier.rb +10 -0
- data/lib/pubid/amca/urn_generator.rb +51 -0
- data/lib/pubid/amca/urn_parser.rb +28 -0
- data/lib/pubid/amca.rb +73 -0
- data/lib/pubid/ansi/builder.rb +54 -0
- data/lib/pubid/ansi/identifier.rb +31 -0
- data/lib/pubid/ansi/identifiers/american_national_standard.rb +13 -0
- data/lib/pubid/ansi/identifiers/standard.rb +15 -0
- data/lib/pubid/ansi/identifiers.rb +11 -0
- data/lib/pubid/ansi/parser.rb +91 -0
- data/lib/pubid/ansi/renderer.rb +53 -0
- data/lib/pubid/ansi/single_identifier.rb +16 -0
- data/lib/pubid/ansi/urn_generator.rb +41 -0
- data/lib/pubid/ansi/urn_parser.rb +23 -0
- data/lib/pubid/ansi.rb +68 -0
- data/lib/pubid/api/builder.rb +58 -0
- data/lib/pubid/api/components/code.rb +9 -0
- data/lib/pubid/api/identifier.rb +42 -0
- data/lib/pubid/api/identifiers/base.rb +12 -0
- data/lib/pubid/api/identifiers/bulletin.rb +13 -0
- data/lib/pubid/api/identifiers/continuous_operations_standard.rb +13 -0
- data/lib/pubid/api/identifiers/mpms.rb +26 -0
- data/lib/pubid/api/identifiers/publication.rb +13 -0
- data/lib/pubid/api/identifiers/recommended_practice.rb +13 -0
- data/lib/pubid/api/identifiers/specification.rb +13 -0
- data/lib/pubid/api/identifiers/standard.rb +13 -0
- data/lib/pubid/api/identifiers/technical_report.rb +13 -0
- data/lib/pubid/api/identifiers/typeless_standard.rb +11 -0
- data/lib/pubid/api/identifiers.rb +18 -0
- data/lib/pubid/api/parser.rb +140 -0
- data/lib/pubid/api/renderer.rb +98 -0
- data/lib/pubid/api/single_identifier.rb +24 -0
- data/lib/pubid/api/urn_generator.rb +23 -0
- data/lib/pubid/api/urn_parser.rb +35 -0
- data/lib/pubid/api.rb +68 -0
- data/lib/pubid/ashrae/builder.rb +519 -0
- data/lib/pubid/ashrae/identifier.rb +8 -0
- data/lib/pubid/ashrae/identifiers/addenda_package.rb +42 -0
- data/lib/pubid/ashrae/identifiers/addendum.rb +44 -0
- data/lib/pubid/ashrae/identifiers/base.rb +119 -0
- data/lib/pubid/ashrae/identifiers/combined_addenda.rb +43 -0
- data/lib/pubid/ashrae/identifiers/errata.rb +39 -0
- data/lib/pubid/ashrae/identifiers/guideline.rb +41 -0
- data/lib/pubid/ashrae/identifiers/interpretation.rb +45 -0
- data/lib/pubid/ashrae/identifiers/standard.rb +41 -0
- data/lib/pubid/ashrae/identifiers.rb +15 -0
- data/lib/pubid/ashrae/parser.rb +748 -0
- data/lib/pubid/ashrae/renderer.rb +117 -0
- data/lib/pubid/ashrae/single_identifier.rb +10 -0
- data/lib/pubid/ashrae/supplement_identifier.rb +38 -0
- data/lib/pubid/ashrae/urn_generator.rb +57 -0
- data/lib/pubid/ashrae/urn_parser.rb +27 -0
- data/lib/pubid/ashrae.rb +77 -0
- data/lib/pubid/asme/builder.rb +162 -0
- data/lib/pubid/asme/components/code.rb +26 -0
- data/lib/pubid/asme/identifier.rb +24 -0
- data/lib/pubid/asme/identifiers/base.rb +10 -0
- data/lib/pubid/asme/identifiers/standard.rb +96 -0
- data/lib/pubid/asme/identifiers.rb +10 -0
- data/lib/pubid/asme/parser.rb +308 -0
- data/lib/pubid/asme/renderer.rb +66 -0
- data/lib/pubid/asme/single_identifier.rb +38 -0
- data/lib/pubid/asme/urn_generator.rb +133 -0
- data/lib/pubid/asme/urn_parser.rb +31 -0
- data/lib/pubid/asme.rb +67 -0
- data/lib/pubid/astm/builder.rb +166 -0
- data/lib/pubid/astm/components/code.rb +42 -0
- data/lib/pubid/astm/components.rb +9 -0
- data/lib/pubid/astm/identifier.rb +24 -0
- data/lib/pubid/astm/identifiers/adjunct.rb +28 -0
- data/lib/pubid/astm/identifiers/base.rb +13 -0
- data/lib/pubid/astm/identifiers/code_number.rb +81 -0
- data/lib/pubid/astm/identifiers/data_series.rb +13 -0
- data/lib/pubid/astm/identifiers/iso_dual_published.rb +65 -0
- data/lib/pubid/astm/identifiers/manual.rb +23 -0
- data/lib/pubid/astm/identifiers/monograph.rb +13 -0
- data/lib/pubid/astm/identifiers/research_report.rb +21 -0
- data/lib/pubid/astm/identifiers/standard.rb +23 -0
- data/lib/pubid/astm/identifiers/technical_report.rb +12 -0
- data/lib/pubid/astm/identifiers/work_in_progress.rb +12 -0
- data/lib/pubid/astm/identifiers.rb +19 -0
- data/lib/pubid/astm/parser.rb +244 -0
- data/lib/pubid/astm/renderer.rb +172 -0
- data/lib/pubid/astm/single_identifier.rb +47 -0
- data/lib/pubid/astm/urn_generator.rb +101 -0
- data/lib/pubid/astm/urn_parser.rb +30 -0
- data/lib/pubid/astm.rb +55 -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 +91 -0
- data/lib/pubid/bsi/builder.rb +1495 -0
- data/lib/pubid/bsi/components/code.rb +11 -0
- data/lib/pubid/bsi/components/date.rb +11 -0
- data/lib/pubid/bsi/components/publisher.rb +11 -0
- data/lib/pubid/bsi/components/type.rb +11 -0
- data/lib/pubid/bsi/identifier.rb +6 -0
- data/lib/pubid/bsi/identifiers/addendum_document.rb +30 -0
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +67 -0
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +51 -0
- data/lib/pubid/bsi/identifiers/aerospace_standard.rb +65 -0
- data/lib/pubid/bsi/identifiers/amendment.rb +48 -0
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +21 -0
- data/lib/pubid/bsi/identifiers/british_standard.rb +34 -0
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +40 -0
- data/lib/pubid/bsi/identifiers/committee_document.rb +44 -0
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +84 -0
- data/lib/pubid/bsi/identifiers/corrigendum.rb +44 -0
- data/lib/pubid/bsi/identifiers/detailed_specification.rb +33 -0
- data/lib/pubid/bsi/identifiers/disc.rb +27 -0
- data/lib/pubid/bsi/identifiers/draft_document.rb +27 -0
- data/lib/pubid/bsi/identifiers/electronic_book.rb +16 -0
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +36 -0
- data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +35 -0
- data/lib/pubid/bsi/identifiers/flex.rb +30 -0
- data/lib/pubid/bsi/identifiers/handbook.rb +23 -0
- data/lib/pubid/bsi/identifiers/index.rb +30 -0
- data/lib/pubid/bsi/identifiers/method.rb +35 -0
- data/lib/pubid/bsi/identifiers/national_annex.rb +48 -0
- data/lib/pubid/bsi/identifiers/practice_guide.rb +21 -0
- data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +27 -0
- data/lib/pubid/bsi/identifiers/published_document.rb +27 -0
- data/lib/pubid/bsi/identifiers/section.rb +32 -0
- data/lib/pubid/bsi/identifiers/set.rb +40 -0
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +40 -0
- data/lib/pubid/bsi/identifiers/supplement_document.rb +29 -0
- data/lib/pubid/bsi/identifiers/supplementary_index.rb +35 -0
- data/lib/pubid/bsi/identifiers/technical_specification.rb +34 -0
- data/lib/pubid/bsi/identifiers/test_method.rb +35 -0
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +37 -0
- data/lib/pubid/bsi/identifiers.rb +51 -0
- data/lib/pubid/bsi/model.rb +196 -0
- data/lib/pubid/bsi/parser.rb +673 -0
- data/lib/pubid/bsi/renderer.rb +1064 -0
- data/lib/pubid/bsi/single_identifier.rb +141 -0
- data/lib/pubid/bsi/urn_generator.rb +92 -0
- data/lib/pubid/bsi/urn_parser.rb +52 -0
- data/lib/pubid/bsi.rb +282 -0
- data/lib/pubid/builder/base.rb +187 -0
- data/lib/pubid/bundled_identifier.rb +134 -0
- 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 +82 -0
- data/lib/pubid/ccsds/builder.rb +57 -0
- data/lib/pubid/ccsds/identifier.rb +76 -0
- data/lib/pubid/ccsds/identifiers/base.rb +41 -0
- data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +70 -0
- data/lib/pubid/ccsds/identifiers/corrigendum.rb +40 -0
- data/lib/pubid/ccsds/identifiers.rb +10 -0
- data/lib/pubid/ccsds/parser.rb +73 -0
- data/lib/pubid/ccsds/single_identifier.rb +77 -0
- data/lib/pubid/ccsds/supplement_identifier.rb +37 -0
- data/lib/pubid/ccsds/urn_generator.rb +115 -0
- data/lib/pubid/ccsds/urn_parser.rb +20 -0
- data/lib/pubid/ccsds.rb +64 -0
- data/lib/pubid/cen_cenelec/builder.rb +362 -0
- data/lib/pubid/cen_cenelec/identifier.rb +38 -0
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +45 -0
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +19 -0
- data/lib/pubid/cen_cenelec/identifiers/base.rb +34 -0
- data/lib/pubid/cen_cenelec/identifiers/cen_report.rb +29 -0
- data/lib/pubid/cen_cenelec/identifiers/cen_workshop_agreement.rb +28 -0
- data/lib/pubid/cen_cenelec/identifiers/cenelec_harmonization_document.rb +28 -0
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +40 -0
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +20 -0
- data/lib/pubid/cen_cenelec/identifiers/european_norm.rb +99 -0
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +50 -0
- data/lib/pubid/cen_cenelec/identifiers/european_specification.rb +29 -0
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +18 -0
- data/lib/pubid/cen_cenelec/identifiers/guide.rb +27 -0
- data/lib/pubid/cen_cenelec/identifiers/harmonization_document.rb +28 -0
- data/lib/pubid/cen_cenelec/identifiers/technical_report.rb +28 -0
- data/lib/pubid/cen_cenelec/identifiers/technical_specification.rb +36 -0
- data/lib/pubid/cen_cenelec/identifiers.rb +32 -0
- data/lib/pubid/cen_cenelec/parser.rb +144 -0
- data/lib/pubid/cen_cenelec/renderer.rb +261 -0
- data/lib/pubid/cen_cenelec/single_identifier.rb +49 -0
- data/lib/pubid/cen_cenelec/supplement_identifier.rb +47 -0
- data/lib/pubid/cen_cenelec/urn_generator.rb +129 -0
- data/lib/pubid/cen_cenelec/urn_parser.rb +28 -0
- data/lib/pubid/cen_cenelec.rb +208 -0
- data/lib/pubid/cie/builder.rb +524 -0
- data/lib/pubid/cie/components/language.rb +58 -0
- data/lib/pubid/cie/identifier.rb +33 -0
- data/lib/pubid/cie/identifiers/bundle.rb +50 -0
- data/lib/pubid/cie/identifiers/code_attributes.rb +52 -0
- data/lib/pubid/cie/identifiers/conference.rb +37 -0
- data/lib/pubid/cie/identifiers/corrigendum.rb +34 -0
- data/lib/pubid/cie/identifiers/dual_published.rb +41 -0
- data/lib/pubid/cie/identifiers/identical.rb +64 -0
- data/lib/pubid/cie/identifiers/joint_published.rb +52 -0
- data/lib/pubid/cie/identifiers/proceedings.rb +41 -0
- data/lib/pubid/cie/identifiers/standard.rb +93 -0
- data/lib/pubid/cie/identifiers/supplement.rb +47 -0
- data/lib/pubid/cie/identifiers/tutorial_bundle.rb +24 -0
- data/lib/pubid/cie/identifiers.rb +19 -0
- data/lib/pubid/cie/parser.rb +396 -0
- data/lib/pubid/cie/single_identifier.rb +69 -0
- data/lib/pubid/cie/supplement_identifier.rb +39 -0
- data/lib/pubid/cie/urn_generator.rb +126 -0
- data/lib/pubid/cie/urn_parser.rb +28 -0
- data/lib/pubid/cie.rb +83 -0
- data/lib/pubid/components/adoption.rb +104 -0
- data/lib/pubid/components/code.rb +47 -0
- data/lib/pubid/components/date.rb +72 -0
- data/lib/pubid/components/edition.rb +35 -0
- data/lib/pubid/components/iteration.rb +32 -0
- data/lib/pubid/components/language.rb +39 -0
- data/lib/pubid/components/locality.rb +19 -0
- data/lib/pubid/components/publisher.rb +39 -0
- data/lib/pubid/components/relationship.rb +151 -0
- data/lib/pubid/components/stage.rb +45 -0
- data/lib/pubid/components/supplement.rb +184 -0
- data/lib/pubid/components/type.rb +48 -0
- data/lib/pubid/components/typed_stage.rb +58 -0
- data/lib/pubid/components.rb +19 -0
- data/lib/pubid/core/pattern_doc_generator.rb +272 -0
- data/lib/pubid/core/update_codes.rb +98 -0
- data/lib/pubid/core.rb +8 -0
- data/lib/pubid/csa/builder.rb +671 -0
- data/lib/pubid/csa/components/code.rb +9 -0
- data/lib/pubid/csa/components.rb +9 -0
- data/lib/pubid/csa/composite_identifier.rb +38 -0
- data/lib/pubid/csa/identifier.rb +570 -0
- data/lib/pubid/csa/identifiers/base.rb +10 -0
- data/lib/pubid/csa/identifiers/bundled.rb +141 -0
- data/lib/pubid/csa/identifiers/canadian_adopted.rb +82 -0
- data/lib/pubid/csa/identifiers/cec.rb +66 -0
- data/lib/pubid/csa/identifiers/combined.rb +158 -0
- data/lib/pubid/csa/identifiers/csa_adopted.rb +78 -0
- data/lib/pubid/csa/identifiers/package.rb +65 -0
- data/lib/pubid/csa/identifiers/series.rb +23 -0
- data/lib/pubid/csa/identifiers/standard.rb +10 -0
- data/lib/pubid/csa/identifiers.rb +17 -0
- data/lib/pubid/csa/parser.rb +449 -0
- data/lib/pubid/csa/renderer.rb +300 -0
- data/lib/pubid/csa/single_identifier.rb +119 -0
- data/lib/pubid/csa/urn_generator.rb +87 -0
- data/lib/pubid/csa/urn_parser.rb +33 -0
- data/lib/pubid/csa/wrapper_identifier.rb +64 -0
- data/lib/pubid/csa.rb +80 -0
- 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 +55 -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 +52 -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 +67 -0
- data/lib/pubid/errors.rb +79 -0
- data/lib/pubid/etsi/builder.rb +142 -0
- data/lib/pubid/etsi/components/code.rb +43 -0
- data/lib/pubid/etsi/components/version.rb +32 -0
- data/lib/pubid/etsi/components.rb +10 -0
- data/lib/pubid/etsi/identifier.rb +4 -0
- data/lib/pubid/etsi/identifiers/amendment.rb +15 -0
- data/lib/pubid/etsi/identifiers/base.rb +74 -0
- data/lib/pubid/etsi/identifiers/corrigendum.rb +15 -0
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +222 -0
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +123 -0
- data/lib/pubid/etsi/identifiers.rb +13 -0
- data/lib/pubid/etsi/parser.rb +139 -0
- data/lib/pubid/etsi/renderer.rb +48 -0
- data/lib/pubid/etsi/urn_generator.rb +76 -0
- data/lib/pubid/etsi/urn_parser.rb +34 -0
- data/lib/pubid/etsi.rb +71 -0
- data/lib/pubid/export/auditor.rb +89 -0
- data/lib/pubid/export/exporter.rb +33 -0
- data/lib/pubid/export/flavor_exporter.rb +250 -0
- data/lib/pubid/export/result.rb +97 -0
- data/lib/pubid/export.rb +12 -0
- data/lib/pubid/format_detector.rb +16 -0
- data/lib/pubid/format_registry.rb +42 -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 +87 -0
- data/lib/pubid/gost/builder.rb +148 -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 +49 -0
- data/lib/pubid/iala/builder.rb +102 -0
- data/lib/pubid/iala/identifier.rb +90 -0
- data/lib/pubid/iala/identifiers/advice.rb +15 -0
- data/lib/pubid/iala/identifiers/annex.rb +57 -0
- data/lib/pubid/iala/identifiers/general_assembly.rb +19 -0
- data/lib/pubid/iala/identifiers/guideline.rb +17 -0
- data/lib/pubid/iala/identifiers/letter.rb +16 -0
- data/lib/pubid/iala/identifiers/manual.rb +18 -0
- data/lib/pubid/iala/identifiers/model_course.rb +17 -0
- data/lib/pubid/iala/identifiers/recommendation.rb +17 -0
- data/lib/pubid/iala/identifiers/report.rb +16 -0
- data/lib/pubid/iala/identifiers/resolution.rb +16 -0
- data/lib/pubid/iala/identifiers/standard.rb +17 -0
- data/lib/pubid/iala/identifiers.rb +19 -0
- data/lib/pubid/iala/parser.rb +138 -0
- data/lib/pubid/iala/renderer.rb +36 -0
- data/lib/pubid/iala/urn_generator.rb +49 -0
- data/lib/pubid/iala/urn_parser.rb +67 -0
- data/lib/pubid/iala.rb +71 -0
- 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 +69 -0
- data/lib/pubid/identifier.rb +1118 -0
- data/lib/pubid/identifier_metadata.rb +148 -0
- data/lib/pubid/idf/builder.rb +82 -0
- data/lib/pubid/idf/identifier.rb +79 -0
- data/lib/pubid/idf/identifiers/amendment.rb +28 -0
- data/lib/pubid/idf/identifiers/corrigendum.rb +28 -0
- data/lib/pubid/idf/identifiers/international_standard.rb +124 -0
- data/lib/pubid/idf/identifiers/reviewed_method.rb +101 -0
- data/lib/pubid/idf/identifiers.rb +13 -0
- data/lib/pubid/idf/parser.rb +144 -0
- data/lib/pubid/idf/renderer.rb +84 -0
- data/lib/pubid/idf/single_identifier.rb +19 -0
- data/lib/pubid/idf/supplement_identifier.rb +35 -0
- data/lib/pubid/idf/urn_generator.rb +49 -0
- data/lib/pubid/idf/urn_parser.rb +25 -0
- data/lib/pubid/idf.rb +89 -0
- data/lib/pubid/iec/builder.rb +458 -0
- data/lib/pubid/iec/components/code.rb +36 -0
- data/lib/pubid/iec/components/consolidated_amendment.rb +59 -0
- data/lib/pubid/iec/components/publisher.rb +35 -0
- data/lib/pubid/iec/components/sheet.rb +32 -0
- data/lib/pubid/iec/components/trf_info.rb +38 -0
- data/lib/pubid/iec/components/vap_suffix.rb +41 -0
- data/lib/pubid/iec/components.rb +14 -0
- data/lib/pubid/iec/identifier.rb +341 -0
- data/lib/pubid/iec/identifiers/amendment.rb +97 -0
- data/lib/pubid/iec/identifiers/base.rb +54 -0
- data/lib/pubid/iec/identifiers/component_specification.rb +29 -0
- data/lib/pubid/iec/identifiers/conformity_assessment.rb +28 -0
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +85 -0
- data/lib/pubid/iec/identifiers/corrigendum.rb +93 -0
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +148 -0
- data/lib/pubid/iec/identifiers/guide.rb +86 -0
- data/lib/pubid/iec/identifiers/international_standard.rb +162 -0
- data/lib/pubid/iec/identifiers/interpretation_sheet.rb +103 -0
- data/lib/pubid/iec/identifiers/operational_document.rb +29 -0
- data/lib/pubid/iec/identifiers/publicly_available_specification.rb +88 -0
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +68 -0
- data/lib/pubid/iec/identifiers/societal_technology_trend_report.rb +30 -0
- data/lib/pubid/iec/identifiers/systems_reference_document.rb +29 -0
- data/lib/pubid/iec/identifiers/technical_group.rb +30 -0
- data/lib/pubid/iec/identifiers/technical_report.rb +114 -0
- data/lib/pubid/iec/identifiers/technical_specification.rb +114 -0
- data/lib/pubid/iec/identifiers/technology_report.rb +28 -0
- data/lib/pubid/iec/identifiers/test_report_form.rb +35 -0
- data/lib/pubid/iec/identifiers/vap_identifier.rb +76 -0
- data/lib/pubid/iec/identifiers/white_paper.rb +29 -0
- data/lib/pubid/iec/identifiers/working_document.rb +62 -0
- data/lib/pubid/iec/identifiers.rb +31 -0
- data/lib/pubid/iec/parser.rb +443 -0
- data/lib/pubid/iec/renderer.rb +267 -0
- data/lib/pubid/iec/rendering_style.rb +113 -0
- data/lib/pubid/iec/single_identifier.rb +72 -0
- data/lib/pubid/iec/supplement_identifier.rb +178 -0
- data/lib/pubid/iec/urn_generator.rb +245 -0
- data/lib/pubid/iec/urn_parser.rb +128 -0
- data/lib/pubid/iec.rb +64 -0
- data/lib/pubid/ieee/aiee/builder.rb +85 -0
- data/lib/pubid/ieee/aiee/identifier.rb +89 -0
- data/lib/pubid/ieee/aiee/parser.rb +130 -0
- data/lib/pubid/ieee/aiee.rb +11 -0
- data/lib/pubid/ieee/builder.rb +1554 -0
- data/lib/pubid/ieee/compaction.rb +121 -0
- data/lib/pubid/ieee/components/code.rb +110 -0
- data/lib/pubid/ieee/components/draft.rb +147 -0
- data/lib/pubid/ieee/components/relationship.rb +13 -0
- data/lib/pubid/ieee/components/typed_stage.rb +100 -0
- data/lib/pubid/ieee/identifier.rb +5 -0
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +81 -0
- data/lib/pubid/ieee/identifiers/amendment.rb +40 -0
- data/lib/pubid/ieee/identifiers/base.rb +384 -0
- data/lib/pubid/ieee/identifiers/code_number.rb +82 -0
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +29 -0
- data/lib/pubid/ieee/identifiers/corrigendum.rb +40 -0
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +62 -0
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +14 -0
- data/lib/pubid/ieee/identifiers/dual_published.rb +79 -0
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +115 -0
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +48 -0
- data/lib/pubid/ieee/identifiers/joint_development.rb +223 -0
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +85 -0
- data/lib/pubid/ieee/identifiers/nesc/base.rb +127 -0
- data/lib/pubid/ieee/identifiers/nesc/draft.rb +43 -0
- data/lib/pubid/ieee/identifiers/nesc/edition.rb +32 -0
- data/lib/pubid/ieee/identifiers/nesc/handbook.rb +43 -0
- data/lib/pubid/ieee/identifiers/nesc/redline.rb +35 -0
- data/lib/pubid/ieee/identifiers/nesc/standard.rb +41 -0
- data/lib/pubid/ieee/identifiers/nesc.rb +16 -0
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +14 -0
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +49 -0
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +26 -0
- data/lib/pubid/ieee/identifiers/si_standard.rb +38 -0
- data/lib/pubid/ieee/identifiers/standard.rb +44 -0
- data/lib/pubid/ieee/identifiers/supplement_identifier.rb +42 -0
- data/lib/pubid/ieee/identifiers.rb +34 -0
- data/lib/pubid/ieee/ire/builder.rb +62 -0
- data/lib/pubid/ieee/ire/identifier.rb +73 -0
- data/lib/pubid/ieee/ire/parser.rb +91 -0
- data/lib/pubid/ieee/ire.rb +11 -0
- data/lib/pubid/ieee/nesc/builder.rb +114 -0
- data/lib/pubid/ieee/nesc/parser.rb +155 -0
- data/lib/pubid/ieee/nesc.rb +10 -0
- data/lib/pubid/ieee/parser.rb +1644 -0
- data/lib/pubid/ieee/pre_parser.rb +301 -0
- data/lib/pubid/ieee/renderer.rb +408 -0
- data/lib/pubid/ieee/typed_stages.rb +183 -0
- data/lib/pubid/ieee/urn_generator.rb +215 -0
- data/lib/pubid/ieee/urn_parser.rb +34 -0
- data/lib/pubid/ieee.rb +163 -0
- data/lib/pubid/ieee_debug.rb +30 -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 +85 -0
- data/lib/pubid/iho/builder.rb +37 -0
- data/lib/pubid/iho/identifier.rb +7 -0
- data/lib/pubid/iho/identifiers/base.rb +75 -0
- data/lib/pubid/iho/identifiers/bibliographic.rb +16 -0
- data/lib/pubid/iho/identifiers/circular_letter.rb +15 -0
- data/lib/pubid/iho/identifiers/miscellaneous.rb +16 -0
- data/lib/pubid/iho/identifiers/publication.rb +15 -0
- data/lib/pubid/iho/identifiers/standard.rb +15 -0
- data/lib/pubid/iho/identifiers.rb +13 -0
- data/lib/pubid/iho/parser.rb +68 -0
- data/lib/pubid/iho/renderer.rb +30 -0
- data/lib/pubid/iho/urn_generator.rb +29 -0
- data/lib/pubid/iho/urn_parser.rb +58 -0
- data/lib/pubid/iho.rb +77 -0
- 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 +52 -0
- data/lib/pubid/iso/builder.rb +316 -0
- data/lib/pubid/iso/bundled_identifier.rb +138 -0
- data/lib/pubid/iso/combined_identifier.rb +24 -0
- data/lib/pubid/iso/components/code.rb +24 -0
- data/lib/pubid/iso/components/publisher.rb +62 -0
- data/lib/pubid/iso/components.rb +10 -0
- data/lib/pubid/iso/format_resolver.rb +45 -0
- data/lib/pubid/iso/identifier.rb +318 -0
- data/lib/pubid/iso/identifiers/addendum.rb +107 -0
- data/lib/pubid/iso/identifiers/amendment.rb +132 -0
- data/lib/pubid/iso/identifiers/corrigendum.rb +108 -0
- data/lib/pubid/iso/identifiers/data.rb +75 -0
- data/lib/pubid/iso/identifiers/directives.rb +65 -0
- data/lib/pubid/iso/identifiers/directives_supplement.rb +148 -0
- data/lib/pubid/iso/identifiers/extract.rb +30 -0
- data/lib/pubid/iso/identifiers/guide.rb +99 -0
- data/lib/pubid/iso/identifiers/international_standard.rb +168 -0
- data/lib/pubid/iso/identifiers/international_standardized_profile.rb +94 -0
- data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +95 -0
- data/lib/pubid/iso/identifiers/pas.rb +93 -0
- data/lib/pubid/iso/identifiers/recommendation.rb +45 -0
- data/lib/pubid/iso/identifiers/supplement.rb +95 -0
- data/lib/pubid/iso/identifiers/tc_document.rb +137 -0
- data/lib/pubid/iso/identifiers/technical_report.rb +103 -0
- data/lib/pubid/iso/identifiers/technical_specification.rb +102 -0
- data/lib/pubid/iso/identifiers/technology_trends_assessments.rb +95 -0
- data/lib/pubid/iso/identifiers.rb +32 -0
- data/lib/pubid/iso/normalizer.rb +89 -0
- data/lib/pubid/iso/parser.rb +534 -0
- data/lib/pubid/iso/rendering_style.rb +120 -0
- data/lib/pubid/iso/single_identifier.rb +60 -0
- data/lib/pubid/iso/supplement_identifier.rb +53 -0
- data/lib/pubid/iso/urn_generator.rb +313 -0
- data/lib/pubid/iso/urn_parser.rb +442 -0
- data/lib/pubid/iso/utilities.rb +86 -0
- data/lib/pubid/iso.rb +236 -0
- data/lib/pubid/itu/builder.rb +360 -0
- data/lib/pubid/itu/components/code.rb +84 -0
- data/lib/pubid/itu/components/designation.rb +35 -0
- data/lib/pubid/itu/components/sector.rb +46 -0
- data/lib/pubid/itu/components/series.rb +25 -0
- data/lib/pubid/itu/components.rb +12 -0
- data/lib/pubid/itu/i18n.rb +9 -0
- data/lib/pubid/itu/i18n.yaml +30 -0
- data/lib/pubid/itu/identifier.rb +4 -0
- data/lib/pubid/itu/identifiers/addendum.rb +15 -0
- data/lib/pubid/itu/identifiers/amendment.rb +19 -0
- data/lib/pubid/itu/identifiers/annex.rb +83 -0
- 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 +482 -0
- data/lib/pubid/itu/identifiers/combined_identifier.rb +121 -0
- data/lib/pubid/itu/identifiers/corrigendum.rb +35 -0
- 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 +15 -0
- data/lib/pubid/itu/identifiers/report.rb +39 -0
- data/lib/pubid/itu/identifiers/special_publication.rb +31 -0
- data/lib/pubid/itu/identifiers/standard_serialization.rb +58 -0
- data/lib/pubid/itu/identifiers/supplement.rb +149 -0
- data/lib/pubid/itu/identifiers.rb +25 -0
- data/lib/pubid/itu/model.rb +111 -0
- data/lib/pubid/itu/parser.rb +679 -0
- data/lib/pubid/itu/urn_generator.rb +135 -0
- data/lib/pubid/itu/urn_parser.rb +31 -0
- data/lib/pubid/itu.rb +78 -0
- data/lib/pubid/jcgm/builder.rb +106 -0
- data/lib/pubid/jcgm/components/publisher.rb +20 -0
- data/lib/pubid/jcgm/components.rb +9 -0
- data/lib/pubid/jcgm/identifier.rb +21 -0
- data/lib/pubid/jcgm/identifiers/amendment.rb +24 -0
- data/lib/pubid/jcgm/identifiers/corrigendum.rb +34 -0
- data/lib/pubid/jcgm/identifiers/guide.rb +21 -0
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +39 -0
- data/lib/pubid/jcgm/identifiers/meeting.rb +47 -0
- data/lib/pubid/jcgm/identifiers.rb +13 -0
- data/lib/pubid/jcgm/parser.rb +151 -0
- data/lib/pubid/jcgm/renderer.rb +89 -0
- data/lib/pubid/jcgm/single_identifier.rb +118 -0
- data/lib/pubid/jcgm/supplement_identifier.rb +51 -0
- data/lib/pubid/jcgm/urn_generator.rb +116 -0
- data/lib/pubid/jcgm/urn_parser.rb +177 -0
- data/lib/pubid/jcgm.rb +86 -0
- data/lib/pubid/jis/builder.rb +116 -0
- data/lib/pubid/jis/identifier.rb +194 -0
- data/lib/pubid/jis/identifiers/amendment.rb +16 -0
- data/lib/pubid/jis/identifiers/corrigendum.rb +16 -0
- data/lib/pubid/jis/identifiers/explanation.rb +22 -0
- data/lib/pubid/jis/identifiers/japanese_industrial_standard.rb +16 -0
- data/lib/pubid/jis/identifiers/standard.rb +28 -0
- data/lib/pubid/jis/identifiers/technical_report.rb +32 -0
- data/lib/pubid/jis/identifiers/technical_specification.rb +32 -0
- data/lib/pubid/jis/identifiers.rb +17 -0
- data/lib/pubid/jis/parser.rb +135 -0
- data/lib/pubid/jis/renderer.rb +69 -0
- data/lib/pubid/jis/single_identifier.rb +31 -0
- data/lib/pubid/jis/supplement_identifier.rb +50 -0
- data/lib/pubid/jis/urn_generator.rb +25 -0
- data/lib/pubid/jis/urn_parser.rb +23 -0
- data/lib/pubid/jis.rb +69 -0
- data/lib/pubid/lutaml/no_store_registration.rb +30 -0
- data/lib/pubid/nist/builder.rb +481 -0
- data/lib/pubid/nist/caster.rb +1234 -0
- data/lib/pubid/nist/circular_supplement_builder.rb +293 -0
- data/lib/pubid/nist/components/code.rb +27 -0
- data/lib/pubid/nist/components/edition.rb +134 -0
- data/lib/pubid/nist/components/issue_number.rb +28 -0
- data/lib/pubid/nist/components/part.rb +77 -0
- data/lib/pubid/nist/components/stage.rb +53 -0
- data/lib/pubid/nist/components/supplement.rb +191 -0
- data/lib/pubid/nist/components/translation.rb +42 -0
- data/lib/pubid/nist/components/update.rb +103 -0
- data/lib/pubid/nist/components/version.rb +35 -0
- data/lib/pubid/nist/components/volume.rb +32 -0
- data/lib/pubid/nist/components.rb +18 -0
- data/lib/pubid/nist/configuration.rb +87 -0
- data/lib/pubid/nist/identifier.rb +8 -0
- data/lib/pubid/nist/identifiers/base.rb +744 -0
- data/lib/pubid/nist/identifiers/circular.rb +80 -0
- data/lib/pubid/nist/identifiers/circular_supplement.rb +60 -0
- data/lib/pubid/nist/identifiers/commercial_standard.rb +42 -0
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +58 -0
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +69 -0
- data/lib/pubid/nist/identifiers/crpl_report.rb +138 -0
- data/lib/pubid/nist/identifiers/dated_document.rb +49 -0
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +95 -0
- data/lib/pubid/nist/identifiers/grant_contractor_report.rb +36 -0
- data/lib/pubid/nist/identifiers/handbook.rb +58 -0
- data/lib/pubid/nist/identifiers/internal_report.rb +64 -0
- data/lib/pubid/nist/identifiers/letter_circular.rb +46 -0
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +74 -0
- data/lib/pubid/nist/identifiers/monograph.rb +80 -0
- data/lib/pubid/nist/identifiers/ncstar.rb +41 -0
- data/lib/pubid/nist/identifiers/nsrds.rb +41 -0
- data/lib/pubid/nist/identifiers/owmwp.rb +35 -0
- data/lib/pubid/nist/identifiers/report.rb +77 -0
- data/lib/pubid/nist/identifiers/special_publication.rb +46 -0
- data/lib/pubid/nist/identifiers/technical_note.rb +91 -0
- data/lib/pubid/nist/identifiers.rb +33 -0
- data/lib/pubid/nist/parser.rb +752 -0
- data/lib/pubid/nist/parser_output_normalizer.rb +233 -0
- data/lib/pubid/nist/preprocessor.rb +443 -0
- data/lib/pubid/nist/renderer.rb +43 -0
- data/lib/pubid/nist/router.rb +149 -0
- data/lib/pubid/nist/series/base.rb +58 -0
- data/lib/pubid/nist/series/crpl.rb +13 -0
- data/lib/pubid/nist/series/fips.rb +14 -0
- data/lib/pubid/nist/series/ir.rb +57 -0
- data/lib/pubid/nist/series/letter_preserving.rb +15 -0
- data/lib/pubid/nist/series/mono.rb +19 -0
- data/lib/pubid/nist/series/ncstar.rb +20 -0
- data/lib/pubid/nist/series.rb +49 -0
- data/lib/pubid/nist/supplement_identifier.rb +84 -0
- data/lib/pubid/nist/urn_generator.rb +133 -0
- data/lib/pubid/nist/urn_parser.rb +67 -0
- data/lib/pubid/nist.rb +138 -0
- 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 +79 -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 +71 -0
- data/lib/pubid/oiml/builder.rb +270 -0
- data/lib/pubid/oiml/components/code.rb +37 -0
- data/lib/pubid/oiml/components.rb +9 -0
- data/lib/pubid/oiml/identifier.rb +64 -0
- data/lib/pubid/oiml/identifiers/amendment.rb +13 -0
- data/lib/pubid/oiml/identifiers/annex.rb +29 -0
- data/lib/pubid/oiml/identifiers/basic_publication.rb +15 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +137 -0
- data/lib/pubid/oiml/identifiers/code_number.rb +90 -0
- data/lib/pubid/oiml/identifiers/document.rb +15 -0
- data/lib/pubid/oiml/identifiers/errata.rb +15 -0
- data/lib/pubid/oiml/identifiers/expert_report.rb +15 -0
- data/lib/pubid/oiml/identifiers/guide.rb +15 -0
- data/lib/pubid/oiml/identifiers/recommendation.rb +15 -0
- data/lib/pubid/oiml/identifiers/seminar_report.rb +15 -0
- data/lib/pubid/oiml/identifiers/vocabulary.rb +15 -0
- data/lib/pubid/oiml/identifiers.rb +20 -0
- data/lib/pubid/oiml/parser.rb +274 -0
- data/lib/pubid/oiml/renderer.rb +232 -0
- data/lib/pubid/oiml/single_identifier.rb +113 -0
- data/lib/pubid/oiml/supplement_identifier.rb +88 -0
- data/lib/pubid/oiml/urn_generator.rb +78 -0
- data/lib/pubid/oiml/urn_parser.rb +39 -0
- data/lib/pubid/oiml.rb +81 -0
- data/lib/pubid/omg/builder.rb +19 -0
- data/lib/pubid/omg/identifier.rb +47 -0
- data/lib/pubid/omg/identifiers/specification.rb +32 -0
- data/lib/pubid/omg/identifiers.rb +9 -0
- data/lib/pubid/omg/parser.rb +40 -0
- data/lib/pubid/omg/renderer.rb +19 -0
- data/lib/pubid/omg.rb +51 -0
- data/lib/pubid/parser/common_parse_methods.rb +13 -0
- data/lib/pubid/parser/common_parse_rules.rb +56 -0
- data/lib/pubid/parser/grammar.rb +74 -0
- data/lib/pubid/parser.rb +9 -0
- data/lib/pubid/parsers/base.rb +11 -0
- data/lib/pubid/parsers/mr_string.rb +206 -0
- data/lib/pubid/plateau/builder.rb +54 -0
- data/lib/pubid/plateau/identifier.rb +4 -0
- data/lib/pubid/plateau/identifiers/annex.rb +16 -0
- data/lib/pubid/plateau/identifiers/base.rb +55 -0
- data/lib/pubid/plateau/identifiers/handbook.rb +28 -0
- data/lib/pubid/plateau/identifiers/technical_report.rb +16 -0
- data/lib/pubid/plateau/identifiers.rb +11 -0
- data/lib/pubid/plateau/parser.rb +73 -0
- data/lib/pubid/plateau/renderer.rb +51 -0
- data/lib/pubid/plateau/supplement_identifier.rb +68 -0
- data/lib/pubid/plateau/urn_generator.rb +29 -0
- data/lib/pubid/plateau/urn_parser.rb +43 -0
- data/lib/pubid/plateau.rb +82 -0
- data/lib/pubid/prefixes_support.rb +51 -0
- data/lib/pubid/renderers/annotator.rb +233 -0
- data/lib/pubid/renderers/base.rb +66 -0
- data/lib/pubid/renderers/directives_renderer.rb +75 -0
- data/lib/pubid/renderers/guide_renderer.rb +26 -0
- data/lib/pubid/renderers/human_readable.rb +83 -0
- data/lib/pubid/renderers/iwa_renderer.rb +20 -0
- data/lib/pubid/renderers/mr_string.rb +64 -0
- data/lib/pubid/renderers/supplement_renderer.rb +36 -0
- data/lib/pubid/renderers/urn.rb +11 -0
- data/lib/pubid/renderers.rb +15 -0
- data/lib/pubid/rendering/context.rb +168 -0
- data/lib/pubid/rendering/date.rb +27 -0
- data/lib/pubid/rendering/language.rb +21 -0
- data/lib/pubid/rendering/numbering.rb +42 -0
- data/lib/pubid/rendering/publisher.rb +25 -0
- data/lib/pubid/rendering/stage.rb +38 -0
- data/lib/pubid/rendering/supplement.rb +46 -0
- data/lib/pubid/rendering.rb +13 -0
- data/lib/pubid/sae/builder.rb +32 -0
- data/lib/pubid/sae/components/code.rb +9 -0
- data/lib/pubid/sae/components/date.rb +27 -0
- data/lib/pubid/sae/components/type.rb +23 -0
- data/lib/pubid/sae/components.rb +11 -0
- data/lib/pubid/sae/identifier.rb +4 -0
- data/lib/pubid/sae/identifiers/base.rb +47 -0
- data/lib/pubid/sae/identifiers.rb +8 -0
- data/lib/pubid/sae/parser.rb +55 -0
- data/lib/pubid/sae/renderer.rb +36 -0
- data/lib/pubid/sae/urn_generator.rb +30 -0
- data/lib/pubid/sae/urn_parser.rb +36 -0
- data/lib/pubid/sae.rb +66 -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 +83 -0
- data/lib/pubid/type_resolver.rb +59 -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 +46 -0
- data/lib/pubid/urn_generator/base.rb +110 -0
- data/lib/pubid/urn_parser/base.rb +81 -0
- data/lib/pubid/urn_parser/errors.rb +16 -0
- data/lib/pubid/urn_parser.rb +14 -0
- data/lib/pubid/utils/string_normalizer.rb +196 -0
- data/lib/pubid/utils.rb +7 -0
- data/lib/pubid/version.rb +3 -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 +67 -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 +25 -0
- data/lib/pubid/xsf/renderer.rb +23 -0
- data/lib/pubid/xsf/urn_generator.rb +13 -0
- data/lib/pubid/xsf/urn_parser.rb +18 -0
- data/lib/pubid/xsf.rb +81 -0
- data/lib/pubid.rb +551 -13
- data/lib/tasks/docs.rake +37 -0
- data/lib/tasks/export.rake +39 -0
- data/lib/tasks/website-data.json +7546 -0
- metadata +875 -171
- data/lib/pubid/registry.rb +0 -30
|
@@ -0,0 +1,1644 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parslet"
|
|
4
|
+
|
|
5
|
+
module Pubid
|
|
6
|
+
module Ieee
|
|
7
|
+
# Parser class for IEEE identifiers
|
|
8
|
+
# Single Responsibility: Parsing IEEE identifier syntax
|
|
9
|
+
# Note: IEEE is extremely complex with many edge cases
|
|
10
|
+
class Parser < ::Pubid::Parser::Grammar
|
|
11
|
+
# Basic building blocks
|
|
12
|
+
rule(:space) { str(" ") }
|
|
13
|
+
rule(:space?) { space.maybe }
|
|
14
|
+
rule(:dash) { str("-") }
|
|
15
|
+
rule(:dash?) { dash.maybe }
|
|
16
|
+
rule(:dot) { str(".") }
|
|
17
|
+
rule(:slash) { str("/") }
|
|
18
|
+
rule(:comma) { str(", ") }
|
|
19
|
+
rule(:digit) { match("[0-9]") }
|
|
20
|
+
rule(:digits) { digit.repeat(1) }
|
|
21
|
+
rule(:letter) { match("[A-Za-z]") }
|
|
22
|
+
rule(:upper) { match("[A-Z]") }
|
|
23
|
+
rule(:lower) { match("[a-z]") }
|
|
24
|
+
|
|
25
|
+
# Year pattern (4 digits starting with 19 or 20), optionally followed by letter(s)
|
|
26
|
+
# e.g. 2012, 201x, 2010a
|
|
27
|
+
rule(:year_digits) do
|
|
28
|
+
(str("19") | str("20")) >> digit.repeat(2,
|
|
29
|
+
2) >> lower.repeat(0,
|
|
30
|
+
2) >> digits.absent?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Month patterns - numeric format (01-12)
|
|
34
|
+
rule(:month_numeric) do
|
|
35
|
+
(str("0") >> match("[1-9]")) | # 01-09
|
|
36
|
+
(str("1") >> match("[0-2]")) # 10-12
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Comprehensive date parsing
|
|
40
|
+
# Format 1: "September 2018" or "Sept 2018" (text month + year)
|
|
41
|
+
rule(:date_with_month_text) do
|
|
42
|
+
month_name.as(:month) >> space >> year_digits.as(:year)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Format 2: "2018-09" (year-numeric month)
|
|
46
|
+
rule(:date_with_month_numeric) do
|
|
47
|
+
year_digits.as(:year) >> dash >> month_numeric.as(:month)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Format 3: Just year "2018"
|
|
51
|
+
rule(:date_year_only) do
|
|
52
|
+
year_digits.as(:year)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Combined date rule - longest match first
|
|
56
|
+
rule(:date_standalone) do
|
|
57
|
+
date_with_month_text | date_with_month_numeric | date_year_only
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Trailing print/reaffirm date "<sep>Month YYYY" — captured under the
|
|
61
|
+
# distinct :trailing_month/:trailing_year keys so it never collides with a
|
|
62
|
+
# base -YYYY identity year (the builder promotes it only when no base year
|
|
63
|
+
# exists). Accepts BOTH a month name ("May 2014") and a month-first numeric
|
|
64
|
+
# month ("05 2014"). The two variants are unambiguous: month_name never
|
|
65
|
+
# starts with a digit, and month_numeric (01-12) never matches a bare
|
|
66
|
+
# 19xx/20xx year — so a bare trailing year still falls through to callers'
|
|
67
|
+
# own bare-year clause.
|
|
68
|
+
rule(:trailing_month_year) do
|
|
69
|
+
# The numeric branch accepts `-` as well as space before the year:
|
|
70
|
+
# preprocessing (the `(\d)\s+(\d{4})` gsub) rewrites a trailing
|
|
71
|
+
# "05 2014" → "05-2014", so a numeric month reaches the grammar
|
|
72
|
+
# dash-joined; the month-name branch escapes that gsub (the char before
|
|
73
|
+
# the space is a letter) and stays space-joined.
|
|
74
|
+
((comma | space) >> month_name.as(:trailing_month) >> space >> year_digits.as(:trailing_year)) |
|
|
75
|
+
((comma | space) >> month_numeric.as(:trailing_month) >> (space | dash) >> year_digits.as(:trailing_year))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Month patterns
|
|
79
|
+
rule(:month_name) do
|
|
80
|
+
# Period-suffixed abbreviations (longest first)
|
|
81
|
+
str("Sept.") | str("Oct.") | str("Nov.") | str("Dec.") |
|
|
82
|
+
str("Jan.") | str("Feb.") | str("Mar.") | str("Apr.") |
|
|
83
|
+
str("Jun.") | str("Jul.") | str("Aug.") |
|
|
84
|
+
# Full month names
|
|
85
|
+
str("January") | str("February") | str("March") | str("April") |
|
|
86
|
+
str("May") | str("June") | str("July") | str("August") |
|
|
87
|
+
str("September") | str("October") | str("November") | str("December") |
|
|
88
|
+
# Non-period abbreviations
|
|
89
|
+
str("Jan") | str("Feb") | str("Mar") | str("Apr") | str("Jun") |
|
|
90
|
+
str("Jul") | str("Aug") | str("Sep") | str("Sept") | str("Oct") | str("Nov") | str("Dec")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Organizations
|
|
94
|
+
rule(:organization) do
|
|
95
|
+
str("IEEE") | str("AIEE") | str("ANSI") | str("ASA") |
|
|
96
|
+
# ANS (American Nuclear Society) — a third co-publisher on nuclear
|
|
97
|
+
# standards ("ANSI/IEEE/ANS 7.4-3-2-1982"). Listed AFTER ANSI so it
|
|
98
|
+
# never shadows the longer token.
|
|
99
|
+
str("ANS") |
|
|
100
|
+
str("IEC") | str("ISO") | str("ASTM") | str("CSA") | str("ASME") |
|
|
101
|
+
str("NACE") | str("NSF") | str("ASHRAE") | str("NCTA") | str("AESC") |
|
|
102
|
+
str("EIA") | # NEW Session 224: Add EIA support
|
|
103
|
+
# Historical / foreign co-publishers seen in relaton-data-ieee
|
|
104
|
+
# (bucket 4): AMPP, USAS (both standalone), and the IEEE sub-board /
|
|
105
|
+
# partner co-publishers USEMCSC, EAB, MPAI.
|
|
106
|
+
str("USEMCSC") | str("AMPP") | str("USAS") | str("EAB") | str("MPAI")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Complex organization prefixes (Category 5: ANSI Complex)
|
|
110
|
+
rule(:complex_org_prefix) do
|
|
111
|
+
str("ANSI/IEEE-ANS") | str("ANSI/IEEE") | str("ANSI")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Characteristic IEEE number patterns (without prefix)
|
|
115
|
+
# These patterns are distinctly IEEE even without "IEEE Std" prefix
|
|
116
|
+
rule(:characteristic_ieee_number) do
|
|
117
|
+
# C37.xxx series (power systems) - C followed by 2 digits, dot, more digits
|
|
118
|
+
(str("C") >> digit.repeat(2,
|
|
119
|
+
2) >> dot >> digits >> match("[a-z]").repeat.maybe) |
|
|
120
|
+
# 802.xxx series (networking) - 802 followed by dot, digits, optional letter suffix
|
|
121
|
+
(str("802") >> dot >> digits >> match("[a-z]").repeat.maybe) |
|
|
122
|
+
# P followed by digits (draft projects)
|
|
123
|
+
(str("P") >> digits.repeat(1))
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
rule(:publisher) do
|
|
127
|
+
complex_org_prefix.as(:publisher) | organization.as(:publisher)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
rule(:copublisher) do
|
|
131
|
+
# Three-way copublisher strings (treat as single unit, longest first)
|
|
132
|
+
str("/ISO/IEC").as(:copublisher) |
|
|
133
|
+
str("/IEC/ISO").as(:copublisher) |
|
|
134
|
+
# Two-way copublishers (original pattern)
|
|
135
|
+
(slash >> space? >> organization.as(:copublisher))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Conformance document patterns (/Conformance01-2003, /Conformance02-2014)
|
|
139
|
+
# Allow optional space before slash for malformed inputs
|
|
140
|
+
rule(:conformance) do
|
|
141
|
+
(space? >> slash >> str("Conformance") >> match("[0-9]").repeat(1).as(:conf_number) >> dash >> year_digits.as(:conf_year)).as(:conformance)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# ASHRAE joint publication patterns (/ASHRAE Guideline 21-2012)
|
|
145
|
+
# Also handles /ASHRAE 21 without "Guideline"
|
|
146
|
+
rule(:ashrae_copub) do
|
|
147
|
+
(slash >> str("ASHRAE") >> space >>
|
|
148
|
+
(str("Guideline") >> space).maybe >>
|
|
149
|
+
digits.as(:ashrae_number) >>
|
|
150
|
+
(dash >> year_digits.as(:ashrae_year)).maybe).as(:ashrae_copub)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# IEEE cross-reference patterns (/C62.22.1-1996)
|
|
154
|
+
# References another IEEE standard from a specific series (e.g., C62, C37, C57)
|
|
155
|
+
rule(:ieee_crossref) do
|
|
156
|
+
(slash >> str("C") >> digits >> dot >> digits >> dot >> digits >> dash >> year_digits).as(:ieee_crossref)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# IPCEA co-designation suffix (/IPCEA P-46-426-1962). Captured verbatim
|
|
160
|
+
# (leading slash included) so it round-trips through the `crossref`
|
|
161
|
+
# attribute. Used only by the S-designation rule below.
|
|
162
|
+
rule(:ipcea_copub) do
|
|
163
|
+
(slash >> str("IPCEA") >> space >>
|
|
164
|
+
match('[A-Za-z0-9.\-]').repeat(1)).as(:ipcea_copub)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Historical IEEE/IPCEA co-published cable designation (e.g. S-135).
|
|
168
|
+
# The "S-<digits>" number has a dash between the letter series and the
|
|
169
|
+
# digits, which the shared `number` rule deliberately rejects (that
|
|
170
|
+
# tightening is what keeps a bare "IEEE S" from parsing). So this one-off
|
|
171
|
+
# family gets its own rule rather than loosening `number` and risking the
|
|
172
|
+
# 12k-row corpus. Requiring `str("S") >> dash >> digits` keeps "IEEE S"
|
|
173
|
+
# (no dash+digit) rejected. Handles: "IEEE Std S-135", "IEEE S-135",
|
|
174
|
+
# bare "S-135", the "/IPCEA …" slash co-designation, and the
|
|
175
|
+
# "(IPCEA …)" parenthetical variant.
|
|
176
|
+
rule(:s_designation) do
|
|
177
|
+
(publisher >> space).maybe >>
|
|
178
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
179
|
+
(str("S") >> dash >> digits).as(:s_number) >>
|
|
180
|
+
ipcea_copub.maybe >>
|
|
181
|
+
parenthetical.maybe
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Document number - support letters and digits, with optional prefix P
|
|
185
|
+
# Complex multi-part numbers like P11073-10404-10419 should be fully captured
|
|
186
|
+
# But simple cases like "623-1976" should not consume the dash before year
|
|
187
|
+
rule(:number) do
|
|
188
|
+
(str("P").maybe >>
|
|
189
|
+
# The numeric core must contain at least one digit: an optional letter
|
|
190
|
+
# prefix (C, S, …) then a required `digits` run, then any digit/letter
|
|
191
|
+
# tail. The old `(digits | upper).repeat(1)` wrongly accepted an
|
|
192
|
+
# all-letter token like a bare "S" (a prefix with no number — e.g.
|
|
193
|
+
# "IEEE S"), which is not a valid IEEE identifier.
|
|
194
|
+
upper.repeat(0) >> digits >> (digits | upper).repeat(0) >>
|
|
195
|
+
# Only consume dash+digits if followed by another dash+digits (multi-part pattern)
|
|
196
|
+
# OR if the digits don't look like a year (not 4 digits starting with 19/20)
|
|
197
|
+
# This prevents consuming "623-1976" as a number but allows "P11073-10404-10419"
|
|
198
|
+
(dash >> digits >> year_digits.absent? >> (dash >> digits).repeat).maybe >>
|
|
199
|
+
lower.maybe).as(:number)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Type - handle "No." and "No" (case-insensitive), longest first
|
|
203
|
+
rule(:type_word) do
|
|
204
|
+
str("Draft Std") | str("STD") | str("Standard") |
|
|
205
|
+
str("Std No.") | str("Std") | # Add "Std No." before "Std"
|
|
206
|
+
str("PTC") | # ASME Performance Test Code
|
|
207
|
+
(match("[Nn]") >> str("o.")) | (match("[Nn]") >> str("o")) |
|
|
208
|
+
str("No")
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Part and subpart - handle both dot and dash separators
|
|
212
|
+
rule(:part) do
|
|
213
|
+
(dot | dash) >> match("[0-9A-Za-z]").repeat(1).as(:part)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
rule(:subpart) do
|
|
217
|
+
(dot | dash | str("_")) >>
|
|
218
|
+
((str("REV") | str("Rev")).maybe >> match("[0-9a-z]").repeat(1) >>
|
|
219
|
+
(dot >> digits).maybe).as(:subpart)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Year component - updated to use comprehensive date parsing
|
|
223
|
+
rule(:year) do
|
|
224
|
+
(dot | dash) >> date_standalone >> str("(E)").maybe
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Draft patterns
|
|
228
|
+
rule(:draft_status) do
|
|
229
|
+
# "Active" (bucket 3) joins the generic draft-status path so
|
|
230
|
+
# "IEEE Active Std P… /D…" parses like the "Unapproved" forms, without
|
|
231
|
+
# touching ieee_approved_draft_identifier (which would break the
|
|
232
|
+
# issue-#209 unapproved-drops-Std rendering). "Active Approved" completes
|
|
233
|
+
# the two-word matrix alongside "Active Unapproved" (draft-grammar
|
|
234
|
+
# coverage: the "<status> Draft P…/D…" prefix forms). Longest token first.
|
|
235
|
+
(str("Active Unapproved") | str("Active Approved") | str("Unapproved") |
|
|
236
|
+
str("Approved") | str("Active")) >> space
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
rule(:draft_prefix) do
|
|
240
|
+
space? >> (str("/") | str("_") | dash | space)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
rule(:draft_version) do
|
|
244
|
+
# Enhanced to handle multiple draft notation patterns
|
|
245
|
+
# D is optional to handle /08 style drafts (e.g., IEEE P1052/08)
|
|
246
|
+
# A draft never begins with "R-" — that is the revision suffix
|
|
247
|
+
# (revision_suffix rule); guard so the D-less path doesn't swallow a
|
|
248
|
+
# bare "/R-<id>" (e.g. the no-draft "P1722/R-1") as a draft.
|
|
249
|
+
(str("R") >> dash).absent? >>
|
|
250
|
+
(str("D") >> str("IS").absent?).maybe >> # Avoid matching "DIS" (ISO stage)
|
|
251
|
+
(
|
|
252
|
+
# Pattern: D3.1 (decimal with 1-2 digits on each side) - MOST COMMON, put first
|
|
253
|
+
# Also handles trailing letter: D7.3A, D2.0E
|
|
254
|
+
(match("[0-9]").repeat(1,
|
|
255
|
+
2) >> dot >> match("[0-9]").repeat(1,
|
|
256
|
+
2) >> lower.maybe) |
|
|
257
|
+
# Pattern: D.XX (decimal starting with dot) - e.g., D.19
|
|
258
|
+
(dot >> digits) |
|
|
259
|
+
# Pattern: DX+X (plus sign) - e.g., D1+1
|
|
260
|
+
(digits >> str("+") >> digits) |
|
|
261
|
+
# Pattern: DXXXXeYY or DXXXX.eYY (complex) - e.g., D2012.e27
|
|
262
|
+
(digits >> dot.maybe >> str("e") >> digits) |
|
|
263
|
+
# Pattern: D-X or DX or DX-d or DX_letter (original patterns)
|
|
264
|
+
# Handles: D12, D3.0, D043Rev18, suffixes like D15Sept
|
|
265
|
+
(str("-").maybe >> match("[0-9A-Za-z]").repeat(1) >> (str("-d") | (str("_") >> match("[0-9A-Za-z]").repeat(0))).maybe)
|
|
266
|
+
).as(:draft_version)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
rule(:draft_date) do
|
|
270
|
+
# Enhanced to handle: ", Sept 2008" or " Sept 2008" or ", Month Year"
|
|
271
|
+
((comma | space) >> month_name.as(:month) >> space >> year_digits.as(:year)) |
|
|
272
|
+
# Numeric-month form ", 05 2007" / " 05 2007" — no text month name. The
|
|
273
|
+
# year separator may be a dash: preprocessing (parser.rb ~1278) rewrites
|
|
274
|
+
# a trailing " <digits> <year>" to "<digits>-<year>", so "05 2007"
|
|
275
|
+
# reaches the grammar as "05-2007".
|
|
276
|
+
((comma | space) >> month_numeric.as(:month) >> (space | dash) >> year_digits.as(:year)) |
|
|
277
|
+
(((space? >> comma >> space?) | space) >> month_name.as(:month) >>
|
|
278
|
+
(
|
|
279
|
+
# "Month DD, Year" (day then comma) and "Month DD Year" (day, no
|
|
280
|
+
# comma) — the day/year separator may be a dash for the same
|
|
281
|
+
# preprocessing reason ("July 15 2012" → "July 15-2012").
|
|
282
|
+
((space >> digits.as(:day)) >> ((comma | space | dash) >> year_digits.as(:year))) |
|
|
283
|
+
((space >> digits.as(:day)).maybe >> comma >> year_digits.as(:year)) |
|
|
284
|
+
(comma >> space? >> year_digits.as(:year)) |
|
|
285
|
+
(space >> year_digits.as(:year))
|
|
286
|
+
))
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# FDIS and similar ISO stage codes without D prefix (Pattern 3)
|
|
290
|
+
# These appear after / in IEEE P identifiers but don't have the D prefix
|
|
291
|
+
# Examples: IEEE P15939/FDIS, IEEE P1234/CDV
|
|
292
|
+
rule(:fdraft) do
|
|
293
|
+
(slash >>
|
|
294
|
+
(str("FDIS") | str("CDV") | str("CD") | str("WD") | str("PWI") | str("NP")) >>
|
|
295
|
+
(
|
|
296
|
+
((comma | space) >> month_name.as(:month) >> space >> year_digits.as(:year)) | # Month Year
|
|
297
|
+
((comma | space) >> year_digits.as(:year)) # Year only (e.g., /FDIS, 2016)
|
|
298
|
+
).maybe >>
|
|
299
|
+
parenthetical.maybe).as(:fdraft)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
rule(:draft) do
|
|
303
|
+
(draft_prefix >> draft_version.repeat(1, 2) >>
|
|
304
|
+
(dot >> digits.as(:revision)).maybe >>
|
|
305
|
+
draft_date.maybe).as(:draft)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Trailing revision suffix "/R-<id>". Normalization funnels every revision
|
|
309
|
+
# spelling here — IEEE's native inline "Rev<n>" (repositioned) and
|
|
310
|
+
# relaton's synthetic "/R-<x>" (kept in place) — so a single trailing rule
|
|
311
|
+
# captures them all. The id is alphanumeric ("2", "18", "i").
|
|
312
|
+
rule(:revision_suffix) do
|
|
313
|
+
slash >> str("R") >> dash >> match('[0-9A-Za-z]').repeat(1).as(:revision)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Edition - enhanced to support IEC formats like "Edition 1.0 2015-03"
|
|
317
|
+
#
|
|
318
|
+
# The edition's own year is captured as :edition_year (NOT :year). The
|
|
319
|
+
# generic Std branch carries a base "-YYYY" slot AND a separate trailing
|
|
320
|
+
# `edition.maybe`; a bare :year here would collide with the base :year
|
|
321
|
+
# when both fire, so Parslet warns "Duplicate subtrees … keys: [:year]"
|
|
322
|
+
# and drops the base identity year (the same failure #299 fixed for the
|
|
323
|
+
# trailing month/year clause). The builder promotes :edition_year to the
|
|
324
|
+
# identity year only when there is no base year.
|
|
325
|
+
rule(:edition) do
|
|
326
|
+
(comma >> year_digits.as(:edition_year) >> str(" Edition")) |
|
|
327
|
+
((space | dash) >> str("Edition ") >>
|
|
328
|
+
(digits >> dot >> digits).as(:edition) >>
|
|
329
|
+
# Year separator: a space, " - ", or a bare dash (preprocessing
|
|
330
|
+
# rewrites "Edition 3.0 2016" -> "Edition 3.0-2016", the shape the
|
|
331
|
+
# normalized "/E-<n>-YYYY" suffix produces — nil-residue item 1).
|
|
332
|
+
(str(" - ") | space | dash) >>
|
|
333
|
+
year_digits.as(:edition_year) >>
|
|
334
|
+
(dash >> digit.repeat(2, 2).as(:edition_month)).maybe) # Capture -MM as edition_month
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Part/subpart/year combinations
|
|
338
|
+
rule(:part_subpart_year) do
|
|
339
|
+
(part >> subpart.repeat(1, 2) >> year) |
|
|
340
|
+
(part >> subpart >> year) |
|
|
341
|
+
(part >> year) |
|
|
342
|
+
(part >> subpart) |
|
|
343
|
+
year |
|
|
344
|
+
part
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# Corrigendum
|
|
348
|
+
rule(:corrigendum) do
|
|
349
|
+
# Enhanced: Accept space as separator, make separators more flexible
|
|
350
|
+
# Also accept "Corrigendum" as alternative to "Cor"
|
|
351
|
+
((str("_") | slash | dash | space) >>
|
|
352
|
+
(str("Corrigendum") | str("Cor")) >>
|
|
353
|
+
(dash | dot | space).maybe >> # More flexible separator after "Cor"
|
|
354
|
+
space? >> # Add space handling after separator
|
|
355
|
+
digits.as(:cor_number).maybe >>
|
|
356
|
+
((dash | str(":") | space) >> year_digits.as(:cor_year)).maybe).as(:corrigendum)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Amendment — mirrors the corrigendum rule's separator flexibility so
|
|
360
|
+
# IEEE-format "/Amd 2-2004" and "/Amd2-2004" parse the same way as
|
|
361
|
+
# their Cor counterparts (issue #210).
|
|
362
|
+
rule(:amendment) do
|
|
363
|
+
((str("_") | slash | dash | space) >>
|
|
364
|
+
(str("Amendment") | str("Amd")) >>
|
|
365
|
+
(dash | dot | space).maybe >>
|
|
366
|
+
space? >>
|
|
367
|
+
digits.as(:amd_number).maybe >>
|
|
368
|
+
((dash | str(":") | space) >> year_digits.as(:amd_year)).maybe).as(:amendment)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Interpretation notation (/INT)
|
|
372
|
+
# Enhanced to support optional year suffix: /INT-1991, /INT 1991
|
|
373
|
+
rule(:interpretation) do
|
|
374
|
+
(slash >> str("INT") >> ((dash | str(":") | space) >> year_digits.as(:int_year)).maybe).as(:interpretation)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# Reaffirmed - enhanced to support (R1992) format without space
|
|
378
|
+
rule(:reaffirmed) do
|
|
379
|
+
(
|
|
380
|
+
# Format: "Reaffirmed 1992"
|
|
381
|
+
(str("Reaffirmed ") >> year_digits.as(:year)) |
|
|
382
|
+
# Format: "(R1992)" - parentheses with R prefix (with or without space before)
|
|
383
|
+
(space.maybe >> str("(R") >> year_digits.as(:year) >> str(")"))
|
|
384
|
+
).as(:reaffirmed)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Redline suffix at the very end. Accepts relaton's canonical " Redline"
|
|
388
|
+
# (space, no dash) and pubid's older " - Redline" (space-dash-space),
|
|
389
|
+
# case-insensitive. Captured (presence only) so the builder sets a
|
|
390
|
+
# `redline: true` flag the renderer restores — a redline is a distinct
|
|
391
|
+
# document and must not collapse to its base standard.
|
|
392
|
+
rule(:redline) do
|
|
393
|
+
(space >> (dash >> space).maybe >>
|
|
394
|
+
(str("Redline") | str("REDLINE") | str("redline"))).as(:redline)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Book nickname (e.g., "[The Orange Book]", "[IEEE Gold Book]")
|
|
398
|
+
rule(:book_nickname) do
|
|
399
|
+
space >> str("[") >> match("[^\\]]").repeat(1).as(:nickname) >> str("]")
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Relationship type keywords for Pattern 4 identifiers
|
|
403
|
+
rule(:relationship_revision_of) do
|
|
404
|
+
str("Revision of ") | str("Revison of ")
|
|
405
|
+
end
|
|
406
|
+
rule(:relationship_amendment_to) { str("Amendment to ") }
|
|
407
|
+
rule(:relationship_corrigendum_to) do
|
|
408
|
+
str("Corrigendum to ") | str("Corrigenda to ")
|
|
409
|
+
end
|
|
410
|
+
rule(:relationship_incorporates) do
|
|
411
|
+
str("incorporates ") | str("Incorporating ") | str("Incorporates ")
|
|
412
|
+
end
|
|
413
|
+
rule(:relationship_adoption_of) { str("Adoption of ") }
|
|
414
|
+
rule(:relationship_supplement_to) { str("Supplement to ") }
|
|
415
|
+
rule(:relationship_draft_amendment) do
|
|
416
|
+
str("Draft Amendment to ") | str("DRAFT Amendment to ")
|
|
417
|
+
end
|
|
418
|
+
rule(:relationship_draft_revision) { str("Draft Revision of ") }
|
|
419
|
+
rule(:relationship_reaffirmation) { str("Reaffirmation of ") }
|
|
420
|
+
rule(:relationship_redesignation) do
|
|
421
|
+
str("Redesignation of ") | str("redesignated as ")
|
|
422
|
+
end
|
|
423
|
+
rule(:relationship_supersedes) { str("Supersedes ") | str("Supercedes ") }
|
|
424
|
+
rule(:relationship_previously_designated) do
|
|
425
|
+
str("Previously designated as ")
|
|
426
|
+
end
|
|
427
|
+
rule(:relationship_includes) { str("Includes ") } # NEW Session 171
|
|
428
|
+
|
|
429
|
+
# Combined relationship type (longest match first)
|
|
430
|
+
rule(:relationship_type) do
|
|
431
|
+
relationship_draft_amendment.as(:draft_amendment_to) |
|
|
432
|
+
relationship_draft_revision.as(:draft_revision_of) |
|
|
433
|
+
relationship_previously_designated.as(:previously_designated_as) |
|
|
434
|
+
relationship_reaffirmation.as(:reaffirmation_of) |
|
|
435
|
+
relationship_redesignation.as(:redesignation_of) |
|
|
436
|
+
relationship_supersedes.as(:supersedes) |
|
|
437
|
+
relationship_includes.as(:includes) | # NEW Session 171
|
|
438
|
+
relationship_revision_of.as(:revision_of) |
|
|
439
|
+
relationship_amendment_to.as(:amendment_to) |
|
|
440
|
+
relationship_corrigendum_to.as(:corrigendum_to) |
|
|
441
|
+
relationship_incorporates.as(:incorporates) |
|
|
442
|
+
relationship_adoption_of.as(:adoption_of) |
|
|
443
|
+
relationship_supplement_to.as(:supplement_to)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Identifier string (for parsing list of related identifiers)
|
|
447
|
+
# Captures text until delimiter: comma, closing paren, "and", " / ", "; ", "as amended by"
|
|
448
|
+
# Uses absent? to ensure we stop at these delimiters
|
|
449
|
+
rule(:identifier_string) do
|
|
450
|
+
(
|
|
451
|
+
str(", and ").absent? >>
|
|
452
|
+
str(" and ").absent? >>
|
|
453
|
+
str(", ").absent? >>
|
|
454
|
+
str(" as amended by ").absent? >>
|
|
455
|
+
# Stop at any "/", ";", or "-" that introduces another relationship
|
|
456
|
+
# (look-ahead: separator + relationship_type keyword). This lets the
|
|
457
|
+
# slash inside "IEEE Std 525-2007/Cor 1-2015" stay part of the
|
|
458
|
+
# identifier, while the slash before "Incorporates ..." splits.
|
|
459
|
+
relationship_break.absent? >>
|
|
460
|
+
str(")").absent? >>
|
|
461
|
+
match(".")
|
|
462
|
+
).repeat(1)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# Identifier list (comma and "and" separated)
|
|
466
|
+
rule(:identifier_list) do
|
|
467
|
+
identifier_string.as(:id) >>
|
|
468
|
+
(
|
|
469
|
+
(str(", and ") | str(" and ") | str(", ")) >>
|
|
470
|
+
identifier_string.as(:id)
|
|
471
|
+
).repeat
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# "as amended by" clause with identifier list
|
|
475
|
+
rule(:as_amended_by_clause) do
|
|
476
|
+
# Variant 1: "as amended by IEEE's X, Y, Z"
|
|
477
|
+
(str(" as amended by IEEE's ") >> identifier_list.as(:amendments)) |
|
|
478
|
+
# Variant 2: "as amended by X, Y, Z" (standard)
|
|
479
|
+
(str(" as amended by ") >> identifier_list.as(:amendments)) |
|
|
480
|
+
# Variant 3: "and its approved amendments" (no specific list)
|
|
481
|
+
str(" and its approved amendments").as(:approved_amendments)
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# A character sequence that may separate two relationships inside the
|
|
485
|
+
# parenthetical: a "/", ";", or "-" with optional surrounding spaces.
|
|
486
|
+
# Standalone it is permissive — the actual decision to split is gated by
|
|
487
|
+
# `relationship_break`, which requires another relationship_type to
|
|
488
|
+
# follow. This way the slash in "IEEE Std 525-2007/Cor 1-2015" stays
|
|
489
|
+
# part of the related identifier.
|
|
490
|
+
rule(:relationship_separator) do
|
|
491
|
+
(space.maybe >> str("/") >> space.maybe) |
|
|
492
|
+
(space.maybe >> str(";") >> space.maybe) |
|
|
493
|
+
(space.maybe >> str("-") >> space.maybe)
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# Look-ahead: a separator followed by another relationship_type keyword.
|
|
497
|
+
# Used as an absent? guard in identifier_string so the parser stops
|
|
498
|
+
# consuming characters right before a new relationship begins.
|
|
499
|
+
rule(:relationship_break) do
|
|
500
|
+
relationship_separator >> space.maybe >> relationship_type
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
# Relationship clause (handles all relationship types)
|
|
504
|
+
rule(:relationship_clause) do
|
|
505
|
+
space.maybe >> str("(") >>
|
|
506
|
+
relationship_type.as(:relationship_type) >>
|
|
507
|
+
identifier_list.as(:related_ids) >>
|
|
508
|
+
as_amended_by_clause.maybe >>
|
|
509
|
+
# Additional relationships separated by "/", ";", or "-" (optionally
|
|
510
|
+
# surrounded by spaces). The separator is only honored when followed
|
|
511
|
+
# by another relationship_type — identifier-internal slashes like
|
|
512
|
+
# "/Cor 1-2015" are not mistaken for relationship breaks because
|
|
513
|
+
# identifier_string stops at relationship_break ahead.
|
|
514
|
+
(
|
|
515
|
+
relationship_separator >>
|
|
516
|
+
relationship_type.as(:relationship_type) >>
|
|
517
|
+
identifier_list.as(:related_ids) >>
|
|
518
|
+
as_amended_by_clause.maybe
|
|
519
|
+
).repeat.as(:additional_rels) >>
|
|
520
|
+
str(")")
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
# Title portion separated by colon (Category 8)
|
|
524
|
+
rule(:title_portion) do
|
|
525
|
+
str(":") >> space >> match('[^\n]').repeat(1).as(:title)
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
# Approved Draft suffix (Category 7)
|
|
529
|
+
rule(:approved_draft_suffix) do
|
|
530
|
+
(space >> str("- (Approved Draft)")) | (space >> str("(Approved Draft)"))
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
# Additional parameters (inside parentheses)
|
|
534
|
+
rule(:additional_parameters) do
|
|
535
|
+
(space.maybe >> str("(") >> # Make space before '(' optional
|
|
536
|
+
(reaffirmed |
|
|
537
|
+
# Handle "Revision of IEEE Std ..." with optional space after Std
|
|
538
|
+
(str("Revision of IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:revision_of)) |
|
|
539
|
+
# Handle typo "Revison of IEEE Std ..." with optional space after Std
|
|
540
|
+
(str("Revison of IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:revision_of)) |
|
|
541
|
+
# Handle "Revision to IEEE Std ..." with optional space after Std
|
|
542
|
+
(str("Revision to IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:revision_of)) |
|
|
543
|
+
# Handle "Revison to IEEE Std ..." with optional space after Std
|
|
544
|
+
(str("Revison to IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:revision_of)) |
|
|
545
|
+
# Amendment patterns (case-insensitive DRAFT)
|
|
546
|
+
((str("DRAFT") | str("Draft") | str("draft")) >> str(" Amendment to ") >> match("[^)]").repeat(1).as(:draft_amendment_to)) |
|
|
547
|
+
(str("Amendment to IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:amendment_to)) |
|
|
548
|
+
# Adoption patterns
|
|
549
|
+
(str("Adoption of ") >> match("[^)]").repeat(1).as(:adoption)) |
|
|
550
|
+
# Other specific patterns
|
|
551
|
+
(str("Notebooks") >> space? >> match("[^,\\)]").repeat(1).as(:notebooks)) |
|
|
552
|
+
(str("Standard Newspaper(s)") >> space? >> match("[^,\\)]").repeat(1).as(:standard_newspapers)) |
|
|
553
|
+
# Catch-all for any other parenthetical content (MUST BE LAST)
|
|
554
|
+
match("[^)]").repeat(1).as(:parenthetical_content)
|
|
555
|
+
) >>
|
|
556
|
+
str(")").maybe).as(:parameters)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
# Parenthetical - try relationship_clause first, then fall back to additional_parameters
|
|
560
|
+
rule(:parenthetical) do
|
|
561
|
+
relationship_clause | additional_parameters
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
# IEC/IEEE copublished pattern - handle all variations comprehensively
|
|
565
|
+
# BUT exclude P prefix patterns (those are joint development)
|
|
566
|
+
rule(:iec_ieee_copublished) do
|
|
567
|
+
str("IEC/IEEE") >>
|
|
568
|
+
space >>
|
|
569
|
+
str("P").absent? >> # NOT a P prefix (would be joint development)
|
|
570
|
+
# The copublished number must contain at least one digit. This rejects
|
|
571
|
+
# an all-letter placeholder like "IEC/IEEE TR" (no real document
|
|
572
|
+
# number) — the same "require a digit" tightening the Standard number
|
|
573
|
+
# rule got, applied to the copublished number grammar.
|
|
574
|
+
(match("[^0-9\n]").repeat >> digit).present? >>
|
|
575
|
+
match("[^\n]").repeat(1).as(:content)
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
# Joint development patterns (ISO/IEC/IEEE in either IEEE or ISO format)
|
|
579
|
+
rule(:joint_development_ieee_format) do
|
|
580
|
+
# ISO/IEC/IEEE P26511/D8-2018 or ISO/IEEE P1003.1-2008 or IEC/IEEE P62582-1-2011
|
|
581
|
+
# ALSO handle: IEC/IEEE P60780-323, CDV1 2014 (comma before stage code)
|
|
582
|
+
# ALSO handle: IEEE/CSA P844.1/293.1/D2 (CSA dual numbering)
|
|
583
|
+
(str("ISO/IEC/IEEE") | str("ISO/IEEE") | str("IEC/IEEE") | str("IEEE/CSA")).as(:joint_publishers) >>
|
|
584
|
+
space >>
|
|
585
|
+
str("P") >> # P indicates IEEE-led
|
|
586
|
+
digits.as(:number) >>
|
|
587
|
+
((dot | dash) >> digits.as(:part)).maybe >> # Optional part like .1 or -1
|
|
588
|
+
# CSA dual numbering: /293.1 (second number)
|
|
589
|
+
(slash >> digits >> (dot >> digits).maybe >> (dash >> digits.as(:draft_version)).maybe).maybe >>
|
|
590
|
+
(
|
|
591
|
+
# Variant 1: /D8 notation (original)
|
|
592
|
+
(slash >> str("D") >> digits.as(:draft_version)) |
|
|
593
|
+
# Variant 2: , CDV1 notation (comma before stage code)
|
|
594
|
+
(comma >> (str("CDV") | str("FDIS") | str("CD") | str("DIS")).as(:iec_stage) >> digits.maybe.as(:stage_iteration))
|
|
595
|
+
).maybe >>
|
|
596
|
+
# Optional edition, from relaton's "/E-<n>" suffix normalized to
|
|
597
|
+
# "Edition <n>.0[ YYYY]" (nil-residue hand-off item 1). The edition
|
|
598
|
+
# rule carries its own year, so the year clause below simply doesn't
|
|
599
|
+
# fire when an edition is present.
|
|
600
|
+
edition.maybe >>
|
|
601
|
+
((dash >> year_digits.as(:year)) | # Either -YEAR
|
|
602
|
+
(comma.maybe >> space >> month_name.as(:month) >> space.maybe >> year_digits.as(:year))).maybe >> # Or Month YEAR (with optional comma)
|
|
603
|
+
revision_suffix.maybe
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
rule(:joint_development_iso_format) do
|
|
607
|
+
# ISO-led stage designations. Two spellings:
|
|
608
|
+
# colon form : "ISO/IEC/IEEE FDIS 26511:2018" (already used)
|
|
609
|
+
# corpus form : "ISO/IEC/IEEE FDIS P26515-2018-05" (historical)
|
|
610
|
+
# The corpus form adds a leading "P" on the number, a trailing
|
|
611
|
+
# "-YYYY[-MM]" date (instead of ":YYYY"), multi-digit committee-draft
|
|
612
|
+
# stage codes (CD1..CD4) plus CDV, and a wider set of joint publishers.
|
|
613
|
+
# (roadmap items 2/3, phase 1). longest publisher token first.
|
|
614
|
+
(str("ISO/IEC/IEEE") | str("IEEE/ISO/IEC") | str("IEEE/IEC/ISO") |
|
|
615
|
+
str("ISO/IEEE") | str("IEC/IEEE") | str("IEEE/IEC") | str("ISO/IEC") |
|
|
616
|
+
str("IEEE")).as(:joint_publishers) >>
|
|
617
|
+
space >>
|
|
618
|
+
# ISO stage codes: FDIS, FCD, CDV; DIS/CD with an optional round digit
|
|
619
|
+
# (DIS2, CD1..CD4); WD/PWI/NP. (FCD before FDIS is fine — distinct.)
|
|
620
|
+
(str("FDIS") | str("FCD") | str("CDV") |
|
|
621
|
+
(str("DIS") >> digit.maybe) |
|
|
622
|
+
(str("CD") >> digit.maybe) |
|
|
623
|
+
str("WD") | str("PWI") | str("NP")).as(:iso_stage) >>
|
|
624
|
+
# optional " Std" noise word after the stage (e.g. "FDIS Std P15288")
|
|
625
|
+
(space >> str("Std")).maybe >>
|
|
626
|
+
space >>
|
|
627
|
+
str("P").maybe >> # optional project marker on the number
|
|
628
|
+
digits.as(:number) >>
|
|
629
|
+
# part must not swallow the trailing year (year_digits.absent?)
|
|
630
|
+
((dot | dash) >> year_digits.absent? >> digits.as(:part)).maybe >>
|
|
631
|
+
(
|
|
632
|
+
(str(":") >> year_digits.as(:year)) |
|
|
633
|
+
(dash >> year_digits.as(:year) >>
|
|
634
|
+
(dash >> month_numeric.as(:month)).maybe) |
|
|
635
|
+
# Trailing text date ", April 2015" / " April 2015" (build_joint_development
|
|
636
|
+
# already reads :month/:year). No :year collision — the iso rule has no
|
|
637
|
+
# other :year capture (edition uses :edition_year).
|
|
638
|
+
((comma | space) >> month_name.as(:month) >> space >> year_digits.as(:year))
|
|
639
|
+
).maybe >>
|
|
640
|
+
# Optional /D<draft> tail. normalize_relaton_suffixes repositions the
|
|
641
|
+
# historical "…/D-3-2017" onto the number as "…-2017/D3", so by the
|
|
642
|
+
# time this rule runs the draft usually trails the date (bucket 5);
|
|
643
|
+
# a date-less "/D-4" keeps its hyphen (bucket 7), hence dash.maybe.
|
|
644
|
+
(slash >> str("D") >> dash.maybe >>
|
|
645
|
+
match('[0-9.]').repeat(1).as(:draft_version)).maybe >>
|
|
646
|
+
# Optional edition, from relaton's "/E-<n>" suffix normalized to
|
|
647
|
+
# "Edition <n>.0[ YYYY]" (nil-residue hand-off item 1).
|
|
648
|
+
edition.maybe >>
|
|
649
|
+
revision_suffix.maybe
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
# Embedded (stage-LAST) ISO-led designations: the corpus writes the ISO
|
|
653
|
+
# stage AFTER the (dotted or dashed) part —
|
|
654
|
+
# "ISO/IEC/IEEE 29119.4.FDIS, April 2015" (dot part .4, stage .FDIS)
|
|
655
|
+
# "ISO/IEC/IEEE 24748-5.CD3, February 2015" (dash part -5, stage .CD3)
|
|
656
|
+
# "IEEE P24748.5.CD3, July 2015" (bare IEEE + P)
|
|
657
|
+
# — rather than before the number (joint_development_iso_format). Same
|
|
658
|
+
# meaning as the stage-first form: `29119.4`/`29119-4` = "29119 part 4" and
|
|
659
|
+
# the trailing `.FDIS` is the ISO stage, NOT a second part. Routes through
|
|
660
|
+
# the same build_joint_development (via :joint_publishers/:iso_stage), so the
|
|
661
|
+
# stage is modeled correctly and the numeric part stays separate.
|
|
662
|
+
rule(:joint_development_embedded_stage) do
|
|
663
|
+
# publisher set mirrors joint_development_iso_format (incl. bare IEEE);
|
|
664
|
+
# longest token first.
|
|
665
|
+
(str("ISO/IEC/IEEE") | str("IEEE/ISO/IEC") | str("IEEE/IEC/ISO") |
|
|
666
|
+
str("ISO/IEEE") | str("IEC/IEEE") | str("IEEE/IEC") | str("ISO/IEC") |
|
|
667
|
+
str("IEEE")).as(:joint_publishers) >>
|
|
668
|
+
space >>
|
|
669
|
+
str("P").maybe >> # optional project marker on the number
|
|
670
|
+
digits.as(:number) >>
|
|
671
|
+
# optional numeric part (dot or dash); must not swallow a year
|
|
672
|
+
((dot | dash) >> year_digits.absent? >> digits.as(:part)).maybe >>
|
|
673
|
+
# the embedded stage, dot-separated, closed vocab (same as iso_stage).
|
|
674
|
+
# The (digit|letter) look-ahead keeps it at a token boundary so "CD"
|
|
675
|
+
# can't match inside a longer token and a glued no-space date
|
|
676
|
+
# (".DISMay2013") is left to fall through.
|
|
677
|
+
dot >>
|
|
678
|
+
(str("FDIS") | str("FCD") | str("CDV") |
|
|
679
|
+
(str("DIS") >> digit.maybe) |
|
|
680
|
+
(str("CD") >> digit.maybe) |
|
|
681
|
+
str("WD") | str("PWI") | str("NP")).as(:iso_stage) >>
|
|
682
|
+
(digit | match("[A-Za-z]")).absent? >>
|
|
683
|
+
# optional trailing date: :YYYY, -YYYY[-MM], or text "Month YYYY"
|
|
684
|
+
(
|
|
685
|
+
(str(":") >> year_digits.as(:year)) |
|
|
686
|
+
(dash >> year_digits.as(:year) >>
|
|
687
|
+
(dash >> month_numeric.as(:month)).maybe) |
|
|
688
|
+
((comma | space) >> month_name.as(:month) >> space >> year_digits.as(:year))
|
|
689
|
+
).maybe
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
# Number-first pattern: "1873-2015 IEEE Standard..."
|
|
693
|
+
rule(:number_first_identifier) do
|
|
694
|
+
number >>
|
|
695
|
+
(dash >> year_digits.as(:year)).maybe >>
|
|
696
|
+
space >>
|
|
697
|
+
(publisher >> copublisher.repeat.as(:copublishers)).as(:publishers) >>
|
|
698
|
+
space >>
|
|
699
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
700
|
+
match("[^\n]").repeat(0).as(:title)
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
# IEEE P pattern (without Std): "IEEE P1003.1..." OR just "P1003.1..." (prefix optional)
|
|
704
|
+
rule(:ieee_p_identifier) do
|
|
705
|
+
(str("IEEE").as(:publisher) >> space).maybe >> # Make IEEE prefix optional
|
|
706
|
+
str("P") >> space.maybe >> # Make space after P optional
|
|
707
|
+
number >>
|
|
708
|
+
(part_subpart_year | edition).maybe >>
|
|
709
|
+
# Pattern for /08 style drafts (digits without D prefix) - MUST come before corrigendum
|
|
710
|
+
(slash >> digits.as(:draft_version)).as(:digit_draft).maybe >>
|
|
711
|
+
# FDIS and other ISO stage codes without D prefix (Pattern 3)
|
|
712
|
+
fdraft.maybe >>
|
|
713
|
+
# Trailing "Month YYYY" print/reaffirm date. Captured under distinct
|
|
714
|
+
# keys so it never collides with the base -YYYY identity year (a
|
|
715
|
+
# collision made Parslet drop the base year and warn "Duplicate
|
|
716
|
+
# subtrees … keys: [:year]"). The builder promotes it to the identity
|
|
717
|
+
# only when there is no base year.
|
|
718
|
+
trailing_month_year.maybe >>
|
|
719
|
+
corrigendum.maybe >>
|
|
720
|
+
draft.maybe >>
|
|
721
|
+
# Revision trails the draft (before any date), matching normalization's
|
|
722
|
+
# ".../D<n>/R-<x>" repositioning of "P802.16Rev2/D3 Feb 2008".
|
|
723
|
+
revision_suffix.maybe >>
|
|
724
|
+
# ALSO accept month/year after draft (some patterns like /DX, Month YEAR)
|
|
725
|
+
trailing_month_year.maybe >>
|
|
726
|
+
# Trailing corrigendum AFTER the draft+date ("…/D1, Jan 2007/Cor. 1").
|
|
727
|
+
# The draft's own draft_date has already consumed the date, leaving
|
|
728
|
+
# "/Cor. 1" here; the resulting flat corrigendum+draft tree routes to
|
|
729
|
+
# build_flat_corrigendum (disjoint from the pre-draft corrigendum slot,
|
|
730
|
+
# which only fires when no draft precedes it).
|
|
731
|
+
corrigendum.maybe >>
|
|
732
|
+
parenthetical.maybe
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
# ANSI P pattern: "ANSI PN42.34-D9a, 2015" OR "ANSI P1234/D5"
|
|
736
|
+
rule(:ansi_p_identifier) do
|
|
737
|
+
str("ANSI").as(:publisher) >> space >>
|
|
738
|
+
str("P") >> space.maybe >> # Make space after P optional
|
|
739
|
+
number >>
|
|
740
|
+
(part_subpart_year | edition).maybe >>
|
|
741
|
+
# Trailing "Month YYYY"/bare-year date under distinct keys so they
|
|
742
|
+
# never collide with the base -YYYY identity year (see ieee_p_identifier).
|
|
743
|
+
trailing_month_year.maybe >>
|
|
744
|
+
corrigendum.maybe >>
|
|
745
|
+
draft.maybe >>
|
|
746
|
+
revision_suffix.maybe >>
|
|
747
|
+
# ALSO accept month/year after draft
|
|
748
|
+
trailing_month_year.maybe >>
|
|
749
|
+
# Accept bare year after draft: ", 2015"
|
|
750
|
+
((comma | space) >> year_digits.as(:trailing_year)).maybe >>
|
|
751
|
+
# Trailing corrigendum after the draft+date (parity with ieee_p_identifier).
|
|
752
|
+
corrigendum.maybe >>
|
|
753
|
+
parenthetical.maybe
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
# IEEE Draft P pattern: "IEEE Draft P802.11..." OR "Draft P802.11..." (IEEE prefix optional)
|
|
757
|
+
# An optional status phrase may precede "Draft" — "IEEE Unapproved Draft P…",
|
|
758
|
+
# "IEEE Active Approved Draft P…" — the largest index-v2 draft bucket. The
|
|
759
|
+
# status is captured (draft_status ends in a space, so "Approved Draft"
|
|
760
|
+
# splits cleanly) and round-trips as the draft_status attribute; the literal
|
|
761
|
+
# "Draft" stays a bare marker (dropped on render, like the plain form).
|
|
762
|
+
rule(:ieee_draft_p_identifier) do
|
|
763
|
+
(str("IEEE").as(:publisher) >> space).maybe >> # Make IEEE prefix optional
|
|
764
|
+
draft_status.as(:draft_status).maybe >>
|
|
765
|
+
str("Draft") >> space >>
|
|
766
|
+
# `P` is optional — a status-word draft may carry a bare number
|
|
767
|
+
# ("IEEE Unapproved Draft 802.1ah/D4.2"), mirroring
|
|
768
|
+
# ieee_approved_draft_identifier's str("P").maybe. The `number` rule
|
|
769
|
+
# already accepts the bare forms (802.1ah, C57.15, 11073-10471).
|
|
770
|
+
str("P").maybe >>
|
|
771
|
+
number >>
|
|
772
|
+
(part_subpart_year | edition).maybe >>
|
|
773
|
+
# Trailing "Month YYYY" date under distinct keys so it never collides
|
|
774
|
+
# with the base -YYYY identity year (see ieee_p_identifier).
|
|
775
|
+
((space >> month_name.as(:trailing_month) >> space >> year_digits.as(:trailing_year)) |
|
|
776
|
+
(space >> month_numeric.as(:trailing_month) >> (space | dash) >> year_digits.as(:trailing_year))).maybe >>
|
|
777
|
+
draft.maybe >>
|
|
778
|
+
revision_suffix.maybe >>
|
|
779
|
+
# Trailing corrigendum after the draft ("…/D2.0/Cor. 1", or
|
|
780
|
+
# "…/D1.0, Dec 2007/Cor. 1" where the draft's own draft_date consumes
|
|
781
|
+
# the date, leaving "/Cor. N"). The flat corrigendum+draft tree (no
|
|
782
|
+
# :base) routes to build_flat_corrigendum, which rebuilds the base
|
|
783
|
+
# standard (carrying the draft + draft_status) and wraps it.
|
|
784
|
+
corrigendum.maybe >>
|
|
785
|
+
parenthetical.maybe
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
# IEEE Approved Draft pattern: "IEEE Approved Draft Std P..."
|
|
789
|
+
rule(:ieee_approved_draft_identifier) do
|
|
790
|
+
str("IEEE").as(:publisher) >>
|
|
791
|
+
space >>
|
|
792
|
+
str("Approved") >> space >>
|
|
793
|
+
(str("Draft Std") | str("Std")).as(:type) >> space >>
|
|
794
|
+
str("P").maybe >>
|
|
795
|
+
number >>
|
|
796
|
+
(part_subpart_year | edition).maybe >>
|
|
797
|
+
draft.maybe >>
|
|
798
|
+
revision_suffix.maybe >>
|
|
799
|
+
parenthetical.maybe
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
# Combined AIEE identifier pattern: "AIEE No 72-1932 and AIEE No 73-1932"
|
|
803
|
+
# Handles "and"-separated AIEE identifiers (from "Nos X and Y" preprocessing)
|
|
804
|
+
rule(:combined_aiee_identifier) do
|
|
805
|
+
# First AIEE identifier
|
|
806
|
+
Aiee::Parser.new.aiee_identifier.as(:first_aiee) >>
|
|
807
|
+
# "and" separator
|
|
808
|
+
space >> str("and") >> space >>
|
|
809
|
+
# Second AIEE identifier
|
|
810
|
+
Aiee::Parser.new.aiee_identifier.as(:second_aiee)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
# AIEE (American Institute of Electrical Engineers) patterns
|
|
814
|
+
# Detect AIEE patterns and delegate to AIEE parser
|
|
815
|
+
rule(:aiee_identifier) do
|
|
816
|
+
# Lookahead for AIEE patterns - do not consume input
|
|
817
|
+
(
|
|
818
|
+
# IEEE-AIEE transitional pattern
|
|
819
|
+
(str("IEEE-AIEE") >> space >> (str("No.") | str("Nos") | str("No") | str("Standard") | str("Trans."))) |
|
|
820
|
+
# A.I.E.E. pattern (with dots, no spaces)
|
|
821
|
+
(str("A.I.E.E.") >> space >> (str("No.") | str("Nos") | str("No"))) |
|
|
822
|
+
# A. I. E. E. pattern (with dots and spaces)
|
|
823
|
+
(str("A. I. E. E.") >> space >> (str("No.") | str("Nos") | str("No") | str("Standard"))) |
|
|
824
|
+
# AIEE pattern - extended to include more type words
|
|
825
|
+
(str("AIEE") >> space >> (str("No.") | str("Nos") | str("No") | str("Standard") | str("Trans.") | str("Std")))
|
|
826
|
+
).present? >>
|
|
827
|
+
# Delegate to AIEE parser if pattern detected
|
|
828
|
+
Aiee::Parser.new.aiee_identifier.as(:aiee)
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
# IRE (Institute of Radio Engineers) patterns
|
|
832
|
+
# Detect IRE patterns and delegate to IRE parser
|
|
833
|
+
rule(:ire_identifier) do
|
|
834
|
+
# Lookahead for IRE patterns - do not consume input
|
|
835
|
+
(
|
|
836
|
+
# Year-first pattern: "52 IRE 7.S2" or "60 IRE 28 PS7"
|
|
837
|
+
((match("[1-6]") >> digit >> space >> str("IRE")) | # 2-digit year format
|
|
838
|
+
(str("19") >> digit.repeat(2, 2) >> space >> str("IRE"))) |
|
|
839
|
+
# IEEE-IRE transitional pattern
|
|
840
|
+
(str("IEEE-IRE") >> space)
|
|
841
|
+
).present? >>
|
|
842
|
+
# Delegate to IRE parser if pattern detected
|
|
843
|
+
Ire::Parser.new.ire_identifier.as(:ire)
|
|
844
|
+
end
|
|
845
|
+
|
|
846
|
+
# NESC (National Electrical Safety Code) patterns
|
|
847
|
+
# Detect NESC patterns and delegate to NESC parser
|
|
848
|
+
rule(:nesc_identifier) do
|
|
849
|
+
# Lookahead for NESC patterns - do not consume input
|
|
850
|
+
(
|
|
851
|
+
# C2-YYYY pattern
|
|
852
|
+
(str("C2-") >> year_digits) |
|
|
853
|
+
# YYYY NESC pattern
|
|
854
|
+
(year_digits >> space >> (str("NESC") | str("National Electrical Safety Code"))) |
|
|
855
|
+
# Draft NESC pattern
|
|
856
|
+
(str("Draft") >> space >> (str("NESC") | str("National Electrical Safety Code"))) |
|
|
857
|
+
# Name-first pattern (NEW)
|
|
858
|
+
(str("National Electrical Safety Code") >> str(",") >> space >> str("C2-"))
|
|
859
|
+
).present? >>
|
|
860
|
+
# Delegate to NESC parser if pattern detected
|
|
861
|
+
Nesc::Parser.new.nesc_identifier.as(:nesc)
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
# IEEE/ASTM SI/PSI (Système International) patterns
|
|
865
|
+
# SI = Published metric system standard
|
|
866
|
+
# PSI = Proposed SI (draft)
|
|
867
|
+
rule(:ieee_astm_si_psi) do
|
|
868
|
+
str("IEEE/ASTM").as(:publishers) >>
|
|
869
|
+
space >>
|
|
870
|
+
(str("PSI") | str("SI")).as(:si_type) >>
|
|
871
|
+
space >>
|
|
872
|
+
digits.as(:number) >>
|
|
873
|
+
# Draft notation for PSI (e.g., /D2, /D3)
|
|
874
|
+
(slash >> str("D") >> digits.as(:draft_version)).maybe >>
|
|
875
|
+
# Year with optional month
|
|
876
|
+
(
|
|
877
|
+
# Format: ", Month Year"
|
|
878
|
+
(comma >> month_name.as(:month) >> space >> year_digits.as(:year)) |
|
|
879
|
+
# Format: "-YEAR"
|
|
880
|
+
(dash >> year_digits.as(:year))
|
|
881
|
+
).maybe >>
|
|
882
|
+
# Optional parenthetical (revision relationships)
|
|
883
|
+
parenthetical.maybe
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
# No-prefix IEEE identifier (characteristic patterns without "IEEE Std")
|
|
887
|
+
# These are patterns that are distinctly IEEE even without explicit publisher
|
|
888
|
+
rule(:no_prefix_ieee) do
|
|
889
|
+
characteristic_ieee_number.as(:number) >>
|
|
890
|
+
# Optional suffix (like -a, -b)
|
|
891
|
+
(dash >> match("[A-Za-z]")).maybe.as(:suffix) >>
|
|
892
|
+
# Optional year
|
|
893
|
+
(dash >> year_digits).maybe.as(:year) >>
|
|
894
|
+
# Optional draft notation
|
|
895
|
+
draft.maybe >>
|
|
896
|
+
# Optional language portion
|
|
897
|
+
(str("(E)") | str("(F)")).maybe >>
|
|
898
|
+
# Optional parenthetical content
|
|
899
|
+
parenthetical.maybe
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
# Corrigendum identifier with recursive base parsing
|
|
903
|
+
# Captures base identifier for recursive parsing, then corrigendum supplement
|
|
904
|
+
# Example: IEEE Std 535-2013/Cor. 1-2017
|
|
905
|
+
rule(:corrigendum_identifier) do
|
|
906
|
+
# Match a complete base identifier (reuse existing patterns)
|
|
907
|
+
# Try standard patterns that would match "IEEE Std 535-2013"
|
|
908
|
+
(
|
|
909
|
+
((publisher >> copublisher.repeat.as(:copublishers)).as(:publishers) >> space).maybe >>
|
|
910
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
911
|
+
number >>
|
|
912
|
+
part_subpart_year.maybe # This captures the full identifier before /Cor
|
|
913
|
+
).as(:base) >>
|
|
914
|
+
# Now match the corrigendum portion
|
|
915
|
+
(slash | dash | space) >>
|
|
916
|
+
str("Cor") >>
|
|
917
|
+
(dash | dot | space).maybe >> # More flexible separator after "Cor"
|
|
918
|
+
space? >>
|
|
919
|
+
digits.as(:cor_number) >>
|
|
920
|
+
((dash | str(":") | space) >> year_digits.as(:cor_year)).maybe >> # Optional cor year suffix
|
|
921
|
+
parenthetical.maybe
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
# Interpretation identifier with recursive base parsing
|
|
925
|
+
# Captures base identifier for recursive parsing, then interpretation supplement
|
|
926
|
+
# Example: IEEE Std 1076/INT-1991, IEEE Std 1003.1-1988/INT
|
|
927
|
+
rule(:interpretation_identifier) do
|
|
928
|
+
# Match a complete base identifier
|
|
929
|
+
(
|
|
930
|
+
((publisher >> copublisher.repeat.as(:copublishers)).as(:publishers) >> space).maybe >>
|
|
931
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
932
|
+
number >>
|
|
933
|
+
part_subpart_year.maybe
|
|
934
|
+
).as(:base) >>
|
|
935
|
+
# Now match the interpretation portion
|
|
936
|
+
(slash | dash | space) >>
|
|
937
|
+
str("INT") >>
|
|
938
|
+
((dash | str(":") | space) >> year_digits.as(:int_year)).maybe >> # Optional year suffix
|
|
939
|
+
parenthetical.maybe
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
# Conformance identifier with recursive base parsing
|
|
943
|
+
# Captures base identifier for recursive parsing, then conformance supplement
|
|
944
|
+
# Example: IEEE Std 802.16/Conformance01-2003
|
|
945
|
+
rule(:conformance_identifier) do
|
|
946
|
+
# Match a complete base identifier
|
|
947
|
+
(
|
|
948
|
+
((publisher >> copublisher.repeat.as(:copublishers)).as(:publishers) >> space).maybe >>
|
|
949
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
950
|
+
number >>
|
|
951
|
+
part_subpart_year.maybe
|
|
952
|
+
).as(:base) >>
|
|
953
|
+
# Now match the conformance portion
|
|
954
|
+
(slash | dash | space) >>
|
|
955
|
+
str("Conformance") >>
|
|
956
|
+
match("[0-9]").repeat(1).as(:conf_number) >>
|
|
957
|
+
dash >>
|
|
958
|
+
year_digits.as(:conf_year) >>
|
|
959
|
+
parenthetical.maybe
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
# Multi-numbered identifier: same document with multiple numbers
|
|
963
|
+
# Examples: IEEE Std 1299/C62.22.1-1996, IEEE Std 960-1989, Std 1177-1989
|
|
964
|
+
rule(:multi_numbered_identifier) do
|
|
965
|
+
# Primary identifier (full IEEE identifier)
|
|
966
|
+
((
|
|
967
|
+
(publisher >> space).maybe >>
|
|
968
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
969
|
+
number >>
|
|
970
|
+
(part_subpart_year | edition).maybe
|
|
971
|
+
).as(:primary_identifier) >>
|
|
972
|
+
# Separator: slash for cross-ref format, comma for joint standard
|
|
973
|
+
(slash >> str("C") >> digits >> dot >> digits >> dot >> digits >> dash >> year_digits).as(:secondary_crossref)) |
|
|
974
|
+
(comma >> space >> (type_word.as(:type) >> space?).maybe >> number >> dash >> year_digits).as(:secondary_joint)
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
# CSA dual published pattern: IEEE Std 844.1-2017/CSA C22.2 No. 293.1-17
|
|
978
|
+
rule(:csa_dual_published) do
|
|
979
|
+
# IEEE portion (full identifier)
|
|
980
|
+
(
|
|
981
|
+
publisher >> space >>
|
|
982
|
+
(type_word.as(:type) >> space?).maybe >>
|
|
983
|
+
number >>
|
|
984
|
+
(part_subpart_year | edition).maybe
|
|
985
|
+
).as(:ieee_portion) >>
|
|
986
|
+
# CSA portion with slash separator
|
|
987
|
+
slash >>
|
|
988
|
+
str("CSA") >> space >>
|
|
989
|
+
# CSA number formats (various patterns observed)
|
|
990
|
+
(
|
|
991
|
+
# Format 1: C22.2 No. 293.1-17 (with NO.)
|
|
992
|
+
(str("C") >> digit.repeat(2) >> dot >> digit >> space >> str("No") >> dot >> space >>
|
|
993
|
+
match("[0-9.]").repeat(1) >> (dash | str(":")) >> digit.repeat(2)) |
|
|
994
|
+
# Format 2: C293.2-17 (without NO., dash year)
|
|
995
|
+
(str("C") >> match("[0-9.]").repeat(1) >> dash >> digit.repeat(2)) |
|
|
996
|
+
# Format 3: C22.2 No. 293.3:19 (with NO., colon year)
|
|
997
|
+
(str("C") >> digit.repeat(2) >> dot >> digit >> space >> str("No") >> dot >> space >>
|
|
998
|
+
match("[0-9.]").repeat(1) >> str(":") >> digit.repeat(2)) |
|
|
999
|
+
# Format 4: C293.4:19 (without NO., colon year)
|
|
1000
|
+
(str("C") >> match("[0-9.]").repeat(1) >> str(":") >> digit.repeat(2))
|
|
1001
|
+
).as(:csa_portion)
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
# Basic IEEE identifier (no dual PubIDs or complex revisions yet)
|
|
1005
|
+
rule(:identifier) do
|
|
1006
|
+
combined_aiee_identifier |
|
|
1007
|
+
aiee_identifier |
|
|
1008
|
+
combined_aiee_identifier |
|
|
1009
|
+
ire_identifier |
|
|
1010
|
+
nesc_identifier |
|
|
1011
|
+
ieee_astm_si_psi | # NEW Session 171: Add IEEE/ASTM SI/PSI support
|
|
1012
|
+
multi_numbered_identifier | # NEW: Try multi-numbered identifiers before generic patterns
|
|
1013
|
+
csa_dual_published | # NEW: Try CSA dual published before generic patterns
|
|
1014
|
+
s_designation | # Historical IEEE/IPCEA cable designation (S-135)
|
|
1015
|
+
corrigendum_identifier | # NEW: Try corrigendum before generic patterns
|
|
1016
|
+
interpretation_identifier | # NEW: Try interpretation identifier before generic patterns
|
|
1017
|
+
conformance_identifier | # NEW: Try conformance identifier before generic patterns
|
|
1018
|
+
joint_development_ieee_format |
|
|
1019
|
+
joint_development_iso_format |
|
|
1020
|
+
joint_development_embedded_stage | # stage-LAST embedded form (before generic)
|
|
1021
|
+
iec_ieee_copublished |
|
|
1022
|
+
number_first_identifier |
|
|
1023
|
+
ieee_approved_draft_identifier |
|
|
1024
|
+
ieee_draft_p_identifier |
|
|
1025
|
+
ieee_p_identifier |
|
|
1026
|
+
ansi_p_identifier | # NEW: ANSI P prefix support
|
|
1027
|
+
(((publisher >> copublisher.repeat.as(:copublishers)).as(:publishers) >> space).maybe >> # Make publisher optional
|
|
1028
|
+
draft_status.as(:draft_status).maybe >>
|
|
1029
|
+
(str("Draft Std").as(:type) >> space?).maybe >>
|
|
1030
|
+
(type_word.as(:type) >> (space >> str("No") >> space).maybe >> space?).maybe >>
|
|
1031
|
+
number >>
|
|
1032
|
+
(part_subpart_year | edition).maybe >>
|
|
1033
|
+
corrigendum.maybe >>
|
|
1034
|
+
amendment.maybe >>
|
|
1035
|
+
interpretation.maybe >> # NEW: Add /INT support
|
|
1036
|
+
conformance.maybe >> # NEW: Add /Conformance support
|
|
1037
|
+
ashrae_copub.maybe >> # NEW: Add /ASHRAE Guideline support
|
|
1038
|
+
ieee_crossref.maybe >> # NEW: Add /C62.22.1-1996 cross-reference support
|
|
1039
|
+
draft.maybe >>
|
|
1040
|
+
revision_suffix.maybe >>
|
|
1041
|
+
# Trailing "Month YYYY" print/reaffirm date under distinct keys so it
|
|
1042
|
+
# never collides with the base -YYYY identity year (see
|
|
1043
|
+
# ieee_p_identifier). The builder promotes it only when no base year.
|
|
1044
|
+
trailing_month_year.maybe >>
|
|
1045
|
+
# Trailing corrigendum after the draft+date ("IEEE Approved P1015/D1,
|
|
1046
|
+
# Jan 2007/Cor. 1"): the generic bucket is the only path a status-word
|
|
1047
|
+
# form reaches. Routes via build_flat_corrigendum (disjoint from the
|
|
1048
|
+
# pre-draft corrigendum slot at line 954).
|
|
1049
|
+
corrigendum.maybe >>
|
|
1050
|
+
edition.maybe >>
|
|
1051
|
+
parenthetical.maybe >> # REVERT: Back to single parenthetical
|
|
1052
|
+
book_nickname.maybe >> # NEW: Add book nickname support
|
|
1053
|
+
redline.maybe >>
|
|
1054
|
+
title_portion.maybe >>
|
|
1055
|
+
approved_draft_suffix.maybe) |
|
|
1056
|
+
no_prefix_ieee # NEW: Try no-prefix patterns last (lowest priority)
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
root(:identifier)
|
|
1060
|
+
|
|
1061
|
+
# Rewrite relaton's historical IEEE serialization into canonical pubid
|
|
1062
|
+
# spellings. relaton's own formatter (Relaton::Ieee::PubId::Id#to_s) emits
|
|
1063
|
+
# suffix tokens that differ from pubid's grammar:
|
|
1064
|
+
#
|
|
1065
|
+
# /D-N-YYYY[-MM] draft + trailing numeric date (the dominant form)
|
|
1066
|
+
# /E-N[-YYYY[-MM]] edition
|
|
1067
|
+
# /R-N[-YYYY] revision (pubid has no revision suffix)
|
|
1068
|
+
# " Redline" redline suffix without the " - " pubid expects
|
|
1069
|
+
#
|
|
1070
|
+
# The draft/edition trailing date is repositioned onto the document number
|
|
1071
|
+
# as a base year/month (a form pubid already parses), which also keeps the
|
|
1072
|
+
# draft component clean so it round-trips through to_hash/from_hash.
|
|
1073
|
+
def self.normalize_relaton_suffixes(cleaned)
|
|
1074
|
+
# NOTE: the trailing " Redline"/" - Redline" suffix is NO LONGER stripped
|
|
1075
|
+
# here — the grammar's `redline` rule captures it into a redline flag so
|
|
1076
|
+
# a redline id stays distinct from its base standard.
|
|
1077
|
+
|
|
1078
|
+
# Combined draft + corrigendum: relaton emits "…/D-N/CorM-YYYY" (draft
|
|
1079
|
+
# then corrigendum), but pubid's grammar accepts the corrigendum first.
|
|
1080
|
+
# Swap them so the corrigendum keeps its own year and the draft trails.
|
|
1081
|
+
# The hyphen after "D" is mandatory here: relaton's formatter always
|
|
1082
|
+
# emits "/D-<draft>", whereas pubid's own canonical joint-development
|
|
1083
|
+
# form is "/D<draft>-<year>" (no hyphen, year kept on the draft) — which
|
|
1084
|
+
# already parses and must not be repositioned. A trailing corrigendum
|
|
1085
|
+
# month (the "-MM" in "/CorM-YYYY-MM") is intentionally dropped: pubid's
|
|
1086
|
+
# corrigendum model carries only a year.
|
|
1087
|
+
cleaned = cleaned.sub(
|
|
1088
|
+
%r{\A(.*)/D-([0-9A-Za-z][0-9A-Za-z.+]*?)/Cor\.?[ ]?(\d+)(?:-((?:19|20)\d\d))?(?:-\d\d)?\z},
|
|
1089
|
+
) do
|
|
1090
|
+
base, draft, cor, year = Regexp.last_match.captures
|
|
1091
|
+
"#{base}/Cor #{cor}#{year ? "-#{year}" : ''}/D#{draft}"
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
# Combined draft + revision, and the empty-draft revision-only form:
|
|
1095
|
+
# "…/D-<d>/R-<x>-YYYY[-MM]" and "…/D-/R-<x>-YYYY" (nil-residue #2).
|
|
1096
|
+
# Reposition the base publication date onto the number (pubid's
|
|
1097
|
+
# "-YYYY[-MM]" shape), keep the draft as "/D<d>" (dropped when the draft
|
|
1098
|
+
# is empty), and leave a trailing "/R-<x>" the grammar captures as the
|
|
1099
|
+
# revision. Runs before the plain "/D-…" reposition, which the embedded
|
|
1100
|
+
# "/R-" would otherwise defeat.
|
|
1101
|
+
cleaned = cleaned.sub(
|
|
1102
|
+
%r{\A(.*?)/D-([0-9A-Za-z.+]*)/R-([0-9A-Za-z]+)(?:-((?:19|20)\d\d)(?:-(0[1-9]|1[0-2]))?)?\z},
|
|
1103
|
+
) do
|
|
1104
|
+
base, draft, rev, year, month = Regexp.last_match.captures
|
|
1105
|
+
date = year ? "-#{year}#{month ? "-#{month}" : ''}" : ""
|
|
1106
|
+
draft_part = draft.to_s.empty? ? "" : "/D#{draft}"
|
|
1107
|
+
"#{base}#{date}#{draft_part}/R-#{rev}"
|
|
1108
|
+
end
|
|
1109
|
+
|
|
1110
|
+
# /D-N drafts with a trailing numeric date, when the draft is the last
|
|
1111
|
+
# suffix: reposition the -YYYY[-MM] date onto the number. A following
|
|
1112
|
+
# /Cor, /Amd, /R or /E suffix carries its own year, so the `\z` anchor
|
|
1113
|
+
# keeps this from firing on those combined forms.
|
|
1114
|
+
cleaned = cleaned.sub(
|
|
1115
|
+
%r{\A(.*)/D-([0-9A-Za-z][0-9A-Za-z.+]*?)-((?:19|20)\d\d)(?:-(0[1-9]|1[0-2]))?\z},
|
|
1116
|
+
) do
|
|
1117
|
+
base, draft, year, month = Regexp.last_match.captures
|
|
1118
|
+
"#{base}-#{year}#{month ? "-#{month}" : ''}/D#{draft}"
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
# /E-N editions: relaton's "/E-2-2023-02" → pubid's "Edition 2.0 2023-02".
|
|
1122
|
+
cleaned = cleaned.sub(
|
|
1123
|
+
%r{\A(.*?)/E-(\d+)(?:-((?:19|20)\d\d)(?:-(0[1-9]|1[0-2]))?)?\z},
|
|
1124
|
+
) do
|
|
1125
|
+
base, edition, year, month = Regexp.last_match.captures
|
|
1126
|
+
date = year ? " #{year}#{month ? "-#{month}" : ''}" : ""
|
|
1127
|
+
"#{base} Edition #{edition}.0#{date}"
|
|
1128
|
+
end
|
|
1129
|
+
|
|
1130
|
+
# /R-N revisions: PRESERVE them (the grammar's revision_suffix rule now
|
|
1131
|
+
# captures a trailing "/R-<x>" into the `revision` attribute). Just
|
|
1132
|
+
# reposition any trailing publication year onto the number, keeping the
|
|
1133
|
+
# "/R-<x>" in place for the grammar.
|
|
1134
|
+
cleaned.sub(
|
|
1135
|
+
%r{\A(.*?)/R-([0-9A-Za-z]+)(?:-((?:19|20)\d\d))?\z},
|
|
1136
|
+
) do
|
|
1137
|
+
base, rev, year = Regexp.last_match.captures
|
|
1138
|
+
"#{year ? "#{base}-#{year}" : base}/R-#{rev}"
|
|
1139
|
+
end
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
# Strip the IEEE rawbib revision-notation dialects. `REV`/`Rev`
|
|
1143
|
+
# (case-insensitive) + a trailing revision id `[A-Za-z0-9]+`, glued to the
|
|
1144
|
+
# number or separated by `-`, `/`, `_`, `.`, or a space, and preceding the
|
|
1145
|
+
# draft. pubid's canonical "<num>/D<n>/R-<x>" form already drops the
|
|
1146
|
+
# revision on render (normalize_relaton_suffixes strips a trailing /R-x),
|
|
1147
|
+
# so the revision-less result is *the same identifier* — and stripping
|
|
1148
|
+
# (rather than reordering) leaves any trailing date/parenthetical intact,
|
|
1149
|
+
# which is why forms that already parse (`Draft P…-REVmb/D3.0, Mar 2010`)
|
|
1150
|
+
# are NOT disturbed. Examples:
|
|
1151
|
+
# "P802.16.2-REVa/D8" -> "P802.16.2/D8"
|
|
1152
|
+
# "P802.16/REVd/D5" -> "P802.16/D5"
|
|
1153
|
+
# "P802.15.1REVa/D5" -> "P802.15.1/D5"
|
|
1154
|
+
# "P802.11REVmb" -> "P802.11" (no draft)
|
|
1155
|
+
def self.normalize_revision_notation(cleaned)
|
|
1156
|
+
# NUMBERED revisions ("Rev<digits>") are PRESERVED — repositioned to a
|
|
1157
|
+
# trailing "/R-<n>" suffix the grammar captures as the `revision`
|
|
1158
|
+
# attribute (IEEE's native inline spelling; numbered-revision hand-off).
|
|
1159
|
+
# A "\d+" right after "Rev" both selects the numbered subset and keeps
|
|
1160
|
+
# these off the English word "Revision". Three source positions:
|
|
1161
|
+
# after a draft : "PC37.30.2/D043 Rev 18" -> ".../D043/R-18"
|
|
1162
|
+
cleaned = cleaned.sub(
|
|
1163
|
+
%r{(/D[0-9A-Za-z.]*)\s+[Rr][Ee][Vv]\s*(\d+)}, '\1/R-\2'
|
|
1164
|
+
)
|
|
1165
|
+
# before a draft: "P802.16Rev2/D3" -> "P802.16/D3/R-2"
|
|
1166
|
+
cleaned = cleaned.sub(
|
|
1167
|
+
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?(\d+)(/D[0-9A-Za-z.]*)}, '\2/R-\1'
|
|
1168
|
+
)
|
|
1169
|
+
# no draft, trailing: "P1722-rev1" -> "P1722/R-1"
|
|
1170
|
+
cleaned = cleaned.sub(
|
|
1171
|
+
%r{(\d)[-._]?\s?[Rr][Ee][Vv]\s*(\d+)\s*\z}, '\1/R-\2'
|
|
1172
|
+
)
|
|
1173
|
+
|
|
1174
|
+
# LETTERED inline revisions ("REVa", "REVmb") have no pubid model and are
|
|
1175
|
+
# still STRIPPED (unchanged behaviour). The numbered forms above already
|
|
1176
|
+
# became "/R-<n>", so these regexes only see the lettered residue.
|
|
1177
|
+
# Revision token that PRECEDES a draft: drop it (keep the /D…).
|
|
1178
|
+
cleaned = cleaned.sub(
|
|
1179
|
+
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?[A-Za-z0-9]+(?=/D[0-9])},
|
|
1180
|
+
"",
|
|
1181
|
+
)
|
|
1182
|
+
# Trailing revision glued to the number with no draft ("P802.11REVmb");
|
|
1183
|
+
# a digit must immediately precede REV so a trailing English word like
|
|
1184
|
+
# "…Revision" can't match.
|
|
1185
|
+
cleaned.sub(%r{(\d)[Rr][Ee][Vv][A-Za-z0-9]+\s*\z}, '\1')
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
def self.parse(string)
|
|
1189
|
+
# Strip .pdf extension if present (Pattern 3: File Extensions)
|
|
1190
|
+
cleaned = string.sub(/\.pdf$/i, "")
|
|
1191
|
+
|
|
1192
|
+
# Note: IEC and ANSI identifiers are NOT filtered here because they can have
|
|
1193
|
+
# IEEE co-publication or adoption. The Base.parse method handles determining
|
|
1194
|
+
# which standards are actually IEEE-related.
|
|
1195
|
+
# ISO-only standards are still filtered as they have separate handling.
|
|
1196
|
+
|
|
1197
|
+
# Pattern 3: Replace underscore before ISO stage codes with slash
|
|
1198
|
+
# These are joint development drafts that use underscore instead of slash
|
|
1199
|
+
cleaned = cleaned.gsub(/_(FDIS|CDV|CD|DIS|WD|PWI|NP)/, '/\1')
|
|
1200
|
+
|
|
1201
|
+
# NEW: Normalize multiple spaces to single space
|
|
1202
|
+
# No valid IEEE identifier pattern needs more than 1 space
|
|
1203
|
+
cleaned = cleaned.gsub(/\s+/, " ")
|
|
1204
|
+
|
|
1205
|
+
# A joint ISO-led publisher list is sometimes crawled with a stray slash
|
|
1206
|
+
# (or slash+space) before the ISO stage code — "ISO/IEC/IEEE/ FDIS …" or
|
|
1207
|
+
# "ISO/IEC/IEEE/FDIS …". Restore the space separator so the stage parses
|
|
1208
|
+
# (bucket 7).
|
|
1209
|
+
cleaned = cleaned.gsub(
|
|
1210
|
+
%r{\b(ISO/IEC/IEEE|IEEE/ISO/IEC|IEEE/IEC/ISO|ISO/IEEE|IEC/IEEE|IEEE/IEC|ISO/IEC)/ ?(FDIS|FCD|CDV|DIS\d?|CD\d?|WD|PWI|NP)\b},
|
|
1211
|
+
'\1 \2',
|
|
1212
|
+
)
|
|
1213
|
+
|
|
1214
|
+
# Rewrite the rawbib revision-notation dialects (REVa/REVd/glued) into
|
|
1215
|
+
# the canonical /R-<x> form before the suffix normalization below.
|
|
1216
|
+
cleaned = normalize_revision_notation(cleaned)
|
|
1217
|
+
|
|
1218
|
+
# Normalize relaton's bespoke historical serialization (the spellings
|
|
1219
|
+
# emitted by Relaton::Ieee::PubId::Id#to_s) into canonical pubid forms
|
|
1220
|
+
# so `relaton-data-ieee` parses. See #normalize_relaton_suffixes.
|
|
1221
|
+
cleaned = normalize_relaton_suffixes(cleaned)
|
|
1222
|
+
|
|
1223
|
+
# NEW Session 171: CONSERVATIVE data quality fixes for TODO.IEEE-MUST-DO.txt
|
|
1224
|
+
# Only fix clear typos: space before dash + 4-digit year, OR dash + space + 4-digit year
|
|
1225
|
+
# Do NOT touch " - " (space-dash-space) which is valid formatting
|
|
1226
|
+
cleaned = cleaned.gsub(/(\d)\s+-(\d{4})\b/, '\1-\2') # "C37.101 -2006" → "C37.101-2006"
|
|
1227
|
+
cleaned = cleaned.gsub(/(\d)-\s+(\d{4})\b/, '\1-\2') # "C62.35- 2010" → "C62.35-2010"
|
|
1228
|
+
|
|
1229
|
+
# NEW Session 171: HTML entity for en dash (–)
|
|
1230
|
+
# ONLY convert if not already followed by a dash (avoid creating --)
|
|
1231
|
+
cleaned = cleaned.gsub(/–(?!-)/, "-") # En dash → regular hyphen (if not followed by dash)
|
|
1232
|
+
cleaned = cleaned.gsub("–-", "-") # En-dash-dash → single dash
|
|
1233
|
+
|
|
1234
|
+
# NEW Session 171: Remove wrong ! prefix
|
|
1235
|
+
cleaned = cleaned.gsub(/^!IEEE /, "IEEE ")
|
|
1236
|
+
|
|
1237
|
+
# NEW Session 171: Fix "IEEE/ ASTM" spacing (extra space after slash)
|
|
1238
|
+
cleaned = cleaned.gsub("IEEE/ ASTM", "IEEE/ASTM")
|
|
1239
|
+
|
|
1240
|
+
# NEW Phase 1: Handle HTML entities comprehensively
|
|
1241
|
+
cleaned = cleaned.gsub("™", "™") # Trademark symbol
|
|
1242
|
+
cleaned = cleaned.gsub("’", "'") # Smart apostrophe
|
|
1243
|
+
cleaned = cleaned.gsub("&amp;", "&") # Double-encoded ampersand
|
|
1244
|
+
cleaned = cleaned.gsub("&", "&") # Single-encoded ampersand
|
|
1245
|
+
|
|
1246
|
+
# NEW: Wrap P&V notation in parentheses (Paper & Video, etc.)
|
|
1247
|
+
# Pattern: "IEEE Std 500-1984 P&V" → "IEEE Std 500-1984 (P&V)"
|
|
1248
|
+
cleaned = cleaned.gsub(/\s+(P&V)\s*$/, ' (\1)')
|
|
1249
|
+
|
|
1250
|
+
# NEW Phase 1: Fix number spacing issues (e.g., "C57.1 2.25" → "C57.12.25")
|
|
1251
|
+
# This handles cases where a space appears in the middle of a number
|
|
1252
|
+
cleaned = cleaned.gsub(/(\d+\.\d+)\s+(\d+\.)/, '\1\2')
|
|
1253
|
+
|
|
1254
|
+
# NEW Phase 1: Fix year spacing issues (e.g., "1 996" → "1996")
|
|
1255
|
+
# Remove spaces within 4-digit years
|
|
1256
|
+
cleaned = cleaned.gsub(/\b(1|2)\s+(\d{3})\b/, '\1\2')
|
|
1257
|
+
|
|
1258
|
+
# NEW: Fix month+year spacing (e.g., "March2016" → "March 2016")
|
|
1259
|
+
# Add space between month name and 4-digit year when they're concatenated
|
|
1260
|
+
cleaned = cleaned.gsub(
|
|
1261
|
+
/\b(January|February|March|April|May|June|July|August|September|October|November|December)(\d{4})\b/, '\1 \2'
|
|
1262
|
+
)
|
|
1263
|
+
# Also handle abbreviated months
|
|
1264
|
+
cleaned = cleaned.gsub(
|
|
1265
|
+
/\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Sept|Oct|Nov|Dec)(\d{4})\b/, '\1 \2'
|
|
1266
|
+
)
|
|
1267
|
+
|
|
1268
|
+
# NEW: Convert IEC/IEEE space-separated to semicolon format
|
|
1269
|
+
# Pattern: "IEC 61523-3 First edition 2004-09; IEEE 1497" → already semicolon
|
|
1270
|
+
# Pattern: "IEC 62539 First Edition 2007-07 IEEE 930" → needs semicolon
|
|
1271
|
+
# Pattern: "IEC 60076-21:2011 Edition 1.0 2011-12 IEEE Std C57.15" → needs semicolon (issue #202)
|
|
1272
|
+
# Match: IEC identifier (with optional colon-year, optional "First"/numeric
|
|
1273
|
+
# Edition + YYYY-MM) + space + IEEE identifier.
|
|
1274
|
+
cleaned = cleaned.gsub(
|
|
1275
|
+
/(IEC\s+\d+(?:-\d+)?(?::\d{4})?(?:\s+(?:First\s+)?[Ee]dition\s+\d+(?:\.\d+)?\s+\d{4}-\d{2})?)\s+(IEEE\s+Std\s+\S+|IEEE\s+\S+)/,
|
|
1276
|
+
'\1; \2'
|
|
1277
|
+
)
|
|
1278
|
+
|
|
1279
|
+
# Strip ":YYYY" from IEC numbers when an Edition clause follows — the
|
|
1280
|
+
# IEEE parser's number rule doesn't accept the colon-year form, but
|
|
1281
|
+
# the year is preserved in the "Edition N.M YYYY-MM" suffix.
|
|
1282
|
+
# (issue #202)
|
|
1283
|
+
cleaned = cleaned.gsub(
|
|
1284
|
+
/^(IEC\s+\d+(?:-\d+)?):\d{4}(\s+(?:First\s+)?[Ee]dition\s+\d+(?:\.\d+)?\s+\d{4}-\d{2})/,
|
|
1285
|
+
'\1\2'
|
|
1286
|
+
)
|
|
1287
|
+
|
|
1288
|
+
# NEW Phase 1 (Session 141): Remove literal trademark symbol
|
|
1289
|
+
# "C57.110™-2018" → "C57.110-2018"
|
|
1290
|
+
cleaned = cleaned.gsub(/™/, "")
|
|
1291
|
+
|
|
1292
|
+
# NEW Phase 1 (Session 141): Fix specific year typo
|
|
1293
|
+
# "19969" → "1969" (very specific pattern, won't affect other text)
|
|
1294
|
+
cleaned = cleaned.gsub(/\b19969\b/, "1969")
|
|
1295
|
+
|
|
1296
|
+
# NEW Session 169: Fix comma typo in 802.3 series numbers
|
|
1297
|
+
# "802.3ch-2020,802.3ca-2020" → "802.3ch-2020, 802.3ca-2020"
|
|
1298
|
+
# Very specific: 4 digits, comma, 3 digits (likely 802.3xx typo)
|
|
1299
|
+
cleaned = cleaned.gsub(/(\d{4}),(\d{3})/, '\1, \2')
|
|
1300
|
+
|
|
1301
|
+
# NEW Session 169: Fix /lNT typo (lowercase L as 1)
|
|
1302
|
+
# "1003.1/2003.l/lNT" → "1003.1/2003.1/INT"
|
|
1303
|
+
cleaned = cleaned.gsub(/\/lNT\b/, "/INT")
|
|
1304
|
+
cleaned = cleaned.gsub(".l/", ".1/") # Also fix .l/ -> .1/
|
|
1305
|
+
|
|
1306
|
+
# NEW Session 169: Fix I99O typo (letter I and O instead of digits)
|
|
1307
|
+
# "IEEE 1076-CONC-I99O" → "IEEE 1076-CONC-1990"
|
|
1308
|
+
cleaned = cleaned.gsub(/\bI99O\b/, "1990")
|
|
1309
|
+
|
|
1310
|
+
# NEW: Fix common typos (Category 9)
|
|
1311
|
+
cleaned = cleaned.gsub(/^EEE /, "IEEE ")
|
|
1312
|
+
|
|
1313
|
+
# NEW Session 170: Additional safe typo fixes
|
|
1314
|
+
# Fix "I EEE" (space between I and EEE)
|
|
1315
|
+
cleaned = cleaned.gsub(/^I EEE /, "IEEE ")
|
|
1316
|
+
|
|
1317
|
+
# Fix "lEEE" (lowercase L instead of I)
|
|
1318
|
+
cleaned = cleaned.gsub(/^lEEE /, "IEEE ")
|
|
1319
|
+
|
|
1320
|
+
# Fix missing closing parenthesis at end only (very conservative)
|
|
1321
|
+
# Only if there's exactly one more opening than closing paren
|
|
1322
|
+
open_count = cleaned.count("(")
|
|
1323
|
+
close_count = cleaned.count(")")
|
|
1324
|
+
if open_count == close_count + 1 && !cleaned.end_with?(")")
|
|
1325
|
+
cleaned = "#{cleaned})"
|
|
1326
|
+
end
|
|
1327
|
+
|
|
1328
|
+
# NEW Phase 1: Remove trailing commas/colons and text
|
|
1329
|
+
cleaned = cleaned.gsub(/,\s*Standard\s*$/, "") # ", Standard" at end
|
|
1330
|
+
cleaned = cleaned.gsub(/[,:]\s*$/, "") # Trailing comma/colon
|
|
1331
|
+
cleaned = cleaned.gsub(/,\s+and\s+IEEE\s+Std\s/, " and ") # Handle "IEEE Std and Std" case
|
|
1332
|
+
|
|
1333
|
+
# Enhanced: Fix unbalanced parentheses comprehensively
|
|
1334
|
+
# Handle three cases: missing closing, extra opening, nested unbalanced
|
|
1335
|
+
open_count = cleaned.count("(")
|
|
1336
|
+
close_count = cleaned.count(")")
|
|
1337
|
+
|
|
1338
|
+
if open_count > close_count
|
|
1339
|
+
# More opening than closing - add closing parens at end
|
|
1340
|
+
# This handles both simple missing and nested unbalanced cases
|
|
1341
|
+
missing = open_count - close_count
|
|
1342
|
+
cleaned = cleaned + (")" * missing)
|
|
1343
|
+
elsif close_count > open_count
|
|
1344
|
+
# More closing than opening - remove extra closing from end
|
|
1345
|
+
# Very conservative: only remove trailing excess closing parens
|
|
1346
|
+
extra = close_count - open_count
|
|
1347
|
+
cleaned = cleaned.sub(/\){#{extra}}$/, "")
|
|
1348
|
+
end
|
|
1349
|
+
|
|
1350
|
+
# === SESSION 173: TODO.IEEE-MUST-DO.txt Preprocessing Enhancements ===
|
|
1351
|
+
|
|
1352
|
+
# Part A: Simple Normalizations (Lines 13, 16, 32-35, 36, 39-41 from TODO)
|
|
1353
|
+
|
|
1354
|
+
# 1. Missing dash before year: "802.16g 2007" → "802.16g-2007"
|
|
1355
|
+
# But be careful not to affect month names (already have space)
|
|
1356
|
+
# Only apply if: digit + space + 4-digit year (and not after a month name)
|
|
1357
|
+
cleaned = cleaned.gsub(/(\d)\s+(\d{4})(?=\s*\(|\s*$)/, '\1-\2')
|
|
1358
|
+
|
|
1359
|
+
# 2. Space-dash-space before year: "802.1ag - 2007" → "802.1ag-2007"
|
|
1360
|
+
# This is distinct from " - " in titles, targets space-dash-space-year pattern
|
|
1361
|
+
cleaned = cleaned.gsub(/\s+-\s+(\d{4})\b/, '-\1')
|
|
1362
|
+
|
|
1363
|
+
# 3. Add missing "Std" after IEEE: "IEEE 1070-1995" → "IEEE Std 1070-1995"
|
|
1364
|
+
# Only at start of string, IEEE + space + digit
|
|
1365
|
+
cleaned = cleaned.gsub(/^IEEE\s+(?!Std\b)(\d)/, 'IEEE Std \1')
|
|
1366
|
+
|
|
1367
|
+
# 3.5. Convert "IEEE No." to "IEEE Std": "IEEE No. 264-1968" → "IEEE Std 264-1968"
|
|
1368
|
+
# NOTE: Do NOT convert AIEE No - AIEE uses "No" as standard format
|
|
1369
|
+
cleaned = cleaned.gsub(/^IEEE\s+No\.\s*/, "IEEE Std ")
|
|
1370
|
+
cleaned = cleaned.gsub(/^IEEE\s+No\s/, "IEEE Std ")
|
|
1371
|
+
# Skip AIEE No conversion - AIEE preserves "No" format
|
|
1372
|
+
|
|
1373
|
+
# 4. Space before slash in dual published: "262-1973 /ANSI" → "262-1973/ANSI"
|
|
1374
|
+
cleaned = cleaned.gsub(/\s+\//, "/")
|
|
1375
|
+
|
|
1376
|
+
# 5. Comma before Edition: ", 1998 Edition" → "-1998"
|
|
1377
|
+
# Normalize to standard year format for parser
|
|
1378
|
+
cleaned = cleaned.gsub(/,\s+(\d{4})\s+Edition/, '-\1')
|
|
1379
|
+
|
|
1380
|
+
# 6. ISO/IEC spacing: "ISO/IEC15802" → "ISO/IEC 15802"
|
|
1381
|
+
# Add space between publisher prefix and number
|
|
1382
|
+
cleaned = cleaned.gsub(/(ISO\/IEC)(\d)/, '\1 \2')
|
|
1383
|
+
|
|
1384
|
+
# Part B: Publisher Order (Line 38 from TODO)
|
|
1385
|
+
|
|
1386
|
+
# Fix wrong publisher order: "IEEE Std ANSI/IEEE" → "ANSI/IEEE Std"
|
|
1387
|
+
# This handles cases where IEEE Std appears before ANSI/IEEE publisher
|
|
1388
|
+
cleaned = cleaned.gsub(/^IEEE\s+Std\s+(ANSI\/IEEE)/, '\1 Std')
|
|
1389
|
+
|
|
1390
|
+
# Part C: Dual Published Formats (Lines 8, 19 from TODO)
|
|
1391
|
+
|
|
1392
|
+
# 1. Semicolon to parenthetical for dual published (MultiLabeledIdentifier)
|
|
1393
|
+
# "IEEE Std 120-1955; ASME PTC 19.6-1955" → "IEEE Std 120-1955 (ASME PTC 19.6-1955)"
|
|
1394
|
+
# Only if semicolon + space + organization abbreviation (capital letters)
|
|
1395
|
+
if cleaned.match?(/;\s+[A-Z]{2,}/)
|
|
1396
|
+
cleaned = cleaned.sub(/;\s+([A-Z][^;]+)$/, ' (\1)')
|
|
1397
|
+
end
|
|
1398
|
+
|
|
1399
|
+
# === SESSION 174: Additional TODO.IEEE-MUST-DO.txt Preprocessing ===
|
|
1400
|
+
|
|
1401
|
+
# Part A: Edition Abbreviation Normalization (Lines 10-11)
|
|
1402
|
+
# Pattern: ", 1999 Edn. (Reaff 2003)" → "-1999 (R2003)"
|
|
1403
|
+
# Normalize both the Edition abbreviation and the Reaffirmed format
|
|
1404
|
+
cleaned = cleaned.gsub(/,\s+(\d{4})\s+Edn\.\s+\(Reaff\s+(\d{4})\)/,
|
|
1405
|
+
'-\1 (R\2)')
|
|
1406
|
+
# Also handle without initial comma (might occur in relationships)
|
|
1407
|
+
cleaned = cleaned.gsub(/(\d{4})\s+Edn\.\s+\(Reaff\s+(\d{4})\)/,
|
|
1408
|
+
'\1 (R\2)')
|
|
1409
|
+
|
|
1410
|
+
# Part B: IRE Parenthetical Split (Line 9)
|
|
1411
|
+
# Pattern: "(Reaffirmed 1980, 56 IRE 28.S2)" → "(R1980) (56 IRE 28.S2)"
|
|
1412
|
+
# Split nested reaffirmation + IRE reference into two parentheticals
|
|
1413
|
+
cleaned = cleaned.gsub(/\(Reaffirmed\s+(\d{4}),\s+(\d+\s+IRE[^)]+)\)/,
|
|
1414
|
+
'(R\1) (\2)')
|
|
1415
|
+
|
|
1416
|
+
# Part C: Slash to Parenthetical (Line 37)
|
|
1417
|
+
# Pattern: "number-year/ANSI identifier" → "number-year (ANSI identifier)"
|
|
1418
|
+
# Only convert if slash is followed by ANSI and NOT a relationship keyword
|
|
1419
|
+
# Look ahead to ensure we're at end of main identifier (before paren or end of string)
|
|
1420
|
+
cleaned = cleaned.gsub(%r{(\d{4})/ANSI\s+([^(]+)(?=\s*\(|$)},
|
|
1421
|
+
'\1 (ANSI \2)')
|
|
1422
|
+
|
|
1423
|
+
# Part D: ISO/IEC TR Spacing (Line 40)
|
|
1424
|
+
# Pattern: "ISO/IEC TR11802" → "ISO/IEC TR 11802"
|
|
1425
|
+
# Add space after TR when directly followed by digit
|
|
1426
|
+
cleaned = cleaned.gsub(/(ISO\/IEC\s+TR)(\d)/, '\1 \2')
|
|
1427
|
+
# === SESSION 178: AIEE Dual Numbers Expansion (Line 45) ===
|
|
1428
|
+
|
|
1429
|
+
# Part E: AIEE "Nos X and Y" Expansion
|
|
1430
|
+
# Pattern: "AIEE Nos 72 and 73 - 1932" → "AIEE No 72-1932 and AIEE No 73-1932"
|
|
1431
|
+
# Expands dual AIEE numbers to separate identifiers with shared year
|
|
1432
|
+
if cleaned.match?(/AIEE\s+Nos\s+(\d+)\s+and\s+(\d+)\s+-\s+(\d{4})/)
|
|
1433
|
+
cleaned = cleaned.sub(/AIEE\s+Nos\s+(\d+)\s+and\s+(\d+)\s+-\s+(\d{4})/) do
|
|
1434
|
+
first_num = $1
|
|
1435
|
+
second_num = $2
|
|
1436
|
+
year = $3
|
|
1437
|
+
"AIEE No #{first_num}-#{year} and AIEE No #{second_num}-#{year}"
|
|
1438
|
+
end
|
|
1439
|
+
end
|
|
1440
|
+
|
|
1441
|
+
# === SESSION 222: TODO.IEEE-MUST-FIX-IDs.txt Comprehensive Fixes ===
|
|
1442
|
+
|
|
1443
|
+
# Part A: Typo Fixes
|
|
1444
|
+
# 1. "Stad" -> "Std" (typo)
|
|
1445
|
+
cleaned = cleaned.gsub(/\bStad\b/, "Std")
|
|
1446
|
+
|
|
1447
|
+
# 2. Lowercase "std" -> "Std" when after IEEE/ANSI publishers
|
|
1448
|
+
cleaned = cleaned.gsub(/\b(IEEE|ANSI|AIEE)\s+std\b/, '\1 Std')
|
|
1449
|
+
|
|
1450
|
+
# Part B: Symbol Normalization
|
|
1451
|
+
# 3. Additional (TM) patterns - strip them out
|
|
1452
|
+
cleaned = cleaned.gsub("(TM)", "")
|
|
1453
|
+
|
|
1454
|
+
# Part C: Year-first format normalization
|
|
1455
|
+
# 4. Pattern "62704-4/D4, 2020" -> "IEEE P62704-4/D4, 2020"
|
|
1456
|
+
# Only if starts with digits-dash-digits/D pattern
|
|
1457
|
+
if cleaned.match?(/^(\d+[-.]\d+)\/D\d+/)
|
|
1458
|
+
cleaned = "IEEE P#{cleaned}"
|
|
1459
|
+
end
|
|
1460
|
+
|
|
1461
|
+
# Part D: Suffix Normalization
|
|
1462
|
+
# 5. "/Preprint" -> remove (data quality - not standard suffix)
|
|
1463
|
+
cleaned = cleaned.gsub(/\/Preprint\b/, "")
|
|
1464
|
+
|
|
1465
|
+
# Part E: Relationship Text Normalization
|
|
1466
|
+
# 6. "Proposed Revision of" -> "Revision of"
|
|
1467
|
+
cleaned = cleaned.gsub("Proposed Revision of", "Revision of")
|
|
1468
|
+
|
|
1469
|
+
# 7. "ammended" typo -> "amended"
|
|
1470
|
+
cleaned = cleaned.gsub(/\bammended\b/i, "amended")
|
|
1471
|
+
|
|
1472
|
+
# Part F: Trailing Characters After Special Patterns
|
|
1473
|
+
# 8. Remove trailing periods after /INT, /Cor, etc.
|
|
1474
|
+
cleaned = cleaned.gsub(/(\/INT|\/Cor\s+\d+-\d{4})\./, '\1')
|
|
1475
|
+
|
|
1476
|
+
# Part G: Conformance Pattern Spacing
|
|
1477
|
+
# 9. Fix spacing in "/Conformance" patterns WITHOUT year (malformed only)
|
|
1478
|
+
# "1904.1(TM)/Conformance02" -> "1904.1 /Conformance02" (space before slash)
|
|
1479
|
+
# BUT: DO NOT touch valid patterns like "802.16/Conformance01-2003" (with year)
|
|
1480
|
+
# Use positive check for year suffix to exclude valid patterns
|
|
1481
|
+
# Actually, this preprocessing is breaking valid patterns - just remove it entirely
|
|
1482
|
+
# The parser can handle both "6/Conformance01-2003" and "6 /Conformance02" formats
|
|
1483
|
+
|
|
1484
|
+
# Part H: Edition Text After /INT
|
|
1485
|
+
# 10. Handle ", Month YYYY Edition" after /INT by converting to month-year format
|
|
1486
|
+
# "1003.1/INT, March 1994 Edition" -> "1003.1/INT, March 1994"
|
|
1487
|
+
cleaned = cleaned.gsub(/(\/INT),\s+([A-Z][a-z]+)\s+(\d{4})\s+Edition/,
|
|
1488
|
+
'\1, \2 \3')
|
|
1489
|
+
|
|
1490
|
+
# Part I: Handle "Ed." abbreviation
|
|
1491
|
+
# 11. "Dec. 1994 Ed." -> "Dec. 1994"
|
|
1492
|
+
cleaned = cleaned.gsub(/\s+Ed\.\s*$/, "")
|
|
1493
|
+
|
|
1494
|
+
# === PHASE 2: High-impact preprocessing for fixture failures ===
|
|
1495
|
+
|
|
1496
|
+
# Quick wins from SESSION 224 (must come before more complex fixes)
|
|
1497
|
+
|
|
1498
|
+
# Remove period after "Std": "IEEE Std." -> "IEEE Std"
|
|
1499
|
+
cleaned = cleaned.gsub(/\bStd\.\s+/, "Std ")
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
# Title portion removal after year: "YYYY - IEEE Standard for..."
|
|
1503
|
+
cleaned = cleaned.gsub(
|
|
1504
|
+
/(\d{4})(\s+\([^)]+\))?\s+-\s+IEEE\s+Standard\s+for.*$/, '\1\2'
|
|
1505
|
+
)
|
|
1506
|
+
|
|
1507
|
+
# Fix 2A: "IEEE PC" prefix -> "IEEE Std PC" or "IEEE P" treatment
|
|
1508
|
+
# "IEEE PC37.20.9/D7.3A" -> needs to parse as IEEE project draft
|
|
1509
|
+
# Strategy: Add "Std" after "IEEE" when followed by "PC" to route to standard pattern
|
|
1510
|
+
# Actually, the issue is the number rule consumes "PC37" as P + C37.
|
|
1511
|
+
# Better: normalize "IEEE PC" to "IEEE Std PC" so it hits the standard identifier path
|
|
1512
|
+
cleaned = cleaned.gsub(/^IEEE\s+PC(\d)/, 'IEEE Std PC\1')
|
|
1513
|
+
cleaned = cleaned.gsub(/^IEEE\s+Unapproved\s+Draft\s+Std\s+PC(\d)/,
|
|
1514
|
+
'IEEE Unapproved Draft Std PC\1')
|
|
1515
|
+
|
|
1516
|
+
# Fix 2B: "IEEE P" without "Std"/"Draft" prefix
|
|
1517
|
+
# ieee_p_identifier rule handles these directly - no preprocessing needed
|
|
1518
|
+
# Only handle "IEEE P" followed by "and ASHRAE" (copub case)
|
|
1519
|
+
cleaned = cleaned.gsub(/^IEEE\s+P(\d+)\s+and\s+ASHRAE/,
|
|
1520
|
+
'IEEE Std P\1 and ASHRAE')
|
|
1521
|
+
|
|
1522
|
+
# Fix 2C: "ISO/IEC XXXX-YYYY: Title" -> strip title after colon for ISO/IEC published standards
|
|
1523
|
+
# These are ISO-format identifiers with IEEE adoption, strip the title
|
|
1524
|
+
cleaned = cleaned.gsub(/^(ISO\/IEC \d+[-.]\d+-\d{4}):.*$/, '\1')
|
|
1525
|
+
cleaned = cleaned.gsub(/^(ISO\/IEC \d+-\d{4}):.*$/, '\1')
|
|
1526
|
+
|
|
1527
|
+
# Fix 2D: "ISO/IEC XXXX : YYYY" -> normalize spacing around colon
|
|
1528
|
+
cleaned = cleaned.gsub(/^(ISO\/IEC \d+[-.]\d*)\s*:\s*(\d{4})/, '\1:\2')
|
|
1529
|
+
cleaned = cleaned.gsub(/^(ISO\/IEC \d+)\s*:\s*(\d{4})/, '\1:\2')
|
|
1530
|
+
|
|
1531
|
+
# Fix 2G: "IEC/IEEE PXXX_D5" -> underscore to slash
|
|
1532
|
+
cleaned = cleaned.gsub(/^(IEC\/IEEE P[\w.-]+)_D/, '\1/D')
|
|
1533
|
+
|
|
1534
|
+
# Fix 2H: "IEC XXXX First edition YYYY-MM; IEEE NNNN" -> normalize semicolon
|
|
1535
|
+
# Already handled by earlier semicolon normalization
|
|
1536
|
+
|
|
1537
|
+
# Fix 2I: "IEEE/ISO/IEC PXXX/DIS" -> normalize to "ISO/IEC/IEEE PXXX/DIS"
|
|
1538
|
+
cleaned = cleaned.gsub(/^IEEE\/ISO\/IEC\s+(P[\w.-]+)/,
|
|
1539
|
+
'ISO/IEC/IEEE \1')
|
|
1540
|
+
cleaned = cleaned.gsub(/^IEEE\/IEC\/ISO\s+(P[\w.-]+)/,
|
|
1541
|
+
'IEC/ISO/IEEE \1')
|
|
1542
|
+
|
|
1543
|
+
# Fix 2J: "IEEE/IEC PXXX D5" -> normalize space to slash before D
|
|
1544
|
+
cleaned = cleaned.gsub(/^(IEEE\/IEC P[\w.-]+)\s+D(\d)/, '\1/D\2')
|
|
1545
|
+
cleaned = cleaned.gsub(
|
|
1546
|
+
/^(IEEE\/IEC P[\w.-]+)\s+(CDV|FDIS|CD|DIS|ED\d)/, '\1/\2'
|
|
1547
|
+
)
|
|
1548
|
+
|
|
1549
|
+
# Fix 2K: "ISO /IEC/IEEE" -> fix space before slash
|
|
1550
|
+
cleaned = cleaned.gsub(/^ISO\s+\/IEC\/IEEE/, "ISO/IEC/IEEE")
|
|
1551
|
+
cleaned = cleaned.gsub(/^ISO\s+\/IEC/, "ISO/IEC")
|
|
1552
|
+
|
|
1553
|
+
# Fix 2L: "IS0" typo (letter O instead of digit 0)
|
|
1554
|
+
cleaned = cleaned.gsub(/^IS0\//, "ISO/")
|
|
1555
|
+
|
|
1556
|
+
# Fix 2M: "IEEE-P15026-3-DIS-January 2015" -> dash-separated format
|
|
1557
|
+
# Normalize to "ISO/IEC/IEEE P15026-3/DIS, January 2015"
|
|
1558
|
+
cleaned = cleaned.gsub(/^IEEE-P(\d+)-(\d+)-DIS-(.*)/,
|
|
1559
|
+
'ISO/IEC/IEEE P\1-\2/DIS, \3')
|
|
1560
|
+
|
|
1561
|
+
# Fix 2N: "IEEE/CSA P844.1/293.1/D2" -> normalize CSA dual numbering
|
|
1562
|
+
cleaned = cleaned.gsub(/^IEEE\/CSA\s+(P[\d.]+)\/([\d.]+)\/D(\d+)/,
|
|
1563
|
+
'IEEE/CSA \1/D\3')
|
|
1564
|
+
|
|
1565
|
+
# Fix 2O: "IEEE Approved Draft Std P" -> normalize spacing
|
|
1566
|
+
cleaned = cleaned.gsub(/^IEEE\s+Approved\s+Draft\s+Std\s+(P\d)/,
|
|
1567
|
+
'IEEE Approved Draft Std \1')
|
|
1568
|
+
# Fix: "IEEE Approved Draft Std P1234 / D12" -> remove space before slash
|
|
1569
|
+
cleaned = cleaned.gsub(/^(IEEE Approved Draft Std P[\w.-]+)\s+\/\s*D/,
|
|
1570
|
+
'\1/D')
|
|
1571
|
+
|
|
1572
|
+
# Fix 2P: "IEEE/EIA" -> normalize (parser handles IEEE/EIA via copublisher)
|
|
1573
|
+
# Already works - no fix needed
|
|
1574
|
+
|
|
1575
|
+
# Fix 2Q: AIEE format variations
|
|
1576
|
+
# "AIEE No.1C-1954" -> "AIEE No. 1C-1954" (add space after No.)
|
|
1577
|
+
cleaned = cleaned.gsub(/^AIEE\s+No\.\s*(\d)/, 'AIEE No. \1')
|
|
1578
|
+
# "AIEE no 700-1945" -> "AIEE No 700-1945" (capitalize)
|
|
1579
|
+
cleaned = cleaned.gsub(/^AIEE\s+no\s/, "AIEE No ")
|
|
1580
|
+
# "AIEE Std No. 800" -> "AIEE Standard No 800" (normalize type word)
|
|
1581
|
+
cleaned = cleaned.gsub(/^AIEE\s+Std\s+No\.\s*/, "AIEE Standard No ")
|
|
1582
|
+
# "AIEE No 750.1-1960" -> handled by AIEE parser if decimal support added
|
|
1583
|
+
|
|
1584
|
+
# Fix 2R: "IEEE PSI 10/D2" -> normalize to "IEEE/ASTM PSI 10/D2"
|
|
1585
|
+
cleaned = cleaned.gsub(/^IEEE\s+PSI\s+(\d)/, 'IEEE/ASTM PSI \1')
|
|
1586
|
+
|
|
1587
|
+
# Fix 2S: "IEEE/IEC P62271-111/PC37.60_D5" -> normalize
|
|
1588
|
+
cleaned = cleaned.gsub(/^(IEEE\/IEC P[\d.-]+\/PC[\d.]+)_D/, '\1/D')
|
|
1589
|
+
|
|
1590
|
+
# Fix 2T: "IEC P62271-111/IEEE PC37.60_D5" -> normalize to IEC/IEEE format
|
|
1591
|
+
cleaned = cleaned.gsub(/^IEC\s+(P[\d.-]+)\/IEEE\s+(PC[\d.]+)_D/,
|
|
1592
|
+
'IEC/IEEE \2/D')
|
|
1593
|
+
|
|
1594
|
+
# Fix 2U: "IEC/IEC P" -> "IEC/IEEE P" (typo)
|
|
1595
|
+
cleaned = cleaned.gsub(/^IEC\/IEC\s+(P\d)/, 'IEC/IEEE \1')
|
|
1596
|
+
|
|
1597
|
+
# Fix 2V: "NACE SPXXXX-YYYY/IEEE Std NNNN-YYYY" -> normalize slash to parenthetical
|
|
1598
|
+
cleaned = cleaned.gsub(/^(NACE\s+SP\d+-\d+)\/(IEEE\s+Std\s+\d+-\d+)$/,
|
|
1599
|
+
'\1 (\2)')
|
|
1600
|
+
|
|
1601
|
+
# Fix 2W: "IEEE Std 802.11g-2003 (Amendment to IEEE Std 802.11, 1999 Edn. (Reaff 2003) as amended by"
|
|
1602
|
+
# This is a complex relationship - strip the parenthetical if too complex
|
|
1603
|
+
# Let the parser handle it but fix "Edn." to "Edition"
|
|
1604
|
+
cleaned = cleaned.gsub("Edn.", "Edition")
|
|
1605
|
+
|
|
1606
|
+
# Fix 2X: "IEEE-P15026-3-DIS" format -> normalize
|
|
1607
|
+
# Already handled by Fix 2M
|
|
1608
|
+
|
|
1609
|
+
# Fix 2Y: "P1635/D10/ASHARE 21/D10" -> fix ASHARE typo to ASHRAE
|
|
1610
|
+
cleaned = cleaned.gsub("ASHARE", "ASHRAE")
|
|
1611
|
+
|
|
1612
|
+
# Fix 2Z: "PC37.30.2/D043 Rev 18" -> normalize draft version with Rev
|
|
1613
|
+
# "PC57-15 D2.0" -> normalize to "P57-15/D2.0"
|
|
1614
|
+
cleaned = cleaned.gsub(/^PC(\d)/, 'P\1')
|
|
1615
|
+
|
|
1616
|
+
# Fix 2AA: "IEEE/ISO/IEC 8802-1Q-2020/Amd31-2021" -> normalize
|
|
1617
|
+
cleaned = cleaned.gsub(/^IEEE\/ISO\/IEC\s+(8802[\w.-]+)/,
|
|
1618
|
+
'ISO/IEC/IEEE \1')
|
|
1619
|
+
|
|
1620
|
+
# Fix 2AB: "IEEE C57.139/D14June 2010" -> add missing space
|
|
1621
|
+
cleaned = cleaned.gsub(
|
|
1622
|
+
/^(IEEE\s+C?\d[\d.]*\/D\d+)([A-Z][a-z]+\s+\d{4})/, '\1, \2'
|
|
1623
|
+
)
|
|
1624
|
+
|
|
1625
|
+
# Fix 2AC: "IEEE Std: Title" -> strip colon and title (ANSI/IEEE Std: )
|
|
1626
|
+
cleaned = cleaned.gsub(/^(ANSI\/IEEE Std):\s+.*$/, '\1')
|
|
1627
|
+
|
|
1628
|
+
# Fix 2AD: "IEEE 1076 IEC 61691-1-1 First edition 2004-10" -> semicolon format
|
|
1629
|
+
cleaned = cleaned.gsub(
|
|
1630
|
+
/^(IEEE\s+[\d.]+)\s+(IEC\s+\d+[-\d]*\s+.*edition\s+\d{4}-\d{2})$/i, '\1; \2'
|
|
1631
|
+
)
|
|
1632
|
+
|
|
1633
|
+
# Fix 2AE: "IEEE No 29-1941 / ASA C77.1-1943" -> normalize to IEEE Std format
|
|
1634
|
+
cleaned = cleaned.gsub(/^IEEE\s+No\s+(\d+-\d+)\s+\/\s+ASA\s+(.*)/,
|
|
1635
|
+
'IEEE Std \1 (ASA \2)')
|
|
1636
|
+
|
|
1637
|
+
# Fix 2AF: "IEEE Std 1003.1/2003.l/lNT" -> fix typos
|
|
1638
|
+
# .l -> .1 and lNT -> INT handled by existing fixes
|
|
1639
|
+
|
|
1640
|
+
new.parse(cleaned)
|
|
1641
|
+
end
|
|
1642
|
+
end
|
|
1643
|
+
end
|
|
1644
|
+
end
|