pubid 2.0.1 → 2.0.2
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/data/parg/adobe.json +1 -1
- data/data/parg/amca.json +1 -1
- data/data/parg/ansi.json +1 -1
- data/data/parg/api.json +1 -1
- data/data/parg/ashrae.json +1 -1
- data/data/parg/asme.json +1 -1
- data/data/parg/astm.json +1 -1
- data/data/parg/bipm.json +1 -1
- data/data/parg/bsi.json +1 -1
- data/data/parg/ccsds.json +1 -1
- data/data/parg/cen_cenelec.json +1 -1
- data/data/parg/cie.json +1 -1
- data/data/parg/csa.json +1 -1
- data/data/parg/ecma.json +1 -1
- data/data/parg/etsi.json +1 -1
- data/data/parg/evs.json +1 -1
- data/data/parg/gost.json +1 -1
- data/data/parg/iana.json +1 -1
- data/data/parg/idf.json +1 -1
- data/data/parg/iec.json +1 -1
- data/data/parg/iho.json +1 -0
- data/data/parg/isbn.json +1 -1
- data/data/parg/itu.json +1 -1
- data/data/parg/jcgm.json +1 -1
- data/data/parg/jis.json +1 -1
- data/data/parg/nist.json +1 -1
- data/data/parg/oiml.json +1 -1
- data/data/parg/omg.json +1 -1
- data/data/parg/plateau.json +1 -1
- data/data/parg/tgpp.json +1 -1
- data/data/parg/un.json +1 -1
- data/lib/pubid/adobe/identifier.rb +1 -1
- data/lib/pubid/adobe/parser.rb +2 -113
- data/lib/pubid/amca/identifiers/base.rb +1 -1
- data/lib/pubid/amca/parser.rb +1 -145
- data/lib/pubid/ansi/identifier.rb +1 -1
- data/lib/pubid/ansi/parser.rb +1 -82
- data/lib/pubid/api/builder.rb +32 -1
- data/lib/pubid/api/identifier.rb +1 -1
- data/lib/pubid/api/parser.rb +1 -131
- data/lib/pubid/ashrae/identifiers/base.rb +1 -1
- data/lib/pubid/ashrae/parser.rb +3 -710
- data/lib/pubid/asme/builder.rb +6 -4
- data/lib/pubid/asme/identifier.rb +1 -2
- data/lib/pubid/asme/parser.rb +1 -328
- data/lib/pubid/astm/builder.rb +12 -3
- data/lib/pubid/astm/identifier.rb +1 -2
- data/lib/pubid/astm/parser.rb +1 -227
- data/lib/pubid/bipm/identifier.rb +8 -1
- data/lib/pubid/bipm/parser.rb +2 -224
- data/lib/pubid/bsi/builder.rb +2 -4
- data/lib/pubid/bsi/parser.rb +1 -666
- data/lib/pubid/bsi/single_identifier.rb +38 -1
- data/lib/pubid/calconnect/parser.rb +2 -40
- data/lib/pubid/ccsds/identifier.rb +1 -1
- data/lib/pubid/ccsds/parser.rb +1 -66
- data/lib/pubid/cen_cenelec/identifier.rb +16 -1
- data/lib/pubid/cen_cenelec/parser.rb +3 -136
- data/lib/pubid/cie/identifier.rb +1 -1
- data/lib/pubid/cie/parser.rb +3 -378
- data/lib/pubid/conformance.rb +1 -1
- data/lib/pubid/csa/builder.rb +41 -18
- data/lib/pubid/csa/identifier.rb +12 -4
- data/lib/pubid/csa/identifiers/amendment.rb +28 -0
- data/lib/pubid/csa/identifiers.rb +1 -0
- data/lib/pubid/csa/parser.rb +16 -397
- data/lib/pubid/doi/parser.rb +2 -37
- data/lib/pubid/easc/builder.rb +1 -1
- data/lib/pubid/easc/parser.rb +2 -70
- data/lib/pubid/ecma/CLAUDE.md +8 -1
- data/lib/pubid/ecma/identifier.rb +13 -8
- data/lib/pubid/ecma/parser.rb +2 -54
- data/lib/pubid/ecma/renderer.rb +3 -7
- data/lib/pubid/errors.rb +18 -13
- data/lib/pubid/etsi/builder.rb +8 -5
- data/lib/pubid/etsi/identifiers/base.rb +1 -1
- data/lib/pubid/etsi/parser.rb +1 -132
- data/lib/pubid/evs/identifier.rb +7 -0
- data/lib/pubid/evs/parser.rb +1 -8
- data/lib/pubid/evs.rb +1 -1
- data/lib/pubid/gb/identifier.rb +6 -0
- data/lib/pubid/gb/parser.rb +2 -51
- data/lib/pubid/gost/identifier.rb +9 -1
- data/lib/pubid/gost/parser.rb +4 -81
- data/lib/pubid/iala/parser.rb +2 -121
- data/lib/pubid/iana/identifier.rb +1 -1
- data/lib/pubid/iana/parser.rb +2 -24
- data/lib/pubid/identifier.rb +78 -1
- data/lib/pubid/idf/builder.rb +42 -0
- data/lib/pubid/idf/identifier.rb +1 -1
- data/lib/pubid/idf/parser.rb +1 -137
- data/lib/pubid/idf.rb +1 -2
- data/lib/pubid/iec/builder.rb +158 -50
- data/lib/pubid/iec/identifier.rb +1 -1
- data/lib/pubid/iec/parser.rb +3 -430
- data/lib/pubid/ieee/aiee/identifier.rb +2 -1
- data/lib/pubid/ieee/aiee.rb +0 -1
- data/lib/pubid/ieee/builder.rb +2 -2
- data/lib/pubid/ieee/identifiers/base.rb +1 -1
- data/lib/pubid/ieee/ire/identifier.rb +2 -1
- data/lib/pubid/ieee/ire.rb +0 -1
- data/lib/pubid/ieee/nesc.rb +0 -1
- data/lib/pubid/ieee/parser.rb +1 -1257
- data/lib/pubid/ietf/identifiers/base.rb +17 -1
- data/lib/pubid/ietf/parser.rb +2 -47
- data/lib/pubid/ietf/renderer.rb +17 -2
- data/lib/pubid/iho/CLAUDE.md +89 -0
- data/lib/pubid/iho/builder.rb +4 -1
- data/lib/pubid/iho/identifiers/base.rb +28 -2
- data/lib/pubid/iho/renderer.rb +8 -0
- data/lib/pubid/iho/urn_generator.rb +11 -1
- data/lib/pubid/iho/urn_parser.rb +21 -11
- data/lib/pubid/iho.rb +0 -1
- data/lib/pubid/isbn/identifier.rb +1 -1
- data/lib/pubid/isbn/parser.rb +2 -31
- data/lib/pubid/iso/builder.rb +1 -1
- data/lib/pubid/iso/identifiers/directives.rb +6 -3
- data/lib/pubid/iso/identifiers/guide.rb +6 -3
- data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +6 -3
- data/lib/pubid/iso/normalizer.rb +1 -1
- data/lib/pubid/iso/parser.rb +1 -539
- data/lib/pubid/iso/supplement_identifier.rb +6 -3
- data/lib/pubid/iso/utilities.rb +4 -5
- data/lib/pubid/iso.rb +1 -19
- data/lib/pubid/itu/builder.rb +36 -20
- data/lib/pubid/itu/identifiers/base.rb +15 -2
- data/lib/pubid/itu/parser.rb +1 -775
- data/lib/pubid/jcgm/builder.rb +35 -0
- data/lib/pubid/jcgm/parser.rb +1 -151
- data/lib/pubid/jcgm.rb +1 -2
- data/lib/pubid/jis/builder.rb +18 -29
- data/lib/pubid/jis/identifier.rb +1 -1
- data/lib/pubid/jis/parser.rb +1 -128
- data/lib/pubid/nist/builder.rb +5 -1
- data/lib/pubid/nist/caster.rb +13 -3
- data/lib/pubid/nist/identifiers/base.rb +37 -2
- data/lib/pubid/nist/identifiers/circular.rb +2 -2
- data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -2
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +2 -2
- data/lib/pubid/nist/identifiers/crpl_report.rb +2 -2
- data/lib/pubid/nist/identifiers/handbook.rb +2 -2
- data/lib/pubid/nist/identifiers/internal_report.rb +2 -2
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +2 -2
- data/lib/pubid/nist/identifiers/monograph.rb +2 -2
- data/lib/pubid/nist/identifiers/report.rb +2 -2
- data/lib/pubid/nist/parser.rb +19 -775
- data/lib/pubid/nist/router.rb +4 -1
- data/lib/pubid/nist/supplement_identifier.rb +2 -2
- data/lib/pubid/oasis/parser.rb +2 -16
- data/lib/pubid/ogc/parser.rb +2 -26
- data/lib/pubid/oiml/identifiers/certification_system.rb +7 -0
- data/lib/pubid/oiml/identifiers/dual_published.rb +2 -2
- data/lib/pubid/oiml/parser.rb +1 -303
- data/lib/pubid/oiml.rb +1 -2
- data/lib/pubid/omg/identifier.rb +6 -1
- data/lib/pubid/omg/parser.rb +2 -76
- data/lib/pubid/parser.rb +5 -4
- data/lib/pubid/parsers/mr_string.rb +1 -1
- data/lib/pubid/plateau/parser.rb +1 -66
- data/lib/pubid/plateau.rb +1 -2
- data/lib/pubid/renderers/directives_renderer.rb +1 -1
- data/lib/pubid/renderers/iwa_renderer.rb +1 -1
- data/lib/pubid/renderers/publisher_stripper.rb +82 -0
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/sae/parser.rb +1 -48
- data/lib/pubid/tgpp/identifier.rb +1 -1
- data/lib/pubid/tgpp/parser.rb +2 -59
- data/lib/pubid/un/identifier.rb +1 -1
- data/lib/pubid/un/parser.rb +1 -18
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/parser.rb +2 -27
- data/lib/pubid/xsf/identifier.rb +10 -6
- data/lib/pubid/xsf/parser.rb +3 -31
- data/lib/pubid/xsf/renderer.rb +2 -4
- data/lib/pubid.rb +8 -9
- metadata +6 -23
- data/lib/pubid/ieee/aiee/parser.rb +0 -130
- data/lib/pubid/ieee/ire/parser.rb +0 -109
- data/lib/pubid/ieee/nesc/parser.rb +0 -155
- data/lib/pubid/iho/parser.rb +0 -68
- data/lib/pubid/parser/common_parse_methods.rb +0 -13
- data/lib/pubid/parser/common_parse_rules.rb +0 -56
- data/lib/pubid/parser/grammar.rb +0 -96
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Pubid
|
|
6
|
-
module Ieee
|
|
7
|
-
module Aiee
|
|
8
|
-
# Parser for AIEE (American Institute of Electrical Engineers) identifiers
|
|
9
|
-
# Historical period: 1884-1963 (merged into IEEE in 1963)
|
|
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(:dot) { str(".") }
|
|
16
|
-
rule(:digit) { match("[0-9]") }
|
|
17
|
-
rule(:digits) { digit.repeat(1) }
|
|
18
|
-
rule(:letter) { match("[A-Za-z]") }
|
|
19
|
-
rule(:upper) { match("[A-Z]") }
|
|
20
|
-
|
|
21
|
-
# Year pattern (for AIEE period: 1884-1963)
|
|
22
|
-
rule(:year) do
|
|
23
|
-
(str("18") >> digit.repeat(2, 2)) | # 1884-1899
|
|
24
|
-
(str("19") >> (str("0") | str("1") | str("2") | str("3") | str("4") | str("5")) >> digit) | # 1900-1959
|
|
25
|
-
(str("196") >> match("[0-3]")) # 1960-1963
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Month patterns
|
|
29
|
-
rule(:month_name) do
|
|
30
|
-
str("January") | str("February") | str("March") | str("April") |
|
|
31
|
-
str("May") | str("June") | str("July") | str("August") |
|
|
32
|
-
str("September") | str("October") | str("November") | str("December") |
|
|
33
|
-
str("Jan") | str("Feb") | str("Mar") | str("Apr") | str("Jun") |
|
|
34
|
-
str("Jul") | str("Aug") | str("Sep") | str("Sept") | str("Oct") | str("Nov") | str("Dec")
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# AIEE prefix variations
|
|
38
|
-
rule(:aiee_prefix) do
|
|
39
|
-
(
|
|
40
|
-
str("IEEE-AIEE") | # Transitional period (1963-1965)
|
|
41
|
-
str("A.I.E.E.") | # With dots variant (no spaces)
|
|
42
|
-
str("A. I. E. E.") | # With dots and spaces variant
|
|
43
|
-
str("AIEE")
|
|
44
|
-
).as(:publisher)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Document types
|
|
48
|
-
rule(:aiee_type) do
|
|
49
|
-
(
|
|
50
|
-
str("Standard No.") | # AIEE Standard No. 19-1938 (compound type)
|
|
51
|
-
str("Standard No") | # AIEE Standard No 19-1938 (compound type, no dot)
|
|
52
|
-
str("Std No.") | # AIEE Std No. 800
|
|
53
|
-
str("Std No") | # AIEE Std No 800 (no dot)
|
|
54
|
-
str("Std") | # AIEE Std 800
|
|
55
|
-
str("Nos") | # NEW Session 171: Plural variant (e.g., "Nos 72 and 73")
|
|
56
|
-
str("No.") | # AIEE No. 56
|
|
57
|
-
str("No") | # AIEE No 18 (can be followed by space)
|
|
58
|
-
str("no") | # AIEE no 700 (lowercase variant)
|
|
59
|
-
str("Standard") | # AIEE Standard 56
|
|
60
|
-
str("Trans.") # AIEE Trans. PAS-84
|
|
61
|
-
).as(:type)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Number formats
|
|
65
|
-
rule(:number) do
|
|
66
|
-
(
|
|
67
|
-
# Transaction format: PAS-84, PGI-7
|
|
68
|
-
(upper.repeat(2, 3) >> dash >> digits) |
|
|
69
|
-
|
|
70
|
-
# Complex with letter suffix: 27A, 22A, 1E - allow space before dash
|
|
71
|
-
# But don't match if it's actually "Nos 72 and 73" pattern
|
|
72
|
-
(digits >> upper >> (space >> str("and")).absent?) |
|
|
73
|
-
|
|
74
|
-
# Decimal number: 750.1, 750.11, 750.5
|
|
75
|
-
(digits >> dot >> digits) |
|
|
76
|
-
|
|
77
|
-
# Number with parenthetical variant: 431 (105)
|
|
78
|
-
# Pattern: main number followed by alternate number in parentheses
|
|
79
|
-
(digits.as(:main_number) >> space >> (str("(") >> digits.as(:alt_number) >> str(")")).as(:parenthetical)) |
|
|
80
|
-
|
|
81
|
-
# Simple number: 56, 123, 18, 552
|
|
82
|
-
(digits >>
|
|
83
|
-
|
|
84
|
-
# Handle "Nos X and Y" pattern - we only capture first number
|
|
85
|
-
(space >> str("and") >> space >> digits).absent?)
|
|
86
|
-
).as(:number)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Date formats
|
|
90
|
-
# Long form: ", 1956" or ", November 1955" or ". December 1958" or " -1957" (with space)
|
|
91
|
-
# NEW: Also support "May-1928" (month dash year, no comma)
|
|
92
|
-
rule(:date_long) do
|
|
93
|
-
space? >>
|
|
94
|
-
(
|
|
95
|
-
# Format 1: ", Month Year" or ". Month Year"
|
|
96
|
-
((str(",") | dot).as(:separator) >> space? >>
|
|
97
|
-
(month_name.as(:month) >> space).maybe >> year.as(:year)) |
|
|
98
|
-
# Format 2: " -Year" (space dash year)
|
|
99
|
-
((space >> dash).as(:separator) >> space? >> year.as(:year)) |
|
|
100
|
-
# Format 3: "Month-Year" (NEW - month dash year, no comma/dot/space prefix)
|
|
101
|
-
(month_name.as(:month) >> dash >> year.as(:year))
|
|
102
|
-
)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Short form: "-1962" (directly after number) or " -1958" (with space)
|
|
106
|
-
# ENHANCED: Allow leading space for patterns like "431 (105) -1958"
|
|
107
|
-
rule(:date_short) do
|
|
108
|
-
space.maybe >> dash >> year.as(:year)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Combined date rule
|
|
112
|
-
# Try short form first to avoid matching empty prefix in date_long
|
|
113
|
-
rule(:date) do
|
|
114
|
-
(date_short | date_long).maybe
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Complete AIEE identifier
|
|
118
|
-
rule(:aiee_identifier) do
|
|
119
|
-
aiee_prefix >>
|
|
120
|
-
space >>
|
|
121
|
-
(aiee_type >> space).maybe >>
|
|
122
|
-
number >>
|
|
123
|
-
date
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
root(:aiee_identifier)
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Pubid
|
|
6
|
-
module Ieee
|
|
7
|
-
module Ire
|
|
8
|
-
# Parser for IRE (Institute of Radio Engineers) identifiers
|
|
9
|
-
# Historical period: 1912-1963 (merged into IEEE in 1963)
|
|
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(:dot) { str(".") }
|
|
16
|
-
rule(:digit) { match("[0-9]") }
|
|
17
|
-
rule(:digits) { digit.repeat(1) }
|
|
18
|
-
rule(:letter) { match("[A-Za-z]") }
|
|
19
|
-
rule(:upper) { match("[A-Z]") }
|
|
20
|
-
|
|
21
|
-
# Year pattern - handle both 2-digit (52 = 1952) and 4-digit (1952) formats
|
|
22
|
-
rule(:year_short) do
|
|
23
|
-
# 2-digit year: 12-63 (1912-1963 IRE period)
|
|
24
|
-
match("[1-6]") >> digit
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
rule(:year_full) do
|
|
28
|
-
# 4-digit year for IRE period: 1912-1963
|
|
29
|
-
(str("191") >> digit.repeat(1, 1)) | # 1912-1919
|
|
30
|
-
(str("19") >> (str("2") | str("3") | str("4") | str("5")) >> digit) | # 1920-1959
|
|
31
|
-
(str("196") >> match("[0-3]")) # 1960-1963
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
rule(:year) { year_full | year_short }
|
|
35
|
-
|
|
36
|
-
# IRE prefix variations
|
|
37
|
-
rule(:ire_prefix) do
|
|
38
|
-
(
|
|
39
|
-
str("IEEE-IRE") | # Transitional period (1963-1965)
|
|
40
|
-
str("IRE")
|
|
41
|
-
).as(:publisher)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Document types
|
|
45
|
-
rule(:ire_type) do
|
|
46
|
-
(
|
|
47
|
-
str("Trans.") | # IRE Trans. PGI-7
|
|
48
|
-
str("Standard") | # IRE Standard
|
|
49
|
-
str("Std") # IRE Std
|
|
50
|
-
).as(:type)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Number formats
|
|
54
|
-
rule(:number) do
|
|
55
|
-
(
|
|
56
|
-
# Complex format with spaces: 28 S1, 15.S1, 7.S2
|
|
57
|
-
(digits >> (space | dot) >> upper >> digits) |
|
|
58
|
-
|
|
59
|
-
# Complex format: 1.IRE62.1S1
|
|
60
|
-
(digits >> dot >> str("IRE") >> digits >> dot >> digits >> upper >> digits) |
|
|
61
|
-
|
|
62
|
-
# Transaction format: PGI-7, PGAP-4
|
|
63
|
-
(upper.repeat(2, 4) >> dash >> digits) |
|
|
64
|
-
|
|
65
|
-
# Simple number: 56, 123
|
|
66
|
-
digits
|
|
67
|
-
).as(:number)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Date (year only for IRE)
|
|
71
|
-
rule(:date) do
|
|
72
|
-
(space? >> (dash | str(",")).maybe >> space? >> year.as(:year)).maybe
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Complete IRE identifier - YEAR FIRST format
|
|
76
|
-
rule(:ire_identifier_year_first) do
|
|
77
|
-
# Format: "52 IRE 7.S2" or "1952 IRE 7.S2"
|
|
78
|
-
year.as(:year) >>
|
|
79
|
-
space >>
|
|
80
|
-
ire_prefix >>
|
|
81
|
-
space >>
|
|
82
|
-
(ire_type >> space).maybe >>
|
|
83
|
-
number >>
|
|
84
|
-
(space? >> (dash | str(",")).maybe >> space? >> year_full.as(:full_year)).maybe
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Prefix-first format: "IRE 7.S2-1952" (pubid#316 family 2) — the
|
|
88
|
-
# year trails the designation instead of leading the identifier.
|
|
89
|
-
# The renderer always emits the year-first short-year form, so this
|
|
90
|
-
# spelling canonicalizes onto it ("IRE 7.S2-1952" → "52 IRE 7.S2").
|
|
91
|
-
rule(:ire_identifier_prefix_first) do
|
|
92
|
-
ire_prefix >>
|
|
93
|
-
space >>
|
|
94
|
-
(ire_type >> space).maybe >>
|
|
95
|
-
number >>
|
|
96
|
-
date
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Year-first is tried first so the original spellings keep their
|
|
100
|
-
# match; prefix-first claims only what year-first cannot.
|
|
101
|
-
rule(:ire_identifier) do
|
|
102
|
-
ire_identifier_year_first | ire_identifier_prefix_first
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
root(:ire_identifier)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Pubid
|
|
6
|
-
module Ieee
|
|
7
|
-
module Nesc
|
|
8
|
-
# Parser for National Electrical Safety Code (NESC) identifiers
|
|
9
|
-
#
|
|
10
|
-
# Handles multiple NESC identifier formats including:
|
|
11
|
-
# - Standard C2-YYYY format
|
|
12
|
-
# - Year-first YYYY NESC format
|
|
13
|
-
# - Draft format
|
|
14
|
-
# - Handbook and Redline variations
|
|
15
|
-
#
|
|
16
|
-
# @example Parse C2 standard
|
|
17
|
-
# parser = Parser.new
|
|
18
|
-
# result = parser.parse("C2-1997 National Electric Safety Code")
|
|
19
|
-
#
|
|
20
|
-
# @example Parse handbook
|
|
21
|
-
# parser = Parser.new
|
|
22
|
-
# result = parser.parse("2017 NESC Handbook, Premier Edition")
|
|
23
|
-
class Parser < ::Pubid::Parser::Grammar
|
|
24
|
-
root(:nesc_identifier)
|
|
25
|
-
|
|
26
|
-
rule(:space) { str(" ") }
|
|
27
|
-
rule(:comma) { str(",") }
|
|
28
|
-
rule(:digit) { match("[0-9]") }
|
|
29
|
-
rule(:year) { digit.repeat(4, 4) }
|
|
30
|
-
rule(:dash) { str("-") }
|
|
31
|
-
|
|
32
|
-
# C2 code designation
|
|
33
|
-
rule(:c2_code) do
|
|
34
|
-
str("C2").as(:code)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# NESC name variations (the "(R)" registered mark is captured
|
|
38
|
-
# separately by the `registered` rule so it can be round-tripped)
|
|
39
|
-
rule(:nesc_full_name) do
|
|
40
|
-
str("National Electrical Safety Code") |
|
|
41
|
-
str("National Electric Safety Code") # Typo variation
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
rule(:nesc_abbr) do
|
|
45
|
-
str("NESC")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
rule(:nesc_name) do
|
|
49
|
-
nesc_full_name | nesc_abbr
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Registered trademark notation
|
|
53
|
-
rule(:registered) do
|
|
54
|
-
str("(R)")
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Edition notations
|
|
58
|
-
rule(:edition) do
|
|
59
|
-
(
|
|
60
|
-
str("Premier Edition") |
|
|
61
|
-
str("First Edition") |
|
|
62
|
-
str("Second Edition") |
|
|
63
|
-
str("Third Edition") |
|
|
64
|
-
str("Fourth Edition") |
|
|
65
|
-
str("Fifth Edition") |
|
|
66
|
-
str("Sixth Edition") |
|
|
67
|
-
str("Seventh Edition") |
|
|
68
|
-
str("Eighth Edition") |
|
|
69
|
-
str("Ninth Edition") |
|
|
70
|
-
str("Tenth Edition")
|
|
71
|
-
).as(:edition)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Variant types (Handbook, Redline)
|
|
75
|
-
rule(:variant) do
|
|
76
|
-
(
|
|
77
|
-
str("Handbook") |
|
|
78
|
-
str("Redline")
|
|
79
|
-
).as(:variant)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Month names for drafts
|
|
83
|
-
rule(:month) do
|
|
84
|
-
(
|
|
85
|
-
str("January") | str("February") | str("March") |
|
|
86
|
-
str("April") | str("May") | str("June") |
|
|
87
|
-
str("July") | str("August") | str("September") |
|
|
88
|
-
str("October") | str("November") | str("December")
|
|
89
|
-
).as(:month)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Pattern 1: C2-YYYY Standard format
|
|
93
|
-
# Examples: "C2-1997 National Electric Safety Code (NESC)"
|
|
94
|
-
# "C2-2012 National Electrical Safety Code"
|
|
95
|
-
rule(:c2_standard) do
|
|
96
|
-
c2_code >>
|
|
97
|
-
dash >>
|
|
98
|
-
year.as(:year) >>
|
|
99
|
-
(comma.maybe >> space).maybe >>
|
|
100
|
-
nesc_full_name >> registered.maybe >>
|
|
101
|
-
(space >> str("(") >> nesc_abbr >> registered.maybe >> str(")")).maybe
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Pattern 2: YYYY NESC format (year-first)
|
|
105
|
-
# Examples: "2017 NESC(R) Handbook, Premier Edition"
|
|
106
|
-
# "2017 National Electrical Safety Code(R) (NESC(R))"
|
|
107
|
-
# "2012 NESC Handbook"
|
|
108
|
-
rule(:year_first) do
|
|
109
|
-
year.as(:year) >>
|
|
110
|
-
space >>
|
|
111
|
-
(
|
|
112
|
-
# Full name with optional (NESC) abbreviation suffix
|
|
113
|
-
(nesc_full_name.as(:full_name) >> registered.as(:name_registered).maybe >>
|
|
114
|
-
(space >> str("(") >> nesc_abbr.as(:paren_abbr) >>
|
|
115
|
-
registered.as(:paren_registered).maybe >> str(")")).maybe) |
|
|
116
|
-
# Just the NESC abbreviation (e.g. "2017 NESC(R) Handbook")
|
|
117
|
-
(nesc_abbr.as(:abbr) >> registered.as(:abbr_registered).maybe)
|
|
118
|
-
) >>
|
|
119
|
-
(space >> variant).maybe >>
|
|
120
|
-
(comma >> space >> edition).maybe
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# Pattern 3: Name-first format
|
|
124
|
-
# Examples: "National Electrical Safety Code, C2-2012"
|
|
125
|
-
# "National Electrical Safety Code, C2-2012 - Redline"
|
|
126
|
-
rule(:name_first) do
|
|
127
|
-
nesc_full_name >> registered.maybe >>
|
|
128
|
-
comma >>
|
|
129
|
-
space >>
|
|
130
|
-
c2_code >>
|
|
131
|
-
dash >>
|
|
132
|
-
year.as(:year) >>
|
|
133
|
-
(space >> str("-") >> space >> variant.as(:variant)).maybe
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Pattern 4: Draft format
|
|
137
|
-
# Examples: "Draft National Electrical Safety Code, January 2016"
|
|
138
|
-
# "Draft NESC, June 2011"
|
|
139
|
-
rule(:draft_nesc) do
|
|
140
|
-
str("Draft").as(:draft) >>
|
|
141
|
-
space >>
|
|
142
|
-
nesc_name >> registered.maybe >>
|
|
143
|
-
comma >> space >>
|
|
144
|
-
month >> space >> year.as(:year)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Main identifier rule - try patterns in order
|
|
148
|
-
# Put most specific patterns first
|
|
149
|
-
rule(:nesc_identifier) do
|
|
150
|
-
draft_nesc | name_first | c2_standard | year_first
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
data/lib/pubid/iho/parser.rb
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Pubid
|
|
6
|
-
module Iho
|
|
7
|
-
# Parser class for IHO identifiers
|
|
8
|
-
class Parser < ::Pubid::Parser::Grammar
|
|
9
|
-
rule(:space) { str(" ") }
|
|
10
|
-
rule(:dash) { str("-") }
|
|
11
|
-
rule(:dot) { str(".") }
|
|
12
|
-
rule(:digits) { match("[0-9]").repeat(1) }
|
|
13
|
-
|
|
14
|
-
rule(:series) do
|
|
15
|
-
(str("S") | str("P") | str("M") | str("B") | str("C")).as(:type)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
rule(:number_suffix) do
|
|
19
|
-
(str(":") >> digits) | (str("/") >> digits) | (dash >> digits) | match("[A-Z]")
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
rule(:number) do
|
|
23
|
-
(digits >> number_suffix.maybe).as(:number)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
rule(:appendix) do
|
|
27
|
-
space >> (str("Appendix") | str("Ap.")) >> space >>
|
|
28
|
-
(
|
|
29
|
-
(match("[A-Z]") >> dash >> digits) |
|
|
30
|
-
digits |
|
|
31
|
-
match("[A-Z]")
|
|
32
|
-
).as(:appendix)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
rule(:part) do
|
|
36
|
-
space >> str("Part") >> space >>
|
|
37
|
-
(
|
|
38
|
-
(digits >> match("[a-zA-Z]").repeat).as(:part) |
|
|
39
|
-
match("[A-Z]").as(:part)
|
|
40
|
-
)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
rule(:annex) do
|
|
44
|
-
space >> str("Annex") >> space >> match("[A-Z]").as(:annex)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
rule(:supplement) do
|
|
48
|
-
space >> str("Suppl") >> space >> digits.as(:supplement)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
rule(:version) do
|
|
52
|
-
space >> (digits >> dot >> digits >> dot >> digits).as(:version)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
rule(:identifier) do
|
|
56
|
-
(str("IHO") >> space).maybe >>
|
|
57
|
-
series >> dash >> number >>
|
|
58
|
-
appendix.maybe >> part.maybe >> annex.maybe >> supplement.maybe >> version.maybe
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
root :identifier
|
|
62
|
-
|
|
63
|
-
def self.parse(string)
|
|
64
|
-
new.parse(string.strip)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Pubid
|
|
4
|
-
module Parser
|
|
5
|
-
module CommonParseRules
|
|
6
|
-
def self.included(base)
|
|
7
|
-
base.class_eval do
|
|
8
|
-
rule(:space) { str(" ") }
|
|
9
|
-
rule(:space?) { space.maybe }
|
|
10
|
-
|
|
11
|
-
rule(:digits) do
|
|
12
|
-
match('\d').repeat(1)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
rule(:year) do
|
|
16
|
-
match('\d').repeat(4, 4).as(:year)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
rule(:comma) { str(", ") }
|
|
20
|
-
rule(:comma?) { comma.maybe }
|
|
21
|
-
rule(:comma_space) { comma | space }
|
|
22
|
-
rule(:dash) { str("-") }
|
|
23
|
-
rule(:dot) { str(".") }
|
|
24
|
-
rule(:words_digits) { match('[\dA-Za-z]').repeat(1) }
|
|
25
|
-
rule(:words) { match("[A-Za-z]").repeat(1) }
|
|
26
|
-
rule(:words?) { words.maybe }
|
|
27
|
-
rule(:year_digits) do
|
|
28
|
-
(str("19") | str("20")) >> match('\d').repeat(2,
|
|
29
|
-
2) >> digits.absent?
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
rule(:month_digits) do
|
|
33
|
-
match('\d').repeat(2, 2)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
rule(:day_digits) do
|
|
37
|
-
match('\d').repeat(2, 2)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
rule(:originator) do
|
|
41
|
-
organization.as(:publisher) >>
|
|
42
|
-
(space? >> str("/") >> organization.as(:copublisher)).repeat
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
rule(:comma_month_year) do
|
|
46
|
-
comma >> words.as(:month) >> space >> year_digits.as(:year)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
rule(:year_month) do
|
|
50
|
-
year_digits >> dash >> month_digits
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
data/lib/pubid/parser/grammar.rb
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Pubid
|
|
6
|
-
module Parser
|
|
7
|
-
# The superclass of every flavor grammar.
|
|
8
|
-
#
|
|
9
|
-
# Its only job is to keep parslet out of pubid's public contract. Every
|
|
10
|
-
# grammar failure originates in `Parslet::Atoms::Base#parse`, which
|
|
11
|
-
# `Parslet::Parser` does not override, so one override here covers all 46
|
|
12
|
-
# grammars, both public entry points of every flavor, and the cross-flavor
|
|
13
|
-
# delegation routes (`Pubid::Iso.parse("ITU-T G.711")` runs ITU's grammar)
|
|
14
|
-
# — without touching the 131 `parse` methods.
|
|
15
|
-
#
|
|
16
|
-
# The name is `Grammar`, not `Base`, because {Pubid::Parsers::Base} already
|
|
17
|
-
# exists and means something unrelated (the MR-string parser).
|
|
18
|
-
#
|
|
19
|
-
# Known limit: a rule atom parsed directly, `Parser.new.<rule>.parse(str)`,
|
|
20
|
-
# bypasses this and raises a bare `Parslet::ParseFailed`. Nothing in the
|
|
21
|
-
# gem does that.
|
|
22
|
-
class Grammar < ::Parslet::Parser
|
|
23
|
-
# A trailing "(all parts)" marks the reference as the whole document.
|
|
24
|
-
# The flavor grammars that carry their own rule consume it inside
|
|
25
|
-
# parslet; this shared strip gives every other flavor the same read:
|
|
26
|
-
# the suffix never reaches the flavor grammar, and the parsed tree
|
|
27
|
-
# carries :all_parts for the builder to wrap (see Builder::Base).
|
|
28
|
-
ALL_PARTS_SUFFIX = "(all parts)".freeze
|
|
29
|
-
|
|
30
|
-
# @param io [String, IO]
|
|
31
|
-
# @param options [Hash] passed through to parslet
|
|
32
|
-
# @raise [Pubid::Errors::ParseError]
|
|
33
|
-
def parse(io, options = {})
|
|
34
|
-
if io.is_a?(String) && io.end_with?(ALL_PARTS_SUFFIX)
|
|
35
|
-
base = io.sub(/\s*\(all parts\)\s*\z/, "")
|
|
36
|
-
return mark_all_parts(super(base, options))
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
super
|
|
40
|
-
rescue ::Pubid::Errors::ParseError
|
|
41
|
-
# A nested grammar already wrapped it. Keep the inner flavor and input.
|
|
42
|
-
raise
|
|
43
|
-
rescue ::Parslet::ParseFailed => e
|
|
44
|
-
raise wrap_parse_failure(e, io)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
# Carry the stripped suffix into the tree. Parslet tops are a Hash or
|
|
50
|
-
# an Array of Hashes; the marker joins either shape, and every builder
|
|
51
|
-
# (Builder::Base and the standalone ones) routes it to #to_all_parts.
|
|
52
|
-
def mark_all_parts(tree)
|
|
53
|
-
case tree
|
|
54
|
-
when Hash then tree.merge(all_parts: true)
|
|
55
|
-
when Array then tree.map { |t| t.merge(all_parts: true) }
|
|
56
|
-
else tree
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# @param error [Parslet::ParseFailed]
|
|
61
|
-
# @param io [String, IO] what was handed to {#parse}
|
|
62
|
-
# @return [Pubid::Errors::ParseError]
|
|
63
|
-
def wrap_parse_failure(error, io)
|
|
64
|
-
::Pubid::Errors::ParseError.new(
|
|
65
|
-
error.message,
|
|
66
|
-
error.parse_failure_cause,
|
|
67
|
-
input: io.is_a?(String) ? io : nil,
|
|
68
|
-
flavor: pubid_flavor_name,
|
|
69
|
-
)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# "Pubid::Iso::Parser" -> "iso"; "Pubid::Ieee::Aiee::Parser" -> "ieee".
|
|
73
|
-
#
|
|
74
|
-
# Resolved through {Pubid::Registry} rather than taken from the module
|
|
75
|
-
# name, because the two disagree: `Pubid::Tgpp` registers as `"3gpp"`,
|
|
76
|
-
# and `Pubid::CenCenelec` registers twice (`"cen_cenelec"` first, then
|
|
77
|
-
# the `"cen"` alias). Reporting the registered name is what lets a caller
|
|
78
|
-
# feed `error.flavor` straight back to `Pubid::Registry.get`.
|
|
79
|
-
# @return [String, nil]
|
|
80
|
-
def pubid_flavor_name
|
|
81
|
-
parts = self.class.name.to_s.split("::")
|
|
82
|
-
return nil unless parts[0] == "Pubid" && parts.length > 1
|
|
83
|
-
|
|
84
|
-
registered_flavor_name(parts[1]) || parts[1].downcase
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# @param module_name [String] e.g. "Tgpp"
|
|
88
|
-
# @return [String, nil] the registered name, nil if not registered
|
|
89
|
-
def registered_flavor_name(module_name)
|
|
90
|
-
::Pubid::Registry.canonical_name(::Pubid.const_get(module_name))
|
|
91
|
-
rescue ::NameError
|
|
92
|
-
nil
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|