pubid 2.0.22 → 2.0.23
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/doi_pfs.json +1 -0
- data/data/parg/iec.json +1 -1
- data/data/parg/nist.json +1 -1
- data/lib/pubid/doi_pfs/CLAUDE.md +72 -0
- data/lib/pubid/doi_pfs/builder.rb +18 -0
- data/lib/pubid/doi_pfs/identifier.rb +36 -0
- data/lib/pubid/doi_pfs/identifiers/resource.rb +31 -0
- data/lib/pubid/doi_pfs/identifiers.rb +7 -0
- data/lib/pubid/doi_pfs/parser.rb +10 -0
- data/lib/pubid/doi_pfs/pubid_urn_schema.rb +15 -0
- data/lib/pubid/doi_pfs/renderer.rb +10 -0
- data/lib/pubid/doi_pfs/urn_generator.rb +12 -0
- data/lib/pubid/doi_pfs.rb +68 -0
- data/lib/pubid/nist/CLAUDE.md +36 -0
- data/lib/pubid/nist/builder.rb +10 -0
- data/lib/pubid/nist/identifiers/base.rb +10 -0
- data/lib/pubid/nist/identifiers/special_publication.rb +15 -0
- data/lib/pubid/nist/router.rb +11 -0
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +4 -0
- metadata +12 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# DoiPfs — the PFS-compiled doi dev alias
|
|
2
|
+
|
|
3
|
+
This flavor is **generated**, not hand-written: every file here is compiler
|
|
4
|
+
output from `pubid-grammar`'s `definitions/doi.pfs` (pubid/pubid#706),
|
|
5
|
+
reproduce with
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd ../pubid-grammar
|
|
9
|
+
ruby scripts/pfs compile definitions/doi.pfs --as doi_pfs \
|
|
10
|
+
--parsanol-version <CI pin> --ruby-out ../pubid/lib
|
|
11
|
+
cp artifacts/doi_pfs.json ../pubid/data/parg/doi_pfs.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
DO NOT EDIT these files by hand — a hand edit is silently overwritten by
|
|
15
|
+
the next compile, and the grammar SSOT is the definition, not this module
|
|
16
|
+
(the `data/parg/doi_pfs.json` artifact's freshness envelope and the
|
|
17
|
+
definition's source sha pin the lineage).
|
|
18
|
+
|
|
19
|
+
## The coexistence semantics (read before touching anything)
|
|
20
|
+
|
|
21
|
+
`doi_pfs` is the **dev-alias key** of the doi scheme: it registers beside
|
|
22
|
+
the coded `Pubid::Doi` so the compiled pipeline can be proven against the
|
|
23
|
+
coded flavor without cutover (cutover — replacing `doi` with the compiled
|
|
24
|
+
flavor — is a separate, later decision).
|
|
25
|
+
|
|
26
|
+
- **Wire tag**: the definition declares `tag: "pubid:doi:resource"` — the
|
|
27
|
+
SCHEME's canonical tag — so `to_hash` is byte-identical with the coded
|
|
28
|
+
flavor. `Resource.polymorphic_name` overrides the class-name-derived
|
|
29
|
+
tag for exactly this reason. Consequence: a GLOBAL `Pubid.from_hash` of
|
|
30
|
+
a doi_pfs hash resolves the coded class (one scheme, one `_type`, one
|
|
31
|
+
global resolution); the alias's own `DoiPfs::Identifier.from_hash`
|
|
32
|
+
routes the tag back to `DoiPfs::Identifiers::Resource` through its
|
|
33
|
+
`DOI_TYPE_MAP`.
|
|
34
|
+
- **URN namespace**: the definition declares `urn.namespace: doi`, so the
|
|
35
|
+
generated `UrnGenerator` pins `urn_namespace` to `"doi"` and `to_urn`
|
|
36
|
+
is byte-identical (`"urn:doi"`). The pubid-scheme schema registers
|
|
37
|
+
under the FLAVOR key (`PubidUrn.define("doi_pfs")`) — never re-register
|
|
38
|
+
under `"doi"`, that would overwrite the coded flavor's registration.
|
|
39
|
+
- **Routing**: `Pubid.parse` keeps routing `doi:`-faced strings to the
|
|
40
|
+
coded flavor (registry keys sort `"doi"` first; both flavors claim the
|
|
41
|
+
same prefixes). The alias is reached through `Pubid::DoiPfs.parse`.
|
|
42
|
+
|
|
43
|
+
## The parity gate
|
|
44
|
+
|
|
45
|
+
`spec/pubid/doi_pfs/parity_spec.rb` is the spike's whole point: over the
|
|
46
|
+
full doi inventory (coded fixtures + corpus rows + aliases + constructed
|
|
47
|
+
edge cases), both flavors must agree byte-for-byte on `to_s`, `to_hash`,
|
|
48
|
+
`to_urn`, `to_mr_string`, `to_pubid_urn` and fail on the same inputs with
|
|
49
|
+
`Pubid::Errors::ParseError`. Drift is a defect in the definition or the
|
|
50
|
+
compiler — never relax an expectation here.
|
|
51
|
+
|
|
52
|
+
Non-obvious inventory facts, learned the hard way:
|
|
53
|
+
|
|
54
|
+
- The combined faces (`https://doi.org/doi:10.1000/182`) are rejected by
|
|
55
|
+
the CODED flavor too (the optional faces compose non-backtracking), so
|
|
56
|
+
they are negatives.
|
|
57
|
+
- `Pubid.parse("10.1000/182")` routes to **UN** on main, pre-existing:
|
|
58
|
+
the bare `10.` form is not a doi prefix-owner claim at a token
|
|
59
|
+
boundary (`10.` followed by a digit), and un's token run accepts it.
|
|
60
|
+
Only the scheme-faced form routes to Doi.
|
|
61
|
+
- The coded builder re-adds `"10."` to the registrar digits its grammar
|
|
62
|
+
captures; the doi.pfs pattern captures the whole `10.` face, so the
|
|
63
|
+
doi_pfs builder binds `prefix` directly. Model-level outputs are
|
|
64
|
+
identical; only the bound wire map differs (`prefix: "1000"` vs
|
|
65
|
+
`"10.1000"` in the artifact's corpus).
|
|
66
|
+
|
|
67
|
+
## v1 boundaries
|
|
68
|
+
|
|
69
|
+
Single-type schemes only, `kind: string` fields only, no free-standing
|
|
70
|
+
`stages:`/`supplements:` sections, no semantic decode rules (the
|
|
71
|
+
DAM-family problem) — see `pubid-grammar`'s `definitions/README.md` for
|
|
72
|
+
the language reference and the fail-closed validation rules.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
class Builder
|
|
4
|
+
def self.build(parsed_data)
|
|
5
|
+
new.build(parsed_data)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def build(data)
|
|
9
|
+
Identifiers::Resource.new(
|
|
10
|
+
prefix: data[:prefix],
|
|
11
|
+
suffix: data[:suffix],
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Pubid::DoiPfs::Builder.prepend(Pubid::Builder::AllPartsWrap)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
class Identifier < ::Pubid::Identifier
|
|
4
|
+
attribute :prefix, :string
|
|
5
|
+
attribute :suffix, :string
|
|
6
|
+
|
|
7
|
+
DOI_TYPE_MAP = {
|
|
8
|
+
"pubid:doi:resource" => "Pubid::DoiPfs::Identifiers::Resource",
|
|
9
|
+
}.freeze
|
|
10
|
+
|
|
11
|
+
key_value do
|
|
12
|
+
map "_type", to: :_type, polymorphic_map: DOI_TYPE_MAP
|
|
13
|
+
map "prefix", to: :prefix
|
|
14
|
+
map "suffix", to: :suffix
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
PUBLISHER = "DOI".freeze
|
|
18
|
+
|
|
19
|
+
def self.parse(identifier)
|
|
20
|
+
unless identifier.is_a?(String)
|
|
21
|
+
raise Pubid::Errors::InvalidInputError,
|
|
22
|
+
Pubid::INPUT_NOT_A_STRING_MESSAGE
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if identifier.length > Pubid::MAX_INPUT_LENGTH
|
|
26
|
+
raise Pubid::Errors::InvalidInputError, Pubid::INPUT_TOO_LONG_MESSAGE
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
identifier = ::Pubid.utf8_input(identifier)
|
|
30
|
+
|
|
31
|
+
parsed = Pubid::Parg::Model.bound(:doi_pfs, identifier)
|
|
32
|
+
Builder.build(parsed)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
module Identifiers
|
|
4
|
+
# Concrete DOI identifier type (PFS type `resource`).
|
|
5
|
+
class Resource < Identifier
|
|
6
|
+
TYPED_STAGES = [
|
|
7
|
+
Pubid::Components::TypedStage.new(
|
|
8
|
+
code: :pubdoi,
|
|
9
|
+
stage_code: :published,
|
|
10
|
+
type_code: :doi,
|
|
11
|
+
abbr: ["DOI"],
|
|
12
|
+
name: "DOI",
|
|
13
|
+
harmonized_stages: [],
|
|
14
|
+
),
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
def self.type
|
|
18
|
+
{ key: :doi, web: :doi, title: "DOI", short: "DOI" }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The scheme-canonical wire tag declared in the definition:
|
|
22
|
+
# to_hash stays byte-identical with the scheme's coded
|
|
23
|
+
# flavor, and this flavor's own from_hash routes the tag
|
|
24
|
+
# to this class.
|
|
25
|
+
def self.polymorphic_name
|
|
26
|
+
"pubid:doi:resource"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
# PFS-generated parser shell. Parsing runs through the baked
|
|
4
|
+
# PARG artifact (data/parg/doi_pfs.json) via Pubid::Parg::Model.bound;
|
|
5
|
+
# the grammar source lives in pubid-grammar
|
|
6
|
+
# (grammars/doi_pfs.parg, compiled from definitions/doi.pfs).
|
|
7
|
+
class Parser
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
# The pubid-scheme URN schema, registered under the compiled
|
|
4
|
+
# flavor key. The definition's declared namespace
|
|
5
|
+
# ("doi") is the scheme's canonical
|
|
6
|
+
# namespace; identifiers carry the scheme's wire tag, so their
|
|
7
|
+
# pubid URNs encode through the scheme's own schema.
|
|
8
|
+
PubidUrnSchema = Pubid::PubidUrn.define("doi_pfs") do
|
|
9
|
+
atom "prefix", "prefix"
|
|
10
|
+
atom "suffix", "suffix"
|
|
11
|
+
type "pubid:doi_pfs:identifier", "id", core: []
|
|
12
|
+
type "pubid:doi_pfs:resource", "resource", core: []
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Pubid
|
|
2
|
+
module DoiPfs
|
|
3
|
+
# The official URN generator, pinned to the scheme's declared
|
|
4
|
+
# namespace ("doi") so to_urn stays
|
|
5
|
+
# scheme-canonical under the compiled flavor key.
|
|
6
|
+
class UrnGenerator < ::Pubid::UrnGenerator::Base
|
|
7
|
+
def urn_namespace
|
|
8
|
+
"doi"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# PFS-generated flavor — DO NOT EDIT BY HAND.
|
|
5
|
+
# Source: definitions/doi.pfs (pfs:1) sha256:60abc3c403c61019d727ee44d9a72591c1549672451e6609a72d36189cae6340
|
|
6
|
+
# Compiler: pubid/grammar/pfs 0.1.0 (baked with parsanol 1.3.126)
|
|
7
|
+
# Regenerate: ruby scripts/pfs compile definitions/doi.pfs --as doi_pfs --ruby-out <dir>
|
|
8
|
+
|
|
9
|
+
require "pubid"
|
|
10
|
+
|
|
11
|
+
module Pubid
|
|
12
|
+
# Digital Object Identifier flavor, compiled from its PFS definition
|
|
13
|
+
# (pubid/pubid#706). A compiled flavor is a peer of the coded
|
|
14
|
+
# flavors: same registry, same input guards, same error
|
|
15
|
+
# namespace, same URN contracts.
|
|
16
|
+
module DoiPfs
|
|
17
|
+
extend Pubid::PrefixesSupport
|
|
18
|
+
|
|
19
|
+
PREFIXES = ["doi:", "DOI:", "10."].freeze
|
|
20
|
+
|
|
21
|
+
autoload :Builder, "#{__dir__}/doi_pfs/builder"
|
|
22
|
+
autoload :Identifier, "#{__dir__}/doi_pfs/identifier"
|
|
23
|
+
autoload :Identifiers, "#{__dir__}/doi_pfs/identifiers"
|
|
24
|
+
autoload :Parser, "#{__dir__}/doi_pfs/parser"
|
|
25
|
+
autoload :Renderer, "#{__dir__}/doi_pfs/renderer"
|
|
26
|
+
autoload :PubidUrnSchema, "#{__dir__}/doi_pfs/pubid_urn_schema"
|
|
27
|
+
autoload :UrnGenerator, "#{__dir__}/doi_pfs/urn_generator"
|
|
28
|
+
|
|
29
|
+
def self.parse(identifier)
|
|
30
|
+
Identifier.parse(identifier)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Identifier.format_registry = FormatRegistry.new(parent: Identifier.format_registry)
|
|
34
|
+
Identifier.format_registry.register(:human, renderer: DoiPfs::Renderer)
|
|
35
|
+
|
|
36
|
+
def self.identifier_types
|
|
37
|
+
@identifier_types ||= Identifiers.constants
|
|
38
|
+
.filter_map do |c|
|
|
39
|
+
|
|
40
|
+
Identifiers.const_get(c); rescue NameError; nil
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
.select { |c| c.is_a?(Class) && c.singleton_methods(false).include?(:type) }
|
|
44
|
+
.select { |c| c.type.is_a?(Hash) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.all_typed_stages
|
|
48
|
+
@all_typed_stages ||= identifier_types.flat_map do |klass|
|
|
49
|
+
klass.const_defined?(:TYPED_STAGES) ? klass.const_get(:TYPED_STAGES) : []
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.locate_type(code)
|
|
54
|
+
identifier_types.find { |t| t.type[:key].to_s == code.to_s }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.locate_stage(abbr)
|
|
58
|
+
abbr_str = abbr.to_s.upcase
|
|
59
|
+
all_typed_stages.find do |s|
|
|
60
|
+
s.abbr.any? do |a|
|
|
61
|
+
a.to_s.upcase == abbr_str
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Pubid::Registry.register(:doi_pfs, Pubid::DoiPfs)
|
data/lib/pubid/nist/CLAUDE.md
CHANGED
|
@@ -184,3 +184,39 @@ Read this before you change `lib/pubid/nist/` or `spec/pubid/nist/`. The root
|
|
|
184
184
|
nothing (its flag defaults to true, so it means a spelled form anyway).
|
|
185
185
|
Locked by
|
|
186
186
|
`spec/pubid/nist/bare_fips_publisher_spec.rb`.
|
|
187
|
+
|
|
188
|
+
- **The default-series plain-number branch (pubid#711).** A citation
|
|
189
|
+
shaped like the docnumber — "800-90B", the docid-derived citation face
|
|
190
|
+
of NIST.SP.800-90B — and its publisher-led spelling "NIST 800-90B"
|
|
191
|
+
carry NO series token, and the grammar's series alternatives never
|
|
192
|
+
reached them: every branch demanded a series token (or, after a bare
|
|
193
|
+
publisher, only the dated ISO-date digits). The grammar (nist.parg,
|
|
194
|
+
fleet compiler 1.3.126) gained two trailing `identifier` alternatives
|
|
195
|
+
that ride the SAME report-number tail as the series-bearing branches —
|
|
196
|
+
`(publisher) (space) (report_number) …` and bare `(report_number) …` —
|
|
197
|
+
placed LAST so PEG ordering leaves every previously accepted form on
|
|
198
|
+
its original alternative (they only catch inputs that previously
|
|
199
|
+
failed outright). The identity defaults onto the SP series: the Router
|
|
200
|
+
dispatches `SpecialPublication` when the parse carries no series and
|
|
201
|
+
no dated date, and the Builder fills `series` from the new
|
|
202
|
+
`Identifier.default_series` class method (SP is the default — the
|
|
203
|
+
docid of the real document is NIST.SP.800-90B). The publisher rides
|
|
204
|
+
the #704 machinery: `SpecialPublication.series_default_publisher` is
|
|
205
|
+
now "NIST", so the bare parse fills the publisher after
|
|
206
|
+
`publisher_was_parsed: false` and is `==` to the spelled form (URN-,
|
|
207
|
+
MR- and hash-equal but for that equality-ignored flag; the MR face is
|
|
208
|
+
the exact "NIST.SP.800-90B" DOI surface relaton-data-nist stores).
|
|
209
|
+
The SHORT face keeps the bare spelling (publisher suppressed);
|
|
210
|
+
the MR face always carries the publisher (`to_mr_style` prints
|
|
211
|
+
`(publisher || "NIST")`), so the bare parse lands on the DOI-style
|
|
212
|
+
face directly. The dated alternative keeps priority
|
|
213
|
+
("NIST 2023-04-15 001" stays `DatedDocument`), and the routing probe
|
|
214
|
+
("zzqx-nonsense-9714") still fails, so NIST is not disqualified as a
|
|
215
|
+
`Pubid.parse` fallback. `to_hash` of the two bare-series probes
|
|
216
|
+
("SP 123", "SP 800-90B") gained `publisher: NIST` — the #704 ruling
|
|
217
|
+
generalized to the SP series; no corpus row moved. Locked by
|
|
218
|
+
`spec/pubid/nist/default_series_plain_number_spec.rb`; the corpus
|
|
219
|
+
round froze the four faces (the two publisher-led spellings as
|
|
220
|
+
non-normalized aliases of the canonical cases, the two bare ones as
|
|
221
|
+
canonical `publisher_was_parsed: false` cases) with the gem twin in
|
|
222
|
+
lockstep.
|
data/lib/pubid/nist/builder.rb
CHANGED
|
@@ -99,6 +99,16 @@ module Pubid
|
|
|
99
99
|
# Locate the appropriate identifier class via Router
|
|
100
100
|
identifier = @router.locate_identifier_klass(parsed_hash).new
|
|
101
101
|
|
|
102
|
+
# The default-series plain-number branch (pubid#711): the grammar's
|
|
103
|
+
# trailing alternatives carry no series token ("800-90B" /
|
|
104
|
+
# "NIST 800-90B"), so the identity gains the class's default series
|
|
105
|
+
# and parses == to the spelled "NIST SP 800-90B" form. The bare
|
|
106
|
+
# publisher rides the #704 rule below (apply_series_default_publisher).
|
|
107
|
+
if parsed_hash[:series].nil? &&
|
|
108
|
+
(default = identifier.class.default_series)
|
|
109
|
+
identifier.series = Components::Code.new(value: default)
|
|
110
|
+
end
|
|
111
|
+
|
|
102
112
|
# Resolve the series policy once — every series-specific decision
|
|
103
113
|
# flows through this object instead of branching on the parsed shape.
|
|
104
114
|
series = Series.for(parsed_hash)
|
|
@@ -302,6 +302,16 @@ module Pubid
|
|
|
302
302
|
nil
|
|
303
303
|
end
|
|
304
304
|
|
|
305
|
+
# The series an input implies when it spells none — the grammar's
|
|
306
|
+
# default-series plain-number branch (pubid#711: "800-90B" /
|
|
307
|
+
# "NIST 800-90B" carry no series token). The Router dispatches the
|
|
308
|
+
# class from this default and the Builder fills the attribute, so a
|
|
309
|
+
# docnumber-shaped citation parses onto the same identity as the
|
|
310
|
+
# spelled form. nil: no default.
|
|
311
|
+
def self.default_series
|
|
312
|
+
nil
|
|
313
|
+
end
|
|
314
|
+
|
|
305
315
|
# Fill the series default publisher on an id whose input spelled
|
|
306
316
|
# none. Shared by the Builder and from_hash, so both construction
|
|
307
317
|
# paths agree.
|
|
@@ -35,6 +35,21 @@ module Pubid
|
|
|
35
35
|
{ key: :sp,
|
|
36
36
|
web: :special_publication, title: "NIST Special Publication", short: "SP" }
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
# The default-series plain-number branch (pubid#711): a citation
|
|
40
|
+
# shaped like the docnumber ("800-90B", publisher-led
|
|
41
|
+
# "NIST 800-90B") names an SP document — the docid-derived
|
|
42
|
+
# citation of NIST.SP.800-90B is exactly "800-90B".
|
|
43
|
+
def default_series
|
|
44
|
+
"SP"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# A bare plain-number parse carries the series' NIST publisher
|
|
48
|
+
# (the #704 shape), so it is == to the spelled
|
|
49
|
+
# "NIST SP 800-90B" form a lookup compares against.
|
|
50
|
+
def series_default_publisher
|
|
51
|
+
"NIST"
|
|
52
|
+
end
|
|
38
53
|
end
|
|
39
54
|
|
|
40
55
|
def series_code
|
data/lib/pubid/nist/router.rb
CHANGED
|
@@ -46,6 +46,17 @@ module Pubid
|
|
|
46
46
|
|
|
47
47
|
series = parsed_hash[:series]&.to_s
|
|
48
48
|
|
|
49
|
+
# The default-series plain-number branch (pubid#711): the grammar's
|
|
50
|
+
# trailing alternatives accept a bare report number ("800-90B") and
|
|
51
|
+
# its publisher-led spelling ("NIST 800-90B") with NO series token.
|
|
52
|
+
# The SP series is the default: the docid-derived citation of
|
|
53
|
+
# NIST.SP.800-90B is exactly the bare docnumber "800-90B", and the
|
|
54
|
+
# Builder fills the same SP series the spelled form carries, so the
|
|
55
|
+
# two spellings are one identity to a lookup. No other branch can
|
|
56
|
+
# arrive here series-less (dated shapes returned above; every
|
|
57
|
+
# series-bearing branch captures :series).
|
|
58
|
+
return Identifiers::SpecialPublication if series.nil?
|
|
59
|
+
|
|
49
60
|
# Handle compound series that include publisher (both space and dot separated)
|
|
50
61
|
if series&.start_with?("NBS ")
|
|
51
62
|
simple_series = series.sub("NBS ", "")
|
data/lib/pubid/version.rb
CHANGED
data/lib/pubid.rb
CHANGED
|
@@ -224,6 +224,10 @@ module Pubid
|
|
|
224
224
|
autoload :Ashrae, "pubid/ashrae"
|
|
225
225
|
autoload :Asme, "pubid/asme"
|
|
226
226
|
autoload :Doi, "pubid/doi"
|
|
227
|
+
# The PFS-compiled dev alias of doi (pubid/pubid#706): registered
|
|
228
|
+
# beside the coded flavor, never routed by Pubid.parse (registry keys
|
|
229
|
+
# sort "doi" first).
|
|
230
|
+
autoload :DoiPfs, "pubid/doi_pfs"
|
|
227
231
|
autoload :Easc, "pubid/easc"
|
|
228
232
|
autoload :Astm, "pubid/astm"
|
|
229
233
|
autoload :Bipm, "pubid/bipm"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -97,6 +97,7 @@ files:
|
|
|
97
97
|
- data/parg/cie.json
|
|
98
98
|
- data/parg/csa.json
|
|
99
99
|
- data/parg/doi.json
|
|
100
|
+
- data/parg/doi_pfs.json
|
|
100
101
|
- data/parg/easc.json
|
|
101
102
|
- data/parg/ecma.json
|
|
102
103
|
- data/parg/etsi.json
|
|
@@ -470,6 +471,16 @@ files:
|
|
|
470
471
|
- lib/pubid/doi/parser.rb
|
|
471
472
|
- lib/pubid/doi/pubid_urn_schema.rb
|
|
472
473
|
- lib/pubid/doi/renderer.rb
|
|
474
|
+
- lib/pubid/doi_pfs.rb
|
|
475
|
+
- lib/pubid/doi_pfs/CLAUDE.md
|
|
476
|
+
- lib/pubid/doi_pfs/builder.rb
|
|
477
|
+
- lib/pubid/doi_pfs/identifier.rb
|
|
478
|
+
- lib/pubid/doi_pfs/identifiers.rb
|
|
479
|
+
- lib/pubid/doi_pfs/identifiers/resource.rb
|
|
480
|
+
- lib/pubid/doi_pfs/parser.rb
|
|
481
|
+
- lib/pubid/doi_pfs/pubid_urn_schema.rb
|
|
482
|
+
- lib/pubid/doi_pfs/renderer.rb
|
|
483
|
+
- lib/pubid/doi_pfs/urn_generator.rb
|
|
473
484
|
- lib/pubid/easc.rb
|
|
474
485
|
- lib/pubid/easc/builder.rb
|
|
475
486
|
- lib/pubid/easc/identifier.rb
|