pubid 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/parg/adobe.json +1 -1
- data/data/parg/amca.json +1 -1
- data/data/parg/ansi.json +1 -1
- data/data/parg/api.json +1 -1
- data/data/parg/ashrae.json +1 -1
- data/data/parg/asme.json +1 -1
- data/data/parg/astm.json +1 -1
- data/data/parg/bipm.json +1 -1
- data/data/parg/bsi.json +1 -1
- data/data/parg/ccsds.json +1 -1
- data/data/parg/cen_cenelec.json +1 -1
- data/data/parg/cie.json +1 -1
- data/data/parg/csa.json +1 -1
- data/data/parg/ecma.json +1 -1
- data/data/parg/etsi.json +1 -1
- data/data/parg/evs.json +1 -1
- data/data/parg/gost.json +1 -1
- data/data/parg/iana.json +1 -1
- data/data/parg/idf.json +1 -1
- data/data/parg/iec.json +1 -1
- data/data/parg/iho.json +1 -0
- data/data/parg/isbn.json +1 -1
- data/data/parg/itu.json +1 -1
- data/data/parg/jcgm.json +1 -1
- data/data/parg/jis.json +1 -1
- data/data/parg/nist.json +1 -1
- data/data/parg/oiml.json +1 -1
- data/data/parg/omg.json +1 -1
- data/data/parg/plateau.json +1 -1
- data/data/parg/tgpp.json +1 -1
- data/data/parg/un.json +1 -1
- data/lib/pubid/adobe/identifier.rb +1 -1
- data/lib/pubid/adobe/parser.rb +2 -113
- data/lib/pubid/amca/identifiers/base.rb +1 -1
- data/lib/pubid/amca/parser.rb +1 -145
- data/lib/pubid/ansi/identifier.rb +1 -1
- data/lib/pubid/ansi/parser.rb +1 -82
- data/lib/pubid/api/builder.rb +32 -1
- data/lib/pubid/api/identifier.rb +1 -1
- data/lib/pubid/api/parser.rb +1 -131
- data/lib/pubid/ashrae/identifiers/base.rb +1 -1
- data/lib/pubid/ashrae/parser.rb +3 -710
- data/lib/pubid/asme/builder.rb +6 -4
- data/lib/pubid/asme/identifier.rb +1 -2
- data/lib/pubid/asme/parser.rb +1 -328
- data/lib/pubid/astm/builder.rb +12 -3
- data/lib/pubid/astm/identifier.rb +1 -2
- data/lib/pubid/astm/parser.rb +1 -227
- data/lib/pubid/bipm/identifier.rb +8 -1
- data/lib/pubid/bipm/parser.rb +2 -224
- data/lib/pubid/bsi/builder.rb +2 -4
- data/lib/pubid/bsi/parser.rb +1 -666
- data/lib/pubid/bsi/single_identifier.rb +38 -1
- data/lib/pubid/calconnect/parser.rb +2 -40
- data/lib/pubid/ccsds/identifier.rb +1 -1
- data/lib/pubid/ccsds/parser.rb +1 -66
- data/lib/pubid/cen_cenelec/identifier.rb +16 -1
- data/lib/pubid/cen_cenelec/parser.rb +3 -136
- data/lib/pubid/cie/identifier.rb +1 -1
- data/lib/pubid/cie/parser.rb +3 -378
- data/lib/pubid/conformance.rb +1 -1
- data/lib/pubid/csa/builder.rb +41 -18
- data/lib/pubid/csa/identifier.rb +12 -4
- data/lib/pubid/csa/identifiers/amendment.rb +28 -0
- data/lib/pubid/csa/identifiers.rb +1 -0
- data/lib/pubid/csa/parser.rb +16 -397
- data/lib/pubid/doi/parser.rb +2 -37
- data/lib/pubid/easc/builder.rb +1 -1
- data/lib/pubid/easc/parser.rb +2 -70
- data/lib/pubid/ecma/CLAUDE.md +8 -1
- data/lib/pubid/ecma/identifier.rb +13 -8
- data/lib/pubid/ecma/parser.rb +2 -54
- data/lib/pubid/ecma/renderer.rb +3 -7
- data/lib/pubid/errors.rb +18 -13
- data/lib/pubid/etsi/builder.rb +8 -5
- data/lib/pubid/etsi/identifiers/base.rb +1 -1
- data/lib/pubid/etsi/parser.rb +1 -132
- data/lib/pubid/evs/identifier.rb +7 -0
- data/lib/pubid/evs/parser.rb +1 -8
- data/lib/pubid/evs.rb +1 -1
- data/lib/pubid/gb/identifier.rb +6 -0
- data/lib/pubid/gb/parser.rb +2 -51
- data/lib/pubid/gost/identifier.rb +9 -1
- data/lib/pubid/gost/parser.rb +4 -81
- data/lib/pubid/iala/parser.rb +2 -121
- data/lib/pubid/iana/identifier.rb +1 -1
- data/lib/pubid/iana/parser.rb +2 -24
- data/lib/pubid/identifier.rb +78 -1
- data/lib/pubid/idf/builder.rb +42 -0
- data/lib/pubid/idf/identifier.rb +1 -1
- data/lib/pubid/idf/parser.rb +1 -137
- data/lib/pubid/idf.rb +1 -2
- data/lib/pubid/iec/builder.rb +158 -50
- data/lib/pubid/iec/identifier.rb +1 -1
- data/lib/pubid/iec/parser.rb +3 -430
- data/lib/pubid/ieee/aiee/identifier.rb +2 -1
- data/lib/pubid/ieee/aiee.rb +0 -1
- data/lib/pubid/ieee/builder.rb +2 -2
- data/lib/pubid/ieee/identifiers/base.rb +1 -1
- data/lib/pubid/ieee/ire/identifier.rb +2 -1
- data/lib/pubid/ieee/ire.rb +0 -1
- data/lib/pubid/ieee/nesc.rb +0 -1
- data/lib/pubid/ieee/parser.rb +1 -1257
- data/lib/pubid/ietf/identifiers/base.rb +17 -1
- data/lib/pubid/ietf/parser.rb +2 -47
- data/lib/pubid/ietf/renderer.rb +17 -2
- data/lib/pubid/iho/CLAUDE.md +89 -0
- data/lib/pubid/iho/builder.rb +4 -1
- data/lib/pubid/iho/identifiers/base.rb +28 -2
- data/lib/pubid/iho/renderer.rb +8 -0
- data/lib/pubid/iho/urn_generator.rb +11 -1
- data/lib/pubid/iho/urn_parser.rb +21 -11
- data/lib/pubid/iho.rb +0 -1
- data/lib/pubid/isbn/identifier.rb +1 -1
- data/lib/pubid/isbn/parser.rb +2 -31
- data/lib/pubid/iso/builder.rb +1 -1
- data/lib/pubid/iso/identifiers/directives.rb +6 -3
- data/lib/pubid/iso/identifiers/guide.rb +6 -3
- data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +6 -3
- data/lib/pubid/iso/normalizer.rb +1 -1
- data/lib/pubid/iso/parser.rb +1 -539
- data/lib/pubid/iso/supplement_identifier.rb +6 -3
- data/lib/pubid/iso/utilities.rb +4 -5
- data/lib/pubid/iso.rb +1 -19
- data/lib/pubid/itu/builder.rb +36 -20
- data/lib/pubid/itu/identifiers/base.rb +15 -2
- data/lib/pubid/itu/parser.rb +1 -775
- data/lib/pubid/jcgm/builder.rb +35 -0
- data/lib/pubid/jcgm/parser.rb +1 -151
- data/lib/pubid/jcgm.rb +1 -2
- data/lib/pubid/jis/builder.rb +18 -29
- data/lib/pubid/jis/identifier.rb +1 -1
- data/lib/pubid/jis/parser.rb +1 -128
- data/lib/pubid/nist/builder.rb +5 -1
- data/lib/pubid/nist/caster.rb +13 -3
- data/lib/pubid/nist/identifiers/base.rb +37 -2
- data/lib/pubid/nist/identifiers/circular.rb +2 -2
- data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -2
- data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +2 -2
- data/lib/pubid/nist/identifiers/crpl_report.rb +2 -2
- data/lib/pubid/nist/identifiers/handbook.rb +2 -2
- data/lib/pubid/nist/identifiers/internal_report.rb +2 -2
- data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +2 -2
- data/lib/pubid/nist/identifiers/monograph.rb +2 -2
- data/lib/pubid/nist/identifiers/report.rb +2 -2
- data/lib/pubid/nist/parser.rb +19 -775
- data/lib/pubid/nist/router.rb +4 -1
- data/lib/pubid/nist/supplement_identifier.rb +2 -2
- data/lib/pubid/oasis/parser.rb +2 -16
- data/lib/pubid/ogc/parser.rb +2 -26
- data/lib/pubid/oiml/identifiers/certification_system.rb +7 -0
- data/lib/pubid/oiml/identifiers/dual_published.rb +2 -2
- data/lib/pubid/oiml/parser.rb +1 -303
- data/lib/pubid/oiml.rb +1 -2
- data/lib/pubid/omg/identifier.rb +6 -1
- data/lib/pubid/omg/parser.rb +2 -76
- data/lib/pubid/parser.rb +5 -4
- data/lib/pubid/parsers/mr_string.rb +1 -1
- data/lib/pubid/plateau/parser.rb +1 -66
- data/lib/pubid/plateau.rb +1 -2
- data/lib/pubid/renderers/directives_renderer.rb +1 -1
- data/lib/pubid/renderers/iwa_renderer.rb +1 -1
- data/lib/pubid/renderers/publisher_stripper.rb +82 -0
- data/lib/pubid/renderers/supplement_renderer.rb +1 -1
- data/lib/pubid/renderers.rb +1 -0
- data/lib/pubid/sae/parser.rb +1 -48
- data/lib/pubid/tgpp/identifier.rb +1 -1
- data/lib/pubid/tgpp/parser.rb +2 -59
- data/lib/pubid/un/identifier.rb +1 -1
- data/lib/pubid/un/parser.rb +1 -18
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid/w3c/parser.rb +2 -27
- data/lib/pubid/xsf/identifier.rb +10 -6
- data/lib/pubid/xsf/parser.rb +3 -31
- data/lib/pubid/xsf/renderer.rb +2 -4
- data/lib/pubid.rb +8 -9
- metadata +6 -23
- data/lib/pubid/ieee/aiee/parser.rb +0 -130
- data/lib/pubid/ieee/ire/parser.rb +0 -109
- data/lib/pubid/ieee/nesc/parser.rb +0 -155
- data/lib/pubid/iho/parser.rb +0 -68
- data/lib/pubid/parser/common_parse_methods.rb +0 -13
- data/lib/pubid/parser/common_parse_rules.rb +0 -56
- data/lib/pubid/parser/grammar.rb +0 -96
data/lib/pubid/plateau.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "pubid"
|
|
4
|
-
require "parslet"
|
|
5
4
|
|
|
6
5
|
module Pubid
|
|
7
6
|
module Plateau
|
|
@@ -31,7 +30,7 @@ module Pubid
|
|
|
31
30
|
|
|
32
31
|
# Apply legacy update_codes normalization first
|
|
33
32
|
normalized = Core::UpdateCodes.apply(input, :plateau)
|
|
34
|
-
parsed = Pubid::Parg::
|
|
33
|
+
parsed = Pubid::Parg::Model.bound(:plateau, normalized)
|
|
35
34
|
Builder.build(parsed)
|
|
36
35
|
end
|
|
37
36
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Renderers
|
|
5
5
|
class DirectivesRenderer < HumanReadable
|
|
6
|
-
def render(context:, with_edition: false)
|
|
6
|
+
def render(context:, with_edition: false, **_opts)
|
|
7
7
|
parts = []
|
|
8
8
|
parts << render_publisher_portion(context)
|
|
9
9
|
num_port = render_number_portion(context)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Renderers
|
|
5
|
+
# Removes the leading publisher token from an already-rendered identifier,
|
|
6
|
+
# for `to_s(with_publisher: false)`.
|
|
7
|
+
#
|
|
8
|
+
# relaton#49 asks for an internal form of every identifier: the form an SDO
|
|
9
|
+
# uses when it cites its own documents, with the publisher prefix dropped
|
|
10
|
+
# (`NIST SP 800-113` -> `SP 800-113`). Teaching 40-odd flavor renderers to
|
|
11
|
+
# omit the publisher would mean 40 chances to drift, and a flavor added
|
|
12
|
+
# tomorrow would get nothing. This class works from the OUTSIDE instead,
|
|
13
|
+
# the way {Annotator} does: the identifier names the prefixes its rendering
|
|
14
|
+
# can start with (`Pubid::Identifier#publisher_prefixes`), and the prefix
|
|
15
|
+
# is cut off together with the one separator that follows it.
|
|
16
|
+
#
|
|
17
|
+
# Deliberate limits:
|
|
18
|
+
#
|
|
19
|
+
# * A prefix must be followed by a separator (space, `-`, `/` or `.`), so
|
|
20
|
+
# `ISO` never cuts into `ISOFIX`.
|
|
21
|
+
# * When no prefix matches, or cutting it would leave nothing, the input
|
|
22
|
+
# comes back unchanged: the option is ignored rather than producing a
|
|
23
|
+
# broken identifier.
|
|
24
|
+
class PublisherStripper
|
|
25
|
+
SEPARATOR = %r{\A(?:\s+|[-/.]\s*)}
|
|
26
|
+
|
|
27
|
+
def initialize(identifier)
|
|
28
|
+
@id = identifier
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# A co-published group is not always joined by `/`: CIE prints
|
|
32
|
+
# `CIE ISO 10916:2024`. The cut therefore repeats while a publisher
|
|
33
|
+
# token still leads, so the group drops whole whatever its joiner.
|
|
34
|
+
# The cap only guards against a cycle; no corpus id has more than three.
|
|
35
|
+
MAX_CUTS = 4
|
|
36
|
+
|
|
37
|
+
# @param rendered [String] the default human rendering of the identifier
|
|
38
|
+
# @return [String] the rendering without its leading publisher token
|
|
39
|
+
def strip(rendered)
|
|
40
|
+
return rendered unless rendered.is_a?(String)
|
|
41
|
+
|
|
42
|
+
candidates = prefixes
|
|
43
|
+
MAX_CUTS.times do
|
|
44
|
+
stripped = cut_once(rendered, candidates)
|
|
45
|
+
break if stripped.equal?(rendered)
|
|
46
|
+
|
|
47
|
+
rendered = stripped
|
|
48
|
+
end
|
|
49
|
+
rendered
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def cut_once(rendered, candidates)
|
|
55
|
+
candidates.each do |prefix|
|
|
56
|
+
next unless rendered.start_with?(prefix)
|
|
57
|
+
|
|
58
|
+
rest = rendered[prefix.length..]
|
|
59
|
+
next unless rest.match?(SEPARATOR)
|
|
60
|
+
|
|
61
|
+
stripped = rest.sub(SEPARATOR, "")
|
|
62
|
+
return stripped unless stripped.empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
rendered
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Longest first, so `ISO/IEC` wins over `ISO`. Each prefix also comes in
|
|
69
|
+
# its annotated spelling: ISO annotates inside its own renderer, so its
|
|
70
|
+
# string already reads `<span class="publisher">ISO</span> …` when it
|
|
71
|
+
# reaches this class.
|
|
72
|
+
def prefixes
|
|
73
|
+
Array(@id.publisher_prefixes)
|
|
74
|
+
.map { |p| p.to_s.strip }
|
|
75
|
+
.reject(&:empty?)
|
|
76
|
+
.flat_map { |p| [%(<span class="publisher">#{p}</span>), p] }
|
|
77
|
+
.uniq
|
|
78
|
+
.sort_by { |p| -p.length }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
data/lib/pubid/renderers.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Renderers
|
|
5
5
|
autoload :Annotator, "pubid/renderers/annotator"
|
|
6
|
+
autoload :PublisherStripper, "pubid/renderers/publisher_stripper"
|
|
6
7
|
autoload :Base, "pubid/renderers/base"
|
|
7
8
|
autoload :DirectivesRenderer, "pubid/renderers/directives_renderer"
|
|
8
9
|
autoload :GuideRenderer, "pubid/renderers/guide_renderer"
|
data/lib/pubid/sae/parser.rb
CHANGED
|
@@ -1,55 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Sae
|
|
7
|
-
class Parser
|
|
8
|
-
rule(:space) { str(" ") }
|
|
9
|
-
rule(:digit) { match["0-9"] }
|
|
10
|
-
rule(:digits) { digit.repeat(1) }
|
|
11
|
-
rule(:letter) { match["A-Z"] }
|
|
12
|
-
rule(:colon) { str(":") }
|
|
13
|
-
|
|
14
|
-
# Publisher
|
|
15
|
-
rule(:publisher) { str("SAE").as(:publisher) }
|
|
16
|
-
|
|
17
|
-
# Document types with optional number suffix (e.g., J300, J308A)
|
|
18
|
-
rule(:doc_type) do
|
|
19
|
-
(
|
|
20
|
-
str("AMS") | # Aerospace Material Specification
|
|
21
|
-
str("AIR") | # Aerospace Information Report
|
|
22
|
-
str("ARP") | # Aerospace Recommended Practice
|
|
23
|
-
str("AS") | # Aerospace Standard
|
|
24
|
-
str("J") | # SAE Standard (e.g., J300)
|
|
25
|
-
str("MA") # Material Advisory
|
|
26
|
-
).as(:type)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Number with optional letter prefix or suffix
|
|
30
|
-
rule(:number) do
|
|
31
|
-
((letter.repeat(1,
|
|
32
|
-
1) >> digits) | (digits >> letter.repeat(0,
|
|
33
|
-
1))).as(:number)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Year
|
|
37
|
-
rule(:year) { digit.repeat(4, 4).as(:year) }
|
|
38
|
-
|
|
39
|
-
# Date
|
|
40
|
-
rule(:date) { colon >> year }
|
|
41
|
-
|
|
42
|
-
# Main identifier
|
|
43
|
-
rule(:identifier) do
|
|
44
|
-
publisher >> space >> doc_type >> space.maybe >>
|
|
45
|
-
number >> date.maybe
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
root(:identifier)
|
|
49
|
-
|
|
50
|
-
def self.parse(input)
|
|
51
|
-
new.parse(input)
|
|
52
|
-
end
|
|
5
|
+
class Parser
|
|
53
6
|
end
|
|
54
7
|
end
|
|
55
8
|
end
|
|
@@ -113,7 +113,7 @@ module Pubid
|
|
|
113
113
|
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
parsed = Pubid::Parg::
|
|
116
|
+
parsed = Pubid::Parg::Model.bound(:tgpp, identifier)
|
|
117
117
|
Builder.build(parsed)
|
|
118
118
|
end
|
|
119
119
|
end
|
data/lib/pubid/tgpp/parser.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Tgpp
|
|
7
|
-
#
|
|
5
|
+
# Grammar for 3GPP identifiers.
|
|
8
6
|
#
|
|
9
7
|
# Form: `[3GPP ]<TR|TS> <NN.NNN>[suffix][-part…][:<release>][/<version>]`
|
|
10
8
|
# TS 23.207:REL-4/2.0.0
|
|
@@ -17,62 +15,7 @@ module Pubid
|
|
|
17
15
|
# document alone ("3GPP TS 23.207"), and relaton parses that bare form to
|
|
18
16
|
# search the index. Only the type and the dotted number core are required,
|
|
19
17
|
# so "TS" and "TS foo" are still rejected.
|
|
20
|
-
class Parser
|
|
21
|
-
rule(:digit) { match["0-9"] }
|
|
22
|
-
rule(:digits) { digit.repeat(1) }
|
|
23
|
-
rule(:space) { str(" ") }
|
|
24
|
-
|
|
25
|
-
# Optional leading publisher token.
|
|
26
|
-
rule(:publisher_prefix) { str("3GPP") >> space }
|
|
27
|
-
|
|
28
|
-
# Document type.
|
|
29
|
-
rule(:type) { (str("TR") | str("TS")).as(:type) }
|
|
30
|
-
|
|
31
|
-
# Dotted number core, kept as a string (preserves leading zeros).
|
|
32
|
-
rule(:number_core) { (digits >> str(".") >> digits).as(:number) }
|
|
33
|
-
|
|
34
|
-
# Letter suffix directly after the number ("U"/"dcs"/"ext"…). Generic so
|
|
35
|
-
# future controlled-vocabulary values keep round-tripping.
|
|
36
|
-
rule(:suffix) { match["A-Za-z"].repeat(1).as(:suffix) }
|
|
37
|
-
|
|
38
|
-
# Hyphen parts.
|
|
39
|
-
rule(:part) { str("-") >> digits.as(:part) }
|
|
40
|
-
rule(:parts) { part.repeat(0).as(:parts) }
|
|
41
|
-
|
|
42
|
-
# Release token, stored verbatim: everything up to the version separator.
|
|
43
|
-
# Excludes ":" (as well as "/") so the ":"-delimited URN scheme can always
|
|
44
|
-
# encode it — every real release ("REL-4", "Ph1", "UMTS", "Release 2000")
|
|
45
|
-
# is colon-free.
|
|
46
|
-
#
|
|
47
|
-
# A trailing segment shaped exactly like a version is a mistyped "/"
|
|
48
|
-
# separator ("TS 23.207:2.0.0"), not a release: no release in the 88,464
|
|
49
|
-
# published index rows contains a dot at all. Reject it rather than
|
|
50
|
-
# silently misfiling the version as the release — which only became
|
|
51
|
-
# reachable once the version segment was made optional.
|
|
52
|
-
rule(:release) do
|
|
53
|
-
(version_core >> any.absent?).absent? >>
|
|
54
|
-
match["^/:"].repeat(1).as(:release)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Three-part version, kept as a string.
|
|
58
|
-
rule(:version_core) do
|
|
59
|
-
digits >> str(".") >> digits >> str(".") >> digits
|
|
60
|
-
end
|
|
61
|
-
rule(:version) { version_core.as(:version) }
|
|
62
|
-
|
|
63
|
-
rule(:identifier) do
|
|
64
|
-
publisher_prefix.maybe >>
|
|
65
|
-
type >> space >>
|
|
66
|
-
number_core >> suffix.maybe >> parts >>
|
|
67
|
-
(str(":") >> release).maybe >>
|
|
68
|
-
(str("/") >> version).maybe
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
rule(:root) { identifier }
|
|
72
|
-
|
|
73
|
-
def self.parse(input)
|
|
74
|
-
new.parse(input)
|
|
75
|
-
end
|
|
18
|
+
class Parser
|
|
76
19
|
end
|
|
77
20
|
end
|
|
78
21
|
end
|
data/lib/pubid/un/identifier.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Pubid
|
|
|
32
32
|
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
parsed = Pubid::Parg::
|
|
35
|
+
parsed = Pubid::Parg::Model.bound(:un, identifier)
|
|
36
36
|
Builder.build(parsed)
|
|
37
37
|
end
|
|
38
38
|
end
|
data/lib/pubid/un/parser.rb
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Un
|
|
7
|
-
class Parser
|
|
8
|
-
rule(:slash) { str("/") }
|
|
9
|
-
rule(:un_prefix) { (str("UN") >> str(" ")).maybe }
|
|
10
|
-
rule(:token) { match("[A-Z0-9.]").repeat(1) }
|
|
11
|
-
|
|
12
|
-
rule(:identifier) do
|
|
13
|
-
un_prefix >>
|
|
14
|
-
token.as(:token) >>
|
|
15
|
-
(slash >> token.as(:token)).repeat(1)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
rule(:root) { identifier }
|
|
19
|
-
|
|
20
|
-
def self.parse(input)
|
|
21
|
-
new.parse(input)
|
|
22
|
-
end
|
|
5
|
+
class Parser
|
|
23
6
|
end
|
|
24
7
|
end
|
|
25
8
|
end
|
data/lib/pubid/version.rb
CHANGED
data/lib/pubid/w3c/parser.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module W3c
|
|
7
|
-
#
|
|
5
|
+
# Grammar for printed W3C identifiers, e.g.
|
|
8
6
|
# "W3C WD-charmod-19991129" (type + code + date)
|
|
9
7
|
# "W3C NOTE-xml-names" (type + code)
|
|
10
8
|
# "W3C 2dcontext" (bare code)
|
|
@@ -14,30 +12,7 @@ module Pubid
|
|
|
14
12
|
# greedily consume the trailing date and make a `.maybe` date rule
|
|
15
13
|
# unreliable. This is safe: no real W3C code ends in a same-width (4/6/8)
|
|
16
14
|
# digit run, so the Builder's fixed-width trailing-date test never collides.
|
|
17
|
-
class Parser
|
|
18
|
-
rule(:prefix) { str("W3C") >> str(" ") }
|
|
19
|
-
|
|
20
|
-
# Known W3C maturity tokens. Order matters for shared prefixes: CRD before
|
|
21
|
-
# CR, PER before PR, DNOTE before NOTE.
|
|
22
|
-
rule(:type_token) do
|
|
23
|
-
str("DNOTE") | str("NOTE") | str("WD") | str("CRD") | str("CR") |
|
|
24
|
-
str("REC") | str("PER") | str("PR") | str("SPSD") | str("OBSL")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# A leading token is only a type when immediately followed by "-".
|
|
28
|
-
rule(:type_part) { type_token.as(:type) >> str("-") }
|
|
29
|
-
|
|
30
|
-
# The remainder: code plus an optional trailing date. Captured whole and
|
|
31
|
-
# split in the Builder.
|
|
32
|
-
rule(:rest) { any.repeat(1).as(:rest) }
|
|
33
|
-
|
|
34
|
-
rule(:identifier) { prefix >> type_part.maybe >> rest }
|
|
35
|
-
|
|
36
|
-
rule(:root) { identifier }
|
|
37
|
-
|
|
38
|
-
def self.parse(input)
|
|
39
|
-
new.parse(input)
|
|
40
|
-
end
|
|
15
|
+
class Parser
|
|
41
16
|
end
|
|
42
17
|
end
|
|
43
18
|
end
|
data/lib/pubid/xsf/identifier.rb
CHANGED
|
@@ -30,15 +30,19 @@ module Pubid
|
|
|
30
30
|
# publisher name in an identifier — the leading token is "XEP".
|
|
31
31
|
PUBLISHER = "XSF"
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
# Basic string representation. Delegates to renderer.
|
|
34
|
+
#
|
|
35
|
+
# `with_publisher:` is accepted and has no effect: `XEP` names the
|
|
36
|
+
# series, and XSF itself cites `XEP 0001`, so the internal form is the
|
|
37
|
+
# external one (see {#publisher_prefixes}).
|
|
38
|
+
def to_s(**opts)
|
|
39
39
|
render(format: :human, **opts)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def publisher_prefixes
|
|
43
|
+
[]
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
# from_hash is the shared polymorphic dispatch on Pubid::Identifier;
|
|
43
47
|
# XSF_TYPE_MAP remains as the key_value polymorphic_map.
|
|
44
48
|
|
data/lib/pubid/xsf/parser.rb
CHANGED
|
@@ -1,38 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
3
|
module Pubid
|
|
6
4
|
module Xsf
|
|
7
|
-
#
|
|
8
|
-
# named documents
|
|
9
|
-
class Parser
|
|
10
|
-
# The XMPP extensions repository publishes two documents whose name is
|
|
11
|
-
# not a number: the editor README and the `xep-xxxx` template. Both reach
|
|
12
|
-
# pubid as real primary docids ("XEP README", "XEP xxxx"), so the number
|
|
13
|
-
# rule admits these two literals beside the digits. Exact case, and no
|
|
14
|
-
# other word: the flavor still rejects "XEP foo".
|
|
15
|
-
SPECIAL_NUMBERS = %w[README xxxx].freeze
|
|
16
|
-
|
|
17
|
-
rule(:digit) { match["0-9"] }
|
|
18
|
-
rule(:digits) { digit.repeat(1) }
|
|
19
|
-
|
|
20
|
-
rule(:special_number) do
|
|
21
|
-
SPECIAL_NUMBERS.map { |name| str(name) }.reduce(:|)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# "XEP 0001" — publisher token, a single space, then the number kept as
|
|
25
|
-
# a string of digits (leading zeros preserved by the builder), or the
|
|
26
|
-
# name of one of the two named documents.
|
|
27
|
-
rule(:identifier) do
|
|
28
|
-
str("XEP") >> str(" ") >> (digits | special_number).as(:number)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
rule(:root) { identifier }
|
|
32
|
-
|
|
33
|
-
def self.parse(input)
|
|
34
|
-
new.parse(input)
|
|
35
|
-
end
|
|
5
|
+
# Grammar for XSF identifiers. Two shapes: "XEP NNNN", and the two
|
|
6
|
+
# named documents (README and the four-x placeholder).
|
|
7
|
+
class Parser
|
|
36
8
|
end
|
|
37
9
|
end
|
|
38
10
|
end
|
data/lib/pubid/xsf/renderer.rb
CHANGED
|
@@ -4,8 +4,8 @@ module Pubid
|
|
|
4
4
|
module Xsf
|
|
5
5
|
# Human-readable renderer for XSF identifiers.
|
|
6
6
|
#
|
|
7
|
-
# Produces strings like "XEP 0001".
|
|
8
|
-
#
|
|
7
|
+
# Produces strings like "XEP 0001". The `XEP` token is the series and is
|
|
8
|
+
# always rendered.
|
|
9
9
|
#
|
|
10
10
|
# Registered as the `:human` format in the XSF format registry and invoked
|
|
11
11
|
# via `render(format: :human)`.
|
|
@@ -14,8 +14,6 @@ module Pubid
|
|
|
14
14
|
|
|
15
15
|
def render(context: nil, **opts)
|
|
16
16
|
id = @id
|
|
17
|
-
return id.number.to_s if id.with_publisher == false
|
|
18
|
-
|
|
19
17
|
"#{PUBLISHER} #{id.number}"
|
|
20
18
|
end
|
|
21
19
|
end
|
data/lib/pubid.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
|
-
require "parslet"
|
|
5
4
|
|
|
6
5
|
# Eagerly load the Lutaml::Model patch (disables reference store to avoid
|
|
7
6
|
# unbounded memory growth during bulk parsing, and adds a default +to_urn+
|
|
@@ -114,7 +113,7 @@ module Pubid
|
|
|
114
113
|
#
|
|
115
114
|
# @param string [String] the identifier string
|
|
116
115
|
# @return [Pubid::Identifier]
|
|
117
|
-
# @raise [
|
|
116
|
+
# @raise [Pubid::Errors::ParseError] when no flavor can parse it
|
|
118
117
|
def parse(string, **opts)
|
|
119
118
|
Pubid.parse(string, **opts)
|
|
120
119
|
end
|
|
@@ -238,7 +237,7 @@ module Pubid
|
|
|
238
237
|
# @param format [Symbol] :auto, :human, :mr_string, or :urn
|
|
239
238
|
# @return [Identifier] The parsed identifier
|
|
240
239
|
# @raise [ArgumentError] for a non-String, or one over {MAX_INPUT_LENGTH}
|
|
241
|
-
# @raise [
|
|
240
|
+
# @raise [Pubid::Errors::ParseError] when no flavor can parse the string — the
|
|
242
241
|
# class every flavor's own +parse+ raises (see the parse-failure contract)
|
|
243
242
|
def self.parse(string, format: :auto)
|
|
244
243
|
unless string.is_a?(String)
|
|
@@ -259,13 +258,13 @@ module Pubid
|
|
|
259
258
|
# standing example. Fall through to prefix routing when the MR parse
|
|
260
259
|
# fails, rather than reporting an MR error for a string that was never
|
|
261
260
|
# an MR string. A genuine MR failure still surfaces, from the second
|
|
262
|
-
# attempt, as
|
|
261
|
+
# attempt, as Pubid::Errors::ParseError.
|
|
263
262
|
#
|
|
264
263
|
# Narrow, for the reason spelled out on {parse_by_prefix}: only a parse
|
|
265
264
|
# failure means "wrong shape". Anything else is a defect and propagates.
|
|
266
265
|
begin
|
|
267
266
|
Parsers::MrString.parse(string)
|
|
268
|
-
rescue
|
|
267
|
+
rescue Pubid::Errors::ParseError
|
|
269
268
|
parse_by_prefix(string)
|
|
270
269
|
end
|
|
271
270
|
when :urn
|
|
@@ -358,7 +357,7 @@ module Pubid
|
|
|
358
357
|
#
|
|
359
358
|
# @param string [String] a human-readable identifier
|
|
360
359
|
# @return [Identifier]
|
|
361
|
-
# @raise [
|
|
360
|
+
# @raise [Pubid::Errors::ParseError] when no flavor accepts the string
|
|
362
361
|
# @api private
|
|
363
362
|
def self.parse_by_prefix(string)
|
|
364
363
|
eager_load_flavors!
|
|
@@ -370,7 +369,7 @@ module Pubid
|
|
|
370
369
|
(prefix_owners + other_candidates(prefix_owners)).each do |mod|
|
|
371
370
|
begin
|
|
372
371
|
parsed = mod.parse(string)
|
|
373
|
-
rescue
|
|
372
|
+
rescue Pubid::Errors::ParseError => e
|
|
374
373
|
# ONLY a parse failure means "not this flavor's identifier". Every
|
|
375
374
|
# other exception is a defect in that flavor and must propagate.
|
|
376
375
|
#
|
|
@@ -411,7 +410,7 @@ module Pubid
|
|
|
411
410
|
return fallback if fallback
|
|
412
411
|
raise first_error if first_error
|
|
413
412
|
|
|
414
|
-
raise
|
|
413
|
+
raise Pubid::Errors::ParseError,
|
|
415
414
|
"no registered flavor could parse #{string.inspect}"
|
|
416
415
|
end
|
|
417
416
|
private_class_method :parse_by_prefix
|
|
@@ -474,7 +473,7 @@ module Pubid
|
|
|
474
473
|
begin
|
|
475
474
|
mod.parse(ROUTING_PROBE)
|
|
476
475
|
true
|
|
477
|
-
rescue StandardError,
|
|
476
|
+
rescue StandardError, Pubid::Errors::ParseError
|
|
478
477
|
false
|
|
479
478
|
end
|
|
480
479
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pubid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -24,20 +24,6 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0.8'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: parslet
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
27
|
- !ruby/object:Gem::Dependency
|
|
42
28
|
name: parsanol
|
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -112,6 +98,7 @@ files:
|
|
|
112
98
|
- data/parg/iec.json
|
|
113
99
|
- data/parg/ieee.json
|
|
114
100
|
- data/parg/ietf.json
|
|
101
|
+
- data/parg/iho.json
|
|
115
102
|
- data/parg/ire.json
|
|
116
103
|
- data/parg/ire.parg
|
|
117
104
|
- data/parg/isbn.json
|
|
@@ -429,6 +416,7 @@ files:
|
|
|
429
416
|
- lib/pubid/csa/composite_identifier.rb
|
|
430
417
|
- lib/pubid/csa/identifier.rb
|
|
431
418
|
- lib/pubid/csa/identifiers.rb
|
|
419
|
+
- lib/pubid/csa/identifiers/amendment.rb
|
|
432
420
|
- lib/pubid/csa/identifiers/base.rb
|
|
433
421
|
- lib/pubid/csa/identifiers/bundled.rb
|
|
434
422
|
- lib/pubid/csa/identifiers/canadian_adopted.rb
|
|
@@ -627,7 +615,6 @@ files:
|
|
|
627
615
|
- lib/pubid/ieee/aiee.rb
|
|
628
616
|
- lib/pubid/ieee/aiee/builder.rb
|
|
629
617
|
- lib/pubid/ieee/aiee/identifier.rb
|
|
630
|
-
- lib/pubid/ieee/aiee/parser.rb
|
|
631
618
|
- lib/pubid/ieee/builder.rb
|
|
632
619
|
- lib/pubid/ieee/compaction.rb
|
|
633
620
|
- lib/pubid/ieee/components/code.rb
|
|
@@ -666,11 +653,9 @@ files:
|
|
|
666
653
|
- lib/pubid/ieee/ire.rb
|
|
667
654
|
- lib/pubid/ieee/ire/builder.rb
|
|
668
655
|
- lib/pubid/ieee/ire/identifier.rb
|
|
669
|
-
- lib/pubid/ieee/ire/parser.rb
|
|
670
656
|
- lib/pubid/ieee/long_renderer.rb
|
|
671
657
|
- lib/pubid/ieee/nesc.rb
|
|
672
658
|
- lib/pubid/ieee/nesc/builder.rb
|
|
673
|
-
- lib/pubid/ieee/nesc/parser.rb
|
|
674
659
|
- lib/pubid/ieee/parser.rb
|
|
675
660
|
- lib/pubid/ieee/pre_parser.rb
|
|
676
661
|
- lib/pubid/ieee/project_renderer.rb
|
|
@@ -696,6 +681,7 @@ files:
|
|
|
696
681
|
- lib/pubid/ietf/urn_generator.rb
|
|
697
682
|
- lib/pubid/ietf/urn_parser.rb
|
|
698
683
|
- lib/pubid/iho.rb
|
|
684
|
+
- lib/pubid/iho/CLAUDE.md
|
|
699
685
|
- lib/pubid/iho/builder.rb
|
|
700
686
|
- lib/pubid/iho/identifier.rb
|
|
701
687
|
- lib/pubid/iho/identifiers.rb
|
|
@@ -705,7 +691,6 @@ files:
|
|
|
705
691
|
- lib/pubid/iho/identifiers/miscellaneous.rb
|
|
706
692
|
- lib/pubid/iho/identifiers/publication.rb
|
|
707
693
|
- lib/pubid/iho/identifiers/standard.rb
|
|
708
|
-
- lib/pubid/iho/parser.rb
|
|
709
694
|
- lib/pubid/iho/renderer.rb
|
|
710
695
|
- lib/pubid/iho/urn_generator.rb
|
|
711
696
|
- lib/pubid/iho/urn_parser.rb
|
|
@@ -941,9 +926,6 @@ files:
|
|
|
941
926
|
- lib/pubid/parg/backend.rb
|
|
942
927
|
- lib/pubid/parg/model.rb
|
|
943
928
|
- lib/pubid/parser.rb
|
|
944
|
-
- lib/pubid/parser/common_parse_methods.rb
|
|
945
|
-
- lib/pubid/parser/common_parse_rules.rb
|
|
946
|
-
- lib/pubid/parser/grammar.rb
|
|
947
929
|
- lib/pubid/parsers/base.rb
|
|
948
930
|
- lib/pubid/parsers/mr_string.rb
|
|
949
931
|
- lib/pubid/parsers/urn.rb
|
|
@@ -970,6 +952,7 @@ files:
|
|
|
970
952
|
- lib/pubid/renderers/human_readable.rb
|
|
971
953
|
- lib/pubid/renderers/iwa_renderer.rb
|
|
972
954
|
- lib/pubid/renderers/mr_string.rb
|
|
955
|
+
- lib/pubid/renderers/publisher_stripper.rb
|
|
973
956
|
- lib/pubid/renderers/supplement_renderer.rb
|
|
974
957
|
- lib/pubid/renderers/urn.rb
|
|
975
958
|
- lib/pubid/rendering.rb
|