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/jcgm/builder.rb
CHANGED
|
@@ -24,7 +24,18 @@ module Pubid
|
|
|
24
24
|
Jcgm.locate_type(typed_stage.type_code)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# The bound grammar flattens the old `(base as base)` wrapper (the
|
|
28
|
+
# bindings cannot nest): the base document keeps the canonical
|
|
29
|
+
# number/date captures and the supplement layer captures
|
|
30
|
+
# supp_number/supp_date. Rebuild the nested shape the builder has
|
|
31
|
+
# always consumed — the base fields rename under :base and the
|
|
32
|
+
# supplement layer takes type_with_stage plus its own
|
|
33
|
+
# supp_number/supp_date, which is exactly the tree the
|
|
34
|
+
# amendment/corrigendum rules produced before the flatten.
|
|
35
|
+
SUPPLEMENT_STAGES = %w[Amd Cor Corrigendum].freeze
|
|
36
|
+
|
|
27
37
|
def build(parsed_hash)
|
|
38
|
+
parsed_hash = unflatten_supplement(parsed_hash)
|
|
28
39
|
klass = locate_identifier_klass(parsed_hash)
|
|
29
40
|
|
|
30
41
|
# GUM guides store their part number in the shared `number` attribute
|
|
@@ -52,6 +63,30 @@ module Pubid
|
|
|
52
63
|
|
|
53
64
|
private
|
|
54
65
|
|
|
66
|
+
def unflatten_supplement(parsed_hash)
|
|
67
|
+
stage = parsed_hash[:type_with_stage]
|
|
68
|
+
return parsed_hash if parsed_hash[:base] || stage.nil? ||
|
|
69
|
+
!SUPPLEMENT_STAGES.include?(stage)
|
|
70
|
+
|
|
71
|
+
base_hash = {}
|
|
72
|
+
%i[publisher number gum_number date languages].each do |key|
|
|
73
|
+
base_hash[key] = parsed_hash.delete(key) if parsed_hash[key]
|
|
74
|
+
end
|
|
75
|
+
stage = parsed_hash.delete(:type_with_stage)
|
|
76
|
+
supplement_hash = { type_with_stage: stage }
|
|
77
|
+
if parsed_hash[:supp_number]
|
|
78
|
+
supplement_hash[:number] = parsed_hash.delete(:supp_number)
|
|
79
|
+
end
|
|
80
|
+
if parsed_hash[:supp_date]
|
|
81
|
+
supplement_hash[:date] = parsed_hash.delete(:supp_date)
|
|
82
|
+
end
|
|
83
|
+
# Keep the base as a raw hash: the shared assign_attributes loop
|
|
84
|
+
# routes :base through cast, which recursively builds it — the
|
|
85
|
+
# same path the tree backend's nested subtree took.
|
|
86
|
+
supplement_hash[:base] = base_hash
|
|
87
|
+
parsed_hash.merge(supplement_hash)
|
|
88
|
+
end
|
|
89
|
+
|
|
55
90
|
def default_identifier_class
|
|
56
91
|
Identifiers::Guide
|
|
57
92
|
end
|
data/lib/pubid/jcgm/parser.rb
CHANGED
|
@@ -1,158 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Jcgm
|
|
7
|
-
class Parser
|
|
8
|
-
include ::Pubid::Parser::CommonParseRules
|
|
9
|
-
include ::Pubid::Parser::CommonParseMethods
|
|
10
|
-
|
|
11
|
-
root :identifier
|
|
12
|
-
|
|
13
|
-
rule(:identifier) do
|
|
14
|
-
meeting_identifier | amendment_identifier | corrigendum_identifier |
|
|
15
|
-
numbered_corrigendum_identifier | base | named_guide_identifier
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# "JCGM 200:2008 Corrigendum" — a base guide plus a trailing
|
|
19
|
-
# " Corrigendum" word (no number). Must precede base: Parslet
|
|
20
|
-
# is an ordered PEG that commits to the first matching alternative, so if
|
|
21
|
-
# base ran first it would consume "JCGM 200:2008" and root
|
|
22
|
-
# would fail on the leftover " Corrigendum". Emits type_with_stage so the
|
|
23
|
-
# builder routes it to Corrigendum.
|
|
24
|
-
rule(:corrigendum_identifier) do
|
|
25
|
-
base.as(:base) >> space >>
|
|
26
|
-
str("Corrigendum").as(:type_with_stage)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# "JCGM 101:2008/Cor 1:2009" — a base guide plus a slash-separated
|
|
30
|
-
# numbered corrigendum (mirrors the ISO/IEC supplement form). The
|
|
31
|
-
# trailing :YYYY is optional so "JCGM 101:2008/Cor 1" also parses.
|
|
32
|
-
# Must precede base for the same PEG-commit reason as corrigendum_identifier.
|
|
33
|
-
rule(:numbered_corrigendum_identifier) do
|
|
34
|
-
base.as(:base) >>
|
|
35
|
-
str("/") >> str("Cor").as(:type_with_stage) >>
|
|
36
|
-
supplement_separator >> digits.as(:number) >>
|
|
37
|
-
corrigendum_date.maybe
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# "Amd 1" and the dotted "Amd.1:2026" BIPM prints on its
|
|
41
|
-
# publications page (bipm.org, JCGM 100:2008/Amd.1:2026) are both
|
|
42
|
-
# accepted on input; rendering stays "Amd 1".
|
|
43
|
-
rule(:supplement_separator) do
|
|
44
|
-
space | (str(".") >> space.maybe)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Dateless "named" guides: "JCGM GUM", "JCGM VIM-3" (and future "VIM-N").
|
|
48
|
-
# Last in the alternation — only reached when base fully fails
|
|
49
|
-
# (these have no date, so number_portion/date_portion never match).
|
|
50
|
-
rule(:named_guide_identifier) do
|
|
51
|
-
publisher >> space >> named_number
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
rule(:named_number) do
|
|
55
|
-
(str("GUM") | (str("VIM") >> (str("-") >> digits).maybe)).as(:number)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Committee/meeting record, e.g. "JCGM 17th Meeting (2012)". Diverges
|
|
59
|
-
# from base right after the digits (base wants ":", meeting
|
|
60
|
-
# wants the ordinal suffix), so ordered choice is unambiguous. Emits the
|
|
61
|
-
# same tokens as a guide plus type_with_stage "Meeting", so the generic
|
|
62
|
-
# builder path resolves it to Identifiers::Meeting (like "Amd").
|
|
63
|
-
#
|
|
64
|
-
# The trailing " (YYYY)" group is optional, so the partial reference
|
|
65
|
-
# "JCGM 11st Meeting" parses with `date` left nil. JCGM numbers its
|
|
66
|
-
# meetings in one sequence, so the ordinal alone names the event and the
|
|
67
|
-
# year is redundant detail. The whole group is `.maybe` (not the year
|
|
68
|
-
# inside it), so a dangling "(" or a truncated year still fails —
|
|
69
|
-
# the same shape as `date_portion.maybe` in `rule(:base)`.
|
|
70
|
-
rule(:meeting_identifier) do
|
|
71
|
-
publisher >> space >> digits.as(:number) >> ordinal_suffix >>
|
|
72
|
-
space >> str("Meeting").as(:type_with_stage) >>
|
|
73
|
-
(space >> str("(") >> year_digits.as(:date) >> str(")")).maybe
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
rule(:ordinal_suffix) do
|
|
77
|
-
str("st") | str("nd") | str("rd") | str("th")
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# `date_portion` is optional so a partial reference that omits the
|
|
81
|
-
# trailing `:YYYY` date (e.g. "JCGM 100") parses with `date` left nil,
|
|
82
|
-
# letting relaton match a collection via `matches?(row, ignore: [:date])`.
|
|
83
|
-
# The whole sub-rule is `.maybe` (not the year inside it) so a dangling
|
|
84
|
-
# ":" still fails. Mirrors ETSI (lib/pubid/etsi/parser.rb).
|
|
85
|
-
rule(:base) do
|
|
86
|
-
publisher >> space >> number_portion >>
|
|
87
|
-
date_portion.maybe >> language_portion.maybe
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
rule(:amendment_identifier) do
|
|
91
|
-
base.as(:base) >>
|
|
92
|
-
str("/") >> amendment_type >>
|
|
93
|
-
supplement_separator >> digits.as(:number) >>
|
|
94
|
-
amendment_date.maybe
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
rule(:publisher) do
|
|
98
|
-
str("JCGM").as(:publisher)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Number can be plain (100, 200) or GUM-prefixed (GUM-1, GUM-6)
|
|
102
|
-
rule(:number_portion) do
|
|
103
|
-
gum_number | standard_number
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
rule(:standard_number) do
|
|
107
|
-
digits.as(:number)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
rule(:gum_number) do
|
|
111
|
-
str("GUM-") >> digits.as(:gum_number)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Date can be YYYY or YYYY-MM-DD
|
|
115
|
-
rule(:date_portion) do
|
|
116
|
-
str(":") >> (full_date | year_only)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
rule(:year_only) do
|
|
120
|
-
year_digits.as(:date)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
rule(:full_date) do
|
|
124
|
-
(year_digits >> str("-") >> month_digits >> str("-") >> day_digits).as(:date)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# Language: "(E)", "(F)", "(E/F)", "(F/E)"
|
|
128
|
-
rule(:language_portion) do
|
|
129
|
-
str("(") >>
|
|
130
|
-
(
|
|
131
|
-
# Multi-language: E/F, F/E
|
|
132
|
-
(str("E/F") | str("F/E")) |
|
|
133
|
-
# Single language: E, F, R, etc.
|
|
134
|
-
match("[A-Z]")
|
|
135
|
-
).as(:languages) >>
|
|
136
|
-
str(")")
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Amendment support
|
|
140
|
-
rule(:amendment_type) do
|
|
141
|
-
str("Amd").as(:type_with_stage)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
rule(:amendment_number) do
|
|
145
|
-
digits.as(:number)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
rule(:amendment_date) do
|
|
149
|
-
str(":") >> (full_date | year_only)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# Numbered corrigendum date: same shape as amendment_date.
|
|
153
|
-
rule(:corrigendum_date) do
|
|
154
|
-
str(":") >> (full_date | year_only)
|
|
155
|
-
end
|
|
5
|
+
class Parser
|
|
156
6
|
end
|
|
157
7
|
end
|
|
158
8
|
end
|
data/lib/pubid/jcgm.rb
CHANGED
|
@@ -32,10 +32,9 @@ module Pubid
|
|
|
32
32
|
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
parser = Parser.new
|
|
36
35
|
builder = Builder.new
|
|
37
36
|
|
|
38
|
-
parsed = Pubid::Parg::
|
|
37
|
+
parsed = Pubid::Parg::Model.bound(:jcgm, identifier)
|
|
39
38
|
builder.build(parsed)
|
|
40
39
|
end
|
|
41
40
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# JIS flavor notes
|
|
2
|
+
|
|
3
|
+
## WES lives in the JIS flavor (relaton-jis#18)
|
|
4
|
+
|
|
5
|
+
- WES (Japan Welding Engineering Society) ids — `WES 7700-1:2019`,
|
|
6
|
+
`WES 7301:2020R` — parse as `Identifiers::WeldingEngineeringStandard`
|
|
7
|
+
(`_type: pubid:jis:welding-engineering-standard`). JSA Webdesk sells WES next
|
|
8
|
+
to JIS and relaton crawls both into one `relaton-data-jis` index, so a
|
|
9
|
+
separate `Pubid::Wes` flavor was rejected.
|
|
10
|
+
- **Grammar**: `data/parg/jis.json` is `identifier = wes_identifier /
|
|
11
|
+
jis_identifier`. The WES branch is `"WES" space number parts …` with the same
|
|
12
|
+
tail as JIS (year, `R`, language, 規格群, supplements, SYMBOL) and binds a
|
|
13
|
+
`wes` capture, which the builder keys on. `JIS WES 7700` and `WES X 7700`
|
|
14
|
+
are rejected: the JIS prefix and a series letter belong only to JIS. The
|
|
15
|
+
source of record is pubid/pubid-grammar; the artifact was rebaked here with
|
|
16
|
+
parsanol **1.3.114** — the PATH `parsanol` shim may be a newer version, so
|
|
17
|
+
bake with the 1.3.114 gem's `exe/parsanol` and check `compiler_version`.
|
|
18
|
+
- **`series` is nil** for WES (JIS keeps its `""`-coerced String), so the hash
|
|
19
|
+
carries no `series` key. `number` is the bare number (`"7700"`), the index
|
|
20
|
+
key.
|
|
21
|
+
- **"WES" is the root, not a publisher**: `publisher_prefix` is nil, `code`
|
|
22
|
+
is `"WES 7700-1"`, so `to_s(with_publisher: false)` still prints `WES …`,
|
|
23
|
+
also as the base of a supplement. The URN is `urn:jis:WES 7700-1:2019`;
|
|
24
|
+
`UrnParser` does not prepend `JIS ` to a code that starts with `WES `.
|
|
25
|
+
- `PREFIXES` includes `"WES"`, so `Pubid.parse("WES …")` routes to JIS.
|
|
26
|
+
|
|
27
|
+
## Equality includes the class
|
|
28
|
+
|
|
29
|
+
- `Identifier#==` requires `other.instance_of?(self.class)`: `JIS TR X
|
|
30
|
+
0014:1999` is not `JIS X 0014:1999` (3 such pairs are in the published
|
|
31
|
+
index), and `WES 7700` is never a JIS standard. `#matches?` follows, since it
|
|
32
|
+
compares `exclude(…)` results with `==`.
|
|
33
|
+
- `SupplementIdentifier#==` also compares `symbol` and `reaffirmed?`:
|
|
34
|
+
`…/AMD 3:2025R SYMBOL 65700` is not `…/AMD 3:2025`.
|
|
35
|
+
- The all-parts match is `===` (`Pubid::AllParts`), not `==`, and is
|
|
36
|
+
unchanged.
|
data/lib/pubid/jis/builder.rb
CHANGED
|
@@ -9,12 +9,14 @@ module Pubid
|
|
|
9
9
|
|
|
10
10
|
def build(data)
|
|
11
11
|
# Handle supplement case first; the SYMBOL clause (if any) attaches to
|
|
12
|
-
# the outermost identifier, be it the base or the supplement.
|
|
13
|
-
|
|
12
|
+
# the outermost identifier, be it the base or the supplement. The
|
|
13
|
+
# bindings bind the supplement's fields flat (amd_type/amd_number/…),
|
|
14
|
+
# so their presence marks the supplement kind.
|
|
15
|
+
identifier = if data[:amd_type]
|
|
14
16
|
build_amendment(data)
|
|
15
|
-
elsif data[:
|
|
17
|
+
elsif data[:expl_type]
|
|
16
18
|
build_explanation(data)
|
|
17
|
-
elsif data[:
|
|
19
|
+
elsif data[:corr_type]
|
|
18
20
|
build_corrigendum(data)
|
|
19
21
|
else
|
|
20
22
|
build_single_identifier(data)
|
|
@@ -35,72 +37,59 @@ module Pubid
|
|
|
35
37
|
|
|
36
38
|
def build_single_identifier(data)
|
|
37
39
|
attrs = {
|
|
38
|
-
series: data[:series].to_s,
|
|
39
40
|
number: data[:number].to_s,
|
|
40
41
|
parts: extract_part_strings(data[:parts]),
|
|
41
42
|
year: data[:year]&.to_i,
|
|
42
43
|
language: data[:language]&.to_s,
|
|
43
44
|
reaffirmed: (true if data[:reaffirmed]),
|
|
44
45
|
}
|
|
46
|
+
# A WES id carries no series letter, so its series stays nil.
|
|
47
|
+
wes = Identifiers::WeldingEngineeringStandard
|
|
48
|
+
return wes.new(**attrs) if data[:wes]
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
when "TR"
|
|
50
|
-
Identifiers::TechnicalReport
|
|
51
|
-
when "TS"
|
|
52
|
-
Identifiers::TechnicalSpecification
|
|
53
|
-
else
|
|
54
|
-
Identifiers::JapaneseIndustrialStandard
|
|
55
|
-
end
|
|
50
|
+
jis_class_for_type(data[:type]&.to_s)
|
|
51
|
+
.new(series: data[:series].to_s, **attrs)
|
|
52
|
+
end
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
def jis_class_for_type(type)
|
|
55
|
+
case type
|
|
56
|
+
when "TR" then Identifiers::TechnicalReport
|
|
57
|
+
when "TS" then Identifiers::TechnicalSpecification
|
|
58
|
+
else Identifiers::JapaneseIndustrialStandard
|
|
59
|
+
end
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def build_amendment(data)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
base_data = data.except(:amendment)
|
|
65
|
-
base = build_single_identifier(base_data)
|
|
63
|
+
# The bindings carry the supplement's fields at the top level; the
|
|
64
|
+
# base document shares them.
|
|
65
|
+
base = build_single_identifier(data)
|
|
66
66
|
|
|
67
|
-
# Build amendment
|
|
68
67
|
Identifiers::Amendment.new(
|
|
69
68
|
base: base,
|
|
70
|
-
number:
|
|
71
|
-
year:
|
|
72
|
-
reaffirmed: (true if
|
|
69
|
+
number: data[:amd_number].to_i,
|
|
70
|
+
year: data[:amd_year].to_i,
|
|
71
|
+
reaffirmed: (true if data[:amd_reaffirmed]),
|
|
73
72
|
)
|
|
74
73
|
end
|
|
75
74
|
|
|
76
75
|
def build_explanation(data)
|
|
77
|
-
|
|
76
|
+
base = build_single_identifier(data)
|
|
78
77
|
|
|
79
|
-
# Build base document (without supplement)
|
|
80
|
-
base_data = data.except(:explanation)
|
|
81
|
-
base = build_single_identifier(base_data)
|
|
82
|
-
|
|
83
|
-
# Build explanation
|
|
84
78
|
Identifiers::Explanation.new(
|
|
85
79
|
base: base,
|
|
86
|
-
number:
|
|
80
|
+
number: data[:expl_number]&.to_i,
|
|
87
81
|
year: base.year,
|
|
88
82
|
)
|
|
89
83
|
end
|
|
90
84
|
|
|
91
85
|
def build_corrigendum(data)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
# Build base document (without supplement)
|
|
95
|
-
base_data = data.except(:corrigendum)
|
|
96
|
-
base = build_single_identifier(base_data)
|
|
86
|
+
base = build_single_identifier(data)
|
|
97
87
|
|
|
98
|
-
# Build corrigendum
|
|
99
88
|
Identifiers::Corrigendum.new(
|
|
100
89
|
base: base,
|
|
101
|
-
number:
|
|
102
|
-
year:
|
|
103
|
-
reaffirmed: (true if
|
|
90
|
+
number: data[:corr_number].to_i,
|
|
91
|
+
year: data[:corr_year].to_i,
|
|
92
|
+
reaffirmed: (true if data[:corr_reaffirmed]),
|
|
104
93
|
)
|
|
105
94
|
end
|
|
106
95
|
|
data/lib/pubid/jis/identifier.rb
CHANGED
|
@@ -43,6 +43,8 @@ module Pubid
|
|
|
43
43
|
"pubid:jis:amendment" => "Pubid::Jis::Identifiers::Amendment",
|
|
44
44
|
"pubid:jis:corrigendum" => "Pubid::Jis::Identifiers::Corrigendum",
|
|
45
45
|
"pubid:jis:explanation" => "Pubid::Jis::Identifiers::Explanation",
|
|
46
|
+
"pubid:jis:welding-engineering-standard" =>
|
|
47
|
+
"Pubid::Jis::Identifiers::WeldingEngineeringStandard",
|
|
46
48
|
}.freeze
|
|
47
49
|
|
|
48
50
|
key_value do
|
|
@@ -63,6 +65,12 @@ module Pubid
|
|
|
63
65
|
# would otherwise fail serialization type validation.
|
|
64
66
|
PUBLISHER = "JIS"
|
|
65
67
|
|
|
68
|
+
# The token the human render prints before the designation, and drops
|
|
69
|
+
# for `to_s(with_publisher: false)`; nil when the designation has none.
|
|
70
|
+
def publisher_prefix
|
|
71
|
+
PUBLISHER
|
|
72
|
+
end
|
|
73
|
+
|
|
66
74
|
def reaffirmed?
|
|
67
75
|
reaffirmed == true
|
|
68
76
|
end
|
|
@@ -88,8 +96,10 @@ module Pubid
|
|
|
88
96
|
result
|
|
89
97
|
end
|
|
90
98
|
|
|
99
|
+
# The class is part of the identity: "JIS TR X 0014:1999" is not
|
|
100
|
+
# "JIS X 0014:1999", and "WES 7700" is not a JIS standard.
|
|
91
101
|
def ==(other)
|
|
92
|
-
return false unless other.
|
|
102
|
+
return false unless other.instance_of?(self.class)
|
|
93
103
|
|
|
94
104
|
series == other.series &&
|
|
95
105
|
number == other.number &&
|
|
@@ -174,7 +184,7 @@ module Pubid
|
|
|
174
184
|
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
175
185
|
end
|
|
176
186
|
|
|
177
|
-
parsed = Pubid::Parg::
|
|
187
|
+
parsed = Pubid::Parg::Model.bound(:jis, identifier)
|
|
178
188
|
Builder.build(parsed)
|
|
179
189
|
end
|
|
180
190
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Jis
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Japan Welding Engineering Society standard. JSA sells WES next to JIS,
|
|
7
|
+
# so it parses through the JIS flavor, but the id carries no series
|
|
8
|
+
# letter and no JIS prefix.
|
|
9
|
+
# Examples: WES 7700-1:2019, WES 7301:2020R
|
|
10
|
+
class WeldingEngineeringStandard < SingleIdentifier
|
|
11
|
+
PUBLISHER = "WES"
|
|
12
|
+
|
|
13
|
+
def type_prefix
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# "WES" is the root of the designation, not a publisher token, so
|
|
18
|
+
# `to_s(with_publisher: false)` keeps it.
|
|
19
|
+
def publisher_prefix
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def code
|
|
24
|
+
result = "#{PUBLISHER} #{number}"
|
|
25
|
+
result += parts.map { |p| "-#{p}" }.join if parts&.any?
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def mr_publisher
|
|
30
|
+
PUBLISHER.downcase
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -13,6 +13,8 @@ module Pubid
|
|
|
13
13
|
autoload :TechnicalReport, "#{__dir__}/identifiers/technical_report"
|
|
14
14
|
autoload :TechnicalSpecification,
|
|
15
15
|
"#{__dir__}/identifiers/technical_specification"
|
|
16
|
+
autoload :WeldingEngineeringStandard,
|
|
17
|
+
"#{__dir__}/identifiers/welding_engineering_standard"
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
data/lib/pubid/jis/parser.rb
CHANGED
|
@@ -1,135 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Jis
|
|
7
|
-
class Parser
|
|
8
|
-
# Japanese character normalization
|
|
9
|
-
rule(:jp_dash) { str("ー") } # Full-width dash
|
|
10
|
-
rule(:jp_space) { str(" ") } # Full-width space
|
|
11
|
-
rule(:jp_colon) { str(":") } # Full-width colon
|
|
12
|
-
rule(:jp_lparen) { str("(") }
|
|
13
|
-
rule(:jp_rparen) { str(")") }
|
|
14
|
-
|
|
15
|
-
# Normalized separators
|
|
16
|
-
rule(:dash) { (str("-") | jp_dash).as(:dash) }
|
|
17
|
-
rule(:space) { str(" ") | jp_space }
|
|
18
|
-
rule(:colon) { str(":") | jp_colon }
|
|
19
|
-
|
|
20
|
-
# Basic elements
|
|
21
|
-
rule(:digit) { match["0-9"] }
|
|
22
|
-
rule(:digits) { digit.repeat(1) }
|
|
23
|
-
rule(:letter) { match["A-Z"] }
|
|
24
|
-
|
|
25
|
-
# JIS prefix (optional, handles both "JIS " and "JIS/")
|
|
26
|
-
rule(:jis_prefix) { str("JIS") >> (space | str("/")).maybe }
|
|
27
|
-
|
|
28
|
-
# Type prefix (TR or TS, can come with or without slash)
|
|
29
|
-
rule(:type_prefix) do
|
|
30
|
-
(str("TR") | str("TS")).as(:type) >> (space | str("/"))
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Series letter
|
|
34
|
-
rule(:series) { letter.as(:series) }
|
|
35
|
-
|
|
36
|
-
# Number (preserve as string to maintain leading zeros)
|
|
37
|
-
rule(:number) { digits.as(:number) }
|
|
38
|
-
|
|
39
|
-
# Parts (multi-level: -1, -2-1, -3-2-1, etc.)
|
|
40
|
-
rule(:part) do
|
|
41
|
-
dash >> digits.as(:part)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
rule(:parts) { part.repeat(0).as(:parts) }
|
|
45
|
-
|
|
46
|
-
# Reaffirmation marker (再確認): trailing "R" on a year
|
|
47
|
-
rule(:reaffirmed) { str("R").maybe.as(:reaffirmed) }
|
|
48
|
-
|
|
49
|
-
# Year
|
|
50
|
-
rule(:year) do
|
|
51
|
-
colon >> digits.as(:year) >> reaffirmed
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Language code
|
|
55
|
-
rule(:language) do
|
|
56
|
-
(str("(") | jp_lparen) >>
|
|
57
|
-
match["EJ"].as(:language) >>
|
|
58
|
-
(str(")") | jp_rparen)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# All-parts notation (Japanese)
|
|
62
|
-
rule(:all_parts) do
|
|
63
|
-
((jp_lparen >> str("規格群") >> jp_rparen) |
|
|
64
|
-
(str("(") >> str("規格群") >> str(")"))).as(:all_parts)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Amendment supplement
|
|
68
|
-
rule(:amendment) do
|
|
69
|
-
str("/") >>
|
|
70
|
-
(str("AMENDMENT") | str("AMD")).as(:amd_type) >>
|
|
71
|
-
space >>
|
|
72
|
-
digits.as(:amd_number) >>
|
|
73
|
-
colon >>
|
|
74
|
-
digits.as(:amd_year) >>
|
|
75
|
-
str("R").maybe.as(:amd_reaffirmed)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Explanation supplement
|
|
79
|
-
rule(:explanation) do
|
|
80
|
-
str("/") >>
|
|
81
|
-
(str("EXPLANATION") | str("EXPL")).as(:expl_type) >>
|
|
82
|
-
(space >> digits.as(:expl_number)).maybe
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Corrigendum supplement
|
|
86
|
-
rule(:corrigendum) do
|
|
87
|
-
str("/") >>
|
|
88
|
-
(str("CORRIGENDUM") | str("CORR")).as(:corr_type) >>
|
|
89
|
-
space >>
|
|
90
|
-
digits.as(:corr_number) >>
|
|
91
|
-
colon >>
|
|
92
|
-
digits.as(:corr_year) >>
|
|
93
|
-
str("R").maybe.as(:corr_reaffirmed)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Supplements (AMD, EXPL or CORRIGENDUM, only one for JIS)
|
|
97
|
-
rule(:supplement) do
|
|
98
|
-
amendment.as(:amendment) | explanation.as(:explanation) |
|
|
99
|
-
corrigendum.as(:corrigendum)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Graphical-symbol sub-reference (e.g. JIS Z 8210 safety signs):
|
|
103
|
-
# "SYMBOL <id>" where <id> runs to the end of the string and may be a
|
|
104
|
-
# number, an alphanumeric code or a free-text phrase. The keyword may
|
|
105
|
-
# also appear bare with no value.
|
|
106
|
-
rule(:symbol_clause) do
|
|
107
|
-
space >> str("SYMBOL").as(:symbol_present) >>
|
|
108
|
-
(space >> match["^\n"].repeat(1).as(:symbol_value)).maybe
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Main identifier
|
|
112
|
-
rule(:identifier) do
|
|
113
|
-
jis_prefix.maybe >>
|
|
114
|
-
type_prefix.maybe >>
|
|
115
|
-
space.maybe >>
|
|
116
|
-
series >>
|
|
117
|
-
space.maybe >>
|
|
118
|
-
number >>
|
|
119
|
-
parts >>
|
|
120
|
-
year.maybe >>
|
|
121
|
-
language.maybe >>
|
|
122
|
-
all_parts.maybe >>
|
|
123
|
-
supplement.maybe >>
|
|
124
|
-
symbol_clause.maybe
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
rule(:root) { identifier }
|
|
128
|
-
|
|
129
|
-
# Parse and normalize Japanese characters
|
|
130
|
-
def self.parse(input)
|
|
131
|
-
new.parse(input)
|
|
132
|
-
end
|
|
5
|
+
class Parser
|
|
133
6
|
end
|
|
134
7
|
end
|
|
135
8
|
end
|
data/lib/pubid/jis/renderer.rb
CHANGED
|
@@ -44,7 +44,7 @@ module Pubid
|
|
|
44
44
|
def render_single(id)
|
|
45
45
|
with_pub = with_publisher?(id)
|
|
46
46
|
parts = []
|
|
47
|
-
parts <<
|
|
47
|
+
parts << id.publisher_prefix if with_pub && id.publisher_prefix
|
|
48
48
|
parts << id.type_prefix if id.class.method_defined?(:type_prefix) && id.type_prefix
|
|
49
49
|
result = parts.join(" ")
|
|
50
50
|
result += " " if result.length.positive?
|
|
@@ -38,12 +38,12 @@ module Pubid
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def ==(other)
|
|
41
|
-
return false unless other.
|
|
42
|
-
return false unless other.class == self.class
|
|
41
|
+
return false unless other.instance_of?(self.class)
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
# A supplement carries its own reaffirmation and SYMBOL clause.
|
|
44
|
+
%i[base number year reaffirmed? symbol].all? do |field|
|
|
45
|
+
public_send(field) == other.public_send(field)
|
|
46
|
+
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
end
|
data/lib/pubid/jis/urn_parser.rb
CHANGED
|
@@ -9,12 +9,13 @@ module Pubid
|
|
|
9
9
|
#
|
|
10
10
|
# Examples:
|
|
11
11
|
# - urn:jis:X 0201:1997 → JIS X 0201:1997
|
|
12
|
+
# - urn:jis:WES 7700-1:2019 → WES 7700-1:2019 (the code carries its root)
|
|
12
13
|
class UrnParser < Pubid::UrnParser::Base
|
|
13
14
|
def parse_urn(urn)
|
|
14
15
|
body = strip_namespace(urn)
|
|
15
16
|
parts = split_parts(body)
|
|
16
17
|
code, year = parts
|
|
17
|
-
text = "JIS #{code}"
|
|
18
|
+
text = code.to_s.start_with?("WES ") ? code.dup : "JIS #{code}"
|
|
18
19
|
text += ":#{year}" if year
|
|
19
20
|
flavor_parse(text)
|
|
20
21
|
end
|
data/lib/pubid/jis.rb
CHANGED
|
@@ -5,9 +5,10 @@ module Pubid
|
|
|
5
5
|
module Jis
|
|
6
6
|
extend Pubid::PrefixesSupport
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# The JIS publisher token, and WES, the root of a Japan Welding
|
|
9
|
+
# Engineering Society id (the grammar's `wes_identifier` rule). Document
|
|
9
10
|
# types (TR/TS) follow the JIS prefix and are excluded.
|
|
10
|
-
PREFIXES = ["JIS"].freeze
|
|
11
|
+
PREFIXES = ["JIS", "WES"].freeze
|
|
11
12
|
|
|
12
13
|
autoload :Builder, "#{__dir__}/jis/builder"
|
|
13
14
|
autoload :Identifier, "#{__dir__}/jis/identifier"
|
data/lib/pubid/nist/builder.rb
CHANGED
|
@@ -85,9 +85,13 @@ module Pubid
|
|
|
85
85
|
|
|
86
86
|
# NEW: Check for CIRC supplement pattern
|
|
87
87
|
# Note: :base_portion is lost during parser merge, so check for supplement indicators
|
|
88
|
+
# circ_series routes the bare "NBS.CIRC.sup" form: the edition-2
|
|
89
|
+
# grammar cannot carry the zero-width supplement_empty marker the
|
|
90
|
+
# Parslet tree used, and the series capture marks every circular
|
|
91
|
+
# supplement head.
|
|
88
92
|
if parsed_hash[:supplement_date_range] || parsed_hash[:supplement_slash_year] ||
|
|
89
93
|
parsed_hash[:supplement_month_year] || parsed_hash[:supplement_year] ||
|
|
90
|
-
parsed_hash[:supplement_empty] ||
|
|
94
|
+
parsed_hash[:supplement_empty] || parsed_hash[:circ_series] ||
|
|
91
95
|
parsed_hash[:supplement] || parsed_hash[:base_portion]
|
|
92
96
|
return build_circular_supplement(parsed_hash)
|
|
93
97
|
end
|