pubid 2.0.10 → 2.0.12
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/lib/pubid/adobe/pubid_urn_schema.rb +10 -3
- data/lib/pubid/amca/pubid_urn_schema.rb +25 -0
- data/lib/pubid/amca.rb +1 -0
- data/lib/pubid/bipm/CLAUDE.md +9 -0
- data/lib/pubid/bipm/pubid_urn_schema.rb +42 -0
- data/lib/pubid/bipm.rb +1 -0
- data/lib/pubid/bsi/CLAUDE.md +13 -0
- data/lib/pubid/bsi/pubid_urn_schema.rb +114 -0
- data/lib/pubid/bsi.rb +1 -0
- data/lib/pubid/cen_cenelec/CLAUDE.md +11 -0
- data/lib/pubid/cen_cenelec/pubid_urn_schema.rb +26 -8
- data/lib/pubid/cie/CLAUDE.md +9 -0
- data/lib/pubid/cie/pubid_urn_schema.rb +51 -0
- data/lib/pubid/cie.rb +1 -0
- data/lib/pubid/csa/CLAUDE.md +12 -0
- data/lib/pubid/csa/pubid_urn_schema.rb +58 -0
- data/lib/pubid/csa.rb +1 -0
- data/lib/pubid/doi/pubid_urn_schema.rb +19 -0
- data/lib/pubid/doi.rb +1 -0
- data/lib/pubid/evs/CLAUDE.md +10 -0
- data/lib/pubid/format_registry.rb +5 -1
- data/lib/pubid/gb/pubid_urn_schema.rb +23 -0
- data/lib/pubid/gb.rb +1 -0
- data/lib/pubid/idf/pubid_urn_schema.rb +44 -0
- data/lib/pubid/idf.rb +1 -0
- data/lib/pubid/iec/CLAUDE.md +13 -0
- data/lib/pubid/iec/pubid_urn_schema.rb +46 -8
- data/lib/pubid/ietf/pubid_urn_schema.rb +24 -0
- data/lib/pubid/ietf.rb +1 -0
- data/lib/pubid/iho/CLAUDE.md +11 -0
- data/lib/pubid/iho/pubid_urn_schema.rb +49 -0
- data/lib/pubid/iho.rb +1 -0
- data/lib/pubid/isbn/pubid_urn_schema.rb +20 -0
- data/lib/pubid/isbn.rb +1 -0
- data/lib/pubid/jis/pubid_urn_schema.rb +29 -0
- data/lib/pubid/jis.rb +1 -0
- data/lib/pubid/omg/pubid_urn_schema.rb +21 -0
- data/lib/pubid/omg.rb +1 -0
- data/lib/pubid/sae/pubid_urn_schema.rb +33 -0
- data/lib/pubid/sae.rb +1 -0
- data/lib/pubid/tgpp/pubid_urn_schema.rb +23 -0
- data/lib/pubid/tgpp.rb +1 -0
- data/lib/pubid/un/pubid_urn_schema.rb +19 -0
- data/lib/pubid/un.rb +1 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +28 -2
- metadata +18 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Idf
|
|
5
|
+
# The pubid-scheme URN of IDF (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# IDF 146:2003/AMD 1:2023 ->
|
|
8
|
+
# urn:pubid:idf:is:146:pubbody-IDF:year-2003:amd:1:year-2023
|
|
9
|
+
#
|
|
10
|
+
# The current urn:idf:… form of #to_urn is pubid-invented and stays
|
|
11
|
+
# there. `type`, `stage` and `typed_stage` serialize every registry
|
|
12
|
+
# field of their components, so each field is its own atom (the NIST
|
|
13
|
+
# ruling): reducing them to one identifying value would change to_hash
|
|
14
|
+
# and need a relaton-data re-crawl — a separate decision.
|
|
15
|
+
PubidUrnSchema = Pubid::PubidUrn.define("idf") do
|
|
16
|
+
atom "publisher.body", "pubbody"
|
|
17
|
+
atom "type.abbr", "typeabbr"
|
|
18
|
+
atom "type.name", "typename"
|
|
19
|
+
atom "type.type_code", "typetypecode"
|
|
20
|
+
atom "part", "part"
|
|
21
|
+
atom "year", "year"
|
|
22
|
+
atom "stage.abbr", "stageabbr"
|
|
23
|
+
atom "stage.name", "stagename"
|
|
24
|
+
atom "stage.stage_code", "stagestagecode"
|
|
25
|
+
atom "stage.harmonized_stages", "stageharmonizedstages", kind: :list
|
|
26
|
+
atom "typed_stage.abbr", "typedstageabbr", kind: :list
|
|
27
|
+
atom "typed_stage.name", "typedstagename"
|
|
28
|
+
atom "typed_stage.code", "typedstage"
|
|
29
|
+
atom "typed_stage.long_abbr", "typedstagelongabbr"
|
|
30
|
+
atom "typed_stage.short_abbr", "typedstageshortabbr"
|
|
31
|
+
atom "typed_stage.stage_code", "typedstagestagecode"
|
|
32
|
+
atom "typed_stage.type_code", "typedstagetypecode"
|
|
33
|
+
atom "typed_stage.harmonized_stages", "typedstageharmonizedstages",
|
|
34
|
+
kind: :list
|
|
35
|
+
|
|
36
|
+
type "pubid:idf:all-parts", "all"
|
|
37
|
+
type "pubid:idf:amendment", "amd"
|
|
38
|
+
type "pubid:idf:corrigendum", "cor"
|
|
39
|
+
type "pubid:idf:identifier", "id"
|
|
40
|
+
type "pubid:idf:international-standard", "is"
|
|
41
|
+
type "pubid:idf:reviewed-method", "rm"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/pubid/idf.rb
CHANGED
|
@@ -17,6 +17,7 @@ module Pubid
|
|
|
17
17
|
autoload :SupplementIdentifier, "#{__dir__}/idf/supplement_identifier"
|
|
18
18
|
autoload :UrnGenerator, "#{__dir__}/idf/urn_generator"
|
|
19
19
|
autoload :UrnParser, "#{__dir__}/idf/urn_parser"
|
|
20
|
+
autoload :PubidUrnSchema, "#{__dir__}/idf/pubid_urn_schema"
|
|
20
21
|
|
|
21
22
|
def self.parse(identifier)
|
|
22
23
|
unless identifier.is_a?(String)
|
data/lib/pubid/iec/CLAUDE.md
CHANGED
|
@@ -31,3 +31,16 @@ These notes were part of the root `CLAUDE.md`. Read them before you change `lib/
|
|
|
31
31
|
**Two parent-slot gaps recorded by the cross-flavor `base` survey** (`lib/pubid/bsi/CLAUDE.md` has the measured version). `Identifiers::TestReportForm#cispr_identifier` is a polymorphic `Identifier` parent slot with no `#root` override, so `root` returns the form itself. And `Identifiers::ConsolidatedIdentifier#base_document` returns `identifiers&.first` **without** the recursive `&.base_document` that its BSI, CSA and CEN counterparts use — a one-level peel where the others peel fully, so a consolidated edition of a supplement does not reduce to the bare standard. Neither is chased here; both are pinned by nothing, which is why they are written down.
|
|
32
32
|
|
|
33
33
|
**Stage codes — the SSOT and what is settled.** The authoritative source for IEC stage abbreviations is committed in this repo: **`data/iec/stage-codes.md`** — the 52-row IEC/ISO stage-code correspondence table transcribed from IEC's official *IEC/ISO Harmonized APIs* documents (v0.0.8 2023-06, api-portal.iec.ch; v0.0.7 2021-05, iec-apiportal.apigee.io — the successors that replace the IEC Data Feeds), the legacy Data-Feeds field examples, and the IS-lifecycle ladder from `StageCodes_IS_v2.pdf` (2023-06). `www.iec.ch` itself is fully WAF-gated to non-browsers and the Wayback Machine holds no snapshots of its PDFs, so the extract — not the unreachable original — is the reference. **`Pubid::Iec.locate_stage` reads `TYPED_STAGES` only** (`lib/pubid/iec.rb`); `PROJECT_STAGES` (AFDIS, TCDV, PRVC…) are not queryable through it. Every one of metanorma-iec's 55 `STAGE_CODES` — the list quoted in pubid#237 — resolves, locked by `spec/pubid/iec/typed_stages_spec.rb` in the issue's own order; aliases are always **appended, never prepended**, so `abbr.first` (what renders) is unchanged. Notable rulings from that pass: **ADIS** is the legacy Data-Feeds spelling of AFDIS ("Approved for FDIS circulation", ISO_LEVEL 40.99) and is an alias on `cdv` (the typed stage claiming 40.99); **CDISH/CDPAS** are the 50.20 rows of the DISH/DPAS deliverables, not "committee draft ISH/PAS" (30.xx); **Reconciliation items recorded in the extract, deliberately not applied:** DELPUB sits at 99.60 there while the `is` ladder does not claim 99.60; CAN carries two codes (30.98 IS/TR/TS, 50.98 PAS/ISH/COR); the rows CDISH-table-siblings DECDISH/MERGED/SPLIT/PCC/PRVN/DEL/RPUB/TPUB and the per-deliverable translation/preparation families are not registered as typed-stage abbreviations.
|
|
34
|
+
|
|
35
|
+
## pubid-scheme URN (issue #670)
|
|
36
|
+
|
|
37
|
+
`lib/pubid/iec/pubid_urn_schema.rb` completes the partial schema the IEEE
|
|
38
|
+
and GOST waves landed; rulings in `docs/URN-SCHEMES.adoc` (`[[urn-iec]]`).
|
|
39
|
+
Invariant: every atom added after those waves sits after `database-` and
|
|
40
|
+
before `lang-`, so a landed URN encodes identically (`database` became the
|
|
41
|
+
bool the corpus serializes before any URN carried it). The URN inherits
|
|
42
|
+
the unserialized-identity gaps pinned above: a WorkingDocument's URN is
|
|
43
|
+
the type-only `urn:pubid:iec:wd` (all WD rows share one hash — a shared
|
|
44
|
+
hash, not a collision), and a TestReportForm's CISPR document rides
|
|
45
|
+
`cispr_identifier`. Mapping them stays the wire-format decision it
|
|
46
|
+
already was.
|
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Iec
|
|
5
|
-
# The pubid-scheme URN of IEC
|
|
5
|
+
# The pubid-scheme URN of IEC (issue #670 completes the flavor;
|
|
6
6
|
# docs/URN-SCHEMES.adoc).
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
8
|
+
# CISPR 12:2007/AMD1:2009 ->
|
|
9
|
+
# urn:pubid:iec:is:12:pub-CISPR:year-2007:amd:1:pub-CISPR:year-2009
|
|
10
|
+
#
|
|
11
|
+
# The partial schema landed with IEEE named the one type IEEE nests; the
|
|
12
|
+
# GOST wave added the TS, TR, amendment and consolidated identifier a
|
|
13
|
+
# GOST adoption can name. This wave declares the rest of the flavor and
|
|
14
|
+
# the atoms its types serialize (`vap`, the sheet/fragment numbers);
|
|
15
|
+
# every new atom sits after the ones earlier waves placed, so the
|
|
16
|
+
# published URNs are unchanged. `database` was a string atom before any
|
|
17
|
+
# URN carried it — the corpus holds only `true`, so it is a bool.
|
|
18
|
+
#
|
|
19
|
+
# Known identity gaps the URN inherits, because it carries exactly what
|
|
20
|
+
# to_hash carries (pinned in lib/pubid/iec/CLAUDE.md): a WorkingDocument
|
|
21
|
+
# serializes only `_type`, and a TestReportForm's CISPR document sits in
|
|
22
|
+
# the unserialized `cispr_identifier` — such rows emit type-only URNs
|
|
23
|
+
# (`urn:pubid:iec:wd`) and are one hash, so they are not a collision.
|
|
24
|
+
# Mapping them is a wire-format change and stays the separate decision
|
|
25
|
+
# it already was. The official RFC 5141-style urn:iec:std: form stays
|
|
26
|
+
# on #to_urn.
|
|
14
27
|
PubidUrnSchema = Pubid::PubidUrn.define("iec") do
|
|
15
28
|
atom "publisher", "pub"
|
|
16
29
|
atom "copublishers", "co", kind: :list
|
|
@@ -23,17 +36,42 @@ module Pubid
|
|
|
23
36
|
atom "edition", "ed"
|
|
24
37
|
atom "stage", "stage"
|
|
25
38
|
atom "stage_iteration", "iter"
|
|
26
|
-
atom "database", "database"
|
|
39
|
+
atom "database", "database", kind: :bool
|
|
40
|
+
atom "fragment_number", "frag"
|
|
41
|
+
atom "sheet_number", "sheet"
|
|
42
|
+
atom "sheet_year", "sheetyear"
|
|
43
|
+
atom "vap", "vap", kind: :list
|
|
27
44
|
atom "languages.*.code", "lang"
|
|
28
45
|
atom "identifiers", "ids", kind: :ids
|
|
29
46
|
|
|
30
47
|
facet "languages.*.original_code", "langsrc"
|
|
31
48
|
|
|
49
|
+
type "pubid:iec:all-parts", "all"
|
|
32
50
|
type "pubid:iec:amendment", "amd"
|
|
51
|
+
type "pubid:iec:base", "base"
|
|
52
|
+
type "pubid:iec:component-specification", "cs"
|
|
53
|
+
type "pubid:iec:conformity-assessment", "ca"
|
|
33
54
|
type "pubid:iec:consolidated-identifier", "consol", core: []
|
|
55
|
+
type "pubid:iec:corrigendum", "cor"
|
|
56
|
+
type "pubid:iec:fragment-identifier", "fi", core: []
|
|
57
|
+
type "pubid:iec:guide", "guide"
|
|
58
|
+
type "pubid:iec:identifier", "id"
|
|
34
59
|
type "pubid:iec:international-standard", "is"
|
|
60
|
+
type "pubid:iec:interpretation-sheet", "is2"
|
|
61
|
+
type "pubid:iec:operational-document", "od"
|
|
62
|
+
type "pubid:iec:publicly-available-specification", "pas"
|
|
63
|
+
type "pubid:iec:sheet-identifier", "si", core: []
|
|
64
|
+
type "pubid:iec:single-identifier", "si2"
|
|
65
|
+
type "pubid:iec:societal-technology-trend-report", "sttr"
|
|
66
|
+
type "pubid:iec:systems-reference-document", "srd"
|
|
67
|
+
type "pubid:iec:technical-group", "tg"
|
|
35
68
|
type "pubid:iec:technical-report", "tr"
|
|
36
69
|
type "pubid:iec:technical-specification", "ts"
|
|
70
|
+
type "pubid:iec:technology-report", "tr2"
|
|
71
|
+
type "pubid:iec:test-report-form", "trf"
|
|
72
|
+
type "pubid:iec:vap-identifier", "vi"
|
|
73
|
+
type "pubid:iec:white-paper", "wp"
|
|
74
|
+
type "pubid:iec:working-document", "wd"
|
|
37
75
|
end
|
|
38
76
|
end
|
|
39
77
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Ietf
|
|
5
|
+
# The pubid-scheme URN of IETF (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# draft-3gpp-collaboration-01 ->
|
|
8
|
+
# urn:pubid:ietf:id2:3gpp-collaboration:v-01
|
|
9
|
+
#
|
|
10
|
+
# The official urn:ietf:rfc:… namespace (RFC 2648) stays on #to_urn.
|
|
11
|
+
# The internet-draft token is `id2`, because `id` names the flavor's
|
|
12
|
+
# bare identifier.
|
|
13
|
+
PubidUrnSchema = Pubid::PubidUrn.define("ietf") do
|
|
14
|
+
atom "version", "v"
|
|
15
|
+
|
|
16
|
+
type "pubid:ietf:bcp", "bcp"
|
|
17
|
+
type "pubid:ietf:fyi", "fyi"
|
|
18
|
+
type "pubid:ietf:identifier", "id"
|
|
19
|
+
type "pubid:ietf:internet-draft", "id2"
|
|
20
|
+
type "pubid:ietf:rfc", "rfc"
|
|
21
|
+
type "pubid:ietf:std", "std"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/pubid/ietf.rb
CHANGED
|
@@ -24,6 +24,7 @@ module Pubid
|
|
|
24
24
|
autoload :Renderer, "#{__dir__}/ietf/renderer"
|
|
25
25
|
autoload :UrnGenerator, "#{__dir__}/ietf/urn_generator"
|
|
26
26
|
autoload :UrnParser, "#{__dir__}/ietf/urn_parser"
|
|
27
|
+
autoload :PubidUrnSchema, "#{__dir__}/ietf/pubid_urn_schema"
|
|
27
28
|
|
|
28
29
|
# Parse an IETF identifier string
|
|
29
30
|
def self.parse(identifier)
|
data/lib/pubid/iho/CLAUDE.md
CHANGED
|
@@ -172,3 +172,14 @@ edition rename (the serialized key moved `version` → `edition`) and
|
|
|
172
172
|
the volume unification; relaton-cli's `MachineIndex::REFINABLE_KEYS`
|
|
173
173
|
needs `edition`/`volume` beside the retired `version`/`year` keys; the
|
|
174
174
|
pubid pin moves in step with the relaton-data-iho re-key.
|
|
175
|
+
|
|
176
|
+
## pubid-scheme URN (issue #670)
|
|
177
|
+
|
|
178
|
+
`lib/pubid/iho/pubid_urn_schema.rb`; rulings in `docs/URN-SCHEMES.adoc`
|
|
179
|
+
(`[[urn-iho]]`). The atoms follow the containment order of
|
|
180
|
+
`UrnGenerator::SEGMENTS` — the document's `ed-`/`year-` first, then each
|
|
181
|
+
component with its own edition/year right after it (`sup-`, `part-`,
|
|
182
|
+
`parted-`, `appendix-`, `appsub-`, `vol-`, `issue-` …). Case is preserved
|
|
183
|
+
(`part-A`); the yearbook year is a volume (`vol-2024`, no `year-` value —
|
|
184
|
+
the legacy `y.` marker stays decodable in the official URN parser, never
|
|
185
|
+
emitted). The official `urn:mrn:iho:…` form stays on `#to_urn`.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Iho
|
|
5
|
+
# The pubid-scheme URN of IHO (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# IHO S-100 5.0.0 Part 2 (2024) ->
|
|
8
|
+
# urn:pubid:iho:std:100:ed-5.0.0:year-2024:part-2
|
|
9
|
+
#
|
|
10
|
+
# The atoms follow the containment order of the official URN
|
|
11
|
+
# (urn:iho:s:100:ed-5.2.0:part-2, Pubid::Iho::UrnGenerator): the
|
|
12
|
+
# document's edition and year first, then each component with its own
|
|
13
|
+
# edition/year right after it — supplement, part, annex, appendix (the
|
|
14
|
+
# two-level Appendix D-2 keeps the subnumber as its own atom), volume
|
|
15
|
+
# (the unified locator, yearbook volumes included: `vol-2024`), issue.
|
|
16
|
+
# Letters stay case-preserved (`part-A`). The legacy `y.` yearbook
|
|
17
|
+
# marker is decodable in the official URN parser, never emitted here:
|
|
18
|
+
# a periodical has no `year-` atom value, its volume carries the year.
|
|
19
|
+
# The official urn:mrn:iho:… form stays on #to_urn.
|
|
20
|
+
PubidUrnSchema = Pubid::PubidUrn.define("iho") do
|
|
21
|
+
atom "edition", "ed"
|
|
22
|
+
atom "year", "year"
|
|
23
|
+
atom "supplement", "sup"
|
|
24
|
+
atom "supplement_edition", "suped"
|
|
25
|
+
atom "supplement_year", "supyear"
|
|
26
|
+
atom "part", "part"
|
|
27
|
+
atom "part_edition", "parted"
|
|
28
|
+
atom "part_year", "party"
|
|
29
|
+
atom "annex", "annex"
|
|
30
|
+
atom "annex_edition", "anned"
|
|
31
|
+
atom "annex_year", "annyear"
|
|
32
|
+
atom "appendix", "appendix"
|
|
33
|
+
atom "appendix_subnumber", "appsub"
|
|
34
|
+
atom "appendix_edition", "apped"
|
|
35
|
+
atom "appendix_year", "appyear"
|
|
36
|
+
atom "volume", "vol"
|
|
37
|
+
atom "issue", "issue"
|
|
38
|
+
atom "volume_edition", "voled"
|
|
39
|
+
atom "volume_year", "voly"
|
|
40
|
+
|
|
41
|
+
type "pubid:iho:bibliographic", "b"
|
|
42
|
+
type "pubid:iho:circular-letter", "cl"
|
|
43
|
+
type "pubid:iho:identifier", "id"
|
|
44
|
+
type "pubid:iho:miscellaneous", "m"
|
|
45
|
+
type "pubid:iho:publication", "pub"
|
|
46
|
+
type "pubid:iho:standard", "std"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/pubid/iho.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Pubid
|
|
|
14
14
|
autoload :Renderer, "#{__dir__}/iho/renderer"
|
|
15
15
|
autoload :UrnGenerator, "#{__dir__}/iho/urn_generator"
|
|
16
16
|
autoload :UrnParser, "#{__dir__}/iho/urn_parser"
|
|
17
|
+
autoload :PubidUrnSchema, "#{__dir__}/iho/pubid_urn_schema"
|
|
17
18
|
|
|
18
19
|
# Parse an IHO identifier string into an identifier object
|
|
19
20
|
# @param identifier [String] The IHO identifier string to parse
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Isbn
|
|
5
|
+
# The pubid-scheme URN of ISBN (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# ISBN 0-306-40615-2 -> urn:pubid:isbn:book:hyphenated-0-306-40615-2:raw-0306406152
|
|
8
|
+
#
|
|
9
|
+
# There is no positional core: the hyphenated and raw spellings are both
|
|
10
|
+
# optional atoms (an ISBN given bare serializes only `raw`). The official
|
|
11
|
+
# urn:isbn: namespace (RFC 3187) stays on #to_urn.
|
|
12
|
+
PubidUrnSchema = Pubid::PubidUrn.define("isbn") do
|
|
13
|
+
atom "hyphenated", "hyphenated"
|
|
14
|
+
atom "raw", "raw"
|
|
15
|
+
|
|
16
|
+
type "pubid:isbn:book", "book", core: []
|
|
17
|
+
type "pubid:isbn:identifier", "id", core: []
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/pubid/isbn.rb
CHANGED
|
@@ -18,6 +18,7 @@ module Pubid
|
|
|
18
18
|
autoload :Identifiers, "#{__dir__}/isbn/identifiers"
|
|
19
19
|
autoload :Parser, "#{__dir__}/isbn/parser"
|
|
20
20
|
autoload :Renderer, "#{__dir__}/isbn/renderer"
|
|
21
|
+
autoload :PubidUrnSchema, "#{__dir__}/isbn/pubid_urn_schema"
|
|
21
22
|
|
|
22
23
|
def self.parse(identifier)
|
|
23
24
|
Identifier.parse(identifier)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Jis
|
|
5
|
+
# The pubid-scheme URN of JIS (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# JIS A 0001:1999 -> urn:pubid:jis:jis:0001:series-A:year-1999
|
|
8
|
+
#
|
|
9
|
+
# The current urn:jis:… form of #to_urn is pubid-invented and stays
|
|
10
|
+
# there.
|
|
11
|
+
PubidUrnSchema = Pubid::PubidUrn.define("jis") do
|
|
12
|
+
atom "series", "series"
|
|
13
|
+
atom "parts", "part", kind: :list
|
|
14
|
+
atom "year", "year", kind: :int
|
|
15
|
+
atom "reaffirmed", "reaffirmed", kind: :bool
|
|
16
|
+
|
|
17
|
+
type "pubid:jis:all-parts", "all"
|
|
18
|
+
type "pubid:jis:amendment", "amd"
|
|
19
|
+
type "pubid:jis:corrigendum", "cor"
|
|
20
|
+
type "pubid:jis:explanation", "e"
|
|
21
|
+
type "pubid:jis:identifier", "id"
|
|
22
|
+
type "pubid:jis:japanese-industrial-standard", "jis"
|
|
23
|
+
type "pubid:jis:standard", "std"
|
|
24
|
+
type "pubid:jis:technical-report", "tr"
|
|
25
|
+
type "pubid:jis:technical-specification", "ts"
|
|
26
|
+
type "pubid:jis:welding-engineering-standard", "wes"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/pubid/jis.rb
CHANGED
|
@@ -19,6 +19,7 @@ module Pubid
|
|
|
19
19
|
autoload :SupplementIdentifier, "#{__dir__}/jis/supplement_identifier"
|
|
20
20
|
autoload :UrnGenerator, "#{__dir__}/jis/urn_generator"
|
|
21
21
|
autoload :UrnParser, "#{__dir__}/jis/urn_parser"
|
|
22
|
+
autoload :PubidUrnSchema, "#{__dir__}/jis/pubid_urn_schema"
|
|
22
23
|
|
|
23
24
|
# Parse a JIS identifier string
|
|
24
25
|
def self.parse(identifier)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Omg
|
|
5
|
+
# The pubid-scheme URN of OMG (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# OMG AMI4CCM 1.0 -> urn:pubid:omg:spec:acronym-AMI4CCM:v-1.0
|
|
8
|
+
#
|
|
9
|
+
# No positional core: an OMG specification names itself by its acronym.
|
|
10
|
+
# The current urn:omg:… form of #to_urn is pubid-invented and stays
|
|
11
|
+
# there.
|
|
12
|
+
PubidUrnSchema = Pubid::PubidUrn.define("omg") do
|
|
13
|
+
atom "part", "part"
|
|
14
|
+
atom "version", "v"
|
|
15
|
+
atom "acronym", "acronym"
|
|
16
|
+
|
|
17
|
+
type "pubid:omg:identifier", "id", core: []
|
|
18
|
+
type "pubid:omg:specification", "spec", core: []
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/pubid/omg.rb
CHANGED
|
@@ -17,6 +17,7 @@ module Pubid
|
|
|
17
17
|
autoload :Identifiers, "#{__dir__}/omg/identifiers"
|
|
18
18
|
autoload :Parser, "#{__dir__}/omg/parser"
|
|
19
19
|
autoload :Renderer, "#{__dir__}/omg/renderer"
|
|
20
|
+
autoload :PubidUrnSchema, "#{__dir__}/omg/pubid_urn_schema"
|
|
20
21
|
|
|
21
22
|
def self.parse(identifier)
|
|
22
23
|
Identifier.parse(identifier)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Sae
|
|
5
|
+
# The pubid-scheme URN of SAE (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# SAE J3016_202104 -> urn:pubid:sae:id:3016:typeabbr-J:year-2021:month-4
|
|
8
|
+
# SAE ARP4754A:2010 -> urn:pubid:sae:id:4754:typeabbr-ARP:rev-A:yearflat-2010
|
|
9
|
+
#
|
|
10
|
+
# The current urn:sae:… form of #to_urn is pubid-invented and stays
|
|
11
|
+
# there. The type (`J`, `AS`, `ARP`, `AMS`) is an atom, because the
|
|
12
|
+
# identifier type is one class carrying every series code; the date
|
|
13
|
+
# fields are Integers.
|
|
14
|
+
#
|
|
15
|
+
# SAE's hash carries two date shapes (the canonical flattening keeps a
|
|
16
|
+
# year-alone date flat: pubid#360), so a year gets one prefix per shape
|
|
17
|
+
# — the ashrae ruling. `year-` stays the nested year+month form the
|
|
18
|
+
# first release emitted; `yearflat-` is the flat year-alone form the
|
|
19
|
+
# corpus round (pubid#669) added. A part is top-level in the hash
|
|
20
|
+
# (AMS-QQ-A-250/4B -> part-4).
|
|
21
|
+
PubidUrnSchema = Pubid::PubidUrn.define("sae") do
|
|
22
|
+
atom "type.abbr", "typeabbr"
|
|
23
|
+
atom "revision", "rev"
|
|
24
|
+
atom "amendment", "amd"
|
|
25
|
+
atom "part", "part"
|
|
26
|
+
atom "date.year", "year", kind: :int
|
|
27
|
+
atom "date.month", "month", kind: :int
|
|
28
|
+
atom "year", "yearflat"
|
|
29
|
+
|
|
30
|
+
type "pubid:sae:identifier", "id"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/pubid/sae.rb
CHANGED
|
@@ -17,6 +17,7 @@ module Pubid
|
|
|
17
17
|
autoload :Renderer, "#{__dir__}/sae/renderer"
|
|
18
18
|
autoload :UrnGenerator, "#{__dir__}/sae/urn_generator"
|
|
19
19
|
autoload :UrnParser, "#{__dir__}/sae/urn_parser"
|
|
20
|
+
autoload :PubidUrnSchema, "#{__dir__}/sae/pubid_urn_schema"
|
|
20
21
|
|
|
21
22
|
def self.parse(input)
|
|
22
23
|
Identifier.parse(input)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Tgpp
|
|
5
|
+
# The pubid-scheme URN of 3GPP (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# TS 01.01:REL-96/5.0.0 -> urn:pubid:3gpp:ts:01.01:part-01:release-96:v-5.0.0
|
|
8
|
+
#
|
|
9
|
+
# The official urn:3gpp: namespace (RFC 5279) stays on #to_urn. The
|
|
10
|
+
# parts ("01.01" splits to part "01" and part "01"…) are the list the
|
|
11
|
+
# flavor models; the release and the version close the URN.
|
|
12
|
+
PubidUrnSchema = Pubid::PubidUrn.define("3gpp") do
|
|
13
|
+
atom "parts", "part", kind: :list
|
|
14
|
+
atom "version", "v"
|
|
15
|
+
atom "release", "release"
|
|
16
|
+
atom "suffix", "suffix"
|
|
17
|
+
|
|
18
|
+
type "pubid:3gpp:identifier", "id"
|
|
19
|
+
type "pubid:3gpp:technical-report", "tr"
|
|
20
|
+
type "pubid:3gpp:technical-specification", "ts"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/pubid/tgpp.rb
CHANGED
|
@@ -34,6 +34,7 @@ module Pubid
|
|
|
34
34
|
autoload :Renderer, "#{__dir__}/tgpp/renderer"
|
|
35
35
|
autoload :UrnGenerator, "#{__dir__}/tgpp/urn_generator"
|
|
36
36
|
autoload :UrnParser, "#{__dir__}/tgpp/urn_parser"
|
|
37
|
+
autoload :PubidUrnSchema, "#{__dir__}/tgpp/pubid_urn_schema"
|
|
37
38
|
|
|
38
39
|
# Parse a 3GPP identifier string
|
|
39
40
|
def self.parse(identifier)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pubid
|
|
4
|
+
module Un
|
|
5
|
+
# The pubid-scheme URN of UN (issue #670; docs/URN-SCHEMES.adoc).
|
|
6
|
+
#
|
|
7
|
+
# A/RES/78/1 -> urn:pubid:un:document:A,RES,78:1
|
|
8
|
+
#
|
|
9
|
+
# The path segments are the list before the final number; the number is
|
|
10
|
+
# the positional core. The current urn:un:… form of #to_urn is
|
|
11
|
+
# pubid-invented and stays there.
|
|
12
|
+
PubidUrnSchema = Pubid::PubidUrn.define("un") do
|
|
13
|
+
atom "path", "path", kind: :list
|
|
14
|
+
|
|
15
|
+
type "pubid:un:document", "document"
|
|
16
|
+
type "pubid:un:identifier", "id"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/pubid/un.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Pubid
|
|
|
12
12
|
autoload :Identifiers, "#{__dir__}/un/identifiers"
|
|
13
13
|
autoload :Parser, "#{__dir__}/un/parser"
|
|
14
14
|
autoload :Renderer, "#{__dir__}/un/renderer"
|
|
15
|
+
autoload :PubidUrnSchema, "#{__dir__}/un/pubid_urn_schema"
|
|
15
16
|
|
|
16
17
|
def self.parse(identifier)
|
|
17
18
|
Identifier.parse(identifier)
|
data/lib/pubid/version.rb
CHANGED
data/lib/pubid.rb
CHANGED
|
@@ -238,6 +238,7 @@ module Pubid
|
|
|
238
238
|
# @param format [Symbol] :auto, :human, :mr_string, or :urn
|
|
239
239
|
# @return [Identifier] The parsed identifier
|
|
240
240
|
# @raise [ArgumentError] for a non-String, or one over {MAX_INPUT_LENGTH}
|
|
241
|
+
# (as {Errors::InvalidInputError}, which is one)
|
|
241
242
|
# @raise [Pubid::Errors::ParseError] when no flavor can parse the string — the
|
|
242
243
|
# class every flavor's own +parse+ raises (see the parse-failure contract)
|
|
243
244
|
def self.parse(string, format: :auto)
|
|
@@ -249,6 +250,15 @@ module Pubid
|
|
|
249
250
|
raise Pubid::Errors::InvalidInputError,
|
|
250
251
|
Pubid::INPUT_TOO_LONG_MESSAGE
|
|
251
252
|
end
|
|
253
|
+
# Invalid encoding is bad input, not a grammar failure: the detectors
|
|
254
|
+
# and normalization regexes raise raw `ArgumentError` (invalid byte
|
|
255
|
+
# sequence) or `Encoding::CompatibilityError` on it, which is the leak
|
|
256
|
+
# the contract closes (issue #670). The bytes are read as UTF-8 — a
|
|
257
|
+
# binary string of ASCII bytes (".b") is fine, high bytes are not.
|
|
258
|
+
unless string.dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
|
259
|
+
raise Pubid::Errors::InvalidInputError,
|
|
260
|
+
"input string has invalid encoding"
|
|
261
|
+
end
|
|
252
262
|
|
|
253
263
|
format = FormatDetector.detect(string) if format == :auto
|
|
254
264
|
|
|
@@ -282,22 +292,38 @@ module Pubid
|
|
|
282
292
|
#
|
|
283
293
|
# @param string [String] the URN
|
|
284
294
|
# @return [Identifier] the parsed identifier
|
|
295
|
+
# @raise [Pubid::Errors::InvalidInputError] for a non-String
|
|
285
296
|
#
|
|
286
297
|
# A pubid-scheme URN ("urn:pubid:…", see {PubidUrn}) is decoded by the
|
|
287
298
|
# shared codec; every other namespace goes to its flavor's UrnParser.
|
|
299
|
+
# Every decode failure on this surface is a pubid error (issue #670): an
|
|
300
|
+
# empty string, a missing or unknown namespace, invalid encoding, and a
|
|
301
|
+
# URN a flavor's parser rejects all raise {Errors::UrnParseError} — the
|
|
302
|
+
# raw `ArgumentError` the detection and the flavor parsers raise is the
|
|
303
|
+
# wrapped failure's cause, never the raised class.
|
|
288
304
|
def self.parse_urn(string)
|
|
305
|
+
unless string.is_a?(String)
|
|
306
|
+
raise Pubid::Errors::InvalidInputError,
|
|
307
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
308
|
+
end
|
|
289
309
|
eager_load_flavors!
|
|
290
310
|
return PubidUrn.parse(string) if PubidUrn.pubid_urn?(string)
|
|
291
311
|
|
|
292
312
|
flavor = detect_flavor_from_urn(string)
|
|
293
313
|
flavor_module = Registry.get(flavor)
|
|
294
314
|
unless flavor_module
|
|
295
|
-
raise
|
|
296
|
-
"
|
|
315
|
+
raise Errors::UrnParseError,
|
|
316
|
+
"unknown URN namespace: #{flavor.inspect} (in #{string.inspect})"
|
|
297
317
|
end
|
|
298
318
|
|
|
299
319
|
urn_parser = flavor_module.const_get(:UrnParser)
|
|
300
320
|
urn_parser.parse(string)
|
|
321
|
+
rescue Errors::Error
|
|
322
|
+
raise
|
|
323
|
+
rescue StandardError => e
|
|
324
|
+
raise Errors::UrnParseError,
|
|
325
|
+
"URN #{string.inspect} does not parse as #{flavor.inspect}: #{e.message}",
|
|
326
|
+
cause: e
|
|
301
327
|
end
|
|
302
328
|
|
|
303
329
|
# The slug form (relaton#441): the pubid-scheme URN of +source+ in
|