pubid 2.0.0.pre.alpha.11 → 2.0.0.pre.alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +43 -1
- data/data/ieee/update_codes.yaml +17 -4
- data/data/nist/update_codes.yaml +7 -3
- data/lib/pubid/adobe/builder.rb +2 -0
- data/lib/pubid/all_parts.rb +201 -0
- data/lib/pubid/all_parts_identifier.rb +19 -0
- data/lib/pubid/amca/CLAUDE.md +47 -0
- data/lib/pubid/amca/builder.rb +3 -5
- data/lib/pubid/amca/identifiers/base.rb +10 -0
- data/lib/pubid/amca/identifiers/publication.rb +13 -0
- data/lib/pubid/amca/parser.rb +2 -1
- data/lib/pubid/amca/renderer.rb +22 -33
- data/lib/pubid/amca/urn_generator.rb +21 -2
- data/lib/pubid/amca/urn_parser.rb +36 -10
- data/lib/pubid/ansi/builder.rb +6 -0
- data/lib/pubid/api/CLAUDE.md +23 -0
- data/lib/pubid/api/builder.rb +2 -0
- data/lib/pubid/ashrae/CLAUDE.md +13 -0
- data/lib/pubid/ashrae/builder.rb +58 -14
- data/lib/pubid/ashrae/identifiers/errata.rb +14 -2
- data/lib/pubid/ashrae/identifiers/interpretation.rb +2 -10
- data/lib/pubid/ashrae/parser.rb +62 -28
- data/lib/pubid/ashrae/renderer.rb +32 -1
- data/lib/pubid/ashrae/urn_generator.rb +32 -9
- data/lib/pubid/asme/CLAUDE.md +25 -0
- data/lib/pubid/asme/builder.rb +16 -9
- data/lib/pubid/asme/components/code.rb +2 -0
- data/lib/pubid/asme/identifiers/standard.rb +6 -1
- data/lib/pubid/asme/parser.rb +41 -14
- data/lib/pubid/astm/CLAUDE.md +9 -0
- data/lib/pubid/astm/builder.rb +2 -0
- data/lib/pubid/astm/components/code.rb +2 -0
- data/lib/pubid/astm/parser.rb +4 -1
- data/lib/pubid/bipm/CLAUDE.md +11 -0
- data/lib/pubid/bipm/builder.rb +2 -0
- data/lib/pubid/bsi/CLAUDE.md +93 -0
- data/lib/pubid/bsi/builder.rb +13 -11
- data/lib/pubid/bsi/components/date.rb +10 -4
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -0
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +6 -54
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +5 -22
- data/lib/pubid/bsi/identifiers/amendment.rb +36 -12
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +1 -1
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +2 -0
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +23 -26
- data/lib/pubid/bsi/identifiers/corrigendum.rb +29 -12
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +6 -7
- data/lib/pubid/bsi/identifiers/handbook.rb +1 -1
- data/lib/pubid/bsi/identifiers/national_annex.rb +18 -20
- data/lib/pubid/bsi/identifiers/practice_guide.rb +1 -1
- data/lib/pubid/bsi/identifiers/root_identity.rb +31 -0
- data/lib/pubid/bsi/identifiers/set.rb +2 -0
- data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -0
- data/lib/pubid/bsi/identifiers.rb +1 -0
- data/lib/pubid/bsi/parser.rb +8 -8
- data/lib/pubid/bsi/renderer.rb +20 -20
- data/lib/pubid/bsi/single_identifier.rb +11 -2
- data/lib/pubid/bsi/urn_generator.rb +28 -18
- data/lib/pubid/builder/base.rb +27 -0
- data/lib/pubid/calconnect/builder.rb +2 -0
- data/lib/pubid/calconnect/identifier.rb +4 -0
- data/lib/pubid/ccsds/builder.rb +2 -0
- data/lib/pubid/ccsds/identifier.rb +12 -0
- data/lib/pubid/ccsds/single_identifier.rb +14 -10
- data/lib/pubid/cen_cenelec/CLAUDE.md +59 -0
- data/lib/pubid/cen_cenelec/builder.rb +6 -1
- data/lib/pubid/cen_cenelec/identifier.rb +10 -27
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +3 -10
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +3 -10
- data/lib/pubid/cen_cenelec/parser.rb +11 -3
- data/lib/pubid/cie/CLAUDE.md +58 -0
- data/lib/pubid/cie/builder.rb +2 -0
- data/lib/pubid/cie/components/language.rb +2 -0
- data/lib/pubid/components/adoption.rb +2 -0
- data/lib/pubid/components/code.rb +2 -0
- data/lib/pubid/components/date.rb +8 -6
- data/lib/pubid/components/edition.rb +2 -0
- data/lib/pubid/components/iteration.rb +2 -0
- data/lib/pubid/components/language.rb +2 -0
- data/lib/pubid/components/locality.rb +2 -0
- data/lib/pubid/components/publisher.rb +2 -0
- data/lib/pubid/components/relationship.rb +2 -0
- data/lib/pubid/components/stage.rb +2 -0
- data/lib/pubid/components/supplement.rb +2 -0
- data/lib/pubid/components/type.rb +2 -0
- data/lib/pubid/components/typed_stage.rb +8 -0
- data/lib/pubid/csa/CLAUDE.md +41 -0
- data/lib/pubid/csa/builder.rb +5 -3
- data/lib/pubid/csa/identifier.rb +13 -1
- data/lib/pubid/csa/identifiers/bundled.rb +2 -2
- data/lib/pubid/csa/identifiers/cec.rb +1 -1
- data/lib/pubid/csa/renderer.rb +12 -12
- data/lib/pubid/csa/single_identifier.rb +18 -1
- data/lib/pubid/csa/urn_generator.rb +1 -1
- data/lib/pubid/doi/builder.rb +2 -0
- data/lib/pubid/easc/builder.rb +2 -0
- data/lib/pubid/ecma/CLAUDE.md +28 -0
- data/lib/pubid/ecma/builder.rb +2 -0
- data/lib/pubid/ecma/identifier.rb +7 -0
- data/lib/pubid/etsi/CLAUDE.md +34 -0
- data/lib/pubid/etsi/builder.rb +2 -0
- data/lib/pubid/etsi/components/code.rb +6 -0
- data/lib/pubid/etsi/components/version.rb +2 -0
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +7 -0
- data/lib/pubid/evs/CLAUDE.md +58 -0
- data/lib/pubid/evs/builder.rb +3 -1
- data/lib/pubid/evs/identifier.rb +6 -6
- data/lib/pubid/evs/identifiers/national_adoption.rb +7 -2
- data/lib/pubid/evs/renderer.rb +1 -1
- data/lib/pubid/evs/urn_generator.rb +1 -1
- data/lib/pubid/evs/urn_parser.rb +1 -1
- data/lib/pubid/gb/CLAUDE.md +140 -0
- data/lib/pubid/gb/builder.rb +21 -11
- data/lib/pubid/gb/identifier.rb +28 -7
- data/lib/pubid/gb/identifiers/all_parts.rb +17 -0
- data/lib/pubid/gb/identifiers.rb +1 -0
- data/lib/pubid/gb/parser.rb +4 -0
- data/lib/pubid/gb/renderer.rb +4 -4
- data/lib/pubid/gb.rb +1 -0
- data/lib/pubid/gost/CLAUDE.md +64 -0
- data/lib/pubid/gost/builder.rb +3 -1
- data/lib/pubid/gost/identifier.rb +5 -0
- data/lib/pubid/iala/CLAUDE.md +82 -0
- data/lib/pubid/iala/builder.rb +2 -0
- data/lib/pubid/iana/CLAUDE.md +7 -0
- data/lib/pubid/iana/builder.rb +2 -0
- data/lib/pubid/identifier.rb +172 -20
- data/lib/pubid/idf/builder.rb +6 -1
- data/lib/pubid/idf/identifier.rb +12 -0
- data/lib/pubid/idf/identifiers/all_parts.rb +17 -0
- data/lib/pubid/idf/identifiers/amendment.rb +1 -1
- data/lib/pubid/idf/identifiers/corrigendum.rb +1 -1
- data/lib/pubid/idf/identifiers/international_standard.rb +1 -1
- data/lib/pubid/idf/identifiers/reviewed_method.rb +1 -1
- data/lib/pubid/idf/identifiers.rb +1 -0
- data/lib/pubid/idf/single_identifier.rb +1 -1
- data/lib/pubid/iec/CLAUDE.md +31 -0
- data/lib/pubid/iec/builder.rb +7 -1
- data/lib/pubid/iec/components/consolidated_amendment.rb +4 -0
- data/lib/pubid/iec/components/sheet.rb +2 -0
- data/lib/pubid/iec/components/trf_info.rb +2 -0
- data/lib/pubid/iec/components/vap_suffix.rb +2 -0
- data/lib/pubid/iec/identifier.rb +7 -2
- data/lib/pubid/iec/identifiers/all_parts.rb +19 -0
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/renderer.rb +0 -1
- data/lib/pubid/iec/urn_generator.rb +9 -1
- data/lib/pubid/iec/urn_parser.rb +3 -2
- data/lib/pubid/ieee/CLAUDE.md +97 -0
- data/lib/pubid/ieee/builder.rb +176 -7
- data/lib/pubid/ieee/components/code.rb +2 -0
- data/lib/pubid/ieee/components/draft.rb +35 -2
- data/lib/pubid/ieee/components/typed_stage.rb +2 -0
- data/lib/pubid/ieee/identifiers/base.rb +20 -0
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +9 -0
- data/lib/pubid/ieee/identifiers/joint_development.rb +17 -10
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +8 -1
- data/lib/pubid/ieee/identifiers/si_standard.rb +5 -2
- data/lib/pubid/ieee/ire/parser.rb +19 -1
- data/lib/pubid/ieee/parser.rb +337 -49
- data/lib/pubid/ieee/project_renderer.rb +46 -0
- data/lib/pubid/ieee/renderer.rb +46 -14
- data/lib/pubid/ieee/urn_generator.rb +31 -0
- data/lib/pubid/ieee.rb +2 -0
- data/lib/pubid/ietf/CLAUDE.md +7 -0
- data/lib/pubid/ietf/builder.rb +2 -0
- data/lib/pubid/iho/builder.rb +2 -0
- data/lib/pubid/isbn/builder.rb +2 -0
- data/lib/pubid/iso/CLAUDE.md +47 -0
- data/lib/pubid/iso/builder.rb +29 -16
- data/lib/pubid/iso/components/publisher.rb +2 -0
- data/lib/pubid/iso/components.rb +0 -1
- data/lib/pubid/iso/identifier.rb +17 -18
- data/lib/pubid/iso/identifiers/all_parts.rb +19 -0
- data/lib/pubid/iso/identifiers/directives.rb +7 -4
- data/lib/pubid/iso/identifiers/directives_supplement.rb +4 -2
- data/lib/pubid/iso/identifiers/tc_document.rb +31 -46
- data/lib/pubid/iso/identifiers.rb +1 -0
- data/lib/pubid/iso/normalizer.rb +1 -1
- data/lib/pubid/iso/rendering_style.rb +0 -1
- data/lib/pubid/iso/urn_generator.rb +10 -10
- data/lib/pubid/iso.rb +5 -4
- data/lib/pubid/itu/CLAUDE.md +69 -0
- data/lib/pubid/itu/builder.rb +12 -0
- data/lib/pubid/itu/components/code.rb +2 -0
- data/lib/pubid/itu/components/designation.rb +2 -0
- data/lib/pubid/itu/components/sector.rb +2 -0
- data/lib/pubid/itu/components/series.rb +2 -0
- data/lib/pubid/itu/identifiers/base.rb +10 -0
- data/lib/pubid/itu/identifiers/contribution.rb +31 -0
- data/lib/pubid/itu/identifiers/supplement.rb +15 -0
- data/lib/pubid/itu/identifiers.rb +1 -0
- data/lib/pubid/itu/parser.rb +19 -2
- data/lib/pubid/jcgm/CLAUDE.md +7 -0
- data/lib/pubid/jcgm/builder.rb +2 -0
- data/lib/pubid/jcgm/components/publisher.rb +2 -0
- data/lib/pubid/jis/builder.rb +5 -1
- data/lib/pubid/jis/identifier.rb +5 -17
- data/lib/pubid/jis/identifiers/all_parts.rb +19 -0
- data/lib/pubid/jis/identifiers.rb +1 -0
- data/lib/pubid/jis/renderer.rb +0 -2
- data/lib/pubid/jis/urn_generator.rb +0 -1
- data/lib/pubid/nist/CLAUDE.md +56 -0
- data/lib/pubid/nist/builder.rb +14 -12
- data/lib/pubid/nist/components/edition.rb +2 -0
- data/lib/pubid/nist/components/issue_number.rb +2 -0
- data/lib/pubid/nist/components/part.rb +2 -0
- data/lib/pubid/nist/components/stage.rb +2 -0
- data/lib/pubid/nist/components/supplement.rb +2 -0
- data/lib/pubid/nist/components/translation.rb +2 -0
- data/lib/pubid/nist/components/update.rb +2 -0
- data/lib/pubid/nist/components/version.rb +2 -0
- data/lib/pubid/nist/components/volume.rb +2 -0
- data/lib/pubid/nist/identifiers/base.rb +34 -6
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +5 -6
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +2 -2
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +2 -2
- data/lib/pubid/nist/parser.rb +15 -2
- data/lib/pubid/nist/preprocessor.rb +53 -2
- data/lib/pubid/nist/series/ir.rb +3 -7
- data/lib/pubid/oasis/CLAUDE.md +19 -0
- data/lib/pubid/oasis/builder.rb +2 -0
- data/lib/pubid/oasis/identifier.rb +19 -0
- data/lib/pubid/ogc/CLAUDE.md +34 -0
- data/lib/pubid/ogc/builder.rb +2 -0
- data/lib/pubid/ogc/identifier.rb +11 -0
- data/lib/pubid/oiml/CLAUDE.md +189 -0
- data/lib/pubid/oiml/builder.rb +22 -2
- data/lib/pubid/oiml/components/code.rb +6 -0
- data/lib/pubid/oiml/identifier.rb +13 -0
- data/lib/pubid/oiml/identifiers/annex.rb +4 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +30 -36
- data/lib/pubid/oiml/identifiers/certification_system.rb +34 -0
- data/lib/pubid/oiml/identifiers/code_number.rb +10 -2
- data/lib/pubid/oiml/identifiers/dual_published.rb +174 -0
- data/lib/pubid/oiml/identifiers.rb +2 -0
- data/lib/pubid/oiml/parser.rb +41 -5
- data/lib/pubid/oiml/renderer.rb +26 -4
- data/lib/pubid/oiml/single_identifier.rb +5 -1
- data/lib/pubid/oiml/supplement_identifier.rb +7 -0
- data/lib/pubid/oiml/urn_generator.rb +32 -4
- data/lib/pubid/oiml.rb +5 -0
- data/lib/pubid/omg/CLAUDE.md +15 -0
- data/lib/pubid/omg/builder.rb +2 -0
- data/lib/pubid/parser/grammar.rb +23 -0
- data/lib/pubid/plateau/builder.rb +2 -0
- data/lib/pubid/plateau/identifiers/base.rb +4 -0
- data/lib/pubid/plateau/supplement_identifier.rb +14 -2
- data/lib/pubid/plateau/urn_generator.rb +7 -1
- data/lib/pubid/renderers/directives_renderer.rb +3 -1
- data/lib/pubid/renderers/human_readable.rb +0 -1
- data/lib/pubid/sae/builder.rb +3 -1
- data/lib/pubid/sae/components/date.rb +2 -0
- data/lib/pubid/sae/components/type.rb +2 -0
- data/lib/pubid/sae/identifiers/base.rb +4 -1
- data/lib/pubid/sae/urn_generator.rb +1 -1
- data/lib/pubid/subset_match.rb +197 -0
- data/lib/pubid/tgpp/CLAUDE.md +43 -0
- data/lib/pubid/tgpp/builder.rb +2 -0
- data/lib/pubid/tgpp/identifier.rb +14 -0
- data/lib/pubid/type_resolver.rb +14 -2
- data/lib/pubid/un/builder.rb +2 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/CLAUDE.md +7 -0
- data/lib/pubid/w3c/builder.rb +2 -0
- data/lib/pubid/xsf/CLAUDE.md +11 -0
- data/lib/pubid/xsf/builder.rb +2 -0
- data/lib/pubid.rb +16 -3
- data/lib/tasks/docs.rake +13 -11
- metadata +46 -4
- data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +0 -70
- data/lib/pubid/iso/components/code.rb +0 -24
data/lib/pubid/ieee/parser.rb
CHANGED
|
@@ -269,6 +269,10 @@ module Pubid
|
|
|
269
269
|
rule(:draft_date) do
|
|
270
270
|
# Enhanced to handle: ", Sept 2008" or " Sept 2008" or ", Month Year"
|
|
271
271
|
((comma | space) >> month_name.as(:month) >> space >> year_digits.as(:year)) |
|
|
272
|
+
# Space-separated bare year after the draft designator
|
|
273
|
+
# ("IEEE Draft Std P14764/D1 2004, Nov 2004" - the "D1 2004" draft
|
|
274
|
+
# carries its own year, with the print date still trailing).
|
|
275
|
+
(space >> year_digits.as(:year)) |
|
|
272
276
|
# Numeric-month form ", 05 2007" / " 05 2007" — no text month name. The
|
|
273
277
|
# year separator may be a dash: preprocessing (parser.rb ~1278) rewrites
|
|
274
278
|
# a trailing " <digits> <year>" to "<digits>-<year>", so "05 2007"
|
|
@@ -302,6 +306,15 @@ module Pubid
|
|
|
302
306
|
rule(:draft) do
|
|
303
307
|
(draft_prefix >> draft_version.repeat(1, 2) >>
|
|
304
308
|
(dot >> digits.as(:revision)).maybe >>
|
|
309
|
+
# The compound both-systems form (docs/IEEE-DRAFT-STAGES.md
|
|
310
|
+
# §1.3): "=DDIS.3" - IEEE draft ordinal = draft of the ISO/IEC
|
|
311
|
+
# stage, with its iteration. The glued "=DDIS3" / "=DDIS-3"
|
|
312
|
+
# spellings are accepted aliases of "=DDIS.3".
|
|
313
|
+
(str("=") >> (str("D") >> (str("FDIS") | str("CDV") | str("PWI") |
|
|
314
|
+
str("DIS") | str("WD") | str("NP") | str("CD")) |
|
|
315
|
+
(str("FDIS") | str("CDV") | str("PWI") | str("DIS") | str("WD") |
|
|
316
|
+
str("NP") | str("CD"))).as(:draft_iso_stage) >>
|
|
317
|
+
(dot | dash).maybe >> digits.as(:draft_iso_iteration).maybe).maybe >>
|
|
305
318
|
draft_date.maybe).as(:draft)
|
|
306
319
|
end
|
|
307
320
|
|
|
@@ -532,7 +545,9 @@ module Pubid
|
|
|
532
545
|
|
|
533
546
|
# Additional parameters (inside parentheses)
|
|
534
547
|
rule(:additional_parameters) do
|
|
535
|
-
(space.maybe >> str("(") >> #
|
|
548
|
+
(space.maybe >> str("(") >> space.maybe >> # Space before/after '(' optional
|
|
549
|
+
# ("( Revision of …)" - a crawl space inside the paren must not push
|
|
550
|
+
# the narrative to the catch-all and into the render).
|
|
536
551
|
(reaffirmed |
|
|
537
552
|
# Handle "Revision of IEEE Std ..." with optional space after Std
|
|
538
553
|
(str("Revision of IEEE Std ") >> space.maybe >> match("[^)]").repeat(1).as(:revision_of)) |
|
|
@@ -582,15 +597,32 @@ module Pubid
|
|
|
582
597
|
# ALSO handle: IEEE/CSA P844.1/293.1/D2 (CSA dual numbering)
|
|
583
598
|
(str("ISO/IEC/IEEE") | str("ISO/IEEE") | str("IEC/IEEE") | str("IEEE/CSA")).as(:joint_publishers) >>
|
|
584
599
|
space >>
|
|
585
|
-
|
|
600
|
+
# P = project (the document is a draft): identity-bearing, so it
|
|
601
|
+
# is captured and preserved, never silently consumed.
|
|
602
|
+
str("P").as(:project_marker) >>
|
|
586
603
|
digits.as(:number) >>
|
|
587
604
|
((dot | dash) >> digits.as(:part)).maybe >> # Optional part like .1 or -1
|
|
588
605
|
# CSA dual numbering: /293.1 (second number)
|
|
589
606
|
(slash >> digits >> (dot >> digits).maybe >> (dash >> digits.as(:draft_version)).maybe).maybe >>
|
|
590
607
|
(
|
|
591
|
-
# Variant
|
|
592
|
-
|
|
593
|
-
#
|
|
608
|
+
# Variant 1b: the ordinal-less stage draft "D=CDV[:2020]" -
|
|
609
|
+
# D (draft) = CDV (the IEC stage it drafts). The year rides in
|
|
610
|
+
# the draft clause (a distinct key, so the builder keeps the
|
|
611
|
+
# date inside the designator).
|
|
612
|
+
(slash >> str("D") >> str("=") >>
|
|
613
|
+
(str("CDV") | str("FDIS") | str("PWI") | str("WD") |
|
|
614
|
+
str("NP") | str("DIS") | str("CD")).as(:draft_iso_stage) >>
|
|
615
|
+
(str(":") >> year_digits.as(:draft_stage_year)).maybe) |
|
|
616
|
+
# Variant 1: /D8 notation (original), with the compound
|
|
617
|
+
# both-systems suffix "=DDIS.3" (docs/IEEE-DRAFT-STAGES.md §1.3)
|
|
618
|
+
(slash >> str("D") >> digits.as(:draft_version) >>
|
|
619
|
+
(str("=") >> (str("D") >> (str("FDIS") | str("CDV") | str("PWI") |
|
|
620
|
+
str("DIS") | str("WD") | str("NP") | str("CD")) |
|
|
621
|
+
(str("FDIS") | str("CDV") | str("PWI") | str("DIS") | str("WD") |
|
|
622
|
+
str("NP") | str("CD"))).as(:draft_iso_stage) >>
|
|
623
|
+
(dot | dash).maybe >> digits.as(:draft_iso_iteration).maybe).maybe) |
|
|
624
|
+
# Variant 2: , CDV1 notation (comma before stage code) —
|
|
625
|
+
# the stage draft of the named ISO/IEC stage, its iteration
|
|
594
626
|
(comma >> (str("CDV") | str("FDIS") | str("CD") | str("DIS")).as(:iec_stage) >> digits.maybe.as(:stage_iteration))
|
|
595
627
|
).maybe >>
|
|
596
628
|
# Optional edition, from relaton's "/E-<n>" suffix normalized to
|
|
@@ -611,42 +643,101 @@ module Pubid
|
|
|
611
643
|
# "-YYYY[-MM]" date (instead of ":YYYY"), multi-digit committee-draft
|
|
612
644
|
# stage codes (CD1..CD4) plus CDV, and a wider set of joint publishers.
|
|
613
645
|
# (roadmap items 2/3, phase 1). longest publisher token first.
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
646
|
+
# The stage is OPTIONAL ONLY for ISO-led joint prefixes - the
|
|
647
|
+
# stage-less PUBLISHED form (pubid#317): "ISO/IEC/IEEE 26511:2018",
|
|
648
|
+
# "ISO/IEEE 11073-20101:2004(E)". Every other prefix keeps the
|
|
649
|
+
# stage REQUIREMENT so this rule cannot steal what belongs to
|
|
650
|
+
# iec_ieee_copublished ("IEC/IEEE 60076-2016"), the bare-IEEE
|
|
651
|
+
# project rules ("IEEE P802.16/D-3") or the ISO flavor
|
|
652
|
+
# ("ISO/IEC <n>:<year>").
|
|
653
|
+
iso_led = (str("ISO/IEC/IEEE") | str("IEEE/ISO/IEC") |
|
|
654
|
+
str("IEEE/IEC/ISO") | str("ISO/IEEE"))
|
|
655
|
+
staged_only = (str("IEC/IEEE") | str("IEEE/IEC") |
|
|
656
|
+
str("ISO/IEC") | str("IEEE"))
|
|
657
|
+
# ISO stage codes: FDIS, FCD, CDV; DIS/CD with an optional round
|
|
658
|
+
# digit (DIS2, CD1..CD4); WD/PWI/NP.
|
|
659
|
+
iso_stage = (str("FDIS") | str("FCD") | str("CDV") |
|
|
660
|
+
(str("DIS") >> digit.maybe) |
|
|
661
|
+
(str("CD") >> digit.maybe) |
|
|
662
|
+
str("WD") | str("PWI") | str("NP")).as(:iso_stage)
|
|
663
|
+
std_noise = (space >> str("Std")).maybe
|
|
664
|
+
# The empty-string marker distinguishes the stage-less PUBLISHED
|
|
665
|
+
# tree in the builder (absence of :iso_stage alone means IEEE format).
|
|
666
|
+
((iso_led.as(:joint_publishers) >> space >>
|
|
667
|
+
(iso_stage >> std_noise >> space |
|
|
668
|
+
str("").as(:iso_published) >> space.maybe)) |
|
|
669
|
+
(staged_only.as(:joint_publishers) >> space >>
|
|
670
|
+
iso_stage >> std_noise >> space)) >>
|
|
671
|
+
str("P").as(:project_marker).maybe >> # project marker (P =
|
|
672
|
+
# project/draft; its
|
|
673
|
+
# presence is identity)
|
|
628
674
|
digits.as(:number) >>
|
|
629
|
-
# part must not swallow the trailing year (year_digits.absent?)
|
|
630
|
-
|
|
675
|
+
# part must not swallow the trailing year (year_digits.absent?). A
|
|
676
|
+
# DASH-joined part is tagged (:part_dash) - the catalogue-printed
|
|
677
|
+
# joint form spells the part with a dash ("21451-7") where the ISO
|
|
678
|
+
# form uses the dot.
|
|
679
|
+
((dot >> year_digits.absent? >> digits.as(:part)) |
|
|
680
|
+
(dash >> str("").as(:part_dash) >> year_digits.absent? >>
|
|
681
|
+
digits.as(:part))).maybe >>
|
|
631
682
|
(
|
|
632
683
|
(str(":") >> year_digits.as(:year)) |
|
|
684
|
+
# The dash-year (and ", Month YYYY" text date below) spellings are
|
|
685
|
+
# the catalogue-PRINTED joint form; tag them (:printed_form) so the
|
|
686
|
+
# builder routes to a Standard instead of the ISO joint reference.
|
|
633
687
|
(dash >> year_digits.as(:year) >>
|
|
634
|
-
(dash >> month_numeric.as(:month)).maybe
|
|
688
|
+
(dash >> month_numeric.as(:month)).maybe >>
|
|
689
|
+
str("").as(:printed_dash_year)) |
|
|
635
690
|
# Trailing text date ", April 2015" / " April 2015" (build_joint_development
|
|
636
691
|
# already reads :month/:year). No :year collision — the iso rule has no
|
|
637
692
|
# other :year capture (edition uses :edition_year).
|
|
638
|
-
((comma | space) >> month_name.as(:month) >> space >>
|
|
693
|
+
((comma | space) >> month_name.as(:month) >> space >>
|
|
694
|
+
year_digits.as(:year) >> str("").as(:printed_month_year))
|
|
639
695
|
).maybe >>
|
|
640
696
|
# Optional /D<draft> tail. normalize_relaton_suffixes repositions the
|
|
641
697
|
# historical "…/D-3-2017" onto the number as "…-2017/D3", so by the
|
|
642
698
|
# time this rule runs the draft usually trails the date (bucket 5);
|
|
643
699
|
# a date-less "/D-4" keeps its hyphen (bucket 7), hence dash.maybe.
|
|
700
|
+
# A text date may trail the DRAFT itself (pubid#216:
|
|
701
|
+
# "CD P26515/D1, March 2017", "FDIS P15289/D3, 2017") — distinct
|
|
702
|
+
# keys (:draft_month/:draft_year), because a plain :month/:year
|
|
703
|
+
# here collides with the date clause above and parslet drops the
|
|
704
|
+
# subtree with a "Duplicate subtrees" warning.
|
|
705
|
+
# The ISO/IEC edition marker may sit between the year and an
|
|
706
|
+
# amendment/draft tail: "8802.11:2012 (E)/Amd 1-2014". A distinct
|
|
707
|
+
# key - a second :parameters capture here collides with the
|
|
708
|
+
# trailing parenthetical slot (parslet drops duplicate subtrees).
|
|
709
|
+
(space.maybe >> str("(") >>
|
|
710
|
+
match("[^)]").repeat(1).as(:edition_marker) >> str(")")).maybe >>
|
|
711
|
+
# The stage-draft clause of the ISO-led print: "/D=WD.5" -
|
|
712
|
+
# D (draft) = the ISO/IEC stage it drafts, with its iteration
|
|
713
|
+
# (docs/IEEE-DRAFT-STAGES.md §1.2).
|
|
714
|
+
((slash >> str("D") >> str("=") >>
|
|
715
|
+
(str("FDIS") | str("FCD") | str("CDV") |
|
|
716
|
+
(str("DIS") >> digit.maybe) |
|
|
717
|
+
(str("CD") >> digit.maybe) |
|
|
718
|
+
str("WD") | str("PWI") | str("NP")).as(:draft_iso_stage) >>
|
|
719
|
+
(dot >> (digits >> match("[A-Za-z]").repeat(0, 1)).as(:draft_iso_iteration)).maybe) |
|
|
644
720
|
(slash >> str("D") >> dash.maybe >>
|
|
645
|
-
match('[0-9.]').repeat(1).as(:draft_version)
|
|
721
|
+
match('[0-9.]').repeat(1).as(:draft_version) >>
|
|
722
|
+
(((comma | space) >> month_name.as(:draft_month) >> space >>
|
|
723
|
+
year_digits.as(:draft_year)) |
|
|
724
|
+
(comma >> year_digits.as(:draft_year))).maybe).maybe).maybe >>
|
|
725
|
+
# Optional amendment tail (pubid#317:
|
|
726
|
+
# "8802-11:2012/Amd.1:2014(E)") - the flat tree keys reuse
|
|
727
|
+
# build_flat_amendment.
|
|
728
|
+
(slash >> str("Amd") >> (dot | space).maybe >>
|
|
729
|
+
digits.as(:amd_number) >>
|
|
730
|
+
((str(":") | dash) >> year_digits.as(:amd_year)).maybe).maybe >>
|
|
646
731
|
# Optional edition, from relaton's "/E-<n>" suffix normalized to
|
|
647
732
|
# "Edition <n>.0[ YYYY]" (nil-residue hand-off item 1).
|
|
648
733
|
edition.maybe >>
|
|
649
|
-
revision_suffix.maybe
|
|
734
|
+
revision_suffix.maybe >>
|
|
735
|
+
# Published joint docs print a language marker, after either the
|
|
736
|
+
# year or the amendment tail: "9945:2009(E)", "...Amd.1:2014(E)".
|
|
737
|
+
# The crawl sometimes spaces it ("…(E), January 2017" family,
|
|
738
|
+
# pubid#216), and a relationship parenthetical may follow
|
|
739
|
+
# ("…CD2 P15288-2013-09 (Revision of …)").
|
|
740
|
+
parenthetical.maybe
|
|
650
741
|
end
|
|
651
742
|
|
|
652
743
|
# Embedded (stage-LAST) ISO-led designations: the corpus writes the ISO
|
|
@@ -659,6 +750,28 @@ module Pubid
|
|
|
659
750
|
# the trailing `.FDIS` is the ISO stage, NOT a second part. Routes through
|
|
660
751
|
# the same build_joint_development (via :joint_publishers/:iso_stage), so the
|
|
661
752
|
# stage is modeled correctly and the numeric part stays separate.
|
|
753
|
+
# The stage-less ISO/IEC label with a colon year and the ISO/IEC
|
|
754
|
+
# edition marker: "ISO/IEC 13210:1994 (E)" - the ISO/IEC portion of a
|
|
755
|
+
# double-labeled standard. The (E) parenthetical is REQUIRED: without
|
|
756
|
+
# it this spelling is the ISO flavor's own form and must not be
|
|
757
|
+
# stolen. Routes through build_joint_development like every ISO-led
|
|
758
|
+
# joint reference.
|
|
759
|
+
rule(:joint_development_iso_iec_edition) do
|
|
760
|
+
str("ISO/IEC").as(:joint_publishers) >> space >>
|
|
761
|
+
str("").as(:iso_published) >>
|
|
762
|
+
str("P").as(:project_marker).maybe >>
|
|
763
|
+
digits.as(:number) >>
|
|
764
|
+
# The part may be dot- or dash-joined ("8802-9"); a dash-year
|
|
765
|
+
# ("1234-2012") is not a part.
|
|
766
|
+
# A distinct key: the iso-format route's :part_dash prints as a
|
|
767
|
+
# dot in the joint code (the "P24748.2:2018" convention); only
|
|
768
|
+
# the ISO/IEC LABEL keeps its printed dash.
|
|
769
|
+
((dot | (dash >> str("").as(:iec_label_dash) >> year_digits.absent?)) >>
|
|
770
|
+
digits.as(:part)).maybe >>
|
|
771
|
+
(str(":") >> space.maybe >> year_digits.as(:year)) >>
|
|
772
|
+
space.maybe >> parenthetical
|
|
773
|
+
end
|
|
774
|
+
|
|
662
775
|
rule(:joint_development_embedded_stage) do
|
|
663
776
|
# publisher set mirrors joint_development_iso_format (incl. bare IEEE);
|
|
664
777
|
# longest token first.
|
|
@@ -666,7 +779,9 @@ module Pubid
|
|
|
666
779
|
str("ISO/IEEE") | str("IEC/IEEE") | str("IEEE/IEC") | str("ISO/IEC") |
|
|
667
780
|
str("IEEE")).as(:joint_publishers) >>
|
|
668
781
|
space >>
|
|
669
|
-
str("P").maybe >> #
|
|
782
|
+
str("P").as(:project_marker).maybe >> # project marker (P =
|
|
783
|
+
# project/draft; its
|
|
784
|
+
# presence is identity)
|
|
670
785
|
digits.as(:number) >>
|
|
671
786
|
# optional numeric part (dot or dash); must not swallow a year
|
|
672
787
|
((dot | dash) >> year_digits.absent? >> digits.as(:part)).maybe >>
|
|
@@ -701,9 +816,13 @@ module Pubid
|
|
|
701
816
|
end
|
|
702
817
|
|
|
703
818
|
# IEEE P pattern (without Std): "IEEE P1003.1..." OR just "P1003.1..." (prefix optional)
|
|
819
|
+
# `P` is not consumed here: the `number` rule carries its own optional
|
|
820
|
+
# leading P and captures it into :number ("P1003.1"), so Code.parse
|
|
821
|
+
# peels it as code.prefix and the project marker survives the parse —
|
|
822
|
+
# a bare `str("P")` swallowed it and "P1201/D0.3" came back without
|
|
823
|
+
# its P at all (pubid#18's data-loss complaint).
|
|
704
824
|
rule(:ieee_p_identifier) do
|
|
705
825
|
(str("IEEE").as(:publisher) >> space).maybe >> # Make IEEE prefix optional
|
|
706
|
-
str("P") >> space.maybe >> # Make space after P optional
|
|
707
826
|
number >>
|
|
708
827
|
(part_subpart_year | edition).maybe >>
|
|
709
828
|
# Pattern for /08 style drafts (digits without D prefix) - MUST come before corrigendum
|
|
@@ -759,15 +878,17 @@ module Pubid
|
|
|
759
878
|
# status is captured (draft_status ends in a space, so "Approved Draft"
|
|
760
879
|
# splits cleanly) and round-trips as the draft_status attribute; the literal
|
|
761
880
|
# "Draft" stays a bare marker (dropped on render, like the plain form).
|
|
881
|
+
# `P` is not consumed here: the `number` rule carries its own optional
|
|
882
|
+
# leading P and captures it into :number ("P802.11"), so Code.parse peels
|
|
883
|
+
# it as code.prefix and the project marker round-trips (pubid#318) — a
|
|
884
|
+
# bare `str("P").maybe` here swallowed it and the render lost the P.
|
|
762
885
|
rule(:ieee_draft_p_identifier) do
|
|
763
886
|
(str("IEEE").as(:publisher) >> space).maybe >> # Make IEEE prefix optional
|
|
764
887
|
draft_status.as(:draft_status).maybe >>
|
|
765
888
|
str("Draft") >> space >>
|
|
766
|
-
#
|
|
767
|
-
# ("IEEE Unapproved Draft 802.1ah/D4.2")
|
|
768
|
-
# ieee_approved_draft_identifier's str("P").maybe. The `number` rule
|
|
889
|
+
# A status-word draft may carry a bare number
|
|
890
|
+
# ("IEEE Unapproved Draft 802.1ah/D4.2"). The `number` rule
|
|
769
891
|
# already accepts the bare forms (802.1ah, C57.15, 11073-10471).
|
|
770
|
-
str("P").maybe >>
|
|
771
892
|
number >>
|
|
772
893
|
(part_subpart_year | edition).maybe >>
|
|
773
894
|
# Trailing "Month YYYY" date under distinct keys so it never collides
|
|
@@ -775,7 +896,17 @@ module Pubid
|
|
|
775
896
|
((space >> month_name.as(:trailing_month) >> space >> year_digits.as(:trailing_year)) |
|
|
776
897
|
(space >> month_numeric.as(:trailing_month) >> (space | dash) >> year_digits.as(:trailing_year))).maybe >>
|
|
777
898
|
draft.maybe >>
|
|
899
|
+
# A print date may trail a draft that carries its own date
|
|
900
|
+
# ("IEEE Unapproved Draft 24765/D1 2009, Oct 2009" - the draft's
|
|
901
|
+
# year is "2009", the print date is ", Oct 2009").
|
|
902
|
+
(comma >> space? >> month_name.as(:trailing_month) >> space >>
|
|
903
|
+
year_digits.as(:trailing_year)).maybe >>
|
|
778
904
|
revision_suffix.maybe >>
|
|
905
|
+
# …and the print date may also trail the repositioned revision
|
|
906
|
+
# ("IEEE Unapproved Draft P802.16Rev2/D9a, March 2009" reaches the
|
|
907
|
+
# grammar as "…/D9a/R-2, March 2009" via normalize_revision_notation).
|
|
908
|
+
(comma >> space? >> month_name.as(:trailing_month) >> space >>
|
|
909
|
+
year_digits.as(:trailing_year)).maybe >>
|
|
779
910
|
# Trailing corrigendum after the draft ("…/D2.0/Cor. 1", or
|
|
780
911
|
# "…/D1.0, Dec 2007/Cor. 1" where the draft's own draft_date consumes
|
|
781
912
|
# the date, leaving "/Cor. N"). The flat corrigendum+draft tree (no
|
|
@@ -836,6 +967,11 @@ module Pubid
|
|
|
836
967
|
# Year-first pattern: "52 IRE 7.S2" or "60 IRE 28 PS7"
|
|
837
968
|
((match("[1-6]") >> digit >> space >> str("IRE")) | # 2-digit year format
|
|
838
969
|
(str("19") >> digit.repeat(2, 2) >> space >> str("IRE"))) |
|
|
970
|
+
# Prefix-first pattern: "IRE 7.S2-1952" (pubid#316 family 2) —
|
|
971
|
+
# IRE then a designation (digits or a type word). Loose on
|
|
972
|
+
# purpose: the sub-parser is strict, and a failed delegation just
|
|
973
|
+
# falls through to the remaining alternatives.
|
|
974
|
+
(str("IRE") >> space >> (digits | str("Standard") | str("Std") | str("Trans"))) |
|
|
839
975
|
# IEEE-IRE transitional pattern
|
|
840
976
|
(str("IEEE-IRE") >> space)
|
|
841
977
|
).present? >>
|
|
@@ -855,29 +991,60 @@ module Pubid
|
|
|
855
991
|
# Draft NESC pattern
|
|
856
992
|
(str("Draft") >> space >> (str("NESC") | str("National Electrical Safety Code"))) |
|
|
857
993
|
# Name-first pattern (NEW)
|
|
858
|
-
(str("National Electrical Safety Code") >> str(",") >> space >> str("C2-"))
|
|
994
|
+
(str("National Electrical Safety Code") >> str(",") >> space >> str("C2-")) |
|
|
995
|
+
# Catalogue form: "IEEE Std YYYY NESC ..." / "IEEE Std YYYY National
|
|
996
|
+
# Electrical Safety Code" - the prefix is consumed here (the NESC
|
|
997
|
+
# renderer prepends "IEEE Std" itself) but must not fall through to
|
|
998
|
+
# the generic standard grammar, which would read YYYY as a number.
|
|
999
|
+
(str("IEEE") >> space >> str("Std") >> space >> year_digits >> space >>
|
|
1000
|
+
(str("NESC") | str("National Electrical Safety Code")))
|
|
859
1001
|
).present? >>
|
|
860
1002
|
# Delegate to NESC parser if pattern detected
|
|
861
|
-
|
|
1003
|
+
((str("IEEE") >> space >> str("Std") >> space).maybe >>
|
|
1004
|
+
Nesc::Parser.new.nesc_identifier).as(:nesc)
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
# Draft notation for PSI (e.g., /D2, /D3, rawbib's /D-2)
|
|
1008
|
+
rule(:psi_draft) do
|
|
1009
|
+
slash >> str("D") >> dash.maybe >> digits.as(:draft_version)
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
# Date on an SI/PSI identifier: ", Month Year" or "-YEAR[-MM]". The
|
|
1013
|
+
# comma branch also accepts a NUMERIC month and a DASH before the
|
|
1014
|
+
# year — the renderer emits ", 05 2010" for a numeric-month draft,
|
|
1015
|
+
# and the preprocessing gsub rewrites a trailing " <digits> <year>"
|
|
1016
|
+
# to "<digits>-<year>" (the same load-bearing coupling draft_date
|
|
1017
|
+
# documents), so the re-parse must read its own rendering back.
|
|
1018
|
+
rule(:psi_date) do
|
|
1019
|
+
(comma >> (month_name | month_numeric).as(:month) >> (space | dash) >>
|
|
1020
|
+
year_digits.as(:year)) |
|
|
1021
|
+
(dash >> year_digits.as(:year) >>
|
|
1022
|
+
(dash >> digit.repeat(2, 2).as(:month)).maybe)
|
|
862
1023
|
end
|
|
863
1024
|
|
|
864
1025
|
# IEEE/ASTM SI/PSI (Système International) patterns
|
|
865
1026
|
# SI = Published metric system standard
|
|
866
1027
|
# PSI = Proposed SI (draft)
|
|
1028
|
+
# Rawbib spellings (pubid#316 family 3): a bare "IEEE" publisher, a dot
|
|
1029
|
+
# separator after the type ("PSI.10", "SI 10.1997"), relaton's
|
|
1030
|
+
# hyphenated "/D-<n>" draft, and a dash year-month ("-2010-05").
|
|
867
1031
|
rule(:ieee_astm_si_psi) do
|
|
868
|
-
str("IEEE/ASTM").as(:publishers) >>
|
|
1032
|
+
(str("IEEE/ASTM") | str("IEEE")).as(:publishers) >>
|
|
869
1033
|
space >>
|
|
870
1034
|
(str("PSI") | str("SI")).as(:si_type) >>
|
|
871
|
-
space >>
|
|
1035
|
+
(space | str(".")) >>
|
|
872
1036
|
digits.as(:number) >>
|
|
873
|
-
#
|
|
874
|
-
(
|
|
875
|
-
#
|
|
1037
|
+
# Glued ".YEAR" edition date ("IEEE/ASTM SI 10.1997")
|
|
1038
|
+
(str(".") >> year_digits.as(:year)).maybe >>
|
|
1039
|
+
# The date and the draft appear in EITHER order: the legacy
|
|
1040
|
+
# spelling puts the draft first ("PSI 10/D2, October 2015"),
|
|
1041
|
+
# while normalize_relaton_suffixes repositions the rawbib
|
|
1042
|
+
# hyphenated form onto the number ("PSI 10/D-3-2010" →
|
|
1043
|
+
# "PSI 10-2010/D3"). Draft-first is tried first so the legacy
|
|
1044
|
+
# comma-date keeps its original match; each side is optional so
|
|
1045
|
+
# a date-only or draft-less form still parses.
|
|
876
1046
|
(
|
|
877
|
-
|
|
878
|
-
(comma >> month_name.as(:month) >> space >> year_digits.as(:year)) |
|
|
879
|
-
# Format: "-YEAR"
|
|
880
|
-
(dash >> year_digits.as(:year))
|
|
1047
|
+
(psi_draft >> psi_date.maybe) | (psi_date >> psi_draft.maybe)
|
|
881
1048
|
).maybe >>
|
|
882
1049
|
# Optional parenthetical (revision relationships)
|
|
883
1050
|
parenthetical.maybe
|
|
@@ -988,13 +1155,13 @@ module Pubid
|
|
|
988
1155
|
str("CSA") >> space >>
|
|
989
1156
|
# CSA number formats (various patterns observed)
|
|
990
1157
|
(
|
|
991
|
-
# Format 1: C22.2 No. 293.1-17 (with NO
|
|
992
|
-
(str("C") >> digit.repeat(2) >> dot >> digit >> space >> str("No") >> dot >> space >>
|
|
1158
|
+
# Format 1: C22.2 No. 293.1-17 (with NO., either case)
|
|
1159
|
+
(str("C") >> digit.repeat(2) >> dot >> digit >> space >> (str("No") | str("NO")) >> dot >> space >>
|
|
993
1160
|
match("[0-9.]").repeat(1) >> (dash | str(":")) >> digit.repeat(2)) |
|
|
994
1161
|
# Format 2: C293.2-17 (without NO., dash year)
|
|
995
1162
|
(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 >>
|
|
1163
|
+
# Format 3: C22.2 No. 293.3:19 (with NO., either case, colon year)
|
|
1164
|
+
(str("C") >> digit.repeat(2) >> dot >> digit >> space >> (str("No") | str("NO")) >> dot >> space >>
|
|
998
1165
|
match("[0-9.]").repeat(1) >> str(":") >> digit.repeat(2)) |
|
|
999
1166
|
# Format 4: C293.4:19 (without NO., colon year)
|
|
1000
1167
|
(str("C") >> match("[0-9.]").repeat(1) >> str(":") >> digit.repeat(2))
|
|
@@ -1017,6 +1184,8 @@ module Pubid
|
|
|
1017
1184
|
conformance_identifier | # NEW: Try conformance identifier before generic patterns
|
|
1018
1185
|
joint_development_ieee_format |
|
|
1019
1186
|
joint_development_iso_format |
|
|
1187
|
+
joint_development_iso_iec_edition | # stage-less ISO/IEC label with (E) - double-label portion
|
|
1188
|
+
|
|
1020
1189
|
joint_development_embedded_stage | # stage-LAST embedded form (before generic)
|
|
1021
1190
|
iec_ieee_copublished |
|
|
1022
1191
|
number_first_identifier |
|
|
@@ -1042,6 +1211,15 @@ module Pubid
|
|
|
1042
1211
|
# never collides with the base -YYYY identity year (see
|
|
1043
1212
|
# ieee_p_identifier). The builder promotes it only when no base year.
|
|
1044
1213
|
trailing_month_year.maybe >>
|
|
1214
|
+
# The ASHRAE joint suffix may also trail a draft+date
|
|
1215
|
+
# ("IEEE P1635/D13, December, 2017/ASHRAE Guideline 21"), so a
|
|
1216
|
+
# second slot catches it after the date.
|
|
1217
|
+
ashrae_copub.maybe >>
|
|
1218
|
+
# A bracketed narrative may sit between the base and a trailing
|
|
1219
|
+
# corrigendum: "IEEE Std 671-1985 [Corrigendum to IEEE Std 671-1985
|
|
1220
|
+
# (Reaff 2008)]/Cor. 1-2010" captures the bracket as the base's
|
|
1221
|
+
# nickname before the wrapper is parsed.
|
|
1222
|
+
book_nickname.maybe >>
|
|
1045
1223
|
# Trailing corrigendum after the draft+date ("IEEE Approved P1015/D1,
|
|
1046
1224
|
# Jan 2007/Cor. 1"): the generic bucket is the only path a status-word
|
|
1047
1225
|
# form reaches. Routes via build_flat_corrigendum (disjoint from the
|
|
@@ -1159,12 +1337,15 @@ module Pubid
|
|
|
1159
1337
|
# A "\d+" right after "Rev" both selects the numbered subset and keeps
|
|
1160
1338
|
# these off the English word "Revision". Three source positions:
|
|
1161
1339
|
# after a draft : "PC37.30.2/D043 Rev 18" -> ".../D043/R-18"
|
|
1340
|
+
# The draft captures accept relaton's hyphenated "/D-<n>" spelling
|
|
1341
|
+
# (pubid#316): without the "-?" the before-draft regex matched only
|
|
1342
|
+
# "/D" of "/D-3" and emitted the garbage "/D/R-2-3-2008-02".
|
|
1162
1343
|
cleaned = cleaned.sub(
|
|
1163
|
-
%r{(/D[0-9A-Za-z.]
|
|
1344
|
+
%r{(/D-?[0-9A-Za-z.]+)\s+[Rr][Ee][Vv]\s*(\d+)}, '\1/R-\2'
|
|
1164
1345
|
)
|
|
1165
1346
|
# before a draft: "P802.16Rev2/D3" -> "P802.16/D3/R-2"
|
|
1166
1347
|
cleaned = cleaned.sub(
|
|
1167
|
-
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?(\d+)(/D[0-9A-Za-z.]
|
|
1348
|
+
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?(\d+)(/D-?[0-9A-Za-z.]+)}, '\2/R-\1'
|
|
1168
1349
|
)
|
|
1169
1350
|
# no draft, trailing: "P1722-rev1" -> "P1722/R-1"
|
|
1170
1351
|
cleaned = cleaned.sub(
|
|
@@ -1176,7 +1357,7 @@ module Pubid
|
|
|
1176
1357
|
# became "/R-<n>", so these regexes only see the lettered residue.
|
|
1177
1358
|
# Revision token that PRECEDES a draft: drop it (keep the /D…).
|
|
1178
1359
|
cleaned = cleaned.sub(
|
|
1179
|
-
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?[A-Za-z0-9]+(?=/D[0-
|
|
1360
|
+
%r{[-/_.]?\s?[Rr][Ee][Vv][-\s]?[A-Za-z0-9]+(?=/D-?[0-9A-Za-z])},
|
|
1180
1361
|
"",
|
|
1181
1362
|
)
|
|
1182
1363
|
# Trailing revision glued to the number with no draft ("P802.11REVmb");
|
|
@@ -1185,6 +1366,108 @@ module Pubid
|
|
|
1185
1366
|
cleaned.sub(%r{(\d)[Rr][Ee][Vv][A-Za-z0-9]+\s*\z}, '\1')
|
|
1186
1367
|
end
|
|
1187
1368
|
|
|
1369
|
+
# Rewrite the mechanical spellings of the joint ISO-stage forms that no
|
|
1370
|
+
# grammar branch reaches (pubid#216 residuals). Two safety rules keep
|
|
1371
|
+
# this from stealing inputs other rules already parse:
|
|
1372
|
+
# 1. only BROKEN separators fire — underscore/space glue between
|
|
1373
|
+
# number, draft and stage, a slash-SPACE before the stage, a
|
|
1374
|
+
# dash/underscore month after it. A plain "/FDIS" tail is
|
|
1375
|
+
# natively accepted by ieee_p_identifier (fdraft) and the
|
|
1376
|
+
# stage-LAST embedded rule, so it is never rewritten.
|
|
1377
|
+
# 2. the number carries at most ONE part — joint_development_iso_format
|
|
1378
|
+
# reads a single optional part, while ieee_p_identifier takes
|
|
1379
|
+
# multi-part numbers ("P62271-37-013"); a rewrite that moved a
|
|
1380
|
+
# multi-part number onto the joint rule would break it.
|
|
1381
|
+
def self.normalize_joint_stage_spellings(cleaned)
|
|
1382
|
+
# The separator (slash-optional-space or a space) is INSIDE the
|
|
1383
|
+
# capture so a rewrite re-emits it — an uncaptured separator was
|
|
1384
|
+
# silently eaten, gluing the publisher to the stage.
|
|
1385
|
+
pubs = %r{((?:ISO/IEC/IEEE|IEEE/ISO/IEC|IEEE/IEC/ISO|ISO/IEEE|IEC/IEEE|IEEE/IEC|ISO/IEC|IEEE)(?:/ ?| ))}
|
|
1386
|
+
stage = /(FDIS|FCD|CDV|DIS\d?|CD\d?|WD|PWI|NP)/
|
|
1387
|
+
num = /(P?\d+(?:[.-]\d+)?)/
|
|
1388
|
+
# What the joint grammar can finish reading AFTER the stage: the end
|
|
1389
|
+
# of the string, a (comma-)month-year date, or a dash-year[-month].
|
|
1390
|
+
# Captured and re-emitted so a rewrite never drops the date.
|
|
1391
|
+
tail = /(,? (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Sept|Oct|Nov|Dec)[a-z]* \d{4}|\z|-\d{4}(?:-\d\d)?)/
|
|
1392
|
+
|
|
1393
|
+
# Draft glued to the number with an underscore: "P15289_D3" →
|
|
1394
|
+
# "P15289/D3" (a digit must precede the underscore; "_FDIS" is the
|
|
1395
|
+
# stage, not a draft, and is already slash-rewritten earlier).
|
|
1396
|
+
cleaned = cleaned.gsub(%r{(\d)_D(\d)}, '\1/D\2')
|
|
1397
|
+
|
|
1398
|
+
# Crawl typo: a comma with no space before a month (",March 2021").
|
|
1399
|
+
# In these identifiers a comma is always a date separator, so
|
|
1400
|
+
# spacing it is safe.
|
|
1401
|
+
cleaned = cleaned.sub(/,(?=[A-Za-z])/, ", ")
|
|
1402
|
+
|
|
1403
|
+
# Stage AFTER the draft, both glued with underscores (the early
|
|
1404
|
+
# stage gsub already turned "_CD" into "/CD"):
|
|
1405
|
+
# "…P24748-3/D3/FDIS, April 2020 (E)" → "…FDIS P24748-3/D3, …"
|
|
1406
|
+
cleaned = cleaned.sub(
|
|
1407
|
+
%r{\A#{pubs}#{num}/(D[\d.]+)/ ?#{stage}\b},
|
|
1408
|
+
'\1\4 \2/\3',
|
|
1409
|
+
)
|
|
1410
|
+
|
|
1411
|
+
# Slash-SPACE before the stage ("…P16085/ FDIS, August 2020" —
|
|
1412
|
+
# ieee_p's fdraft has no inner space, so this spelling has no other
|
|
1413
|
+
# home): → "…FDIS P16085, August 2020"
|
|
1414
|
+
cleaned = cleaned.sub(
|
|
1415
|
+
%r{\A#{pubs}#{num}/ #{stage}#{tail}},
|
|
1416
|
+
'\1\3 \2\4',
|
|
1417
|
+
)
|
|
1418
|
+
|
|
1419
|
+
# A space-year after a slash-stage ("…P26511.2/FDIS 2018" — no rule
|
|
1420
|
+
# reads "/FDIS 2018"): → "…FDIS P26511.2-2018" (dash-year clause).
|
|
1421
|
+
cleaned = cleaned.sub(
|
|
1422
|
+
%r{\A#{pubs}#{num}/#{stage} (\d{4})\b},
|
|
1423
|
+
'\1\3 \2-\4',
|
|
1424
|
+
)
|
|
1425
|
+
|
|
1426
|
+
# Stage separated from the number by a SPACE ("IEC/IEEE P63113 CD4,
|
|
1427
|
+
# April 2019"): → "IEC/IEEE CD4 P63113, April 2019". The tail guard
|
|
1428
|
+
# keeps "…FDIS March 2019" (space-month-year, readable after the
|
|
1429
|
+
# swap) while leaving prose suffixes alone.
|
|
1430
|
+
cleaned = cleaned.sub(
|
|
1431
|
+
%r{\A#{pubs}#{num} #{stage}#{tail}},
|
|
1432
|
+
'\1\3 \2\4',
|
|
1433
|
+
)
|
|
1434
|
+
|
|
1435
|
+
# The same space-stage with a space-DRAFT chained after it
|
|
1436
|
+
# ("IEC/IEEE P60980-344 CDV D1, June 2019"): → stage-first with a
|
|
1437
|
+
# slash draft ("…CDV P60980-344/D1, June 2019").
|
|
1438
|
+
cleaned = cleaned.sub(
|
|
1439
|
+
%r{\A#{pubs}#{num} #{stage} (D\d+)\b},
|
|
1440
|
+
'\1\3 \2/\4',
|
|
1441
|
+
)
|
|
1442
|
+
|
|
1443
|
+
# Slash-stage carrying a dash-date ("…P15288/CD2-2013-09 …" — the
|
|
1444
|
+
# dash-year tail is what the joint grammar reads after the number, so
|
|
1445
|
+
# this cannot steal the plain "/FDIS, June 2021" spellings
|
|
1446
|
+
# ieee_p_identifier finishes): → "…CD2 P15288-2013-09 …". The date
|
|
1447
|
+
# must be a plausible year — a 4-digit monthcode (YYMM, e.g.
|
|
1448
|
+
# "…P24748-4/DIS-1404" = April 2014) is a DRAFT designator, not a
|
|
1449
|
+
# dash-date, and rewriting it onto the number breaks the parse.
|
|
1450
|
+
cleaned = cleaned.sub(
|
|
1451
|
+
%r{\A#{pubs}#{num}/ ?#{stage}(-(?:19|20)\d\d(?:-\d\d)?)},
|
|
1452
|
+
'\1\3 \2\4',
|
|
1453
|
+
)
|
|
1454
|
+
|
|
1455
|
+
# Draft separated from a stage-first number by a SPACE:
|
|
1456
|
+
# "…DIS P11073-10418 D13, January 2011" → "…DIS P11073-10418/D13, …"
|
|
1457
|
+
cleaned = cleaned.sub(
|
|
1458
|
+
%r{\A#{pubs}#{stage} #{num}/? ?(D\d+)\b},
|
|
1459
|
+
'\1\2 \3/\4',
|
|
1460
|
+
)
|
|
1461
|
+
|
|
1462
|
+
# NOT rewritten: a month glued to the stage with a dash/underscore
|
|
1463
|
+
# ("…/FDIS_Dec 2012", "…/FDIS-Dec 2015"). Even routed onto the joint
|
|
1464
|
+
# grammar, the joint render of a month+draft is itself not yet
|
|
1465
|
+
# idempotent, and the bare-IEEE fdraft path drops the stage and the
|
|
1466
|
+
# date from to_hash — rewriting would trade a visible parse failure
|
|
1467
|
+
# for silent garbage. Deferred with the pubid#216 semantic residue.
|
|
1468
|
+
cleaned
|
|
1469
|
+
end
|
|
1470
|
+
|
|
1188
1471
|
def self.parse(string)
|
|
1189
1472
|
# Strip .pdf extension if present (Pattern 3: File Extensions)
|
|
1190
1473
|
cleaned = string.sub(/\.pdf$/i, "")
|
|
@@ -1265,6 +1548,11 @@ module Pubid
|
|
|
1265
1548
|
/\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Sept|Oct|Nov|Dec)(\d{4})\b/, '\1 \2'
|
|
1266
1549
|
)
|
|
1267
1550
|
|
|
1551
|
+
# Rewrite the joint ISO-stage glued spellings (pubid#216) AFTER the
|
|
1552
|
+
# month unglue above, so "Dec2015" is already spaced when the
|
|
1553
|
+
# dash-month rewrite looks for it.
|
|
1554
|
+
cleaned = normalize_joint_stage_spellings(cleaned)
|
|
1555
|
+
|
|
1268
1556
|
# NEW: Convert IEC/IEEE space-separated to semicolon format
|
|
1269
1557
|
# Pattern: "IEC 61523-3 First edition 2004-09; IEEE 1497" → already semicolon
|
|
1270
1558
|
# Pattern: "IEC 62539 First Edition 2007-07 IEEE 930" → needs semicolon
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ieee
|
|
5
|
+
# Renders the IEEE PROJECT DESIGNATOR — the short form IEEE itself uses
|
|
6
|
+
# for draft documents ("P1201/D0.3", "P10000/D1.2"): the project marker,
|
|
7
|
+
# the number with its parts, and the draft. No publisher, no type word,
|
|
8
|
+
# no date (pubid#18: metanorma-ieee builds these for drafts and had to
|
|
9
|
+
# post-process the full rendering).
|
|
10
|
+
class ProjectRenderer
|
|
11
|
+
def initialize(id)
|
|
12
|
+
@id = id
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render(context: nil, **_opts)
|
|
16
|
+
id = @id
|
|
17
|
+
body = if id.respond_to?(:code_obj) && id.code_obj
|
|
18
|
+
id.code_obj.to_s
|
|
19
|
+
else
|
|
20
|
+
id.number.to_s
|
|
21
|
+
end
|
|
22
|
+
body = "P#{body}" if project?(id) && !body.start_with?("P")
|
|
23
|
+
|
|
24
|
+
draft = id.draft_obj if id.respond_to?(:draft_obj)
|
|
25
|
+
body += "/D#{draft.version}" if draft&.version
|
|
26
|
+
|
|
27
|
+
body
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# A project identifier carries its marker in one of three places
|
|
33
|
+
# depending on which grammar path built it: the code prefix (the bare
|
|
34
|
+
# "P1201/D0.3" spelling), the "P" type code ("IEEE P802.16/D-3"), or a
|
|
35
|
+
# typed stage with project_status (the D1-D6 draft stages).
|
|
36
|
+
def project?(id)
|
|
37
|
+
return true if id.code_obj&.prefix.to_s == "P"
|
|
38
|
+
return true if id.type.to_s == "P"
|
|
39
|
+
|
|
40
|
+
id.respond_to?(:typed_stage) &&
|
|
41
|
+
id.typed_stage&.respond_to?(:project_status) &&
|
|
42
|
+
id.typed_stage.project_status
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|