pubid 2.0.0.pre.alpha.11 → 2.0.0.pre.alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +43 -1
- data/data/ieee/update_codes.yaml +17 -4
- data/data/nist/update_codes.yaml +7 -3
- data/lib/pubid/adobe/builder.rb +2 -0
- data/lib/pubid/all_parts.rb +201 -0
- data/lib/pubid/all_parts_identifier.rb +19 -0
- data/lib/pubid/amca/CLAUDE.md +47 -0
- data/lib/pubid/amca/builder.rb +3 -5
- data/lib/pubid/amca/identifiers/base.rb +10 -0
- data/lib/pubid/amca/identifiers/publication.rb +13 -0
- data/lib/pubid/amca/parser.rb +2 -1
- data/lib/pubid/amca/renderer.rb +22 -33
- data/lib/pubid/amca/urn_generator.rb +21 -2
- data/lib/pubid/amca/urn_parser.rb +36 -10
- data/lib/pubid/ansi/builder.rb +6 -0
- data/lib/pubid/api/CLAUDE.md +23 -0
- data/lib/pubid/api/builder.rb +2 -0
- data/lib/pubid/ashrae/CLAUDE.md +13 -0
- data/lib/pubid/ashrae/builder.rb +58 -14
- data/lib/pubid/ashrae/identifiers/errata.rb +14 -2
- data/lib/pubid/ashrae/identifiers/interpretation.rb +2 -10
- data/lib/pubid/ashrae/parser.rb +62 -28
- data/lib/pubid/ashrae/renderer.rb +32 -1
- data/lib/pubid/ashrae/urn_generator.rb +32 -9
- data/lib/pubid/asme/CLAUDE.md +25 -0
- data/lib/pubid/asme/builder.rb +16 -9
- data/lib/pubid/asme/components/code.rb +2 -0
- data/lib/pubid/asme/identifiers/standard.rb +6 -1
- data/lib/pubid/asme/parser.rb +41 -14
- data/lib/pubid/astm/CLAUDE.md +9 -0
- data/lib/pubid/astm/builder.rb +2 -0
- data/lib/pubid/astm/components/code.rb +2 -0
- data/lib/pubid/astm/parser.rb +4 -1
- data/lib/pubid/bipm/CLAUDE.md +11 -0
- data/lib/pubid/bipm/builder.rb +2 -0
- data/lib/pubid/bsi/CLAUDE.md +93 -0
- data/lib/pubid/bsi/builder.rb +13 -11
- data/lib/pubid/bsi/components/date.rb +10 -4
- data/lib/pubid/bsi/identifiers/addendum_document.rb +2 -0
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +6 -54
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +5 -22
- data/lib/pubid/bsi/identifiers/amendment.rb +36 -12
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +1 -1
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +2 -0
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +23 -26
- data/lib/pubid/bsi/identifiers/corrigendum.rb +29 -12
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +6 -7
- data/lib/pubid/bsi/identifiers/handbook.rb +1 -1
- data/lib/pubid/bsi/identifiers/national_annex.rb +18 -20
- data/lib/pubid/bsi/identifiers/practice_guide.rb +1 -1
- data/lib/pubid/bsi/identifiers/root_identity.rb +31 -0
- data/lib/pubid/bsi/identifiers/set.rb +2 -0
- data/lib/pubid/bsi/identifiers/supplement_document.rb +2 -0
- data/lib/pubid/bsi/identifiers.rb +1 -0
- data/lib/pubid/bsi/parser.rb +8 -8
- data/lib/pubid/bsi/renderer.rb +20 -20
- data/lib/pubid/bsi/single_identifier.rb +11 -2
- data/lib/pubid/bsi/urn_generator.rb +28 -18
- data/lib/pubid/builder/base.rb +27 -0
- data/lib/pubid/calconnect/builder.rb +2 -0
- data/lib/pubid/calconnect/identifier.rb +4 -0
- data/lib/pubid/ccsds/builder.rb +2 -0
- data/lib/pubid/ccsds/identifier.rb +12 -0
- data/lib/pubid/ccsds/single_identifier.rb +14 -10
- data/lib/pubid/cen_cenelec/CLAUDE.md +59 -0
- data/lib/pubid/cen_cenelec/builder.rb +6 -1
- data/lib/pubid/cen_cenelec/identifier.rb +10 -27
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +3 -10
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +3 -10
- data/lib/pubid/cen_cenelec/parser.rb +11 -3
- data/lib/pubid/cie/CLAUDE.md +58 -0
- data/lib/pubid/cie/builder.rb +2 -0
- data/lib/pubid/cie/components/language.rb +2 -0
- data/lib/pubid/components/adoption.rb +2 -0
- data/lib/pubid/components/code.rb +2 -0
- data/lib/pubid/components/date.rb +8 -6
- data/lib/pubid/components/edition.rb +2 -0
- data/lib/pubid/components/iteration.rb +2 -0
- data/lib/pubid/components/language.rb +2 -0
- data/lib/pubid/components/locality.rb +2 -0
- data/lib/pubid/components/publisher.rb +2 -0
- data/lib/pubid/components/relationship.rb +2 -0
- data/lib/pubid/components/stage.rb +2 -0
- data/lib/pubid/components/supplement.rb +2 -0
- data/lib/pubid/components/type.rb +2 -0
- data/lib/pubid/components/typed_stage.rb +8 -0
- data/lib/pubid/csa/CLAUDE.md +41 -0
- data/lib/pubid/csa/builder.rb +5 -3
- data/lib/pubid/csa/identifier.rb +13 -1
- data/lib/pubid/csa/identifiers/bundled.rb +2 -2
- data/lib/pubid/csa/identifiers/cec.rb +1 -1
- data/lib/pubid/csa/renderer.rb +12 -12
- data/lib/pubid/csa/single_identifier.rb +18 -1
- data/lib/pubid/csa/urn_generator.rb +1 -1
- data/lib/pubid/doi/builder.rb +2 -0
- data/lib/pubid/easc/builder.rb +2 -0
- data/lib/pubid/ecma/CLAUDE.md +28 -0
- data/lib/pubid/ecma/builder.rb +2 -0
- data/lib/pubid/ecma/identifier.rb +7 -0
- data/lib/pubid/etsi/CLAUDE.md +34 -0
- data/lib/pubid/etsi/builder.rb +2 -0
- data/lib/pubid/etsi/components/code.rb +6 -0
- data/lib/pubid/etsi/components/version.rb +2 -0
- data/lib/pubid/etsi/identifiers/etsi_standard.rb +7 -0
- data/lib/pubid/evs/CLAUDE.md +58 -0
- data/lib/pubid/evs/builder.rb +3 -1
- data/lib/pubid/evs/identifier.rb +6 -6
- data/lib/pubid/evs/identifiers/national_adoption.rb +7 -2
- data/lib/pubid/evs/renderer.rb +1 -1
- data/lib/pubid/evs/urn_generator.rb +1 -1
- data/lib/pubid/evs/urn_parser.rb +1 -1
- data/lib/pubid/gb/CLAUDE.md +140 -0
- data/lib/pubid/gb/builder.rb +21 -11
- data/lib/pubid/gb/identifier.rb +28 -7
- data/lib/pubid/gb/identifiers/all_parts.rb +17 -0
- data/lib/pubid/gb/identifiers.rb +1 -0
- data/lib/pubid/gb/parser.rb +4 -0
- data/lib/pubid/gb/renderer.rb +4 -4
- data/lib/pubid/gb.rb +1 -0
- data/lib/pubid/gost/CLAUDE.md +64 -0
- data/lib/pubid/gost/builder.rb +3 -1
- data/lib/pubid/gost/identifier.rb +5 -0
- data/lib/pubid/iala/CLAUDE.md +82 -0
- data/lib/pubid/iala/builder.rb +2 -0
- data/lib/pubid/iana/CLAUDE.md +7 -0
- data/lib/pubid/iana/builder.rb +2 -0
- data/lib/pubid/identifier.rb +172 -20
- data/lib/pubid/idf/builder.rb +6 -1
- data/lib/pubid/idf/identifier.rb +12 -0
- data/lib/pubid/idf/identifiers/all_parts.rb +17 -0
- data/lib/pubid/idf/identifiers/amendment.rb +1 -1
- data/lib/pubid/idf/identifiers/corrigendum.rb +1 -1
- data/lib/pubid/idf/identifiers/international_standard.rb +1 -1
- data/lib/pubid/idf/identifiers/reviewed_method.rb +1 -1
- data/lib/pubid/idf/identifiers.rb +1 -0
- data/lib/pubid/idf/single_identifier.rb +1 -1
- data/lib/pubid/iec/CLAUDE.md +31 -0
- data/lib/pubid/iec/builder.rb +7 -1
- data/lib/pubid/iec/components/consolidated_amendment.rb +4 -0
- data/lib/pubid/iec/components/sheet.rb +2 -0
- data/lib/pubid/iec/components/trf_info.rb +2 -0
- data/lib/pubid/iec/components/vap_suffix.rb +2 -0
- data/lib/pubid/iec/identifier.rb +7 -2
- data/lib/pubid/iec/identifiers/all_parts.rb +19 -0
- data/lib/pubid/iec/identifiers.rb +1 -0
- data/lib/pubid/iec/renderer.rb +0 -1
- data/lib/pubid/iec/urn_generator.rb +9 -1
- data/lib/pubid/iec/urn_parser.rb +3 -2
- data/lib/pubid/ieee/CLAUDE.md +97 -0
- data/lib/pubid/ieee/builder.rb +176 -7
- data/lib/pubid/ieee/components/code.rb +2 -0
- data/lib/pubid/ieee/components/draft.rb +35 -2
- data/lib/pubid/ieee/components/typed_stage.rb +2 -0
- data/lib/pubid/ieee/identifiers/base.rb +20 -0
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +9 -0
- data/lib/pubid/ieee/identifiers/joint_development.rb +17 -10
- data/lib/pubid/ieee/identifiers/project_draft_identifier.rb +8 -1
- data/lib/pubid/ieee/identifiers/si_standard.rb +5 -2
- data/lib/pubid/ieee/ire/parser.rb +19 -1
- data/lib/pubid/ieee/parser.rb +337 -49
- data/lib/pubid/ieee/project_renderer.rb +46 -0
- data/lib/pubid/ieee/renderer.rb +46 -14
- data/lib/pubid/ieee/urn_generator.rb +31 -0
- data/lib/pubid/ieee.rb +2 -0
- data/lib/pubid/ietf/CLAUDE.md +7 -0
- data/lib/pubid/ietf/builder.rb +2 -0
- data/lib/pubid/iho/builder.rb +2 -0
- data/lib/pubid/isbn/builder.rb +2 -0
- data/lib/pubid/iso/CLAUDE.md +47 -0
- data/lib/pubid/iso/builder.rb +29 -16
- data/lib/pubid/iso/components/publisher.rb +2 -0
- data/lib/pubid/iso/components.rb +0 -1
- data/lib/pubid/iso/identifier.rb +17 -18
- data/lib/pubid/iso/identifiers/all_parts.rb +19 -0
- data/lib/pubid/iso/identifiers/directives.rb +7 -4
- data/lib/pubid/iso/identifiers/directives_supplement.rb +4 -2
- data/lib/pubid/iso/identifiers/tc_document.rb +31 -46
- data/lib/pubid/iso/identifiers.rb +1 -0
- data/lib/pubid/iso/normalizer.rb +1 -1
- data/lib/pubid/iso/rendering_style.rb +0 -1
- data/lib/pubid/iso/urn_generator.rb +10 -10
- data/lib/pubid/iso.rb +5 -4
- data/lib/pubid/itu/CLAUDE.md +69 -0
- data/lib/pubid/itu/builder.rb +12 -0
- data/lib/pubid/itu/components/code.rb +2 -0
- data/lib/pubid/itu/components/designation.rb +2 -0
- data/lib/pubid/itu/components/sector.rb +2 -0
- data/lib/pubid/itu/components/series.rb +2 -0
- data/lib/pubid/itu/identifiers/base.rb +10 -0
- data/lib/pubid/itu/identifiers/contribution.rb +31 -0
- data/lib/pubid/itu/identifiers/supplement.rb +15 -0
- data/lib/pubid/itu/identifiers.rb +1 -0
- data/lib/pubid/itu/parser.rb +19 -2
- data/lib/pubid/jcgm/CLAUDE.md +7 -0
- data/lib/pubid/jcgm/builder.rb +2 -0
- data/lib/pubid/jcgm/components/publisher.rb +2 -0
- data/lib/pubid/jis/builder.rb +5 -1
- data/lib/pubid/jis/identifier.rb +5 -17
- data/lib/pubid/jis/identifiers/all_parts.rb +19 -0
- data/lib/pubid/jis/identifiers.rb +1 -0
- data/lib/pubid/jis/renderer.rb +0 -2
- data/lib/pubid/jis/urn_generator.rb +0 -1
- data/lib/pubid/nist/CLAUDE.md +56 -0
- data/lib/pubid/nist/builder.rb +14 -12
- data/lib/pubid/nist/components/edition.rb +2 -0
- data/lib/pubid/nist/components/issue_number.rb +2 -0
- data/lib/pubid/nist/components/part.rb +2 -0
- data/lib/pubid/nist/components/stage.rb +2 -0
- data/lib/pubid/nist/components/supplement.rb +2 -0
- data/lib/pubid/nist/components/translation.rb +2 -0
- data/lib/pubid/nist/components/update.rb +2 -0
- data/lib/pubid/nist/components/version.rb +2 -0
- data/lib/pubid/nist/components/volume.rb +2 -0
- data/lib/pubid/nist/identifiers/base.rb +34 -6
- data/lib/pubid/nist/identifiers/commercial_standard_emergency.rb +1 -1
- data/lib/pubid/nist/identifiers/crpl_report.rb +5 -6
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +2 -2
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +2 -2
- data/lib/pubid/nist/parser.rb +15 -2
- data/lib/pubid/nist/preprocessor.rb +53 -2
- data/lib/pubid/nist/series/ir.rb +3 -7
- data/lib/pubid/oasis/CLAUDE.md +19 -0
- data/lib/pubid/oasis/builder.rb +2 -0
- data/lib/pubid/oasis/identifier.rb +19 -0
- data/lib/pubid/ogc/CLAUDE.md +34 -0
- data/lib/pubid/ogc/builder.rb +2 -0
- data/lib/pubid/ogc/identifier.rb +11 -0
- data/lib/pubid/oiml/CLAUDE.md +189 -0
- data/lib/pubid/oiml/builder.rb +22 -2
- data/lib/pubid/oiml/components/code.rb +6 -0
- data/lib/pubid/oiml/identifier.rb +13 -0
- data/lib/pubid/oiml/identifiers/annex.rb +4 -0
- data/lib/pubid/oiml/identifiers/bulletin.rb +30 -36
- data/lib/pubid/oiml/identifiers/certification_system.rb +34 -0
- data/lib/pubid/oiml/identifiers/code_number.rb +10 -2
- data/lib/pubid/oiml/identifiers/dual_published.rb +174 -0
- data/lib/pubid/oiml/identifiers.rb +2 -0
- data/lib/pubid/oiml/parser.rb +41 -5
- data/lib/pubid/oiml/renderer.rb +26 -4
- data/lib/pubid/oiml/single_identifier.rb +5 -1
- data/lib/pubid/oiml/supplement_identifier.rb +7 -0
- data/lib/pubid/oiml/urn_generator.rb +32 -4
- data/lib/pubid/oiml.rb +5 -0
- data/lib/pubid/omg/CLAUDE.md +15 -0
- data/lib/pubid/omg/builder.rb +2 -0
- data/lib/pubid/parser/grammar.rb +23 -0
- data/lib/pubid/plateau/builder.rb +2 -0
- data/lib/pubid/plateau/identifiers/base.rb +4 -0
- data/lib/pubid/plateau/supplement_identifier.rb +14 -2
- data/lib/pubid/plateau/urn_generator.rb +7 -1
- data/lib/pubid/renderers/directives_renderer.rb +3 -1
- data/lib/pubid/renderers/human_readable.rb +0 -1
- data/lib/pubid/sae/builder.rb +3 -1
- data/lib/pubid/sae/components/date.rb +2 -0
- data/lib/pubid/sae/components/type.rb +2 -0
- data/lib/pubid/sae/identifiers/base.rb +4 -1
- data/lib/pubid/sae/urn_generator.rb +1 -1
- data/lib/pubid/subset_match.rb +197 -0
- data/lib/pubid/tgpp/CLAUDE.md +43 -0
- data/lib/pubid/tgpp/builder.rb +2 -0
- data/lib/pubid/tgpp/identifier.rb +14 -0
- data/lib/pubid/type_resolver.rb +14 -2
- data/lib/pubid/un/builder.rb +2 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/CLAUDE.md +7 -0
- data/lib/pubid/w3c/builder.rb +2 -0
- data/lib/pubid/xsf/CLAUDE.md +11 -0
- data/lib/pubid/xsf/builder.rb +2 -0
- data/lib/pubid.rb +16 -3
- data/lib/tasks/docs.rake +13 -11
- metadata +46 -4
- data/lib/pubid/ccsds/identifiers/base_BASE_88929.rb +0 -70
- data/lib/pubid/iso/components/code.rb +0 -24
data/lib/pubid/jis/identifier.rb
CHANGED
|
@@ -7,6 +7,11 @@ module Pubid
|
|
|
7
7
|
# Pubid::Jis::Identifiers descend from this class, so a parsed JIS id is an
|
|
8
8
|
# instance of Pubid::Jis::Identifier.
|
|
9
9
|
class Identifier < ::Pubid::Identifier
|
|
10
|
+
# JIS prints its own all-parts suffix, "(規格群)".
|
|
11
|
+
def self.all_parts_class
|
|
12
|
+
Identifiers::AllParts
|
|
13
|
+
end
|
|
14
|
+
|
|
10
15
|
# JIS keeps its number flat at the top level (string, to preserve leading
|
|
11
16
|
# zeros like "0205"), with the division letter in `series` and any
|
|
12
17
|
# multi-level part numbers in `parts`. Supplements override `number` with
|
|
@@ -16,9 +21,6 @@ module Pubid
|
|
|
16
21
|
attribute :parts, :string, collection: true # Optional multi-level parts
|
|
17
22
|
attribute :year, :integer
|
|
18
23
|
attribute :language, :string # "E" or "J"
|
|
19
|
-
# Boolean flags carry no default, so they stay nil (and are omitted from
|
|
20
|
-
# the serialized hash) unless actually set true.
|
|
21
|
-
attribute :all_parts, :boolean
|
|
22
24
|
# Reaffirmation (再確認): a trailing "R" on the year marks an edition
|
|
23
25
|
# that was reaffirmed without revision (e.g. ":2019R").
|
|
24
26
|
attribute :reaffirmed, :boolean
|
|
@@ -50,7 +52,6 @@ module Pubid
|
|
|
50
52
|
map "parts", to: :parts
|
|
51
53
|
map "year", to: :year
|
|
52
54
|
map "language", to: :language
|
|
53
|
-
map "all_parts", to: :all_parts
|
|
54
55
|
map "reaffirmed", to: :reaffirmed
|
|
55
56
|
# render_empty keeps a bare "SYMBOL" (empty-string value) in the hash so
|
|
56
57
|
# it round-trips distinctly from "no symbol" (nil).
|
|
@@ -62,10 +63,6 @@ module Pubid
|
|
|
62
63
|
# would otherwise fail serialization type validation.
|
|
63
64
|
PUBLISHER = "JIS"
|
|
64
65
|
|
|
65
|
-
def all_parts?
|
|
66
|
-
all_parts == true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
66
|
def reaffirmed?
|
|
70
67
|
reaffirmed == true
|
|
71
68
|
end
|
|
@@ -91,23 +88,14 @@ module Pubid
|
|
|
91
88
|
result
|
|
92
89
|
end
|
|
93
90
|
|
|
94
|
-
# Comparison with all_parts logic
|
|
95
|
-
# When either identifier has all_parts=true, compare only series and number
|
|
96
91
|
def ==(other)
|
|
97
92
|
return false unless other.is_a?(Identifier)
|
|
98
93
|
|
|
99
|
-
if all_parts? || other.all_parts?
|
|
100
|
-
# Compare only series and number, ignore year, parts, all_parts
|
|
101
|
-
return series == other.series && number == other.number
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Normal full comparison
|
|
105
94
|
series == other.series &&
|
|
106
95
|
number == other.number &&
|
|
107
96
|
(parts || []) == (other.parts || []) &&
|
|
108
97
|
year == other.year &&
|
|
109
98
|
language == other.language &&
|
|
110
|
-
all_parts? == other.all_parts? &&
|
|
111
99
|
reaffirmed? == other.reaffirmed? &&
|
|
112
100
|
symbol == other.symbol
|
|
113
101
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Jis
|
|
5
|
+
module Identifiers
|
|
6
|
+
# Every part of one JIS document: "JIS C 0617(規格群)".
|
|
7
|
+
class AllParts < ::Pubid::Jis::Identifier
|
|
8
|
+
include ::Pubid::AllParts
|
|
9
|
+
|
|
10
|
+
SUFFIX = "(規格群)"
|
|
11
|
+
|
|
12
|
+
# The URN of the document plus the "all" slot.
|
|
13
|
+
def to_urn
|
|
14
|
+
"#{identity.to_urn}:all"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Jis
|
|
5
5
|
module Identifiers
|
|
6
|
+
autoload :AllParts, "#{__dir__}/identifiers/all_parts"
|
|
6
7
|
autoload :Amendment, "#{__dir__}/identifiers/amendment"
|
|
7
8
|
autoload :Corrigendum, "#{__dir__}/identifiers/corrigendum"
|
|
8
9
|
autoload :Explanation, "#{__dir__}/identifiers/explanation"
|
data/lib/pubid/jis/renderer.rb
CHANGED
|
@@ -38,7 +38,6 @@ module Pubid
|
|
|
38
38
|
result = "#{PUBLISHER} #{id.code}"
|
|
39
39
|
result += ":#{id.year_with_reaffirmation}" if id.year
|
|
40
40
|
result += "(#{id.language})" if id.language
|
|
41
|
-
result += "(規格群)" if id.all_parts?
|
|
42
41
|
result + id.symbol_suffix
|
|
43
42
|
end
|
|
44
43
|
|
|
@@ -52,7 +51,6 @@ module Pubid
|
|
|
52
51
|
result += id.code.to_s
|
|
53
52
|
result += ":#{id.year_with_reaffirmation}" if id.year
|
|
54
53
|
result += "(#{id.language})" if id.language
|
|
55
|
-
result += "(規格群)" if id.all_parts?
|
|
56
54
|
result += id.symbol_suffix
|
|
57
55
|
result
|
|
58
56
|
end
|
|
@@ -12,7 +12,6 @@ module Pubid
|
|
|
12
12
|
|
|
13
13
|
parts << identifier.language.to_s.downcase if identifier.language
|
|
14
14
|
|
|
15
|
-
parts << "all" if identifier.all_parts?
|
|
16
15
|
|
|
17
16
|
if identifier.is_a?(SupplementIdentifier) && identifier.supplement_notation
|
|
18
17
|
parts << identifier.supplement_notation.to_s.downcase
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# NIST flavor notes
|
|
2
|
+
|
|
3
|
+
NIST rendering formats and annotated output.
|
|
4
|
+
|
|
5
|
+
Read this before you change `lib/pubid/nist/` or `spec/pubid/nist/`. The root
|
|
6
|
+
`CLAUDE.md` keeps the cross-flavor contract that every flavor obeys.
|
|
7
|
+
|
|
8
|
+
- **Six NIST types rendered plain under `to_s(annotated: true)`, and two
|
|
9
|
+
more carried a latent corruption.** NIST's `to_s` takes a **positional**
|
|
10
|
+
`format`, which Ruby fills with a Hash when a caller passes `annotated:`;
|
|
11
|
+
`Identifiers::Base#to_s` already handles that and annotates. The six that
|
|
12
|
+
did not — `CommercialStandardsMonthly`, `CrplReport`, `InteragencyReport`,
|
|
13
|
+
`MiscellaneousPublication`, `Monograph`, `Report` — either compose their
|
|
14
|
+
own string or hand `super` a **Symbol**, which drops the flag. Each now
|
|
15
|
+
pulls `annotated` out of the Hash itself and wraps its result.
|
|
16
|
+
|
|
17
|
+
**`Circular` and `Handbook` are the interesting half.** Both did
|
|
18
|
+
`result = super` — which annotates — and then rewrote the edition with a
|
|
19
|
+
**`$`-anchored** regex. Once the string ends in `</span>` the anchor
|
|
20
|
+
cannot match, so the rewrite silently stops applying. Both now strip the
|
|
21
|
+
flag before `super`, rewrite, then annotate.
|
|
22
|
+
|
|
23
|
+
**An output assertion cannot catch that**, and this is the lesson: for
|
|
24
|
+
both fixture references (`NBS CIRC 11e2-1915`, `NBS HB 44e2-1955`) the
|
|
25
|
+
annotator matches only the leading publisher, so the tail is bare and the
|
|
26
|
+
wrong order still produces the right string. The spec asserts the
|
|
27
|
+
**ordering** instead — it wraps `annotate_plain_render` and checks the
|
|
28
|
+
string handed to it is already rewritten and carries no span — and that
|
|
29
|
+
assertion was verified to fail when the order is reverted.
|
|
30
|
+
|
|
31
|
+
`CircularSupplement` and `SupplementIdentifier` were also normalised:
|
|
32
|
+
both had a date-range branch that returned a hand-composed string without
|
|
33
|
+
ever reaching `super`. `SupplementIdentifier` has four exits, so its
|
|
34
|
+
composition moved into a private `render_plain`; **`super` is not
|
|
35
|
+
reachable from a private method**, so `to_s` hands it in as a block —
|
|
36
|
+
`render_plain(format) { super(format) }`.
|
|
37
|
+
|
|
38
|
+
- **`all_parts_edition_keys` needed `update`/`update_component`, not
|
|
39
|
+
`edition_year`.** `Identifier.all_parts_edition_keys` defaults to
|
|
40
|
+
`%i[date year edition version]`; NIST's primary edition carrier
|
|
41
|
+
(`edition`, a `Components::Edition`) is already covered, but the Letter
|
|
42
|
+
Circular / Circular "rJun1992"-style revision (`Builder` around the
|
|
43
|
+
"Convert revision with month+year to update component" comment) parses
|
|
44
|
+
into a **separate** attribute, `update`/`update_component`
|
|
45
|
+
(`Components::Update`: number+year+month), which the default list
|
|
46
|
+
missed entirely — `"NBS LC 800 rJun1992"` and `"NBS LC 800 rJul1995"`
|
|
47
|
+
failed to collapse under `#to_all_parts`/`#===`. Fixed with
|
|
48
|
+
`Pubid::Nist::Identifier.all_parts_edition_keys` (`super + %i[update
|
|
49
|
+
update_component]`). **`edition_year` and `revision_year`/
|
|
50
|
+
`revision_month` were investigated and are NOT added**: `Builder` only
|
|
51
|
+
ever sets `edition_year` alongside the real `edition` component (never
|
|
52
|
+
as its sole carrier, e.g. the TechnicalNote "date IS edition" branch),
|
|
53
|
+
and `revision_year`/`revision_month` are transient — converted into
|
|
54
|
+
`update`/`update_component` and cleared to `nil` before the object is
|
|
55
|
+
returned. Neither carries live information `edition`/`update` doesn't
|
|
56
|
+
already cover. Locked by `spec/pubid/all_parts_edition_keys_audit_spec.rb`.
|
data/lib/pubid/nist/builder.rb
CHANGED
|
@@ -253,7 +253,7 @@ module Pubid
|
|
|
253
253
|
elsif decimal_num
|
|
254
254
|
decimal_base = decimal_num[:decimal_base].to_s
|
|
255
255
|
decimal_suffix = decimal_num[:decimal_suffix].to_s
|
|
256
|
-
identifier.number =
|
|
256
|
+
identifier.number = "#{first_num.value}-#{decimal_base}.#{decimal_suffix}"
|
|
257
257
|
# NEW: Handle letter number pattern (e.g., 1-1A, 1-3B for NCSTAR identifiers)
|
|
258
258
|
# letter_num is {:letter_base => "1", :letter_suffix => "A"}
|
|
259
259
|
# Also handles IR series "R" suffix: "79-1786R" -> "79-1786r1"
|
|
@@ -268,10 +268,10 @@ module Pubid
|
|
|
268
268
|
# Series-specific handler took ownership (e.g., IR "R" → r1)
|
|
269
269
|
elsif identifier.part
|
|
270
270
|
# SpecialPublication pattern: letter_suffix is separate Part component
|
|
271
|
-
identifier.number =
|
|
271
|
+
identifier.number = "#{first_num.value}-#{letter_base}"
|
|
272
272
|
else
|
|
273
273
|
# NCSTAR pattern: letter_suffix is part of the number
|
|
274
|
-
identifier.number =
|
|
274
|
+
identifier.number = "#{first_num.value}-#{letter_base}#{letter_suffix}"
|
|
275
275
|
end
|
|
276
276
|
elsif second_num
|
|
277
277
|
# Check for special patterns first
|
|
@@ -285,7 +285,7 @@ module Pubid
|
|
|
285
285
|
# Create Edition component
|
|
286
286
|
edition_obj = Components::Edition.new(type: "r", id: edition_id)
|
|
287
287
|
|
|
288
|
-
identifier.number =
|
|
288
|
+
identifier.number = "#{first_num.value}-#{number_part}"
|
|
289
289
|
identifier.edition = edition_obj
|
|
290
290
|
# CS Emergency pattern: e104-43 -> number=104, edition_year=1943
|
|
291
291
|
# Logic: e104-43 means "emergency 104 from 1943" (43 = 1943)
|
|
@@ -300,7 +300,7 @@ module Pubid
|
|
|
300
300
|
# Create Edition component
|
|
301
301
|
edition_obj = Components::Edition.new(type: "e", id: edition_year)
|
|
302
302
|
|
|
303
|
-
identifier.number =
|
|
303
|
+
identifier.number = number_part
|
|
304
304
|
identifier.edition = edition_obj
|
|
305
305
|
elsif first_num.value.to_s.match?(/^(\d+)e(\d+)$/) &&
|
|
306
306
|
second_num.value.to_s.match?(/^\d{2,4}$/)
|
|
@@ -314,7 +314,7 @@ module Pubid
|
|
|
314
314
|
# Expand 2-digit year to 4-digit (50 -> 1950)
|
|
315
315
|
year_part = "19#{year_part}" if year_part.length == 2
|
|
316
316
|
|
|
317
|
-
identifier.number =
|
|
317
|
+
identifier.number = number_part
|
|
318
318
|
|
|
319
319
|
# For edition+year patterns, handling depends on identifier type:
|
|
320
320
|
# - CIRC: edition number + year as additional_text, rendered with dot ("11e2-1915" -> "11e2.1915")
|
|
@@ -329,7 +329,7 @@ module Pubid
|
|
|
329
329
|
number_part = first_num.value.to_s.match(/^(\d+)supp?$/)[1]
|
|
330
330
|
year_part = second_num.value.to_s
|
|
331
331
|
|
|
332
|
-
identifier.number =
|
|
332
|
+
identifier.number = number_part
|
|
333
333
|
supp[:value] = year_part
|
|
334
334
|
supp[:present] = true
|
|
335
335
|
elsif second_num.value.to_s.match?(/^(\d+)supp?$/)
|
|
@@ -337,14 +337,14 @@ module Pubid
|
|
|
337
337
|
# second number. Strip it and isolate as supplement="" (single-p).
|
|
338
338
|
second_part = second_num.value.to_s.match(/^(\d+)supp?$/)[1]
|
|
339
339
|
compound = "#{first_num.value}-#{second_part}"
|
|
340
|
-
identifier.number =
|
|
340
|
+
identifier.number = compound
|
|
341
341
|
supp[:value] = ""
|
|
342
342
|
supp[:present] = true
|
|
343
343
|
elsif identifier.is_a?(Identifiers::TechnicalNote) &&
|
|
344
344
|
second_num.value.to_s.match?(/^(19|20)\d{2}$/)
|
|
345
345
|
# SPECIAL CASE FOR TN: second_num is edition year
|
|
346
346
|
# Following "date IS edition" rule: -1993 becomes Edition(type: "e", id: "1993")
|
|
347
|
-
identifier.number = first_num
|
|
347
|
+
identifier.number = first_num.value.to_s
|
|
348
348
|
edition_obj = Components::Edition.new(type: "e",
|
|
349
349
|
id: second_num.value.to_s)
|
|
350
350
|
identifier.edition = edition_obj
|
|
@@ -354,16 +354,16 @@ module Pubid
|
|
|
354
354
|
# not folded into the compound number.
|
|
355
355
|
identifier.part = Components::Part.new(type: "pt",
|
|
356
356
|
value: part_num)
|
|
357
|
-
identifier.number =
|
|
357
|
+
identifier.number = "#{first_num.value}-#{second_num.value}"
|
|
358
358
|
else
|
|
359
359
|
# For GCR and others, include part number in compound number
|
|
360
360
|
compound_value = "#{first_num.value}-#{second_num.value}"
|
|
361
361
|
compound_value += "-#{part_num}" if part_num
|
|
362
|
-
identifier.number =
|
|
362
|
+
identifier.number = compound_value
|
|
363
363
|
end
|
|
364
364
|
else
|
|
365
365
|
# No second_num, use first_num directly
|
|
366
|
-
identifier.number = first_num
|
|
366
|
+
identifier.number = first_num.value.to_s
|
|
367
367
|
end
|
|
368
368
|
end
|
|
369
369
|
|
|
@@ -479,3 +479,5 @@ module Pubid
|
|
|
479
479
|
end
|
|
480
480
|
end
|
|
481
481
|
end
|
|
482
|
+
|
|
483
|
+
Pubid::Nist::Builder.prepend(Pubid::Builder::AllPartsWrap)
|
|
@@ -28,6 +28,8 @@ module Pubid
|
|
|
28
28
|
# Edition.new(type: "r", id: "5").to_s # => "r5"
|
|
29
29
|
# Edition.new(type: "r", id: "5", original_prefix: " Rev. ").to_s # => "Rev. 5"
|
|
30
30
|
class Edition < Lutaml::Model::Serializable
|
|
31
|
+
include ::Pubid::SubsetMatch
|
|
32
|
+
|
|
31
33
|
attribute :type, :string # "-", "e", or "r"
|
|
32
34
|
attribute :id, :string # Edition ID (number or year)
|
|
33
35
|
attribute :additional_text, :string # Text after "rev" (WITHOUT "rev" prefix)
|
|
@@ -8,6 +8,8 @@ module Pubid
|
|
|
8
8
|
# IssueNumber component for NIST identifiers
|
|
9
9
|
# Represents the issue/number designation (e.g., "No. 12" in "Vol. 6, No. 12")
|
|
10
10
|
class IssueNumber < Lutaml::Model::Serializable
|
|
11
|
+
include ::Pubid::SubsetMatch
|
|
12
|
+
|
|
11
13
|
attribute :number, :string
|
|
12
14
|
|
|
13
15
|
# Short form rendering: "n12"
|
|
@@ -23,6 +23,8 @@ module Pubid
|
|
|
23
23
|
# - SP: Part number (pt1)
|
|
24
24
|
# - Letter suffixes (A, B, C, etc.)
|
|
25
25
|
class Part < Lutaml::Model::Serializable
|
|
26
|
+
include ::Pubid::SubsetMatch
|
|
27
|
+
|
|
26
28
|
attribute :type, :string # "pt" for part notation, "n" for issue, "" for letter suffix
|
|
27
29
|
attribute :value, :string # Part number or letter (1, 2, A, B, etc.)
|
|
28
30
|
|
|
@@ -13,6 +13,8 @@ module Pubid
|
|
|
13
13
|
# Stage.new(id: "i", type: "pd").to_s(:short) # => "ipd"
|
|
14
14
|
# Stage.new(id: "f", type: "pd").to_s(:long) # => "(Final Public Draft)"
|
|
15
15
|
class Stage < Lutaml::Model::Serializable
|
|
16
|
+
include ::Pubid::SubsetMatch
|
|
17
|
+
|
|
16
18
|
attribute :id, :string # i, f, 1-9
|
|
17
19
|
attribute :type, :string # pd, wd, prd
|
|
18
20
|
|
|
@@ -15,6 +15,8 @@ module Pubid
|
|
|
15
15
|
# Supplement.new(month: "Jan", year: "1924").to_s(:short) # => "supJan1924"
|
|
16
16
|
# Supplement.new(has_revision: true).to_s(:short) # => "suprev"
|
|
17
17
|
class Supplement < Lutaml::Model::Serializable
|
|
18
|
+
include ::Pubid::SubsetMatch
|
|
19
|
+
|
|
18
20
|
attribute :number, :string # Supplement number (e.g., "2" in "supp2")
|
|
19
21
|
attribute :year, :string # Year (4 digits); range START year
|
|
20
22
|
attribute :month, :string # Month abbreviation; range START month
|
|
@@ -13,6 +13,8 @@ module Pubid
|
|
|
13
13
|
# Translation.new(code: "por").to_s(:mr) # => ".por"
|
|
14
14
|
# Translation.new(code: "ind").to_s(:short) # => " ind"
|
|
15
15
|
class Translation < Lutaml::Model::Serializable
|
|
16
|
+
include ::Pubid::SubsetMatch
|
|
17
|
+
|
|
16
18
|
attribute :code, :string # 3-letter ISO 639-2 code: spa, por, ind, etc.
|
|
17
19
|
|
|
18
20
|
# Backward compatibility: language method returns code
|
|
@@ -15,6 +15,8 @@ module Pubid
|
|
|
15
15
|
# Update.new(number: 1, year: 2021, month: 2).to_s(:mr) # => "-upd1-202102"
|
|
16
16
|
# Update.new(number: 1, prefix: "dash").to_s(:short) # => "-upd1" (preserves original prefix)
|
|
17
17
|
class Update < Lutaml::Model::Serializable
|
|
18
|
+
include ::Pubid::SubsetMatch
|
|
19
|
+
|
|
18
20
|
attribute :number, :string # Update number as string
|
|
19
21
|
attribute :year, :string # Year (4 digits as string)
|
|
20
22
|
attribute :month, :string # Month (01-12 as string, optional)
|
|
@@ -12,6 +12,8 @@ module Pubid
|
|
|
12
12
|
# Version.new(value: "1.0.2").to_s(:short) # => "ver1.0.2"
|
|
13
13
|
# Version.new(value: "2.0").to_s(:long) # => "Version 2.0"
|
|
14
14
|
class Version < Lutaml::Model::Serializable
|
|
15
|
+
include ::Pubid::SubsetMatch
|
|
16
|
+
|
|
15
17
|
attribute :value, :string # Dotted notation: "1.0.2"
|
|
16
18
|
|
|
17
19
|
# Render version in specified format
|
|
@@ -27,7 +27,7 @@ module Pubid
|
|
|
27
27
|
# bare { "value" => … } with no part;
|
|
28
28
|
# - drop the redundant build artifacts, decomposed pieces of the
|
|
29
29
|
# canonical number that identity/rendering never read.
|
|
30
|
-
COMPACT_FLAT_CODES = %w[series
|
|
30
|
+
COMPACT_FLAT_CODES = %w[series subseries].freeze
|
|
31
31
|
COMPACT_FLAT_VALUES = %w[volume].freeze
|
|
32
32
|
COMPACT_DROP_ATTRS = %w[first_number second_number].freeze
|
|
33
33
|
|
|
@@ -105,7 +105,14 @@ module Pubid
|
|
|
105
105
|
# equality so a manually-built id (without subseries set) still equals a
|
|
106
106
|
# parsed one.
|
|
107
107
|
attribute :subseries, Components::Code
|
|
108
|
-
|
|
108
|
+
# Plain :string. NIST never populated the Code beyond `value`: `subpart`
|
|
109
|
+
# is set nowhere, and `part` was a reader splitting `value` on "-" that
|
|
110
|
+
# no library code called. `series`, `subseries`, `first_number`,
|
|
111
|
+
# `second_number` and `parts` keep the component.
|
|
112
|
+
attribute :number, :string
|
|
113
|
+
# NIST never uses `subpart`; declare it so the inherited Components::Code
|
|
114
|
+
# does not disagree with this class (the determinism landmine).
|
|
115
|
+
attribute :subpart, :string
|
|
109
116
|
|
|
110
117
|
# V2 COMPONENTS (Lutaml::Model objects) - PROPER SEPARATION
|
|
111
118
|
# `edition` (Components::Edition: type + id + additional_text) is the
|
|
@@ -216,6 +223,30 @@ module Pubid
|
|
|
216
223
|
|
|
217
224
|
alias eql? ==
|
|
218
225
|
|
|
226
|
+
# A subset match skips the same attributes: `to_hash` drops the build
|
|
227
|
+
# artifacts, so an index row rebuilt by `from_hash` never has them.
|
|
228
|
+
def self.subset_ignored_attributes
|
|
229
|
+
EQUALITY_IGNORED_ATTRS
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# `edition` is the primary edition/revision carrier and is already in
|
|
233
|
+
# the default %i[date year edition version] list. `update`/
|
|
234
|
+
# `update_component` (Components::Update: number+year+month) is a
|
|
235
|
+
# SEPARATE, currently-live discriminator the default list misses — the
|
|
236
|
+
# Letter Circular / Circular "rJun1992"-style revision parses into it,
|
|
237
|
+
# not into `edition` (see Builder#build_dated_identifier), so e.g.
|
|
238
|
+
# "NBS LC 800 rJun1992" and "NBS LC 800 rJul1995" failed to collapse
|
|
239
|
+
# under #to_all_parts/#=== before this override. (`edition_year` and
|
|
240
|
+
# `revision_year`/`revision_month` are NOT added here: the builder
|
|
241
|
+
# always sets `edition_year` alongside the real `edition` component
|
|
242
|
+
# (never alone), and `revision_year`/`revision_month` are transient —
|
|
243
|
+
# converted into `update`/`update_component` and cleared to nil before
|
|
244
|
+
# the object is returned — so neither carries live information outside
|
|
245
|
+
# what `edition`/`update` already do.)
|
|
246
|
+
def self.all_parts_edition_keys
|
|
247
|
+
super + %i[update update_component]
|
|
248
|
+
end
|
|
249
|
+
|
|
219
250
|
def hash
|
|
220
251
|
vals = self.class.attributes.each_key.reject do |name|
|
|
221
252
|
EQUALITY_IGNORED_ATTRS.include?(name)
|
|
@@ -406,13 +437,11 @@ module Pubid
|
|
|
406
437
|
match ? match[1].to_i : nil
|
|
407
438
|
end
|
|
408
439
|
|
|
409
|
-
public
|
|
410
|
-
|
|
411
440
|
def to_full_style
|
|
412
441
|
# "National Institute of Standards and Technology Special Publication 800-27, Revision A"
|
|
413
442
|
result = publisher_full_name
|
|
414
443
|
result += " #{series_full_name}" if series
|
|
415
|
-
result += " #{number
|
|
444
|
+
result += " #{number}" if number
|
|
416
445
|
result += parts.map { |p| "-#{p}" }.join if parts&.any?
|
|
417
446
|
|
|
418
447
|
# Render volume and issue number in long form: "Vol. 6, No. 12"
|
|
@@ -739,6 +768,5 @@ module Pubid
|
|
|
739
768
|
"NIST"
|
|
740
769
|
end
|
|
741
770
|
end
|
|
742
|
-
|
|
743
771
|
end
|
|
744
772
|
end
|
|
@@ -44,7 +44,7 @@ module Pubid
|
|
|
44
44
|
result += " CS-E"
|
|
45
45
|
|
|
46
46
|
# Number (already extracted from e104 → 104 in builder)
|
|
47
|
-
result += " #{number
|
|
47
|
+
result += " #{number}" if number
|
|
48
48
|
|
|
49
49
|
# Edition (e1943 for e104-43 pattern) plus any other component the
|
|
50
50
|
# parser attached (volume, supplement, version, ...).
|
|
@@ -46,7 +46,7 @@ module Pubid
|
|
|
46
46
|
def normalized_number
|
|
47
47
|
return nil unless number
|
|
48
48
|
|
|
49
|
-
num_value = number.
|
|
49
|
+
num_value = number.to_s
|
|
50
50
|
|
|
51
51
|
# Pattern: c4-4 → 4-4 (hide 'c' prefix)
|
|
52
52
|
case num_value
|
|
@@ -64,12 +64,12 @@ module Pubid
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Override number to return normalized value
|
|
67
|
-
# Tests expect number
|
|
67
|
+
# Tests expect number to be normalized (c4-4 → 4-4, 4-m-5 → 4-M-5)
|
|
68
68
|
def number
|
|
69
69
|
num = super
|
|
70
70
|
return num unless num
|
|
71
71
|
|
|
72
|
-
num_value = num.
|
|
72
|
+
num_value = num.to_s
|
|
73
73
|
|
|
74
74
|
# Pattern: c4-4 → 4-4 (hide 'c' prefix)
|
|
75
75
|
case num_value
|
|
@@ -83,8 +83,7 @@ module Pubid
|
|
|
83
83
|
num_value = num_value.gsub(/^m-/, "M-")
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
Components::Code.new(value: num_value)
|
|
86
|
+
num_value
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
def to_s(format = nil)
|
|
@@ -106,7 +105,7 @@ module Pubid
|
|
|
106
105
|
|
|
107
106
|
if number
|
|
108
107
|
# Normalize number value for CRPL patterns
|
|
109
|
-
num_value = number.
|
|
108
|
+
num_value = number.to_s
|
|
110
109
|
|
|
111
110
|
# Pattern: c4-4 → 4-4 (hide 'c' prefix)
|
|
112
111
|
case num_value
|
|
@@ -66,14 +66,14 @@ module Pubid
|
|
|
66
66
|
# Convert dash-year patterns to edition format for FIPS
|
|
67
67
|
# Pattern: "14-1971" → "14e1971" (edition year format)
|
|
68
68
|
# But preserve dash for parts: "140-3" stays as-is
|
|
69
|
-
if number
|
|
69
|
+
if number =~ /^(\d{1,3})-(\d{4})$/
|
|
70
70
|
# This is a number-year pattern (e.g., "14-1971")
|
|
71
71
|
# Convert to edition format: "14e1971"
|
|
72
72
|
number_part = $1
|
|
73
73
|
year_part = $2
|
|
74
74
|
result += " #{number_part}e#{year_part}"
|
|
75
75
|
else
|
|
76
|
-
result += " #{number
|
|
76
|
+
result += " #{number}"
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -57,14 +57,14 @@ module Pubid
|
|
|
57
57
|
|
|
58
58
|
def to_short_style
|
|
59
59
|
result = "#{default_publisher} #{series_code}"
|
|
60
|
-
result += " #{number
|
|
60
|
+
result += " #{number}" if number
|
|
61
61
|
result += append_short_components
|
|
62
62
|
result
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def to_mr_style
|
|
66
66
|
result = "#{default_publisher}.#{series_code}"
|
|
67
|
-
result += ".#{number
|
|
67
|
+
result += ".#{number}" if number
|
|
68
68
|
result += append_mr_components
|
|
69
69
|
result
|
|
70
70
|
end
|
data/lib/pubid/nist/parser.rb
CHANGED
|
@@ -13,8 +13,20 @@ module Pubid
|
|
|
13
13
|
# feeds the cleaned string to the Parslet grammar and stamps the
|
|
14
14
|
# detected format onto the parse tree.
|
|
15
15
|
def self.class_parse_with_preprocessing(input)
|
|
16
|
+
# The shared Grammar strips a trailing "(all parts)", but the NIST
|
|
17
|
+
# preprocessor runs first and would swallow it — strip before it and
|
|
18
|
+
# carry the marker to the tree like Grammar#parse does.
|
|
19
|
+
all_parts = input.is_a?(String) && input.match?(::Pubid::Parser::Grammar::ALL_PARTS_SUFFIX)
|
|
20
|
+
input = input.sub(::Pubid::Parser::Grammar::ALL_PARTS_SUFFIX, "") if all_parts
|
|
16
21
|
result = Preprocessor.new(input).call
|
|
17
22
|
parsed = new.parse(result.cleaned)
|
|
23
|
+
if all_parts
|
|
24
|
+
parsed = case parsed
|
|
25
|
+
when Hash then parsed.merge(all_parts: true)
|
|
26
|
+
when Array then parsed.map { |h| h.merge(all_parts: true) }
|
|
27
|
+
else parsed
|
|
28
|
+
end
|
|
29
|
+
end
|
|
18
30
|
|
|
19
31
|
if parsed.is_a?(Hash)
|
|
20
32
|
parsed.merge(parsed_format: result.format)
|
|
@@ -651,8 +663,9 @@ module Pubid
|
|
|
651
663
|
rule(:mr_identifier) do
|
|
652
664
|
hash_prefix.maybe >>
|
|
653
665
|
publisher >> dot >>
|
|
654
|
-
|
|
655
|
-
|
|
666
|
+
# The catalogue also lists bare series identities with no
|
|
667
|
+
# report number ("NBS.CIRC").
|
|
668
|
+
simple_series >> dot.maybe >> report_number.maybe >>
|
|
656
669
|
# Edition with underscore separator (MR format: 1648_2009)
|
|
657
670
|
(str("_") >> digits.as(:edition_year)).maybe >>
|
|
658
671
|
# Support letter suffix before update (e.g., 8286C-upd1) - Session 219
|