pubid 2.0.1 → 2.0.3
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/ieee/update_codes.yaml +2 -2
- data/data/parg/adobe.json +1 -1
- data/data/parg/aiee.json +1 -1
- data/data/parg/aiee.parg +99 -9
- 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/iala.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/ieee.json +1 -1
- data/data/parg/iho.json +1 -0
- data/data/parg/ire.json +1 -1
- data/data/parg/ire.parg +51 -12
- data/data/parg/isbn.json +1 -1
- data/data/parg/iso.json +1 -1
- data/data/parg/iso.parg +751 -0
- data/data/parg/itu.json +1 -1
- data/data/parg/jcgm.json +1 -1
- data/data/parg/jis.json +1 -1
- data/data/parg/nesc.json +1 -1
- data/data/parg/nesc.parg +97 -12
- data/data/parg/nist.json +1 -1
- data/data/parg/oiml.json +1 -1
- data/data/parg/omg.json +1 -1
- data/data/parg/parg.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/builder.rb +48 -39
- data/lib/pubid/iala/identifier.rb +1 -1
- 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/CLAUDE.md +2 -0
- data/lib/pubid/ieee/aiee/identifier.rb +2 -1
- data/lib/pubid/ieee/aiee.rb +0 -1
- data/lib/pubid/ieee/builder.rb +177 -30
- data/lib/pubid/ieee/components/code.rb +46 -7
- data/lib/pubid/ieee/identifiers/base.rb +5 -2
- data/lib/pubid/ieee/identifiers/joint_development.rb +7 -3
- data/lib/pubid/ieee/ire/identifier.rb +2 -1
- data/lib/pubid/ieee/ire.rb +0 -1
- data/lib/pubid/ieee/nesc/builder.rb +1 -1
- data/lib/pubid/ieee/nesc.rb +0 -1
- data/lib/pubid/ieee/parser.rb +1 -1257
- data/lib/pubid/ieee/project_renderer.rb +5 -1
- data/lib/pubid/ieee/renderer.rb +4 -2
- data/lib/pubid/ieee/urn_generator.rb +4 -1
- 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 +98 -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 +14 -1
- data/lib/pubid/iho/urn_parser.rb +45 -32
- 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/CLAUDE.md +66 -0
- data/lib/pubid/iso/builder.rb +229 -15
- data/lib/pubid/iso/identifier.rb +22 -12
- 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 +5 -4
- data/lib/pubid/iso/parser.rb +1 -539
- data/lib/pubid/iso/supplement_identifier.rb +6 -3
- data/lib/pubid/iso/urn_parser.rb +13 -8
- 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/CLAUDE.md +36 -0
- data/lib/pubid/jis/builder.rb +30 -41
- data/lib/pubid/jis/identifier.rb +12 -2
- data/lib/pubid/jis/identifiers/welding_engineering_standard.rb +35 -0
- data/lib/pubid/jis/identifiers.rb +2 -0
- data/lib/pubid/jis/parser.rb +1 -128
- data/lib/pubid/jis/renderer.rb +1 -1
- data/lib/pubid/jis/supplement_identifier.rb +5 -5
- data/lib/pubid/jis/urn_parser.rb +2 -1
- data/lib/pubid/jis.rb +3 -2
- 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 +9 -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
data/lib/pubid/iso/parser.rb
CHANGED
|
@@ -1,547 +1,9 @@
|
|
|
1
|
-
require "parslet"
|
|
2
1
|
# frozen_string_literal: true
|
|
3
2
|
|
|
4
3
|
module Pubid
|
|
5
4
|
module Iso
|
|
6
|
-
class Parser
|
|
7
|
-
include ::Pubid::Parser::CommonParseRules
|
|
8
|
-
include ::Pubid::Parser::CommonParseMethods
|
|
9
|
-
|
|
5
|
+
class Parser
|
|
10
6
|
DASH_CHARS = ["-", "‑", "‐"].freeze
|
|
11
|
-
|
|
12
|
-
# Supplement identifier type keys (kept as a hard-coded list to match
|
|
13
|
-
# the previous identifier split; only the base identifier registry
|
|
14
|
-
# is auto-discovered from the Identifiers namespace).
|
|
15
|
-
SUPPLEMENT_TYPE_KEYS = %i[amd cor suppl ext add].freeze
|
|
16
|
-
|
|
17
|
-
# We need to sort by length to match longest first because that's how Parslet works
|
|
18
|
-
TYPED_STAGES = Pubid::Iso.identifier_types
|
|
19
|
-
.reject { |k| SUPPLEMENT_TYPE_KEYS.include?(k.type[:key]) }
|
|
20
|
-
.flat_map { |k| k.const_defined?(:TYPED_STAGES) ? k.const_get(:TYPED_STAGES) : [] }
|
|
21
|
-
.map(&:abbr).flatten.sort_by(&:length).reverse
|
|
22
|
-
TYPED_STAGES_SUPPLEMENTS = Pubid::Iso.identifier_types
|
|
23
|
-
.select { |k| SUPPLEMENT_TYPE_KEYS.include?(k.type[:key]) }
|
|
24
|
-
.flat_map { |k| k.const_defined?(:TYPED_STAGES) ? k.const_get(:TYPED_STAGES) : [] }
|
|
25
|
-
.map(&:abbr).flatten.sort_by(&:length).reverse
|
|
26
|
-
|
|
27
|
-
root :identifier
|
|
28
|
-
|
|
29
|
-
# TC documents must come first since they start with "ISO/"
|
|
30
|
-
# and we need to distinguish them from regular ISO/IEC identifiers
|
|
31
|
-
rule(:identifier) do
|
|
32
|
-
bare_tc_document |
|
|
33
|
-
nsb_iso_identifier |
|
|
34
|
-
tc_document |
|
|
35
|
-
directives_identifiers |
|
|
36
|
-
jcgm_identifier |
|
|
37
|
-
iso_r_supplement_identifier |
|
|
38
|
-
iso_r_identifier |
|
|
39
|
-
supplement_supplement_supplement_identifier |
|
|
40
|
-
supplement_supplement_identifier |
|
|
41
|
-
supplement_identifier |
|
|
42
|
-
joint_identifier |
|
|
43
|
-
identifier_copublishers
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# JCGM identifiers (Joint Committee for Guides in Metrology)
|
|
47
|
-
# JCGM 200:2008(F)
|
|
48
|
-
rule(:jcgm_identifier) do
|
|
49
|
-
str("JCGM").as(:publisher) >> space >>
|
|
50
|
-
second_part >> third_part
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# TC Document: ISO/TC 184/SC 4/WG 3 N 123
|
|
54
|
-
# ISO/TC 184 N 100
|
|
55
|
-
# ISO/JTC 1 N 456
|
|
56
|
-
# ISO/TC 184/SC 4 N 789 (TC and SC only, no WG)
|
|
57
|
-
rule(:tc_document) do
|
|
58
|
-
# Accept either "ISO/TC 184…" or the lenient space form "ISO TC 184…"
|
|
59
|
-
# (the latter was valid in pubid 1.x via an optional slash).
|
|
60
|
-
prefix_sole_publisher >> (str("/") | space) >> tc_type >> space >> tc_number.as(:tc_number) >>
|
|
61
|
-
tc_subcommittee_part.maybe >>
|
|
62
|
-
space >> str("N") >> space? >> digits.as(:number) >>
|
|
63
|
-
(str(":") >> year_digits.as(:year)).maybe
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Bare TC document reference (pubid-iso#285): "184/SC 4/WG 12 N10291"
|
|
67
|
-
# — the ISO/TC route without the ORIGINATOR prefix; the builder
|
|
68
|
-
# canonicalizes the publisher to ISO. The SC segment is required so
|
|
69
|
-
# bare numbers cannot leak into the route.
|
|
70
|
-
rule(:bare_tc_document) do
|
|
71
|
-
digits.as(:tc_number) >>
|
|
72
|
-
str("/") >> sc_type >> space >> digits.as(:sc_number) >>
|
|
73
|
-
(str("/") >> wg_type >> space >> digits.as(:wg_number)).maybe >>
|
|
74
|
-
space >> str("N") >> space? >> digits.as(:number) >>
|
|
75
|
-
(str(":") >> year_digits.as(:year)).maybe
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
rule(:tc_subcommittee_part) do
|
|
79
|
-
# Full path: TC/SC 4/WG 3
|
|
80
|
-
(str("/") >> sc_type >> space >> digits.as(:sc_number) >> str("/") >>
|
|
81
|
-
wg_type >> space >> digits.as(:wg_number)) |
|
|
82
|
-
# TC and SC only: TC/SC 4 N 789
|
|
83
|
-
(str("/") >> sc_type >> space >> digits.as(:sc_number))
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
rule(:tc_type) do
|
|
87
|
-
array_to_str(Identifiers::TcDocument::TC_TYPES).as(:tc_type)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
rule(:sc_type) do
|
|
91
|
-
# "SC" plus the "SC/QC" quality-committee variant
|
|
92
|
-
# (e.g. ISO/TC 184/SC/QC 4 N 246). Longest first for Parslet.
|
|
93
|
-
(str("SC/QC") | str("SC")).as(:sc_type)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
rule(:wg_type) do
|
|
97
|
-
array_to_str(Identifiers::TcDocument::WG_TYPES).as(:wg_type)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
rule(:tc_number) do
|
|
101
|
-
digits
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# ISO/R 947:1969 (legacy Recommendation without supplement)
|
|
105
|
-
rule(:iso_r_identifier) do
|
|
106
|
-
str("ISO/R").as(:iso_r_prefix) >> space >>
|
|
107
|
-
iso_r_second_part >> third_part
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# ISO/R 947:1969/Add 1:1969 (legacy Recommendation with supplement)
|
|
111
|
-
# Also handles: ISO/R 91-1970 — Addendum 1 (dash for year, em-dash + word)
|
|
112
|
-
rule(:iso_r_supplement_identifier) do
|
|
113
|
-
(
|
|
114
|
-
str("ISO/R").as(:iso_r_prefix) >> space >> iso_r_second_part
|
|
115
|
-
).as(:base) >>
|
|
116
|
-
iso_r_supplement_separator >>
|
|
117
|
-
supplement_type_with_stage >>
|
|
118
|
-
space? >> second_part >> third_part
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# ISO/R supplements can use "/" or em-dash "—" or " - " as separator
|
|
122
|
-
rule(:iso_r_supplement_separator) do
|
|
123
|
-
str("/") | (space? >> str("—") >> space?) | (space >> str("-") >> space)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Special second_part for ISO/R that treats dash as date separator only
|
|
127
|
-
rule(:iso_r_second_part) do
|
|
128
|
-
number.as(:number_with_part) >>
|
|
129
|
-
stage_iteration.maybe >>
|
|
130
|
-
space? >> date.maybe
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# ISO 8601-1:2019
|
|
134
|
-
# ISO/R 947:1969 (legacy Recommendation format)
|
|
135
|
-
rule(:prefix_sole_publisher) do
|
|
136
|
-
(str("ISO") | str("IEC")).as(:publisher)
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# ISO/SAE PAS 22736:2021
|
|
140
|
-
# ISO/R 947:1969 (legacy Recommendation - special handling)
|
|
141
|
-
rule(:prefix_with_copublishers) do
|
|
142
|
-
# Try ISO/R first (must be followed by space + number to avoid confusion with copublishers)
|
|
143
|
-
(str("ISO/R").as(:iso_r_prefix) >> space) |
|
|
144
|
-
# Otherwise normal publisher with optional copublishers
|
|
145
|
-
(prefix_sole_publisher >> space? >> copublishers.maybe)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
ORGANIZATIONS = %w[
|
|
149
|
-
ISO IEC IEEE CIW SAE CIE ASME ASTM OECD ISO HL7 CEI UNDP
|
|
150
|
-
].freeze
|
|
151
|
-
rule(:copublishers) do
|
|
152
|
-
(str("/") >> space? >> array_to_str(ORGANIZATIONS).as(:copublisher)).repeat.as(:copublishers)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
rule(:number_with_part) do
|
|
156
|
-
(number >> part_and_subpart.maybe).as(:number_with_part)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
rule(:number) do
|
|
160
|
-
match('\d').repeat(1, 5)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
rule(:date) do
|
|
164
|
-
# :2005-02 or :-- (undated reference — ISO/IEC undated-reference form,
|
|
165
|
-
# e.g. ISO 16634:--, also accepted as the em-dash variant ISO 16634:—)
|
|
166
|
-
(str(":") | dash) >>
|
|
167
|
-
(
|
|
168
|
-
(str("--") | str("—")).as(:undated_marker) |
|
|
169
|
-
(year_digits >>
|
|
170
|
-
(dash >> month_digits).maybe >>
|
|
171
|
-
(dash >> day_digits).maybe
|
|
172
|
-
).as(:date)
|
|
173
|
-
).maybe
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
rule(:part_and_subpart) do
|
|
177
|
-
# Modern parts
|
|
178
|
-
# ISO 105-A01:1989
|
|
179
|
-
# ISO/IEC/IEEE 8802-1AB
|
|
180
|
-
# ISO/IEC TR 29110-5-1-1
|
|
181
|
-
|
|
182
|
-
# Legacy parts
|
|
183
|
-
# ISO 31/0-1974
|
|
184
|
-
# ISO 105/F (also known as ISO 105-F)
|
|
185
|
-
# ISO 5843/6 (also known as ISO 5843-6)
|
|
186
|
-
|
|
187
|
-
# Modern parts can have subparts using dash
|
|
188
|
-
# the "space?" needed to handle "ISO/TS 10303- 1751:2014"
|
|
189
|
-
(
|
|
190
|
-
dash >> space? >>
|
|
191
|
-
# matches a part
|
|
192
|
-
match('\w').repeat(1) >>
|
|
193
|
-
# matches a subpart, e.g. "A01" or "1-2" (yes we treat {5}-{1-1} as part and subpart)
|
|
194
|
-
(dash >> match('\w').repeat(1)).repeat.maybe
|
|
195
|
-
) |
|
|
196
|
-
# Legacy parts do not have subparts
|
|
197
|
-
# the "/" to handle old style parts: "ISO 5843/6"
|
|
198
|
-
# Guard: don't match supplement type names (Amd, Cor, Sup, etc.)
|
|
199
|
-
(
|
|
200
|
-
str("/") >> space? >>
|
|
201
|
-
supplement_type_with_stage.absent? >>
|
|
202
|
-
# matches a part
|
|
203
|
-
match('\w').repeat(1)
|
|
204
|
-
)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
rule(:all_parts) do
|
|
208
|
-
str("(all parts)").as(:all_parts)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
rule(:type_with_stage) do
|
|
212
|
-
# "DTR"
|
|
213
|
-
# "PRF PAS"
|
|
214
|
-
# "PRF"
|
|
215
|
-
# "PAS"
|
|
216
|
-
array_to_str(TYPED_STAGES).as(:type_with_stage) >>
|
|
217
|
-
(match('\d').as(:stage_iteration) >> space).maybe
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
rule(:language) do
|
|
221
|
-
# ISO 8601-1:2019(en,fr)
|
|
222
|
-
# ISO 8601-1:2019(E/F)
|
|
223
|
-
str("(") >>
|
|
224
|
-
(
|
|
225
|
-
# parse 2-char language codes: ru,en,fr,de,ar,es
|
|
226
|
-
(match["a-z"].repeat(1) >> str(",").maybe) |
|
|
227
|
-
# parse single language codes: R/E/F or R,E,F
|
|
228
|
-
(match["EFARDS"] >> (str("/") | str(",")).maybe)
|
|
229
|
-
).repeat.as(:languages) >>
|
|
230
|
-
str(")")
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
EDITION_STRINGS = %w[Edition Ed. ED Ed].freeze
|
|
234
|
-
rule(:edition) do
|
|
235
|
-
# Capture the entire edition text for exact reproduction
|
|
236
|
-
(array_to_str(EDITION_STRINGS) >> space? >> digits.maybe).as(:edition)
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
rule(:stage_iteration) do
|
|
240
|
-
# "ISO 11243.1"
|
|
241
|
-
str(".") >> match('\d').as(:stage_iteration)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
# Modern identifiers use ':' as year identifier, e.g. "ISO 8601-1:2019"
|
|
245
|
-
# Legacy identifiers use '-' as year identifier, e.g. "ISO 31/0-1974"
|
|
246
|
-
rule(:second_part) do
|
|
247
|
-
number_with_part >>
|
|
248
|
-
stage_iteration.maybe >>
|
|
249
|
-
space? >> date.maybe
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
rule(:third_part_edition) do
|
|
253
|
-
space? >> edition.maybe
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
rule(:third_part) do
|
|
257
|
-
# End of the identifier, we can have language, edition, or all parts
|
|
258
|
-
third_part_edition >> language.maybe >> space? >> all_parts.maybe
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# prefix sole or copublishers with type and stage
|
|
262
|
-
# ISO/WD TR 23642
|
|
263
|
-
# ISO/NP TS 20594-1
|
|
264
|
-
# ISO/PRF PAS 22596
|
|
265
|
-
# ISO/ASTM DTR 52905
|
|
266
|
-
# ISO/IEC WD TS 25025
|
|
267
|
-
#
|
|
268
|
-
## SUPPORTED ABERRATION: ISO TR 16401-2
|
|
269
|
-
## SUPPORTED ABERRATION: ISO/IEC/TS 24192-1
|
|
270
|
-
rule(:identifier_copublishers) do
|
|
271
|
-
identifier_copublishers_no_third >> third_part
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
# TODO: Support parsing Russian style identifiers
|
|
275
|
-
rule(:guide_prefix) do
|
|
276
|
-
str("Guide") | str("GUIDE") # | str("Руководство") | str("Руководства")
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
rule(:identifier_copublishers_no_third) do
|
|
280
|
-
# Guide ISO/CEI 51:1999
|
|
281
|
-
(guide_prefix.as(:type_with_stage_fr) >> space).maybe >>
|
|
282
|
-
# maybe prefix_with_copublishers to handle IWA
|
|
283
|
-
prefix_with_copublishers.maybe >> space? >> str("/").maybe >>
|
|
284
|
-
type_with_stage.maybe >>
|
|
285
|
-
space.maybe >>
|
|
286
|
-
second_part >> third_part_edition
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# For joint identifiers, we do not treat it as a supplementary identifier
|
|
290
|
-
# (hence not a base)
|
|
291
|
-
# ISO only supports IDF in joint identifiers
|
|
292
|
-
# ISO 5537|IDF 26
|
|
293
|
-
# ISO 17678|IDF 202:2010
|
|
294
|
-
# ISO/TS 4985:2023 | IDF/RM 255
|
|
295
|
-
# ISO 4214:2022 | IDF 254:2022
|
|
296
|
-
rule(:joint_identifier) do
|
|
297
|
-
identifier_copublishers_no_third.as(:base) >>
|
|
298
|
-
space? >> str("|") >> space? >>
|
|
299
|
-
scope { idf_identifier }.as(:joint_identifier)
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
rule(:idf_identifier) do
|
|
303
|
-
Idf::Parser.new.identifier
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
# NSB ISO identifiers - National Body prefixed ISO identifiers
|
|
307
|
-
# FprISO 105-A03
|
|
308
|
-
# FprISO/IEC 17029
|
|
309
|
-
# WD/ISO 10360-2
|
|
310
|
-
# WD/ISO 10360-5:2000
|
|
311
|
-
rule(:nsb_iso_identifier) do
|
|
312
|
-
# FprISO, FprISO/IEC - stage prefix directly attached to publisher
|
|
313
|
-
(str("Fpr").as(:nsb_stage) >>
|
|
314
|
-
prefix_sole_publisher >> space? >> copublishers.maybe >>
|
|
315
|
-
space.maybe >>
|
|
316
|
-
type_with_stage.maybe >>
|
|
317
|
-
space.maybe >>
|
|
318
|
-
second_part >> third_part) |
|
|
319
|
-
# WD/ISO - stage prefix with slash before publisher
|
|
320
|
-
(str("WD").as(:nsb_stage) >> str("/") >>
|
|
321
|
-
prefix_sole_publisher >> space? >> copublishers.maybe >>
|
|
322
|
-
space.maybe >>
|
|
323
|
-
type_with_stage.maybe >>
|
|
324
|
-
space.maybe >>
|
|
325
|
-
second_part >> third_part)
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
# TODO: Do something with NSB ISO identifiers like "FprISO", "WD/ISO"
|
|
329
|
-
# Guide ISO/CEI 51:1999
|
|
330
|
-
# FprISO 105-A03
|
|
331
|
-
# FprISO/IEC 17029
|
|
332
|
-
# WD/ISO 10360-5:2000
|
|
333
|
-
# ISO 4918:2016+A1:2018
|
|
334
|
-
# rule(:nsb_iso_identifier) do
|
|
335
|
-
# str("Fpr").as(:stage).maybe >>
|
|
336
|
-
# # Withdrawn e.g: WD/ISO 10360-5:2000
|
|
337
|
-
# str("WD/").maybe >>
|
|
338
|
-
# # for French and Russian PubIDs starting with Guide type
|
|
339
|
-
# (guide_prefix.as(:type) >> space).maybe >>
|
|
340
|
-
# (stage.as(:stage) >> space).maybe >>
|
|
341
|
-
# (typed_stage.as(:stage) >> space).maybe >>
|
|
342
|
-
# (originator >> (space | str("/"))).maybe >>
|
|
343
|
-
# (tc_document_body | std_document_body | (dir_document_body >>
|
|
344
|
-
# (str(" + ") >> (originator >> space >> dir_document_body).as(:dir_joint_document)).maybe))
|
|
345
|
-
# end
|
|
346
|
-
|
|
347
|
-
rule(:supplement_type_with_stage) do
|
|
348
|
-
# "DAM"
|
|
349
|
-
# "NP Amd"
|
|
350
|
-
array_to_str(TYPED_STAGES_SUPPLEMENTS).as(:type_with_stage)
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
# ISO 8601-1:2019/Amd 2:2024
|
|
354
|
-
# ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
|
|
355
|
-
rule(:supplement_identifier_no_third) do
|
|
356
|
-
identifier_copublishers_no_third.as(:base) >>
|
|
357
|
-
str("/") >> supplement_type_with_stage >>
|
|
358
|
-
# The trailing number/date is optional: some draft supplements have no
|
|
359
|
-
# number yet, e.g. "ISO/IEC 9579/WD Amd".
|
|
360
|
-
((space? >> second_part) | (str(".") >> digits.as(:number)) | (space? >> date)).maybe
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
rule(:supplement_identifier) do
|
|
364
|
-
supplement_identifier_no_third >> third_part
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
# ISO/IEC 13818-1:2015/Amd 3:2016/Cor 1:2017
|
|
368
|
-
# ISO/IEC 19794-7:2014/Amd 1:2015/CD Cor 1
|
|
369
|
-
# ISO/IEC 10646-1:1993/pDCOR.2 (legacy dot-prefixed format)
|
|
370
|
-
rule(:supplement_supplement_identifier) do
|
|
371
|
-
supplement_identifier_no_third.as(:base) >>
|
|
372
|
-
str("/") >> supplement_type_with_stage >>
|
|
373
|
-
((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
# ISO 12345:2020/Amd 1:2021/Cor 1:2022/Amd 2:2023 (three-level supplement)
|
|
377
|
-
rule(:supplement_supplement_supplement_identifier) do
|
|
378
|
-
supplement_supplement_identifier.as(:base) >>
|
|
379
|
-
str("/") >> supplement_type_with_stage >>
|
|
380
|
-
((space? >> second_part >> third_part) | (str(".") >> digits.as(:number) >> third_part))
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
# ISO/IEC DIR
|
|
384
|
-
# ISO/IEC DIR 1
|
|
385
|
-
# ISO/IEC DIR 2:2022
|
|
386
|
-
rule(:directives_identifier) do
|
|
387
|
-
directives_identifier_no_third >> third_part.maybe >> space? >> date.maybe
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
# ISO/IEC JTC 1 DIR (JTC 1 Directives)
|
|
391
|
-
rule(:directives_publisher_subgroup) do
|
|
392
|
-
str("JTC 1").as(:subgroup)
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
# Special number_with_part rule for Directives to handle variants
|
|
396
|
-
# We treat the variant as `part` of the number_with_part
|
|
397
|
-
rule(:directives_number_with_part) do
|
|
398
|
-
(number >> directives_part_and_subpart.maybe).as(:number_with_part)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
# ISO/IEC DIR 1 IEC (IEC version of the ISO/IEC DIR 1)
|
|
402
|
-
# ISO/IEC DIR 2 ISO:2022 (ISO version of the ISO/IEC DIR 2)
|
|
403
|
-
# But NOT: ISO/IEC DIR 1 ISO SUP:2022 (ISO is supplement publisher)
|
|
404
|
-
# "1 IEC"
|
|
405
|
-
# "2 ISO"
|
|
406
|
-
rule(:directives_part_and_subpart) do
|
|
407
|
-
# Only match ISO/IEC if NOT followed by "/" (dual publisher) or supplement keywords
|
|
408
|
-
space >> (str("ISO") | str("IEC")) >> str("/").absent? >> (space >> str("SUP")).absent?
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
DIRECTIVES_TYPED_STAGES = Identifiers::Directives::TYPED_STAGES.map(&:abbr).flatten.sort_by(&:length).reverse
|
|
412
|
-
rule(:directives_identifier_no_third) do
|
|
413
|
-
prefix_with_copublishers >> space? >>
|
|
414
|
-
(directives_publisher_subgroup >> space).maybe >>
|
|
415
|
-
array_to_str(DIRECTIVES_TYPED_STAGES).as(:type_with_stage) >>
|
|
416
|
-
# The subgroup may also follow the type, e.g. "ISO/IEC DIR JTC 1"
|
|
417
|
-
# (canonical form is "ISO/IEC JTC 1 DIR"). Guard against a trailing
|
|
418
|
-
# supplement, where "JTC 1" is the supplement publisher instead
|
|
419
|
-
# (e.g. "ISO/IEC DIR JTC 1 SUP").
|
|
420
|
-
(space >> directives_publisher_subgroup >> (space >> str("SUP")).absent?).maybe >>
|
|
421
|
-
(
|
|
422
|
-
(space >> directives_number_with_part).maybe >>
|
|
423
|
-
(str(":") >> date).maybe
|
|
424
|
-
).maybe
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
rule(:directives_supplement_identifier) do
|
|
428
|
-
directives_identifier_no_third.as(:base) >> space? >> directives_supplement_part
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
DIRECTIVES_SUPPLEMENTS_TYPED_STAGES = Identifiers::DirectivesSupplement::TYPED_STAGES.map(&:abbr).flatten.sort_by(&:length).reverse
|
|
432
|
-
|
|
433
|
-
rule(:directives_supplement_part_no_third) do
|
|
434
|
-
# ISO/IEC DIR 1 ISO SUP
|
|
435
|
-
# ISO/IEC DIR 2 ISO SUP:2022
|
|
436
|
-
# ISO/IEC DIR JTC 1 SUP:2021
|
|
437
|
-
# ISO/IEC Directives, Part 1 -- Consolidated ISO Supplement
|
|
438
|
-
(space? >> str("--") >> space? >> str("Consolidated") >> space).maybe >>
|
|
439
|
-
(str("ISO/IEC") | str("ISO") | str("IEC") | str("JTC 1")).as(:publisher) >>
|
|
440
|
-
(space >> array_to_str(DIRECTIVES_SUPPLEMENTS_TYPED_STAGES).as(:type_with_stage)) >>
|
|
441
|
-
date.maybe
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
rule(:directives_supplement_part) do
|
|
445
|
-
directives_supplement_part_no_third >> third_part.maybe
|
|
446
|
-
end
|
|
447
|
-
|
|
448
|
-
# ISO/IEC DIR 1 + IEC SUP:2016-05
|
|
449
|
-
# ISO/IEC DIR 1:2022 + IEC SUP:2022
|
|
450
|
-
rule(:directives_bundled_identifier) do
|
|
451
|
-
(
|
|
452
|
-
directives_identifier_no_third >>
|
|
453
|
-
(third_part >> space?).maybe >>
|
|
454
|
-
(date >> space?).maybe
|
|
455
|
-
).as(:base_document) >>
|
|
456
|
-
(
|
|
457
|
-
str("+ ") >>
|
|
458
|
-
directives_supplement_part_no_third.as(:supplement)
|
|
459
|
-
).repeat(1).as(:supplements)
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
rule(:directives_identifiers) do
|
|
463
|
-
directives_bundled_identifier |
|
|
464
|
-
directives_supplement_identifier |
|
|
465
|
-
directives_identifier
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
rule(:dash) do
|
|
469
|
-
DASH_CHARS.map { |char| str(char) }.reduce(:|)
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
# rule(:tctype) do
|
|
473
|
-
# # tc-types
|
|
474
|
-
# array_to_str(TCTYPES)
|
|
475
|
-
# end
|
|
476
|
-
|
|
477
|
-
# rule(:sctype) do
|
|
478
|
-
# str("SC")
|
|
479
|
-
# end
|
|
480
|
-
|
|
481
|
-
# rule(:wgtype) do
|
|
482
|
-
# array_to_str(WGTYPES)
|
|
483
|
-
# end
|
|
484
|
-
|
|
485
|
-
# rule(:roman_numerals) do
|
|
486
|
-
# str("CD").absent? >> array_to_str(%w[I V X L C D M]).repeat(1).as(:roman_numerals)
|
|
487
|
-
# end
|
|
488
|
-
|
|
489
|
-
# rule(:part_matcher) do
|
|
490
|
-
# year_digits.absent? >>
|
|
491
|
-
# supplements.absent? >>
|
|
492
|
-
# staged_addenda.absent? >> ((roman_numerals >> digits.absent?) | match['[\dA-Z]'].repeat(1)).as(:part)
|
|
493
|
-
# end
|
|
494
|
-
|
|
495
|
-
# rule(:supplement) do
|
|
496
|
-
# ((str("/") | space).maybe >>
|
|
497
|
-
# (((stage.as(:typed_stage) >> space).maybe >> supplements.as(:type)) |
|
|
498
|
-
# staged_supplement.as(:typed_stage)) >>
|
|
499
|
-
# (space | str(".")).repeat(1).maybe >>
|
|
500
|
-
# digits.as(:number).maybe >>
|
|
501
|
-
# (str(".") >> digits.as(:iteration)).maybe >>
|
|
502
|
-
# ((str(":") | dash) >> digits.as(:year)).maybe).repeat(1).as(:supplements)
|
|
503
|
-
# end
|
|
504
|
-
|
|
505
|
-
# # Parse technical committee documents
|
|
506
|
-
# rule(:tc_document_body) do
|
|
507
|
-
# (tctype.as(:tctype) >> str("/").maybe).repeat >> space >> digits.as(:tcnumber) >>
|
|
508
|
-
# (str("/") >> (
|
|
509
|
-
# ((sctype.as(:sctype) >> space >> digits.as(:scnumber) >> str("/")).maybe >>
|
|
510
|
-
# wgtype.as(:wgtype) >> space >> digits.as(:wgnumber)) |
|
|
511
|
-
# (sctype.as(:sctype) >> (space | str("/") >> wgtype.as(:wgtype) >> space) >> digits.as(:scnumber))
|
|
512
|
-
# )).maybe >>
|
|
513
|
-
# space >> str("N") >> space? >> digits.as(:number)
|
|
514
|
-
# end
|
|
515
|
-
|
|
516
|
-
# rule(:dir_supplement_edition) do
|
|
517
|
-
# space >> (str("Edition") | str("Ed")) >> space >> digits.as(:edition)
|
|
518
|
-
# end
|
|
519
|
-
|
|
520
|
-
# rule(:dir_document_body) do
|
|
521
|
-
# ((str("DIR") | str("Directives Part") | str("Directives, Part") | str("Directives,")).as(:type) >> space).maybe >>
|
|
522
|
-
# (str("JTC").as(:dirtype) >> space).maybe >>
|
|
523
|
-
# (digits.as(:number) >> (str(":") >> year).maybe).maybe >>
|
|
524
|
-
# (space >> str("DIR").as(:jtc_dir) >> (str(":") >> year).maybe).maybe >>
|
|
525
|
-
# (str(" -- Consolidated").maybe >> (str("").as(:mark) >> space? >>
|
|
526
|
-
# (organization.as(:publisher) >> space?).maybe >>
|
|
527
|
-
# array_to_str(DIR_SUPPLEMENTS) >> (str(":") >> (year >> (dash >> month_digits.as(:month)).maybe)).maybe >>
|
|
528
|
-
# dir_supplement_edition.maybe).repeat(1).as(:supplements)).maybe >>
|
|
529
|
-
# # parse identifiers with publisher at the end, e.g. "ISO/IEC DIR 2 ISO"
|
|
530
|
-
# (space >> organization.as(:publisher) >> (str(":") >> year).maybe).as(:edition).maybe
|
|
531
|
-
# end
|
|
532
|
-
|
|
533
|
-
# rule(:identifier) do
|
|
534
|
-
# str("Fpr").as(:stage).maybe >>
|
|
535
|
-
# # Withdrawn e.g: WD/ISO 10360-5:2000
|
|
536
|
-
# str("WD/").maybe >>
|
|
537
|
-
# # for French and Russian PubIDs starting with Guide type
|
|
538
|
-
# (guide_prefix.as(:type) >> space).maybe >>
|
|
539
|
-
# (stage.as(:stage) >> space).maybe >>
|
|
540
|
-
# (typed_stage.as(:stage) >> space).maybe >>
|
|
541
|
-
# (originator >> (space | str("/"))).maybe >>
|
|
542
|
-
# (tc_document_body | std_document_body | (dir_document_body >>
|
|
543
|
-
# (str(" + ") >> (originator >> space >> dir_document_body).as(:dir_joint_document)).maybe))
|
|
544
|
-
# end
|
|
545
7
|
end
|
|
546
8
|
end
|
|
547
9
|
end
|
|
@@ -56,9 +56,12 @@ module Pubid
|
|
|
56
56
|
def to_s(**opts)
|
|
57
57
|
return super if opts[:format] && opts[:format] != :human
|
|
58
58
|
|
|
59
|
-
context = build_rendering_context(
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
context = build_rendering_context(
|
|
60
|
+
nil, format: :human, **opts.except(:with_publisher)
|
|
61
|
+
)
|
|
62
|
+
rendered = Pubid::Renderers::SupplementRenderer.new(self)
|
|
63
|
+
.render(context:, **opts.slice(:with_edition))
|
|
64
|
+
apply_with_publisher(rendered, :human, opts[:with_publisher])
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
# MR supplement suffix: `/{type}.{number}.{year}` (e.g. "/amd.1.2020").
|
data/lib/pubid/iso/urn_parser.rb
CHANGED
|
@@ -437,9 +437,14 @@ module Pubid
|
|
|
437
437
|
base_hash[:languages] = languages.join("/")
|
|
438
438
|
end
|
|
439
439
|
|
|
440
|
-
# Build supplements
|
|
441
|
-
# second wraps first, etc. -- matching URN left-to-right
|
|
442
|
-
|
|
440
|
+
# Build supplements (forward order: first supplement wraps base,
|
|
441
|
+
# second wraps first, etc. -- matching URN left-to-right
|
|
442
|
+
# semantics). Each layer captures into the bound hash's
|
|
443
|
+
# position-scoped prefix (supp_ / supp2_ / supp3_), the same
|
|
444
|
+
# names the grammar binds, so the builder peels the wrappers the
|
|
445
|
+
# same way for both parse paths.
|
|
446
|
+
supplements.each_with_index do |supp, index|
|
|
447
|
+
prefix = index.zero? ? "supp_" : "supp#{index + 1}_"
|
|
443
448
|
# A bare language token with no supplement identity names the BASE
|
|
444
449
|
# document: wrapping it would build a supplement with no type,
|
|
445
450
|
# number or base attribute, and a plain standard drops its base —
|
|
@@ -499,11 +504,11 @@ typed_stage
|
|
|
499
504
|
supp_hash[:languages] = supp[:languages].join("/")
|
|
500
505
|
end
|
|
501
506
|
|
|
502
|
-
#
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
+
# Layer the supplement onto the flat bound hash under its
|
|
508
|
+
# position-scoped prefix
|
|
509
|
+
supp_hash.each do |key, value|
|
|
510
|
+
base_hash[:"#{prefix}#{key}"] = value
|
|
511
|
+
end
|
|
507
512
|
end
|
|
508
513
|
|
|
509
514
|
# all_parts belongs on the outermost identifier (after any supplement wrapping)
|
data/lib/pubid/iso/utilities.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
3
|
|
|
5
4
|
module Pubid
|
|
6
5
|
module Iso
|
|
@@ -28,7 +27,7 @@ module Pubid
|
|
|
28
27
|
candidate = match[1]
|
|
29
28
|
begin
|
|
30
29
|
return Pubid::Iso.parse(candidate)
|
|
31
|
-
rescue
|
|
30
|
+
rescue Pubid::Errors::ParseError
|
|
32
31
|
# Continue to next method
|
|
33
32
|
end
|
|
34
33
|
end
|
|
@@ -52,7 +51,7 @@ module Pubid
|
|
|
52
51
|
end
|
|
53
52
|
matches.each do |m|
|
|
54
53
|
return Pubid::Iso.parse(m[0].strip)
|
|
55
|
-
rescue
|
|
54
|
+
rescue Pubid::Errors::ParseError
|
|
56
55
|
# Try next match
|
|
57
56
|
end
|
|
58
57
|
|
|
@@ -62,7 +61,7 @@ module Pubid
|
|
|
62
61
|
candidate = words[-count..].join(" ")
|
|
63
62
|
begin
|
|
64
63
|
return Pubid::Iso.parse(candidate)
|
|
65
|
-
rescue
|
|
64
|
+
rescue Pubid::Errors::ParseError
|
|
66
65
|
# Try with fewer words
|
|
67
66
|
end
|
|
68
67
|
end
|
|
@@ -74,7 +73,7 @@ module Pubid
|
|
|
74
73
|
|
|
75
74
|
begin
|
|
76
75
|
return Pubid::Iso.parse(part.strip)
|
|
77
|
-
rescue
|
|
76
|
+
rescue Pubid::Errors::ParseError
|
|
78
77
|
# Try next part
|
|
79
78
|
end
|
|
80
79
|
end
|
data/lib/pubid/iso.rb
CHANGED
|
@@ -130,7 +130,7 @@ module Pubid
|
|
|
130
130
|
UrnParser.parse(urn)
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
# Build an ISO identifier from a
|
|
133
|
+
# Build an ISO identifier from a parg parse-tree hash (used by other
|
|
134
134
|
# flavors when parsing joint identifiers, e.g. IEC's `IEC … | ISO …` form).
|
|
135
135
|
#
|
|
136
136
|
# This is the public seam: callers should never reach into
|
|
@@ -142,18 +142,6 @@ module Pubid
|
|
|
142
142
|
builder.build(hash)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
# Return the named Parslet rule atom from the ISO parser, for embedding in
|
|
146
|
-
# another flavor's grammar (e.g. IEC joint identifiers).
|
|
147
|
-
#
|
|
148
|
-
# This is the public seam: callers should never instantiate
|
|
149
|
-
# `Pubid::Iso::Parser` directly.
|
|
150
|
-
#
|
|
151
|
-
# @param rule_name [Symbol] the parser rule to expose
|
|
152
|
-
# @return [Parslet::Atoms::Base]
|
|
153
|
-
def self.joint_grammar_atom(rule_name)
|
|
154
|
-
parser.public_send(rule_name)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
145
|
# Auto-discover all identifier types from the Identifiers namespace
|
|
158
146
|
# @return [Array<Class>] identifier classes that define a self.type Hash
|
|
159
147
|
def self.identifier_types
|
|
@@ -181,12 +169,6 @@ module Pubid
|
|
|
181
169
|
@builder ||= Builder.new
|
|
182
170
|
end
|
|
183
171
|
|
|
184
|
-
# Memoized parser instance used by Normalizer
|
|
185
|
-
# @return [Pubid::Iso::Parser]
|
|
186
|
-
def self.parser
|
|
187
|
-
@parser ||= Parser.new
|
|
188
|
-
end
|
|
189
|
-
|
|
190
172
|
# Lookup: type code -> identifier class
|
|
191
173
|
# @param code [String, Symbol] the type key to find
|
|
192
174
|
# @return [Class, nil] the matching identifier class
|