@pubid/pubid 0.1.4 → 0.1.5
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.
- package/artifact/corpus.json.gz +0 -0
- package/dist/flavors/gb/index.d.ts +8 -1
- package/dist/flavors/gb/index.js +55 -7
- package/dist/flavors/ieee/grammar.js +77 -6
- package/dist/flavors/ieee/index.js +76 -4
- package/dist/flavors/ieee/model.d.ts +2 -0
- package/dist/flavors/ieee/model.js +101 -12
- package/dist/flavors/ieee/update_codes.js +10 -4
- package/dist/flavors/oiml/grammar.js +29 -3
- package/dist/flavors/oiml/implementation.js +30 -1
- package/dist/flavors/oiml/model.d.ts +19 -0
- package/dist/flavors/oiml/model.js +133 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/model/identifier.d.ts +1 -0
- package/dist/model/identifier.js +1 -1
- package/package.json +1 -1
package/artifact/corpus.json.gz
CHANGED
|
Binary file
|
|
@@ -18,7 +18,14 @@ export declare class GbIdentifier extends BaseIdentifier {
|
|
|
18
18
|
readonly number: string;
|
|
19
19
|
readonly part: string | undefined;
|
|
20
20
|
readonly date: PubidDate | undefined;
|
|
21
|
-
readonly all_parts: boolean | undefined;
|
|
22
21
|
render(): string;
|
|
23
22
|
}
|
|
23
|
+
export declare class GbAllPartsIdentifier extends BaseIdentifier {
|
|
24
|
+
static polymorphicName: string;
|
|
25
|
+
static get attributes(): import("../../model/attribute.js").AttributeTable;
|
|
26
|
+
static get mappings(): never[];
|
|
27
|
+
readonly identifiers: GbIdentifier[];
|
|
28
|
+
render(): string;
|
|
29
|
+
toUrn(): string;
|
|
30
|
+
}
|
|
24
31
|
export declare function gbGrammarImplementation(): FlavorImplementation;
|
package/dist/flavors/gb/index.js
CHANGED
|
@@ -53,9 +53,17 @@ export class GbIdentifier extends BaseIdentifier {
|
|
|
53
53
|
mandate: { type: "string" },
|
|
54
54
|
number: { type: "string" },
|
|
55
55
|
part: { type: "string" },
|
|
56
|
-
all_parts: { type: "boolean", default: false },
|
|
57
56
|
});
|
|
58
|
-
static mappings = keyValue({
|
|
57
|
+
static mappings = keyValue({
|
|
58
|
+
wire: "publisher",
|
|
59
|
+
to: "publisher",
|
|
60
|
+
// The flat wire form is the Publisher's body scalar; rebuild the
|
|
61
|
+
// component on deserialize (lutaml coerces it on the Ruby side).
|
|
62
|
+
fromWire: (hash) => {
|
|
63
|
+
const value = hash["publisher"];
|
|
64
|
+
return typeof value === "string" ? new Publisher({ body: value }) : value;
|
|
65
|
+
},
|
|
66
|
+
}, { wire: "mandate", to: "mandate" }, { wire: "number", to: "number" }, { wire: "part", to: "part" }, { wire: "date", to: "date" });
|
|
59
67
|
// GB's flat-scalar entry: the Publisher serializes as its body scalar.
|
|
60
68
|
static flatScalarComponents = { publisher: "publisher" };
|
|
61
69
|
static flatScalarFields = { publisher: "body" };
|
|
@@ -68,17 +76,56 @@ export class GbIdentifier extends BaseIdentifier {
|
|
|
68
76
|
numberPortion += `.${this.part}`;
|
|
69
77
|
if (this.date !== undefined && this.date.year !== undefined)
|
|
70
78
|
numberPortion += `-${this.date.year}`;
|
|
71
|
-
|
|
72
|
-
if (this.all_parts)
|
|
73
|
-
result += " (all parts)";
|
|
74
|
-
return result;
|
|
79
|
+
return `${code} ${numberPortion}`;
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
registerType(GbIdentifier);
|
|
83
|
+
// The document a member names: without its part and its edition (the
|
|
84
|
+
// attributes an all-parts reference ignores).
|
|
85
|
+
function gbDocumentOf(member) {
|
|
86
|
+
const r = member;
|
|
87
|
+
return new GbIdentifier({
|
|
88
|
+
publisher: r["publisher"],
|
|
89
|
+
mandate: r["mandate"],
|
|
90
|
+
number: r["number"],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// "GB/T 5606 (all parts)" names every part of one document: the wrapper
|
|
94
|
+
// holds the member identifiers (gem #433 - the mark is a class, not a
|
|
95
|
+
// flag), renders the document plus the suffix, and URNs as the document.
|
|
96
|
+
export class GbAllPartsIdentifier extends BaseIdentifier {
|
|
97
|
+
static polymorphicName = "pubid:gb:all-parts";
|
|
98
|
+
static get attributes() {
|
|
99
|
+
return extendAttributes(BaseIdentifier, {
|
|
100
|
+
identifiers: { type: GbIdentifier, collection: true },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
static get mappings() {
|
|
104
|
+
return [{ wire: "identifiers", to: "identifiers" }];
|
|
105
|
+
}
|
|
106
|
+
render() {
|
|
107
|
+
const first = this.identifiers[0];
|
|
108
|
+
return `${first === undefined ? "" : gbDocumentOf(first).render()} (all parts)`;
|
|
109
|
+
}
|
|
110
|
+
toUrn() {
|
|
111
|
+
const first = this.identifiers[0];
|
|
112
|
+
return gbDocumentOf(first).toUrn();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
registerType(GbAllPartsIdentifier);
|
|
78
116
|
class GbBuilder extends BaseBuilder {
|
|
79
117
|
defaultIdentifierClass() {
|
|
80
118
|
return GbIdentifier;
|
|
81
119
|
}
|
|
120
|
+
build(tree) {
|
|
121
|
+
const id = super.build(tree);
|
|
122
|
+
if (tree["all_parts"] === undefined)
|
|
123
|
+
return id;
|
|
124
|
+
// "(all parts)" wraps the document it parsed.
|
|
125
|
+
return new GbAllPartsIdentifier({
|
|
126
|
+
identifiers: [id],
|
|
127
|
+
});
|
|
128
|
+
}
|
|
82
129
|
cast(key, value) {
|
|
83
130
|
if (key === "publisher_code") {
|
|
84
131
|
// Split an inline /T or /Z mandate out of the code.
|
|
@@ -92,7 +139,8 @@ class GbBuilder extends BaseBuilder {
|
|
|
92
139
|
return value === undefined || value === null ? null : { date: new PubidDate({ year: String(value) }) };
|
|
93
140
|
}
|
|
94
141
|
if (key === "all_parts") {
|
|
95
|
-
|
|
142
|
+
// Presence marker only: the wrapper carries the members.
|
|
143
|
+
return value;
|
|
96
144
|
}
|
|
97
145
|
return value;
|
|
98
146
|
}
|
|
@@ -42,6 +42,10 @@ function buildRules() {
|
|
|
42
42
|
const dashMaybe = () => dash.maybe();
|
|
43
43
|
const monthName = () => literalAlternation(MONTHS);
|
|
44
44
|
const absent = (p) => p.absent();
|
|
45
|
+
// The ISO/IEC draft-stage vocabulary of the D= notation
|
|
46
|
+
// (docs/IEEE-DRAFT-STAGES.md §1.2). Ordered so the longest token wins
|
|
47
|
+
// ("FDIS" over "DIS").
|
|
48
|
+
const stageVocab = () => literalAlternation(["FDIS", "CDV", "PWI", "DIS", "WD", "NP", "CD"]);
|
|
45
49
|
rule("year_digits", () => str("19").or(str("20")).then(digit.repeat(2, 2)).then(lower.repeat(0, 2)).then(absent(digits)));
|
|
46
50
|
rule("month_numeric", () => str("0").then(match("[1-9]")).or(str("1").then(match("[0-2]"))));
|
|
47
51
|
rule("date_with_month_text", () => monthName().as("month").then(space).then(R("year_digits").as("year")));
|
|
@@ -128,6 +132,16 @@ function buildRules() {
|
|
|
128
132
|
rule("draft", () => (ref(rules, "draft_prefix")
|
|
129
133
|
.then(ref(rules, "draft_version").repeat(1, 2))
|
|
130
134
|
.then(dot.then(digits.as("revision")).maybe())
|
|
135
|
+
.then(
|
|
136
|
+
// The compound both-systems form (docs/IEEE-DRAFT-STAGES.md
|
|
137
|
+
// §1.3): "=DDIS.3" - IEEE draft ordinal = draft of the ISO/IEC
|
|
138
|
+
// stage, with its iteration. The glued "=DDIS3" / "=DDIS-3"
|
|
139
|
+
// spellings are accepted aliases of "=DDIS.3".
|
|
140
|
+
str("=")
|
|
141
|
+
.then(str("D").then(stageVocab().as("draft_iso_stage"))
|
|
142
|
+
.or(stageVocab().as("draft_iso_stage")))
|
|
143
|
+
.then((dot.or(dash)).maybe().then(digits.as("draft_iso_iteration")).maybe())
|
|
144
|
+
.maybe())
|
|
131
145
|
.then(ref(rules, "draft_date").maybe())).as("draft"));
|
|
132
146
|
rule("revision_suffix", () => slash.then(str("R")).then(dash).then(match("[0-9A-Za-z]").repeat(1, Infinity).as("revision")));
|
|
133
147
|
rule("edition", () => (comma.then(R("year_digits").as("edition_year")).then(str(" Edition"))).or(space.or(dash)
|
|
@@ -230,13 +244,38 @@ function buildRules() {
|
|
|
230
244
|
.then(match("[^\\n]").repeat(1, Infinity).as("content")));
|
|
231
245
|
rule("joint_development_ieee_format", () => literalAlternation(["ISO/IEC/IEEE", "ISO/IEEE", "IEC/IEEE", "IEEE/CSA"]).as("joint_publishers")
|
|
232
246
|
.then(space)
|
|
233
|
-
|
|
247
|
+
// P = project (the document is a draft): identity-bearing, so it
|
|
248
|
+
// is captured and preserved, never silently consumed.
|
|
249
|
+
.then(str("P").as("project_marker"))
|
|
234
250
|
.then(digits.as("number"))
|
|
235
251
|
.then((dot.or(dash)).then(digits.as("part")).maybe())
|
|
236
252
|
.then(slash.then(digits).then(dot.then(digits).maybe())
|
|
237
253
|
.then(dash.then(digits.as("draft_version")).maybe()).maybe())
|
|
238
|
-
.then(
|
|
239
|
-
|
|
254
|
+
.then(
|
|
255
|
+
// Variant 1b: the ordinal-less stage draft "D=CDV[:2020]" -
|
|
256
|
+
// D (draft) = CDV (the IEC stage it drafts). The year rides in
|
|
257
|
+
// the draft clause (a distinct key, so the builder keeps the
|
|
258
|
+
// date inside the designator).
|
|
259
|
+
slash.then(str("D")).then(str("="))
|
|
260
|
+
.then(stageVocab().as("draft_iso_stage"))
|
|
261
|
+
.then(str(":").then(R("year_digits").as("draft_stage_year")).maybe())
|
|
262
|
+
.or(
|
|
263
|
+
// Variant 1: /D8 notation (original), with the compound
|
|
264
|
+
// both-systems suffix "=DDIS.3" (docs/IEEE-DRAFT-STAGES.md
|
|
265
|
+
// §1.3). The doubled-D spelling is consumed and echoed: the
|
|
266
|
+
// joint form prints the stage as spelled.
|
|
267
|
+
slash.then(str("D")).then(digits.as("draft_version"))
|
|
268
|
+
.then(str("=")
|
|
269
|
+
.then(str("D").as("draft_stage_d").then(stageVocab().as("draft_iso_stage"))
|
|
270
|
+
.or(stageVocab().as("draft_iso_stage")))
|
|
271
|
+
.then((dot.or(dash)).maybe().then(digits.as("draft_iso_iteration")).maybe())
|
|
272
|
+
.maybe()))
|
|
273
|
+
.or(
|
|
274
|
+
// Variant 2: , CDV1 notation (comma before stage code) —
|
|
275
|
+
// the stage draft of the named ISO/IEC stage, its iteration
|
|
276
|
+
comma.then(literalAlternation(["CDV", "FDIS", "CD", "DIS"]).as("iec_stage"))
|
|
277
|
+
.then(digits.maybe().as("stage_iteration")))
|
|
278
|
+
.maybe())
|
|
240
279
|
.then(ref(rules, "edition").maybe())
|
|
241
280
|
.then((dash.then(R("year_digits").as("year"))).or(comma.maybe().then(space).then(monthName().as("month")).then(spaceMaybe())
|
|
242
281
|
.then(R("year_digits").as("year"))).maybe())
|
|
@@ -270,14 +309,27 @@ function buildRules() {
|
|
|
270
309
|
.then(isoStage().then(stdNoise()).then(space)
|
|
271
310
|
.or(str("").as("iso_published").then(spaceMaybe())))
|
|
272
311
|
.or(stagedOnly.as("joint_publishers").then(space).then(isoStage()).then(stdNoise()).then(space)))
|
|
273
|
-
.then(str("P").maybe())
|
|
312
|
+
.then(str("P").as("project_marker").maybe())
|
|
274
313
|
.then(digits.as("number"))
|
|
275
314
|
.then((dot.then(absent(R("year_digits"))).then(digits.as("part")))
|
|
276
315
|
.or(dash.then(str("").as("part_dash")).then(absent(R("year_digits")))
|
|
277
316
|
.then(digits.as("part")))
|
|
278
317
|
.maybe())
|
|
279
318
|
.then(dateClause())
|
|
280
|
-
.then(
|
|
319
|
+
.then(
|
|
320
|
+
// The ISO/IEC edition marker may sit between the year and an
|
|
321
|
+
// amendment/draft tail ("8802.11:2012 (E)/Amd 1-2014").
|
|
322
|
+
(spaceMaybe().then(str("("))
|
|
323
|
+
.then(match("[^)]").repeat(1, Infinity).as("edition_marker"))
|
|
324
|
+
.then(str(")"))).maybe())
|
|
325
|
+
.then(
|
|
326
|
+
// The stage-draft clause of the ISO-led print: "/D=WD.5" - D
|
|
327
|
+
// (draft) = the ISO/IEC stage it drafts, with its iteration
|
|
328
|
+
// (docs/IEEE-DRAFT-STAGES.md §1.2).
|
|
329
|
+
(slash.then(str("D")).then(str("="))
|
|
330
|
+
.then(stageVocab().as("draft_iso_stage"))
|
|
331
|
+
.then(dot.then(digits.then(match("[A-Za-z]").repeat(0, 1)).as("draft_iso_iteration")).maybe()))
|
|
332
|
+
.or(slash.then(str("D")).then(dashMaybe())
|
|
281
333
|
.then(match("[0-9.]").repeat(1, Infinity).as("draft_version"))
|
|
282
334
|
.then(((comma.or(space)).then(monthName().as("draft_month")).then(space)
|
|
283
335
|
.then(R("year_digits").as("draft_year"))).or(comma.then(R("year_digits").as("draft_year"))).maybe())).maybe())
|
|
@@ -288,12 +340,30 @@ function buildRules() {
|
|
|
288
340
|
.then(ref(rules, "revision_suffix").maybe())
|
|
289
341
|
.then(ref(rules, "parenthetical").maybe());
|
|
290
342
|
});
|
|
343
|
+
// The stage-less ISO/IEC label with a colon year and the ISO/IEC
|
|
344
|
+
// edition marker: "ISO/IEC 13210:1994 (E)" - the ISO/IEC portion of a
|
|
345
|
+
// double-labeled standard. The (E) parenthetical is REQUIRED: without it
|
|
346
|
+
// this spelling is the ISO flavor's own form and must not be stolen.
|
|
347
|
+
rule("joint_development_iso_iec_edition", () => str("ISO/IEC").as("joint_publishers")
|
|
348
|
+
.then(space)
|
|
349
|
+
.then(str("").as("iso_published"))
|
|
350
|
+
.then(str("P").as("project_marker").maybe())
|
|
351
|
+
.then(digits.as("number"))
|
|
352
|
+
// The part may be dot- or dash-joined ("8802-9"); a dash-year is
|
|
353
|
+
// not a part. A distinct key: the iso-format route's part_dash
|
|
354
|
+
// prints as a dot in the joint code; only the label keeps its dash.
|
|
355
|
+
.then((dot.then(digits.as("part")))
|
|
356
|
+
.or(dash.then(str("").as("iec_label_dash")).then(absent(R("year_digits"))).then(digits.as("part")))
|
|
357
|
+
.maybe())
|
|
358
|
+
.then(str(":").then(spaceMaybe()).then(R("year_digits").as("year")))
|
|
359
|
+
.then(spaceMaybe())
|
|
360
|
+
.then(ref(rules, "parenthetical")));
|
|
291
361
|
rule("joint_development_embedded_stage", () => literalAlternation([
|
|
292
362
|
"ISO/IEC/IEEE", "IEEE/ISO/IEC", "IEEE/IEC/ISO", "ISO/IEEE",
|
|
293
363
|
"IEC/IEEE", "IEEE/IEC", "ISO/IEC", "IEEE",
|
|
294
364
|
]).as("joint_publishers")
|
|
295
365
|
.then(space)
|
|
296
|
-
.then(str("P").maybe())
|
|
366
|
+
.then(str("P").as("project_marker").maybe())
|
|
297
367
|
.then(digits.as("number"))
|
|
298
368
|
.then((dot.or(dash)).then(absent(R("year_digits"))).then(digits.as("part")).maybe())
|
|
299
369
|
.then(dot)
|
|
@@ -577,6 +647,7 @@ function buildRules() {
|
|
|
577
647
|
.or(ref(rules, "conformance_identifier"))
|
|
578
648
|
.or(ref(rules, "joint_development_ieee_format"))
|
|
579
649
|
.or(ref(rules, "joint_development_iso_format"))
|
|
650
|
+
.or(ref(rules, "joint_development_iso_iec_edition"))
|
|
580
651
|
.or(ref(rules, "joint_development_embedded_stage"))
|
|
581
652
|
.or(ref(rules, "iec_ieee_copublished"))
|
|
582
653
|
.or(ref(rules, "number_first_identifier"))
|
|
@@ -121,6 +121,10 @@ class IeeeBuilder {
|
|
|
121
121
|
attributes["parts"] = codeObj.parts;
|
|
122
122
|
if (codeObj?.originalSeparator !== undefined)
|
|
123
123
|
attributes["separator"] = codeObj.originalSeparator;
|
|
124
|
+
// P = project (the document is a draft): the marker is
|
|
125
|
+
// identity-bearing, so stripping the letter must not strip the
|
|
126
|
+
// fact (docs/IEEE-DRAFT-STAGES.md §1.1).
|
|
127
|
+
attributes["project_marker"] = true;
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
delete attributes["__code"];
|
|
@@ -298,11 +302,23 @@ class IeeeBuilder {
|
|
|
298
302
|
return attributes;
|
|
299
303
|
}
|
|
300
304
|
determineStageAbbr(typeValue, parsed) {
|
|
305
|
+
// An explicit joint stage on the draft ("=DFDIS.3") IS the stage —
|
|
306
|
+
// it outranks the ordinal ladder, which classifies IEEE-internal
|
|
307
|
+
// drafts only (docs/IEEE-DRAFT-STAGES.md §1.3).
|
|
301
308
|
if (parsed["draft"] !== undefined) {
|
|
302
309
|
let draftData = parsed["draft"];
|
|
303
310
|
if (Array.isArray(draftData)) {
|
|
304
311
|
draftData = mergeParsedArray(draftData);
|
|
305
312
|
}
|
|
313
|
+
if (isObj(draftData) && draftData["draft_iso_stage"] !== undefined) {
|
|
314
|
+
const stage = extractValue(draftData["draft_iso_stage"]) ?? "";
|
|
315
|
+
// The doubled-D alias ("DFDIS") carries its own draft marker;
|
|
316
|
+
// the stage is what remains.
|
|
317
|
+
const rest = stage.slice(1);
|
|
318
|
+
return stage.startsWith("D") && ["PWI", "NP", "WD", "CD", "CDV", "DIS", "FDIS"].includes(rest)
|
|
319
|
+
? rest
|
|
320
|
+
: stage;
|
|
321
|
+
}
|
|
306
322
|
if (isObj(draftData) && draftData["draft_version"] !== undefined) {
|
|
307
323
|
const dv = draftData["draft_version"];
|
|
308
324
|
const version = Array.isArray(dv) ? dv.map((v) => extractValue(v) ?? "").join("") : extractValue(dv);
|
|
@@ -343,6 +359,8 @@ class IeeeBuilder {
|
|
|
343
359
|
}
|
|
344
360
|
let version;
|
|
345
361
|
let revision;
|
|
362
|
+
let isoStage;
|
|
363
|
+
let isoIteration;
|
|
346
364
|
let month;
|
|
347
365
|
let year;
|
|
348
366
|
let day;
|
|
@@ -355,6 +373,8 @@ class IeeeBuilder {
|
|
|
355
373
|
version = version.replace(/^-/, "");
|
|
356
374
|
}
|
|
357
375
|
revision = extractValue(draftData["revision"]);
|
|
376
|
+
isoStage = extractValue(draftData["draft_iso_stage"]);
|
|
377
|
+
isoIteration = extractValue(draftData["draft_iso_iteration"]);
|
|
358
378
|
month = extractValue(draftData["month"]);
|
|
359
379
|
year = extractValue(draftData["year"]);
|
|
360
380
|
day = extractValue(draftData["day"]);
|
|
@@ -370,10 +390,12 @@ class IeeeBuilder {
|
|
|
370
390
|
else {
|
|
371
391
|
version = extractValue(draftData);
|
|
372
392
|
}
|
|
373
|
-
if (version !== undefined) {
|
|
393
|
+
if (version !== undefined || (isObj(draftData) && draftData["draft_iso_stage"] !== undefined)) {
|
|
374
394
|
const draftObj = new IeeeDraft({
|
|
375
395
|
version,
|
|
376
396
|
revision,
|
|
397
|
+
iso_stage: isoStage,
|
|
398
|
+
iso_iteration: isoIteration,
|
|
377
399
|
month,
|
|
378
400
|
year,
|
|
379
401
|
day,
|
|
@@ -601,7 +623,14 @@ class IeeeBuilder {
|
|
|
601
623
|
codeParts.push(extractValue(parsed["part"]) ?? "");
|
|
602
624
|
let codeStr = extractValue(parsed["number"]);
|
|
603
625
|
if (codeStr !== undefined && codeParts.length > 0) {
|
|
604
|
-
|
|
626
|
+
// The ISO/IEC label's part may be dash-joined ("8802-9") - keep the
|
|
627
|
+
// printed separator.
|
|
628
|
+
const sep = parsed["iec_label_dash"] !== undefined ? "-" : ".";
|
|
629
|
+
codeStr += `${sep}${codeParts.join(sep)}`;
|
|
630
|
+
}
|
|
631
|
+
// P = project (a draft): identity-bearing, preserved as spelled.
|
|
632
|
+
if (parsed["project_marker"] !== undefined && codeStr !== undefined) {
|
|
633
|
+
codeStr = `P${codeStr}`;
|
|
605
634
|
}
|
|
606
635
|
if (codeStr !== undefined) {
|
|
607
636
|
const codeObj = IeeeCode.parse(codeStr);
|
|
@@ -639,6 +668,37 @@ class IeeeBuilder {
|
|
|
639
668
|
if (draftVer !== "")
|
|
640
669
|
attributes["ieee_draft"] = `D${draftVer}`;
|
|
641
670
|
}
|
|
671
|
+
// The "(E)" edition marker of an ISO/IEC label rides on the joint
|
|
672
|
+
// reference as parenthetical_content - either from the trailing
|
|
673
|
+
// parenthetical slot (the double-label form) or the mid-rule slot
|
|
674
|
+
// before an amendment tail.
|
|
675
|
+
const parenthetical = parsed["parameters"];
|
|
676
|
+
if (parenthetical !== undefined && typeof parenthetical === "object" && !Array.isArray(parenthetical)) {
|
|
677
|
+
const content = parenthetical["parenthetical_content"];
|
|
678
|
+
if (content !== undefined)
|
|
679
|
+
attributes["parenthetical_content"] = extractValue(content);
|
|
680
|
+
}
|
|
681
|
+
if (attributes["parenthetical_content"] === undefined && parsed["edition_marker"] !== undefined) {
|
|
682
|
+
attributes["parenthetical_content"] = extractValue(parsed["edition_marker"]);
|
|
683
|
+
}
|
|
684
|
+
// The joint stage-draft clause (docs/IEEE-DRAFT-STAGES.md §1.3):
|
|
685
|
+
// variant 1's compound tail composes onto the IEEE ordinal
|
|
686
|
+
// ("D5=DIS.3"); variant 1b is the ordinal-less stage draft whose
|
|
687
|
+
// date rides inside the designator ("D=CDV:2020"). The doubled-D
|
|
688
|
+
// alias spelling echoes as spelled.
|
|
689
|
+
if (parsed["draft_iso_stage"] !== undefined) {
|
|
690
|
+
const stageText = `${extractValue(parsed["draft_stage_d"]) ?? ""}${extractValue(parsed["draft_iso_stage"]) ?? ""}`;
|
|
691
|
+
let jointDraft = parsed["draft_version"] !== undefined
|
|
692
|
+
? `D${(extractValue(parsed["draft_version"]) ?? "").replace(/^D/, "")}=${stageText}`
|
|
693
|
+
: `D=${stageText}`;
|
|
694
|
+
if (parsed["draft_iso_iteration"] !== undefined) {
|
|
695
|
+
jointDraft += `.${extractValue(parsed["draft_iso_iteration"])}`;
|
|
696
|
+
}
|
|
697
|
+
if (parsed["draft_stage_year"] !== undefined) {
|
|
698
|
+
jointDraft += `:${extractValue(parsed["draft_stage_year"])}`;
|
|
699
|
+
}
|
|
700
|
+
attributes["ieee_draft"] = jointDraft;
|
|
701
|
+
}
|
|
642
702
|
// The catalogue-PRINTED joint form (dash-year / ", Month YYYY" /
|
|
643
703
|
// date-trailing-the-draft / date-less parenthetical): a Standard
|
|
644
704
|
// carrying publisher/copublisher renders it as printed; the colon-year
|
|
@@ -654,8 +714,11 @@ class IeeeBuilder {
|
|
|
654
714
|
typeof parsed["parameters"] === "object" && !Array.isArray(parsed["parameters"]) &&
|
|
655
715
|
parsed["parameters"]["parenthetical_content"] !== undefined))) {
|
|
656
716
|
const sep = parsed["part_dash"] !== undefined ? "-" : ".";
|
|
657
|
-
|
|
717
|
+
let printedCode = [extractValue(parsed["number"]), extractValue(parsed["part"])]
|
|
658
718
|
.filter((x) => x !== undefined).join(sep);
|
|
719
|
+
// P = project: the marker is identity, preserved as spelled.
|
|
720
|
+
if (parsed["project_marker"] !== undefined)
|
|
721
|
+
printedCode = `P${printedCode}`;
|
|
659
722
|
const printedAttrs = {
|
|
660
723
|
publisher: attributes["publisher"],
|
|
661
724
|
copublisher: attributes["copublisher"],
|
|
@@ -1022,7 +1085,16 @@ function copublishedStructured(copublishedNumber) {
|
|
|
1022
1085
|
}
|
|
1023
1086
|
// --- parse orchestration -------------------------------------------------------
|
|
1024
1087
|
function ieeeParseSingle(input) {
|
|
1025
|
-
const
|
|
1088
|
+
const normalized = applyUpdateCodes(input);
|
|
1089
|
+
// UpdateCodes may introduce the "; " double-label separator (the
|
|
1090
|
+
// ISO/IEC and IEEE labels of one document), but the dispatch ran on
|
|
1091
|
+
// the raw input - re-dispatch so the dual construction sees it.
|
|
1092
|
+
if (normalized !== input && normalized.includes("; ")) {
|
|
1093
|
+
const re = preParse(normalized);
|
|
1094
|
+
if (re.dispatch === "dual_semicolon")
|
|
1095
|
+
return buildDual(re.parts);
|
|
1096
|
+
}
|
|
1097
|
+
const cleaned = preprocessIeee(normalized);
|
|
1026
1098
|
const tree = parseGrammar(ieeeGrammar, cleaned);
|
|
1027
1099
|
const builder = new IeeeBuilder();
|
|
1028
1100
|
builder.originalInput = input;
|
|
@@ -43,6 +43,8 @@ export declare class IeeeCode {
|
|
|
43
43
|
export declare class IeeeDraft {
|
|
44
44
|
readonly version: string;
|
|
45
45
|
readonly revision: string | undefined;
|
|
46
|
+
readonly isoStage: string | undefined;
|
|
47
|
+
readonly isoIteration: string | undefined;
|
|
46
48
|
readonly year: string | undefined;
|
|
47
49
|
readonly month: string | undefined;
|
|
48
50
|
readonly day: string | undefined;
|
|
@@ -126,6 +126,8 @@ const DRAFT_MONTH_NAMES = {
|
|
|
126
126
|
export class IeeeDraft {
|
|
127
127
|
version;
|
|
128
128
|
revision;
|
|
129
|
+
isoStage;
|
|
130
|
+
isoIteration;
|
|
129
131
|
year;
|
|
130
132
|
month;
|
|
131
133
|
day;
|
|
@@ -137,6 +139,8 @@ export class IeeeDraft {
|
|
|
137
139
|
this.commaBeforeMonthSet = "comma_before_month" in attrs;
|
|
138
140
|
this.version = String(attrs["version"] ?? "");
|
|
139
141
|
this.revision = attrs["revision"];
|
|
142
|
+
this.isoStage = attrs["iso_stage"];
|
|
143
|
+
this.isoIteration = attrs["iso_iteration"];
|
|
140
144
|
this.year = attrs["year"];
|
|
141
145
|
this.originalMonth = attrs["month"];
|
|
142
146
|
this.month = attrs["month"] !== undefined
|
|
@@ -155,24 +159,45 @@ export class IeeeDraft {
|
|
|
155
159
|
body = body.slice(1);
|
|
156
160
|
else if (body.startsWith("D") && body.length > 1)
|
|
157
161
|
body = body.slice(1);
|
|
162
|
+
// The compound stage suffix (docs/IEEE-DRAFT-STAGES.md §1.3):
|
|
163
|
+
// "=DIS.3" is canonical - D (draft) = DIS (the stage), iteration 3.
|
|
164
|
+
// "=DDIS.3", "=DDIS3", "=DDIS-3" (the stage echoed with its own D)
|
|
165
|
+
// are accepted aliases. Captures [stage, iteration].
|
|
166
|
+
const compound = /=D?(PWI|NP|WD|CDV|FDIS|DIS|CD)(?:[.-]?(\d+))?$/;
|
|
167
|
+
let isoStage;
|
|
168
|
+
let isoIteration;
|
|
169
|
+
const cm = compound.exec(body);
|
|
170
|
+
if (cm !== null) {
|
|
171
|
+
isoStage = cm[1];
|
|
172
|
+
isoIteration = cm[2];
|
|
173
|
+
body = body.slice(0, cm.index);
|
|
174
|
+
}
|
|
158
175
|
const monthAlt = Object.keys(DRAFT_MONTH_NAMES)
|
|
159
176
|
.sort((a, b) => b.length - a.length)
|
|
160
177
|
.map((m) => `${m.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.?`)
|
|
161
178
|
.join("|");
|
|
162
179
|
const suffix = new RegExp(`(?:(, | )(${monthAlt})(?: (\\d{1,2}))?(?:, | )| )((?:19|20)\\d{2}[a-z]{0,2})$`);
|
|
163
180
|
const m = suffix.exec(body);
|
|
164
|
-
if (m === null)
|
|
165
|
-
return new IeeeDraft({ version: body });
|
|
181
|
+
if (m === null) {
|
|
182
|
+
return new IeeeDraft({ version: body, iso_stage: isoStage, iso_iteration: isoIteration });
|
|
183
|
+
}
|
|
166
184
|
return new IeeeDraft({
|
|
167
185
|
version: body.slice(0, m.index),
|
|
168
186
|
month: m[2],
|
|
169
187
|
day: m[3],
|
|
170
188
|
year: m[4],
|
|
171
189
|
comma_before_month: m[1] === ", ",
|
|
190
|
+
iso_stage: isoStage,
|
|
191
|
+
iso_iteration: isoIteration,
|
|
172
192
|
});
|
|
173
193
|
}
|
|
174
194
|
render() {
|
|
175
195
|
let result = `/D${this.version}`;
|
|
196
|
+
if (this.isoStage !== undefined)
|
|
197
|
+
result += `=${this.isoStage}`;
|
|
198
|
+
if (this.isoStage !== undefined && this.isoIteration !== undefined) {
|
|
199
|
+
result += `.${this.isoIteration}`;
|
|
200
|
+
}
|
|
176
201
|
if (this.revision !== undefined)
|
|
177
202
|
result += `.${this.revision}`;
|
|
178
203
|
if (this.year !== undefined) {
|
|
@@ -432,10 +457,14 @@ export function renderIeeeBase(id) {
|
|
|
432
457
|
const iecIeeOnly = id.publisher === "IEC" && JSON.stringify(id.copublisher) === '["IEEE"]';
|
|
433
458
|
if (codeObj !== undefined) {
|
|
434
459
|
let result = codeObj.render();
|
|
435
|
-
//
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (stageObj?.projectStatus === true && shouldRenderType
|
|
460
|
+
// Prepend P if this is a project AND code doesn't already have P.
|
|
461
|
+
// A recorded project marker (the source spelled the P on a
|
|
462
|
+
// non-IEEE-led publisher) prints regardless of the publisher.
|
|
463
|
+
if ((stageObj?.projectStatus === true && shouldRenderType ||
|
|
464
|
+
id.constructor.polymorphicName ===
|
|
465
|
+
"pubid:ieee:project-draft-identifier" &&
|
|
466
|
+
id["project_marker"] === true) &&
|
|
467
|
+
!result.startsWith("P")) {
|
|
439
468
|
result = `P${result}`;
|
|
440
469
|
}
|
|
441
470
|
if (id.year !== undefined && draftObj === undefined && id.edition === undefined && id.month === undefined) {
|
|
@@ -560,6 +589,12 @@ class IeeeUrnGenerator extends BaseUrnGenerator {
|
|
|
560
589
|
return SPECIAL_URN_OF(this.identifier);
|
|
561
590
|
}
|
|
562
591
|
publisherComponent() {
|
|
592
|
+
// The IEC/IEEE co-published pair is definitional to the class and
|
|
593
|
+
// was previously lost ("urn:ieee:ieee" — no number, no draft).
|
|
594
|
+
if (this.identifier.constructor.polymorphicName ===
|
|
595
|
+
"pubid:ieee:iec-ieee-copublished") {
|
|
596
|
+
return "iec-ieee";
|
|
597
|
+
}
|
|
563
598
|
// Supplements delegate #publisher/#copublisher to their base (Ruby
|
|
564
599
|
// SupplementIdentifier); DualPublished derives publisher from BOTH
|
|
565
600
|
// members; MultiNumbered derives it from its primary.
|
|
@@ -589,12 +624,35 @@ class IeeeUrnGenerator extends BaseUrnGenerator {
|
|
|
589
624
|
return pub;
|
|
590
625
|
}
|
|
591
626
|
typeComponent() {
|
|
627
|
+
// A joint stage draft carries the stage in its draft clause and the
|
|
628
|
+
// project P inside the code — a separate type segment would
|
|
629
|
+
// duplicate both.
|
|
630
|
+
const jointDraft = this.identifier["ieee_draft"];
|
|
631
|
+
if (jointDraft !== undefined && jointDraft.startsWith("D="))
|
|
632
|
+
return undefined;
|
|
592
633
|
const type = this.identifier.type;
|
|
593
634
|
if (type === undefined || type.trim() === "" || type === "Std")
|
|
594
635
|
return undefined;
|
|
595
636
|
return type.toLowerCase().replaceAll(" ", ".");
|
|
596
637
|
}
|
|
597
638
|
codeComponent() {
|
|
639
|
+
const id = this.identifier;
|
|
640
|
+
// The co-published code is number+parts+separators (no year — its
|
|
641
|
+
// own segment), e.g. "61886-1".
|
|
642
|
+
if (id.constructor.polymorphicName ===
|
|
643
|
+
"pubid:ieee:iec-ieee-copublished") {
|
|
644
|
+
const self = id;
|
|
645
|
+
const number = self["number"];
|
|
646
|
+
if (number === undefined || number === "")
|
|
647
|
+
return undefined;
|
|
648
|
+
const parts = self["parts"] ?? [];
|
|
649
|
+
const separators = self["separators"] ?? [];
|
|
650
|
+
let code = number;
|
|
651
|
+
separators.forEach((sep, i) => {
|
|
652
|
+
code += `${sep}${parts[i] ?? ""}`;
|
|
653
|
+
});
|
|
654
|
+
return code;
|
|
655
|
+
}
|
|
598
656
|
// Wrappers delegate code_obj to the identifier they wrap (Ruby
|
|
599
657
|
// AdoptedStandard/CsaDualPublished/MultiNumberedIdentifier).
|
|
600
658
|
const self = this.identifier;
|
|
@@ -615,6 +673,17 @@ class IeeeUrnGenerator extends BaseUrnGenerator {
|
|
|
615
673
|
return root === id ? undefined : root.yearForUrn();
|
|
616
674
|
}
|
|
617
675
|
draftComponent() {
|
|
676
|
+
// The joint stage draft's stage rides in its ieee_draft clause
|
|
677
|
+
// ("D=CDV[:2020]"), emitted directly as the draft segment.
|
|
678
|
+
const jointDraft = this.identifier["ieee_draft"];
|
|
679
|
+
if (jointDraft !== undefined && jointDraft.startsWith("D="))
|
|
680
|
+
return `draft.${jointDraft}`;
|
|
681
|
+
const draftInfo = this.identifier["draft_info"];
|
|
682
|
+
if (draftInfo !== undefined &&
|
|
683
|
+
this.identifier.constructor.polymorphicName ===
|
|
684
|
+
"pubid:ieee:iec-ieee-copublished") {
|
|
685
|
+
return draftInfo === "" ? undefined : `draft.${draftInfo}`;
|
|
686
|
+
}
|
|
618
687
|
const draftObj = this.identifier.draftObject();
|
|
619
688
|
return draftObj === undefined ? undefined : `draft.${draftObj.render()}`;
|
|
620
689
|
}
|
|
@@ -738,7 +807,13 @@ export const SupplementBaseDefs = {
|
|
|
738
807
|
base: { type: IeeeIdentifier },
|
|
739
808
|
};
|
|
740
809
|
export const StandardClass = ieeeClass({ kind: "standard" }, { codeColumns: true });
|
|
741
|
-
export const ProjectDraftIdentifierClass = ieeeClass({ kind: "project-draft-identifier" }, {
|
|
810
|
+
export const ProjectDraftIdentifierClass = ieeeClass({ kind: "project-draft-identifier" }, {
|
|
811
|
+
codeColumns: true,
|
|
812
|
+
extraDefs: {
|
|
813
|
+
project_marker: { type: "boolean", default: false },
|
|
814
|
+
},
|
|
815
|
+
extraMappings: keyValue({ wire: "project_marker", to: "project_marker" }),
|
|
816
|
+
});
|
|
742
817
|
export const SiStandardClass = ieeeClass({ kind: "si-standard" }, {
|
|
743
818
|
codeColumns: true,
|
|
744
819
|
specialUrn: "si",
|
|
@@ -940,8 +1015,9 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
940
1015
|
lead_party: { type: "string" },
|
|
941
1016
|
iso_stage: { type: "string" },
|
|
942
1017
|
ieee_draft: { type: "string" },
|
|
1018
|
+
parenthetical_content: { type: "string" },
|
|
943
1019
|
},
|
|
944
|
-
extraMappings: keyValue({ wire: "publishers", to: "publishers" }, { wire: "lead_party", to: "lead_party" }, { wire: "iso_stage", to: "iso_stage" }, { wire: "ieee_draft", to: "ieee_draft" }),
|
|
1020
|
+
extraMappings: keyValue({ wire: "publishers", to: "publishers" }, { wire: "lead_party", to: "lead_party" }, { wire: "iso_stage", to: "iso_stage" }, { wire: "ieee_draft", to: "ieee_draft" }, { wire: "parenthetical_content", to: "parenthetical_content" }),
|
|
945
1021
|
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
946
1022
|
render: (id) => {
|
|
947
1023
|
const publishers = id["publishers"];
|
|
@@ -951,6 +1027,9 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
951
1027
|
const codeObj = id.codeObj;
|
|
952
1028
|
// ISO-led renders the ISO format ALWAYS (the stage-less published
|
|
953
1029
|
// form "ISO/IEC/IEEE 12207.2:2020" prints colon-year, no stage).
|
|
1030
|
+
// IEEE semantics: P = project (a draft); no P = a standard. The
|
|
1031
|
+
// P-state is identity-bearing and prints as spelled - it is never
|
|
1032
|
+
// added or stripped here.
|
|
954
1033
|
if (leadParty === "ISO") {
|
|
955
1034
|
const parts = [];
|
|
956
1035
|
if (publishers !== undefined && publishers.length > 0)
|
|
@@ -961,21 +1040,31 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
961
1040
|
else if (isoStage !== undefined) {
|
|
962
1041
|
parts.push(isoStage);
|
|
963
1042
|
}
|
|
964
|
-
|
|
1043
|
+
const codeStr = codeObj?.render() ?? "";
|
|
965
1044
|
if (codeStr !== "")
|
|
966
1045
|
parts.push(codeStr);
|
|
967
1046
|
let result = parts.join(" ");
|
|
968
1047
|
if (id.year !== undefined)
|
|
969
1048
|
result += `:${id.year}`;
|
|
1049
|
+
// The joint stage-draft clause ("D=WD.5") rides after the year in
|
|
1050
|
+
// the ISO-led print; only the bare language/edition marker ("(E)")
|
|
1051
|
+
// prints - a relationship narrative is metadata, not identity.
|
|
1052
|
+
const jointDraft = id["ieee_draft"];
|
|
1053
|
+
if (jointDraft !== undefined && jointDraft.startsWith("D="))
|
|
1054
|
+
result += `/${jointDraft}`;
|
|
1055
|
+
const marker = id["parenthetical_content"];
|
|
1056
|
+
if (marker !== undefined && /^[A-Z](?:\s*[/&]\s*[A-Z])*$/.test(marker)) {
|
|
1057
|
+
result += ` (${marker})`;
|
|
1058
|
+
}
|
|
970
1059
|
return result;
|
|
971
1060
|
}
|
|
972
1061
|
// IEEE format
|
|
973
1062
|
const parts = [];
|
|
974
1063
|
if (publishers !== undefined && publishers.length > 0)
|
|
975
1064
|
parts.push(publishers.join("/"));
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1065
|
+
// The P-state prints as spelled (P = project draft; no P =
|
|
1066
|
+
// standard). Never added or stripped.
|
|
1067
|
+
let codeStr = codeObj?.render() ?? "";
|
|
979
1068
|
if (ieeeDraft !== undefined)
|
|
980
1069
|
codeStr += `/${ieeeDraft}`;
|
|
981
1070
|
else if (id.typed_stage?.ieeeDraftEquivalent !== undefined) {
|
|
@@ -110,15 +110,21 @@ export const UPDATE_CODES = [
|
|
|
110
110
|
{ plain: "ISO/IEC/IEEE/P16085_DIS, March 2020", replacement: "ISO/IEC/IEEE DIS P16085-2020-03" },
|
|
111
111
|
{ plain: "ANSI/IEEE Std: Outdoor Apparatus Bushings", replacement: "ANSI/IEEE Std 21-1976-11" },
|
|
112
112
|
{ plain: "Draft National Electrical Safety Code, January 2016", replacement: "IEEE PC2-2016-01" },
|
|
113
|
-
{ plain: "International Standard ISO/IEC 8802-9: 1996(E) ANSI/IEEE Std 802.9, 1996 Edition", replacement: "ISO/IEC/IEEE Std 802.9
|
|
114
|
-
{ plain: "ISO/IEC13210: 1994 (E) ANSI/IEEE Std 1003.3-1991", replacement: "ISO/IEC/IEEE
|
|
113
|
+
{ plain: "International Standard ISO/IEC 8802-9: 1996(E) ANSI/IEEE Std 802.9, 1996 Edition", replacement: "ISO/IEC 8802-9:1996(E); ANSI/IEEE Std 802.9, 1996 Edition" },
|
|
114
|
+
{ plain: "ISO/IEC13210: 1994 (E) ANSI/IEEE Std 1003.3-1991", replacement: "ISO/IEC 13210:1994 (E); ANSI/IEEE Std 1003.3-1991" },
|
|
115
115
|
{ plain: "J-STD-016-1995", replacement: "IEEE 016-1995" },
|
|
116
116
|
{ plain: "Nuclear EQ Sourcebook and Supplement", replacement: "IEEE 7438946" },
|
|
117
117
|
{ plain: "PC37.30.2/D043 Rev 18, May 2015", replacement: "IEEE PC37.30-2/D-043/R-18-2015" },
|
|
118
118
|
{ plain: "IEEE/IEC P62582 CD2 proposal, May 2017", replacement: "IEEE/IEC CD2 P62582-2017-05" },
|
|
119
|
-
{ plain: "ISO/IEC/IEEE P16326:201x WD.4a, July 2017", replacement: "ISO/IEC/IEEE P16326/D
|
|
119
|
+
{ plain: "ISO/IEC/IEEE P16326:201x WD.4a, July 2017", replacement: "ISO/IEC/IEEE P16326:2017/D=WD.4a" },
|
|
120
120
|
{ plain: "ISO/IEC/IEEE CD.1 P21839, October 2017", replacement: "ISO/IEC/IEEE CD1 P21839-2017-10" },
|
|
121
|
-
{ plain: "ISO/IEC/IEEE P16326:201x WD5, December 2017", replacement: "ISO/IEC/IEEE P16326/D
|
|
121
|
+
{ plain: "ISO/IEC/IEEE P16326:201x WD5, December 2017", replacement: "ISO/IEC/IEEE P16326:2017/D=WD.5" },
|
|
122
|
+
// The joint-publisher underscore drafts ("ISO /IEC/IEEE P24774_D1,
|
|
123
|
+
// February 2020") are the slash spellings ("/D1") of rows the ledger
|
|
124
|
+
// already pins as project drafts; the underscore form parsed through
|
|
125
|
+
// the printed-joint family and flipped the classification (pubid#430).
|
|
126
|
+
{ pattern: "\\b(ISO ?\\/ ?IEC ?\\/ ?IEEE|IEC ?\\/ ?IEEE) (P\\d+)_D(\\d+), ([A-Z][a-z]+.?) (\\d{4})\\b", replacement: "\\1 \\2/D\\3, \\4, \\5" },
|
|
127
|
+
{ pattern: "\\b(ISO ?\\/ ?IEC ?\\/ ?IEEE|IEC ?\\/ ?IEEE) (P\\d+)_D(\\d+)\\b", replacement: "\\1 \\2/D\\3" },
|
|
122
128
|
{ plain: "IEEE/ISO/IEC P42010.CD1-V1.0, April 2020", replacement: "IEEE/ISO/IEC CD1 P42010-2020-04" },
|
|
123
129
|
{ plain: "Unapproved Draft Std ISO/IEC FDIS 15288:2007(E) IEEE P15288/D3,", replacement: "ISO/IEC/IEEE FDIS Std P15288/D-3-2007" },
|
|
124
130
|
{ plain: "IS0/IEC/IEEE 8802-11:2012/Amd.5:2015(E) (Adoption of IEEE Std 802.11af-2014)", replacement: "ISO/IEC/IEEE 802.11/Amd5-2012" },
|
|
@@ -47,12 +47,15 @@ function buildRules() {
|
|
|
47
47
|
.or(ref(rules, "annex_identifier"))
|
|
48
48
|
.or(ref(rules, "plus_supplement_identifier"))
|
|
49
49
|
.or(ref(rules, "trailing_supplement_identifier"))
|
|
50
|
+
.or(ref(rules, "cs_identifier"))
|
|
50
51
|
.or(ref(rules, "bulletin_identifier"))
|
|
51
52
|
.or(ref(rules, "base")));
|
|
52
53
|
// Publisher - always "OIML"
|
|
53
54
|
rule("publisher", () => str("OIML").as("publisher").then(ref(rules, "space")));
|
|
54
|
-
// Document type - single letter
|
|
55
|
-
|
|
55
|
+
// Document type - single letter. Strict family set: OIML publishes
|
|
56
|
+
// R D B G E V S documents (the estate grammar's family letters);
|
|
57
|
+
// any other letter is a rejection, not a flavor.
|
|
58
|
+
rule("doc_type", () => match("[BDEGRSV]").as("type").then(ref(rules, "space")));
|
|
56
59
|
// Bulletin locator - structured YYYY[-II[-SS]]
|
|
57
60
|
rule("bulletin_date", () => ref(rules, "space")
|
|
58
61
|
.then(ref(rules, "year_digits").as("year"))
|
|
@@ -108,9 +111,14 @@ function buildRules() {
|
|
|
108
111
|
rule("lang_single", () => match("[EFRXDSCAU]"));
|
|
109
112
|
rule("lang_multi_oiml", () => str("PO").or(str("PT")).or(str("PE")).or(str("SR")));
|
|
110
113
|
rule("lang_multi", () => match("[a-z]").repeat(2, 2));
|
|
114
|
+
// Full-word language markers as OIML prints them ("(Fra)", "(Eng)"),
|
|
115
|
+
// three or more letters, any case. Kept verbatim on the identifier;
|
|
116
|
+
// the URN lowercases.
|
|
117
|
+
rule("lang_word", () => match("[A-Za-z]").repeat(3));
|
|
111
118
|
rule("language_code", () => ref(rules, "lang_single")
|
|
112
119
|
.then(ref(rules, "slash"), ref(rules, "lang_single"))
|
|
113
120
|
.or(ref(rules, "lang_multi_oiml"))
|
|
121
|
+
.or(ref(rules, "lang_word"))
|
|
114
122
|
.or(ref(rules, "lang_single"))
|
|
115
123
|
.or(ref(rules, "lang_multi"))
|
|
116
124
|
.as("language"));
|
|
@@ -137,7 +145,25 @@ function buildRules() {
|
|
|
137
145
|
rule("trailing_supplement_identifier", () => ref(rules, "base_without_language")
|
|
138
146
|
.as("base")
|
|
139
147
|
.then(str(" "), str("Amendment").or(str("Errata")).as("trailing_marker"))
|
|
140
|
-
.then(ref(rules, "language_portion").maybe().as("language")));
|
|
148
|
+
.then(str(" ").then(ref(rules, "digits").as("number")).maybe(), ref(rules, "language_portion").maybe().as("language")));
|
|
149
|
+
// OIML-CS certification-system documents. Two head spellings
|
|
150
|
+
// ("OIML-CS" / "OIML CS") and two family-number separators
|
|
151
|
+
// ("PD-05" / "PD 05"), an "Edition N" instead of a year, and an
|
|
152
|
+
// optional parenthesized trailing amendment - "(Amendment 1)".
|
|
153
|
+
rule("cs_identifier", () => str("OIML")
|
|
154
|
+
.as("publisher")
|
|
155
|
+
.then(ref(rules, "dash")
|
|
156
|
+
.then(str("CS"))
|
|
157
|
+
.or(str(" ").then(str("CS")))
|
|
158
|
+
.as("cs_series"))
|
|
159
|
+
.then(ref(rules, "space"))
|
|
160
|
+
.then(str("PD").or(str("OD")).or(str("CID")).as("cs_family"))
|
|
161
|
+
.then(ref(rules, "dash").or(str(" ")).as("cs_separator"))
|
|
162
|
+
.then(ref(rules, "digits").as("number"))
|
|
163
|
+
.then(str(" "), str("Edition"), str(" "), ref(rules, "digits").as("edition"))
|
|
164
|
+
.then(str(" ")
|
|
165
|
+
.then(ref(rules, "lparen"), str("Amendment"), str(" "), ref(rules, "digits").as("cs_amendment"), ref(rules, "rparen"))
|
|
166
|
+
.maybe()));
|
|
141
167
|
rule("plus_supplement_identifier", () => ref(rules, "base_without_language")
|
|
142
168
|
.as("base")
|
|
143
169
|
.then(str("+"), str("Amendment").or(str("Errata")).as("plus_marker"))
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { ParseFailed, parseGrammar } from "../../grammar/engine.js";
|
|
2
2
|
import { oimlGrammar } from "./grammar.js";
|
|
3
|
-
import { buildOimlIdentifier } from "./model.js";
|
|
3
|
+
import { buildOimlIdentifier, OimlDualPublished } from "./model.js";
|
|
4
|
+
import { grammarImplementation } from "../index.js";
|
|
5
|
+
// The co-publisher prefix (only ISO confirmed so far; the gem routes via
|
|
6
|
+
// Pubid.parse's prefix table).
|
|
7
|
+
function flavorOf(input) {
|
|
8
|
+
return input.toUpperCase().startsWith("ISO ") ? "iso" : "iso";
|
|
9
|
+
}
|
|
4
10
|
/**
|
|
5
11
|
* Grammar-backed OIML on the unified model: the model classes are
|
|
6
12
|
* BaseIdentifier subclasses, so they satisfy the Identifier adapter
|
|
@@ -9,6 +15,29 @@ import { buildOimlIdentifier } from "./model.js";
|
|
|
9
15
|
export function oimlGrammarImplementation() {
|
|
10
16
|
return {
|
|
11
17
|
parse(input) {
|
|
18
|
+
// The co-published form carries both identifiers joined by "|":
|
|
19
|
+
// "ISO 4064-1:2024|OIML R 49-1:2024". The first side is another
|
|
20
|
+
// flavor's identifier (routed by prefix, the Ruby Pubid.parse
|
|
21
|
+
// counterpart); the second is the OIML side.
|
|
22
|
+
if (input.includes("|") && !input.startsWith("|") && !input.endsWith("|")) {
|
|
23
|
+
// Each side may be either flavor ("ISO …|OIML R …" and the
|
|
24
|
+
// reversed print): the OIML side parses through this grammar, the
|
|
25
|
+
// co-publisher's through its own (routed by prefix).
|
|
26
|
+
const parts = input.split("|");
|
|
27
|
+
const members = parts.map((part) => {
|
|
28
|
+
const s = part.trim();
|
|
29
|
+
if (s.toUpperCase().startsWith("OIML")) {
|
|
30
|
+
return buildOimlIdentifier(parseGrammar(oimlGrammar, s));
|
|
31
|
+
}
|
|
32
|
+
const impl = grammarImplementation(flavorOf(s));
|
|
33
|
+
if (impl === undefined)
|
|
34
|
+
throw new ParseFailed(`OIML: no flavor for ${s}`, 0);
|
|
35
|
+
return impl.parse(s);
|
|
36
|
+
});
|
|
37
|
+
if (members.length === 2 && members[0] !== undefined && members[1] !== undefined) {
|
|
38
|
+
return new OimlDualPublished({ first: members[0], second: members[1] });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
12
41
|
return buildOimlIdentifier(parseGrammar(oimlGrammar, input));
|
|
13
42
|
},
|
|
14
43
|
};
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import type { Tree } from "../../grammar/engine.js";
|
|
2
2
|
import { BaseIdentifier } from "../../model/identifier.js";
|
|
3
|
+
import type { AttributeTable } from "../../model/attribute.js";
|
|
4
|
+
declare abstract class OimlBase extends BaseIdentifier {
|
|
5
|
+
readonly publisher: string | undefined;
|
|
6
|
+
readonly language: string | undefined;
|
|
7
|
+
readonly parsed_format: string | undefined;
|
|
8
|
+
effectiveFormat(): "long" | "short";
|
|
9
|
+
}
|
|
3
10
|
/** ---- builder (lib/pubid/oiml/builder.rb) ---- */
|
|
11
|
+
export declare class OimlDualPublished extends OimlBase {
|
|
12
|
+
static polymorphicName: string;
|
|
13
|
+
static get attributes(): AttributeTable;
|
|
14
|
+
static get mappings(): never[];
|
|
15
|
+
readonly first: BaseIdentifier;
|
|
16
|
+
readonly second: BaseIdentifier;
|
|
17
|
+
constructor(attrs?: Record<string, unknown>);
|
|
18
|
+
render(): string;
|
|
19
|
+
toUrn(): string;
|
|
20
|
+
root(): BaseIdentifier;
|
|
21
|
+
}
|
|
4
22
|
export declare function buildOimlIdentifier(tree: Tree): BaseIdentifier;
|
|
23
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ParseFailed } from "../../grammar/engine.js";
|
|
2
|
-
import { BaseIdentifier, registerType } from "../../model/identifier.js";
|
|
2
|
+
import { BaseIdentifier, registerType, resolveType } from "../../model/identifier.js";
|
|
3
3
|
import { extendAttributes, keyValue } from "../../model/attribute.js";
|
|
4
4
|
import { BaseUrnGenerator } from "../../model/urn-generator.js";
|
|
5
5
|
const KIND_BY_TYPE = {
|
|
@@ -13,6 +13,7 @@ const KIND_BY_TYPE = {
|
|
|
13
13
|
};
|
|
14
14
|
const TYPE_STRINGS = {
|
|
15
15
|
"basic-publication": "B",
|
|
16
|
+
"certification-system": "CS",
|
|
16
17
|
document: "D",
|
|
17
18
|
"expert-report": "E",
|
|
18
19
|
guide: "G",
|
|
@@ -108,6 +109,29 @@ class OimlSingle extends OimlBase {
|
|
|
108
109
|
return result;
|
|
109
110
|
}
|
|
110
111
|
}
|
|
112
|
+
/** ---- OIML-CS certification-system documents ---- */
|
|
113
|
+
const CS_ATTRS = {
|
|
114
|
+
...SINGLE_ATTRS,
|
|
115
|
+
family: { type: "string" },
|
|
116
|
+
amendment: { type: "string" },
|
|
117
|
+
space_separator: { type: "boolean", default: false },
|
|
118
|
+
};
|
|
119
|
+
const CS_MAPPINGS = keyValue(...Object.keys(CS_ATTRS).map((name) => ({ wire: name, to: name })));
|
|
120
|
+
// "OIML-CS PD-05 Edition 6 (Amendment 1)": the number keeps its printed
|
|
121
|
+
// zero padding; the print states an edition instead of a year.
|
|
122
|
+
class OimlCertificationSystem extends OimlSingle {
|
|
123
|
+
static polymorphicName = "pubid:oiml:certification-system";
|
|
124
|
+
static attributes = extendAttributes(BaseIdentifier, CS_ATTRS);
|
|
125
|
+
static mappings = CS_MAPPINGS;
|
|
126
|
+
render() {
|
|
127
|
+
let result = `${this.publisher}-CS ${this.family}` +
|
|
128
|
+
`${this.space_separator ? " " : "-"}${this.number} Edition ${this.edition}`;
|
|
129
|
+
if (this.amendment)
|
|
130
|
+
result += ` (Amendment ${this.amendment})`;
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
registerType(OimlCertificationSystem);
|
|
111
135
|
function oimlSingleClass(kind) {
|
|
112
136
|
const isBulletin = kind === "bulletin";
|
|
113
137
|
class OimlSingleIdentifier extends OimlSingle {
|
|
@@ -146,12 +170,13 @@ const SUPP_ATTRS = {
|
|
|
146
170
|
parsed_format: { type: "string", default: "short" },
|
|
147
171
|
base: { type: OimlSingle },
|
|
148
172
|
supp_year: { type: "string" },
|
|
173
|
+
number: { type: "string" },
|
|
149
174
|
trailing: { type: "boolean", default: false },
|
|
150
175
|
joined: { type: "boolean", default: false },
|
|
151
176
|
letter: { type: "string" },
|
|
152
177
|
year_on_base: { type: "boolean", default: false },
|
|
153
178
|
};
|
|
154
|
-
const SUPP_MAPPINGS = keyValue({ wire: "language", to: "language" }, { wire: "parsed_format", to: "parsed_format" }, { wire: "base", to: "base" }, { wire: "year", to: "supp_year" }, { wire: "trailing", to: "trailing" }, { wire: "joined", to: "joined" }, { wire: "letter", to: "letter" }, { wire: "year_on_base", to: "year_on_base" });
|
|
179
|
+
const SUPP_MAPPINGS = keyValue({ wire: "language", to: "language" }, { wire: "parsed_format", to: "parsed_format" }, { wire: "base", to: "base" }, { wire: "year", to: "supp_year" }, { wire: "number", to: "number" }, { wire: "trailing", to: "trailing" }, { wire: "joined", to: "joined" }, { wire: "letter", to: "letter" }, { wire: "year_on_base", to: "year_on_base" });
|
|
155
180
|
/** ---- supplements (Amendment / Errata) and Annex ---- */
|
|
156
181
|
class OimlSupplement extends OimlBase {
|
|
157
182
|
supplementType() {
|
|
@@ -178,6 +203,8 @@ class OimlSupplement extends OimlBase {
|
|
|
178
203
|
}
|
|
179
204
|
if (this.trailing) {
|
|
180
205
|
let result = `${stripLanguage(this.base.render())} ${this.supplementType()}`;
|
|
206
|
+
if (this.number)
|
|
207
|
+
result += ` ${this.number}`;
|
|
181
208
|
if (this.language)
|
|
182
209
|
result += ` (${this.language})`;
|
|
183
210
|
return result;
|
|
@@ -247,6 +274,7 @@ for (const kind of [
|
|
|
247
274
|
]) {
|
|
248
275
|
KIND_CLASSES[kind] = oimlSingleClass(kind);
|
|
249
276
|
}
|
|
277
|
+
KIND_CLASSES["certification-system"] = OimlCertificationSystem;
|
|
250
278
|
KIND_CLASSES["amendment"] = oimlSupplementClass("amendment");
|
|
251
279
|
KIND_CLASSES["errata"] = oimlSupplementClass("errata");
|
|
252
280
|
KIND_CLASSES["annex"] = oimlSupplementClass("annex");
|
|
@@ -270,6 +298,13 @@ class OimlUrnGenerator extends BaseUrnGenerator {
|
|
|
270
298
|
parts.push(id.language.toLowerCase());
|
|
271
299
|
return parts.join(":");
|
|
272
300
|
}
|
|
301
|
+
// Certification-system documents: the family-number pair is the
|
|
302
|
+
// document identity ("cs:pd-05"); the printed edition and trailing
|
|
303
|
+
// amendment are print states, not URN segments.
|
|
304
|
+
if (kind === "certification-system") {
|
|
305
|
+
const cs = id;
|
|
306
|
+
return ["urn", "oiml", "cs", `${(cs.family ?? "").toLowerCase()}-${cs.number ?? ""}`].join(":");
|
|
307
|
+
}
|
|
273
308
|
const isSupp = kind === "amendment" || kind === "errata" || kind === "annex";
|
|
274
309
|
const single = (isSupp ? id.base : id);
|
|
275
310
|
const parts = ["urn", "oiml"];
|
|
@@ -280,8 +315,12 @@ class OimlUrnGenerator extends BaseUrnGenerator {
|
|
|
280
315
|
const code = single.composedCode();
|
|
281
316
|
if (code)
|
|
282
317
|
parts.push(code);
|
|
318
|
+
// The trailing-word form keeps the publication year on the base
|
|
319
|
+
// ("R 138:2009 Amendment 1"); the supplement itself carries only the
|
|
320
|
+
// ordinal.
|
|
283
321
|
const year = id.year ??
|
|
284
|
-
id.supp_year
|
|
322
|
+
id.supp_year ??
|
|
323
|
+
(isSupp ? single.year : undefined);
|
|
285
324
|
if (year)
|
|
286
325
|
parts.push(year);
|
|
287
326
|
const stage = id.stage;
|
|
@@ -292,6 +331,12 @@ class OimlUrnGenerator extends BaseUrnGenerator {
|
|
|
292
331
|
parts.push(iteration);
|
|
293
332
|
if (id.language)
|
|
294
333
|
parts.push(id.language.toLowerCase());
|
|
334
|
+
// Ruby's supplement branch appends the ordinal after the language.
|
|
335
|
+
if (isSupp) {
|
|
336
|
+
const ordinal = id.number;
|
|
337
|
+
if (ordinal)
|
|
338
|
+
parts.push(ordinal);
|
|
339
|
+
}
|
|
295
340
|
return parts.join(":");
|
|
296
341
|
}
|
|
297
342
|
}
|
|
@@ -299,15 +344,97 @@ for (const klass of Object.values(KIND_CLASSES)) {
|
|
|
299
344
|
klass.urnGenerator = OimlUrnGenerator;
|
|
300
345
|
}
|
|
301
346
|
/** ---- builder (lib/pubid/oiml/builder.rb) ---- */
|
|
347
|
+
// OIML co-publishes some documents jointly with another SDO (ISO so
|
|
348
|
+
// far); the printed reference carries both identifiers joined by "|":
|
|
349
|
+
// "ISO 4064-1:2024|OIML R 49-1:2024". The URN is the OIML side's.
|
|
350
|
+
export class OimlDualPublished extends OimlBase {
|
|
351
|
+
static polymorphicName = "pubid:oiml:dual-published";
|
|
352
|
+
static get attributes() {
|
|
353
|
+
return extendAttributes(OimlBase, {
|
|
354
|
+
// "string" keeps objects passing through the scalar coercion
|
|
355
|
+
// untouched (the ieee AdoptedStandard precedent for cross-flavor
|
|
356
|
+
// members); the constructor coerces bare hashes via the registry.
|
|
357
|
+
first: { type: "string" },
|
|
358
|
+
second: { type: "string" },
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
static get mappings() {
|
|
362
|
+
return [
|
|
363
|
+
{ wire: "first", to: "first" },
|
|
364
|
+
{ wire: "second", to: "second" },
|
|
365
|
+
];
|
|
366
|
+
}
|
|
367
|
+
constructor(attrs = {}) {
|
|
368
|
+
super(attrs);
|
|
369
|
+
// The members are cross-flavor (the co-publisher's side arrives as a
|
|
370
|
+
// bare hash with _type); coerce through the registry - the abstract
|
|
371
|
+
// BaseIdentifier attribute type cannot dispatch polymorphically.
|
|
372
|
+
const coerceMember = (v) => {
|
|
373
|
+
if (v instanceof BaseIdentifier)
|
|
374
|
+
return v;
|
|
375
|
+
if (typeof v === "object" && v !== null && "_type" in v) {
|
|
376
|
+
const klass = resolveType(v["_type"]);
|
|
377
|
+
if (klass !== undefined) {
|
|
378
|
+
return klass.fromHash(v);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return undefined;
|
|
382
|
+
};
|
|
383
|
+
const self = this;
|
|
384
|
+
const f = coerceMember(self["first"]);
|
|
385
|
+
const s = coerceMember(self["second"]);
|
|
386
|
+
if (f !== undefined)
|
|
387
|
+
self["first"] = f;
|
|
388
|
+
if (s !== undefined)
|
|
389
|
+
self["second"] = s;
|
|
390
|
+
}
|
|
391
|
+
render() {
|
|
392
|
+
return `${this.first.toHuman()}|${this.second.toHuman()}`;
|
|
393
|
+
}
|
|
394
|
+
toUrn() {
|
|
395
|
+
// The URN is the OIML side's, whichever position it prints in.
|
|
396
|
+
const oimlSide = this.second instanceof OimlBase ? this.second : this.first;
|
|
397
|
+
return oimlSide.toUrn();
|
|
398
|
+
}
|
|
399
|
+
root() {
|
|
400
|
+
return this.second instanceof OimlBase ? this.second : this.first;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
registerType(OimlDualPublished);
|
|
302
404
|
export function buildOimlIdentifier(tree) {
|
|
303
405
|
if (!isObj(tree))
|
|
304
406
|
throw new ParseFailed("OIML: unexpected parse tree", 0);
|
|
407
|
+
if (tree["cs_series"] !== undefined)
|
|
408
|
+
return buildCs(tree);
|
|
305
409
|
if (tree["amd_marker"] !== undefined)
|
|
306
410
|
return buildShortAmendment(tree);
|
|
307
411
|
if (tree["base"] !== undefined)
|
|
308
412
|
return buildSupplement(tree);
|
|
309
413
|
return buildBaseDocument(tree);
|
|
310
414
|
}
|
|
415
|
+
// OIML-CS documents: family (PD/OD/CID), zero-padded number, the
|
|
416
|
+
// printed "Edition N", and an optional parenthesized trailing
|
|
417
|
+
// amendment. The family-number separator is a spelling flag.
|
|
418
|
+
function buildCs(tree) {
|
|
419
|
+
const attrs = {
|
|
420
|
+
publisher: str(tree["publisher"]) ?? "OIML",
|
|
421
|
+
parsed_format: "short",
|
|
422
|
+
};
|
|
423
|
+
const family = str(tree["cs_family"]);
|
|
424
|
+
if (family !== undefined)
|
|
425
|
+
attrs["family"] = family;
|
|
426
|
+
const number = str(tree["number"]);
|
|
427
|
+
if (number !== undefined)
|
|
428
|
+
attrs["number"] = number;
|
|
429
|
+
const edition = str(tree["edition"]);
|
|
430
|
+
if (edition !== undefined)
|
|
431
|
+
attrs["edition"] = edition;
|
|
432
|
+
const amendment = str(tree["cs_amendment"]);
|
|
433
|
+
if (amendment !== undefined)
|
|
434
|
+
attrs["amendment"] = amendment;
|
|
435
|
+
attrs["space_separator"] = tree["cs_separator"] === " ";
|
|
436
|
+
return new KIND_CLASSES["certification-system"](attrs);
|
|
437
|
+
}
|
|
311
438
|
function buildShortAmendment(tree) {
|
|
312
439
|
const baseCode = isObj(tree["base_code"]) ? tree["base_code"] : undefined;
|
|
313
440
|
const base = buildBaseDocument({
|
|
@@ -359,6 +486,9 @@ function buildSupplement(tree) {
|
|
|
359
486
|
const language = extractLanguage(tree["language"]);
|
|
360
487
|
if (language !== undefined)
|
|
361
488
|
attrs["language"] = language;
|
|
489
|
+
const ordinal = str(tree["number"]);
|
|
490
|
+
if (ordinal !== undefined)
|
|
491
|
+
attrs["number"] = ordinal;
|
|
362
492
|
if (marker !== undefined)
|
|
363
493
|
attrs["trailing"] = true;
|
|
364
494
|
if (plusMarker !== undefined)
|
package/dist/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export type { FlavorImplementation, Identifier, ImplementationRegistry } from ".
|
|
|
6
6
|
export { PendingRegistry } from "./conformance/pending.js";
|
|
7
7
|
export { checkCase, runFlavor, runCorpus } from "./conformance/runner.js";
|
|
8
8
|
export { corpusModeImplementation, CorpusBackedIdentifier } from "./implementations/corpus-mode.js";
|
|
9
|
+
export { grammarImplementation } from "./flavors/index.js";
|
package/dist/index.js
CHANGED
|
@@ -4,3 +4,6 @@ export { buildArtifact, loadBundledCorpus, parseArtifact, } from "./corpus/artif
|
|
|
4
4
|
export { PendingRegistry } from "./conformance/pending.js";
|
|
5
5
|
export { checkCase, runFlavor, runCorpus } from "./conformance/runner.js";
|
|
6
6
|
export { corpusModeImplementation, CorpusBackedIdentifier } from "./implementations/corpus-mode.js";
|
|
7
|
+
// Root re-export so consumers needn't deep-import flavor modules
|
|
8
|
+
// (pubid/pubid-ts#63 - the estate serving codec).
|
|
9
|
+
export { grammarImplementation } from "./flavors/index.js";
|
|
@@ -39,6 +39,7 @@ export type UrnGeneratorCtor = new (identifier: BaseIdentifier) => {
|
|
|
39
39
|
};
|
|
40
40
|
/** Register a concrete identifier class under its polymorphic _type (the *_TYPE_MAP role). */
|
|
41
41
|
export declare function registerType(klass: IdentifierStatic): void;
|
|
42
|
+
export declare function resolveType(type: string): IdentifierStatic | undefined;
|
|
42
43
|
export declare abstract class BaseIdentifier {
|
|
43
44
|
static polymorphicName: string;
|
|
44
45
|
/** The human renderer body — the one method every flavor writes. */
|
package/dist/model/identifier.js
CHANGED
|
@@ -25,7 +25,7 @@ const TYPE_REGISTRY = new Map();
|
|
|
25
25
|
export function registerType(klass) {
|
|
26
26
|
TYPE_REGISTRY.set(klass.polymorphicName, klass);
|
|
27
27
|
}
|
|
28
|
-
function resolveType(type) {
|
|
28
|
+
export function resolveType(type) {
|
|
29
29
|
return TYPE_REGISTRY.get(type);
|
|
30
30
|
}
|
|
31
31
|
function isScalarType(t) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubid/pubid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "TypeScript PubID identifiers: resolution, normalization and canonical hashes for every identifier in the pubid-testsuite corpus (41 standards bodies), with a conformance runner mirroring the Ruby reference",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|