@pubid/pubid 0.1.3 → 0.1.4
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/conformance/cli.js +5 -1
- package/dist/flavors/amca/grammar.d.ts +4 -0
- package/dist/flavors/amca/grammar.js +87 -0
- package/dist/flavors/amca/index.d.ts +4 -0
- package/dist/flavors/amca/index.js +76 -0
- package/dist/flavors/amca/model.d.ts +29 -0
- package/dist/flavors/amca/model.js +146 -0
- package/dist/flavors/ansi/index.d.ts +24 -0
- package/dist/flavors/ansi/index.js +147 -0
- package/dist/flavors/api/grammar.d.ts +4 -0
- package/dist/flavors/api/grammar.js +79 -0
- package/dist/flavors/api/index.d.ts +4 -0
- package/dist/flavors/api/index.js +71 -0
- package/dist/flavors/api/model.d.ts +27 -0
- package/dist/flavors/api/model.js +114 -0
- package/dist/flavors/ashrae/grammar.d.ts +2 -0
- package/dist/flavors/ashrae/grammar.js +667 -0
- package/dist/flavors/ashrae/index.d.ts +4 -0
- package/dist/flavors/ashrae/index.js +306 -0
- package/dist/flavors/ashrae/model.d.ts +87 -0
- package/dist/flavors/ashrae/model.js +335 -0
- package/dist/flavors/ashrae/preprocessor.d.ts +7 -0
- package/dist/flavors/ashrae/preprocessor.js +44 -0
- package/dist/flavors/asme/grammar.d.ts +2 -0
- package/dist/flavors/asme/grammar.js +200 -0
- package/dist/flavors/asme/index.d.ts +4 -0
- package/dist/flavors/asme/index.js +138 -0
- package/dist/flavors/asme/model.d.ts +34 -0
- package/dist/flavors/asme/model.js +123 -0
- package/dist/flavors/astm/grammar.d.ts +2 -0
- package/dist/flavors/astm/grammar.js +110 -0
- package/dist/flavors/astm/index.d.ts +2 -0
- package/dist/flavors/astm/index.js +127 -0
- package/dist/flavors/astm/model.d.ts +42 -0
- package/dist/flavors/astm/model.js +263 -0
- package/dist/flavors/bipm/index.d.ts +30 -0
- package/dist/flavors/bipm/index.js +434 -0
- package/dist/flavors/bsi/grammar.d.ts +4 -0
- package/dist/flavors/bsi/grammar.js +535 -0
- package/dist/flavors/bsi/index.d.ts +4 -0
- package/dist/flavors/bsi/index.js +941 -0
- package/dist/flavors/bsi/model.d.ts +127 -0
- package/dist/flavors/bsi/model.js +863 -0
- package/dist/flavors/calconnect/index.d.ts +21 -0
- package/dist/flavors/calconnect/index.js +113 -0
- package/dist/flavors/cen_cenelec/grammar.d.ts +4 -0
- package/dist/flavors/cen_cenelec/grammar.js +107 -0
- package/dist/flavors/cen_cenelec/index.d.ts +5 -0
- package/dist/flavors/cen_cenelec/index.js +263 -0
- package/dist/flavors/cen_cenelec/model.d.ts +45 -0
- package/dist/flavors/cen_cenelec/model.js +490 -0
- package/dist/flavors/cie/grammar.d.ts +5 -0
- package/dist/flavors/cie/grammar.js +127 -0
- package/dist/flavors/cie/index.d.ts +2 -0
- package/dist/flavors/cie/index.js +311 -0
- package/dist/flavors/cie/model.d.ts +122 -0
- package/dist/flavors/cie/model.js +464 -0
- package/dist/flavors/csa/grammar.d.ts +6 -0
- package/dist/flavors/csa/grammar.js +239 -0
- package/dist/flavors/csa/index.d.ts +2 -0
- package/dist/flavors/csa/index.js +634 -0
- package/dist/flavors/csa/model.d.ts +33 -0
- package/dist/flavors/csa/model.js +505 -0
- package/dist/flavors/doi/index.d.ts +13 -0
- package/dist/flavors/doi/index.js +65 -0
- package/dist/flavors/easc/index.d.ts +4 -0
- package/dist/flavors/easc/index.js +107 -0
- package/dist/flavors/ecma/index.d.ts +4 -0
- package/dist/flavors/ecma/index.js +117 -0
- package/dist/flavors/etsi/index.d.ts +14 -0
- package/dist/flavors/etsi/index.js +307 -0
- package/dist/flavors/evs/grammar.d.ts +2 -0
- package/dist/flavors/evs/grammar.js +22 -0
- package/dist/flavors/evs/index.d.ts +2 -0
- package/dist/flavors/evs/index.js +24 -0
- package/dist/flavors/evs/model.d.ts +19 -0
- package/dist/flavors/evs/model.js +36 -0
- package/dist/flavors/gb/index.d.ts +24 -0
- package/dist/flavors/gb/index.js +111 -0
- package/dist/flavors/gost/grammar.d.ts +2 -0
- package/dist/flavors/gost/grammar.js +46 -0
- package/dist/flavors/gost/index.d.ts +2 -0
- package/dist/flavors/gost/index.js +165 -0
- package/dist/flavors/gost/model.d.ts +61 -0
- package/dist/flavors/gost/model.js +147 -0
- package/dist/flavors/gost/prefix_routes.d.ts +15 -0
- package/dist/flavors/gost/prefix_routes.js +192 -0
- package/dist/flavors/iala/index.d.ts +32 -0
- package/dist/flavors/iala/index.js +300 -0
- package/dist/flavors/iana/index.d.ts +19 -0
- package/dist/flavors/iana/index.js +71 -0
- package/dist/flavors/idf/grammar.d.ts +2 -0
- package/dist/flavors/idf/grammar.js +71 -0
- package/dist/flavors/idf/index.d.ts +2 -0
- package/dist/flavors/idf/index.js +100 -0
- package/dist/flavors/idf/model.d.ts +54 -0
- package/dist/flavors/idf/model.js +359 -0
- package/dist/flavors/iec/grammar.d.ts +3 -0
- package/dist/flavors/iec/grammar.js +187 -0
- package/dist/flavors/iec/index.d.ts +4 -0
- package/dist/flavors/iec/index.js +507 -0
- package/dist/flavors/iec/model.d.ts +54 -0
- package/dist/flavors/iec/model.js +437 -0
- package/dist/flavors/ieee/grammar.d.ts +2 -0
- package/dist/flavors/ieee/grammar.js +626 -0
- package/dist/flavors/ieee/index.d.ts +3 -0
- package/dist/flavors/ieee/index.js +1186 -0
- package/dist/flavors/ieee/model.d.ts +142 -0
- package/dist/flavors/ieee/model.js +1148 -0
- package/dist/flavors/ieee/preprocessor.d.ts +8 -0
- package/dist/flavors/ieee/preprocessor.js +410 -0
- package/dist/flavors/ieee/update_codes.d.ts +8 -0
- package/dist/flavors/ieee/update_codes.js +191 -0
- package/dist/flavors/ietf/index.d.ts +30 -0
- package/dist/flavors/ietf/index.js +151 -0
- package/dist/flavors/iho/index.d.ts +4 -0
- package/dist/flavors/iho/index.js +126 -0
- package/dist/flavors/index.d.ts +9 -0
- package/dist/flavors/index.js +136 -0
- package/dist/flavors/isbn/index.d.ts +13 -0
- package/dist/flavors/isbn/index.js +97 -0
- package/dist/flavors/iso/grammar.d.ts +2 -0
- package/dist/flavors/iso/grammar.js +207 -0
- package/dist/flavors/iso/index.d.ts +2 -0
- package/dist/flavors/iso/index.js +343 -0
- package/dist/flavors/iso/model.d.ts +159 -0
- package/dist/flavors/iso/model.js +802 -0
- package/dist/flavors/iso/stages.generated.d.ts +13 -0
- package/dist/flavors/iso/stages.generated.js +391 -0
- package/dist/flavors/itu/grammar.d.ts +4 -0
- package/dist/flavors/itu/grammar.js +205 -0
- package/dist/flavors/itu/index.d.ts +2 -0
- package/dist/flavors/itu/index.js +224 -0
- package/dist/flavors/itu/model.d.ts +184 -0
- package/dist/flavors/itu/model.js +599 -0
- package/dist/flavors/jcgm/index.d.ts +7 -0
- package/dist/flavors/jcgm/index.js +300 -0
- package/dist/flavors/jis/index.d.ts +4 -0
- package/dist/flavors/jis/index.js +267 -0
- package/dist/flavors/nist/grammar.d.ts +2 -0
- package/dist/flavors/nist/grammar.js +287 -0
- package/dist/flavors/nist/index.d.ts +2 -0
- package/dist/flavors/nist/index.js +1244 -0
- package/dist/flavors/nist/model.d.ts +155 -0
- package/dist/flavors/nist/model.js +823 -0
- package/dist/flavors/nist/preprocessor.d.ts +11 -0
- package/dist/flavors/nist/preprocessor.js +281 -0
- package/dist/flavors/oasis/index.d.ts +23 -0
- package/dist/flavors/oasis/index.js +110 -0
- package/dist/flavors/ogc/index.d.ts +20 -0
- package/dist/flavors/ogc/index.js +75 -0
- package/dist/flavors/oiml/grammar.d.ts +2 -0
- package/dist/flavors/oiml/grammar.js +180 -0
- package/dist/flavors/oiml/implementation.d.ts +9 -0
- package/dist/flavors/oiml/implementation.js +16 -0
- package/dist/flavors/oiml/model.d.ts +4 -0
- package/dist/flavors/oiml/model.js +462 -0
- package/dist/flavors/omg/index.d.ts +14 -0
- package/dist/flavors/omg/index.js +73 -0
- package/dist/flavors/plateau/index.d.ts +4 -0
- package/dist/flavors/plateau/index.js +97 -0
- package/dist/flavors/tgpp/index.d.ts +4 -0
- package/dist/flavors/tgpp/index.js +122 -0
- package/dist/flavors/un/index.d.ts +13 -0
- package/dist/flavors/un/index.js +90 -0
- package/dist/flavors/w3c/index.d.ts +14 -0
- package/dist/flavors/w3c/index.js +148 -0
- package/dist/flavors/xsf/index.d.ts +18 -0
- package/dist/flavors/xsf/index.js +65 -0
- package/dist/grammar/engine.d.ts +78 -0
- package/dist/grammar/engine.js +351 -0
- package/dist/model/attribute.d.ts +54 -0
- package/dist/model/attribute.js +53 -0
- package/dist/model/builder.d.ts +39 -0
- package/dist/model/builder.js +124 -0
- package/dist/model/component.d.ts +70 -0
- package/dist/model/component.js +170 -0
- package/dist/model/identifier.d.ts +83 -0
- package/dist/model/identifier.js +270 -0
- package/dist/model/urn-generator.d.ts +27 -0
- package/dist/model/urn-generator.js +91 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1148 @@
|
|
|
1
|
+
import { BaseIdentifier, registerType } from "../../model/identifier.js";
|
|
2
|
+
import { extendAttributes, keyValue } from "../../model/attribute.js";
|
|
3
|
+
import { BaseUrnGenerator } from "../../model/urn-generator.js";
|
|
4
|
+
export const TYPED_STAGES = [
|
|
5
|
+
{ abbr: ["Std"], stage_code: "published", type_code: "standard" },
|
|
6
|
+
{ abbr: ["D1"], stage_code: "working_draft", type_code: "draft", ieee_draft_equivalent: "D1", iso_stage_equivalent: "WD", approval_status: "unapproved", project_status: true },
|
|
7
|
+
{ abbr: ["D2", "D3"], stage_code: "committee_draft", type_code: "draft", ieee_draft_equivalent: "D2-D3", iso_stage_equivalent: "CD", approval_status: "unapproved", project_status: true },
|
|
8
|
+
{ abbr: ["D4", "D5", "D6"], stage_code: "draft_standard", type_code: "draft", ieee_draft_equivalent: "D4-D6", iso_stage_equivalent: "DIS", approval_status: "unapproved", project_status: true },
|
|
9
|
+
{ abbr: ["D7", "D8", "D9"], stage_code: "final_draft", type_code: "draft", ieee_draft_equivalent: "D7-D9", iso_stage_equivalent: "FDIS", approval_status: "approved", project_status: true },
|
|
10
|
+
{ abbr: ["PWI"], stage_code: "preliminary", type_code: "draft", ieee_draft_equivalent: "P", iso_stage_equivalent: "PWI", approval_status: "unapproved", project_status: true },
|
|
11
|
+
{ abbr: ["NP"], stage_code: "new_proposal", type_code: "draft", ieee_draft_equivalent: "P", iso_stage_equivalent: "NP", approval_status: "unapproved", project_status: true },
|
|
12
|
+
{ abbr: ["WD"], stage_code: "working_draft", type_code: "draft", ieee_draft_equivalent: "D1", iso_stage_equivalent: "WD", approval_status: "unapproved", project_status: true },
|
|
13
|
+
{ abbr: ["CD", "CD1", "CD2", "CD3", "CD4"], stage_code: "committee_draft", type_code: "draft", ieee_draft_equivalent: "D2-D3", iso_stage_equivalent: "CD", approval_status: "unapproved", project_status: true },
|
|
14
|
+
{ abbr: ["CDV"], stage_code: "committee_draft_for_vote", type_code: "draft", ieee_draft_equivalent: "D2-D3", iso_stage_equivalent: "CDV", approval_status: "unapproved", project_status: true },
|
|
15
|
+
{ abbr: ["DIS"], stage_code: "draft_international_standard", type_code: "draft", ieee_draft_equivalent: "D5", iso_stage_equivalent: "DIS", approval_status: "unapproved", project_status: true },
|
|
16
|
+
{ abbr: ["FDIS"], stage_code: "final_draft", type_code: "draft", ieee_draft_equivalent: "D8", iso_stage_equivalent: "FDIS", approval_status: "approved", project_status: true },
|
|
17
|
+
{ abbr: ["No", "No."], stage_code: "published", type_code: "standard" },
|
|
18
|
+
{ abbr: ["P"], stage_code: "draft", type_code: "draft", ieee_draft_equivalent: "P", approval_status: "unapproved", project_status: true },
|
|
19
|
+
{ abbr: ["Draft"], stage_code: "draft", type_code: "draft", approval_status: "unapproved", project_status: true },
|
|
20
|
+
];
|
|
21
|
+
const entrySubHash = (ts) => {
|
|
22
|
+
const out = { abbr: ts.abbr, stage_code: ts.stage_code, type_code: ts.type_code };
|
|
23
|
+
if (ts.iso_stage_equivalent !== undefined)
|
|
24
|
+
out["iso_stage_equivalent"] = ts.iso_stage_equivalent;
|
|
25
|
+
if (ts.ieee_draft_equivalent !== undefined)
|
|
26
|
+
out["ieee_draft_equivalent"] = ts.ieee_draft_equivalent;
|
|
27
|
+
if (ts.approval_status !== undefined)
|
|
28
|
+
out["approval_status"] = ts.approval_status;
|
|
29
|
+
if (ts.project_status)
|
|
30
|
+
out["project_status"] = ts.project_status;
|
|
31
|
+
return out;
|
|
32
|
+
};
|
|
33
|
+
const SUB_HASH_FOR = new Map(TYPED_STAGES.map((ts) => [ts.abbr[0], entrySubHash(ts)]));
|
|
34
|
+
export function locateStage(abbr) {
|
|
35
|
+
const up = abbr.toUpperCase();
|
|
36
|
+
return TYPED_STAGES.find((ts) => ts.abbr.some((a) => a.toUpperCase() === up));
|
|
37
|
+
}
|
|
38
|
+
export class IeeeTypedStage {
|
|
39
|
+
record;
|
|
40
|
+
constructor(record) {
|
|
41
|
+
this.record = record;
|
|
42
|
+
}
|
|
43
|
+
get abbr() {
|
|
44
|
+
return this.record.abbr;
|
|
45
|
+
}
|
|
46
|
+
get projectStatus() {
|
|
47
|
+
return this.record.project_status === true;
|
|
48
|
+
}
|
|
49
|
+
get ieeeDraftEquivalent() {
|
|
50
|
+
return this.record.ieee_draft_equivalent;
|
|
51
|
+
}
|
|
52
|
+
get typeCode() {
|
|
53
|
+
return this.record.type_code;
|
|
54
|
+
}
|
|
55
|
+
toWire() {
|
|
56
|
+
return entrySubHash(this.record);
|
|
57
|
+
}
|
|
58
|
+
render() {
|
|
59
|
+
return this.record.abbr[0] ?? "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export class IeeeCode {
|
|
63
|
+
prefix;
|
|
64
|
+
number;
|
|
65
|
+
parts;
|
|
66
|
+
originalSeparator;
|
|
67
|
+
constructor(attrs) {
|
|
68
|
+
this.prefix = attrs["prefix"];
|
|
69
|
+
this.number = String(attrs["number"] ?? "");
|
|
70
|
+
this.parts = Array.isArray(attrs["parts"]) ? attrs["parts"] : [];
|
|
71
|
+
this.originalSeparator = attrs["original_separator"];
|
|
72
|
+
}
|
|
73
|
+
static parse(codeStr) {
|
|
74
|
+
if (codeStr === "")
|
|
75
|
+
return undefined;
|
|
76
|
+
const prefixMatch = /^([A-Z])/.exec(codeStr);
|
|
77
|
+
const prefix = prefixMatch !== null ? prefixMatch[1] : undefined;
|
|
78
|
+
const remainder = prefix !== undefined ? codeStr.slice(prefix.length) : codeStr;
|
|
79
|
+
let separator;
|
|
80
|
+
if (remainder.includes("."))
|
|
81
|
+
separator = ".";
|
|
82
|
+
else if (remainder.includes("-"))
|
|
83
|
+
separator = "-";
|
|
84
|
+
const components = remainder.split(/[.-]/);
|
|
85
|
+
const number = components.shift() ?? "";
|
|
86
|
+
return new IeeeCode({
|
|
87
|
+
prefix,
|
|
88
|
+
number,
|
|
89
|
+
parts: components,
|
|
90
|
+
original_separator: separator,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
render() {
|
|
94
|
+
let result = "";
|
|
95
|
+
if (this.prefix !== undefined)
|
|
96
|
+
result += this.prefix;
|
|
97
|
+
result += this.number;
|
|
98
|
+
if (this.parts.length > 0) {
|
|
99
|
+
let separator = this.originalSeparator;
|
|
100
|
+
if (separator === undefined) {
|
|
101
|
+
if (this.prefix === "P" || (this.prefix === undefined && this.parts[0] !== undefined && this.parts[0].length > 3)) {
|
|
102
|
+
separator = "-";
|
|
103
|
+
}
|
|
104
|
+
else if (this.prefix !== undefined && this.prefix !== "P") {
|
|
105
|
+
separator = ".";
|
|
106
|
+
}
|
|
107
|
+
else if (this.prefix === undefined && this.number.length >= 5) {
|
|
108
|
+
separator = "-";
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
separator = ".";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const part of this.parts)
|
|
115
|
+
result += separator + part;
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const DRAFT_MONTH_NAMES = {
|
|
121
|
+
January: "1", February: "2", March: "3", April: "4", May: "5", June: "6",
|
|
122
|
+
July: "7", August: "8", September: "9", October: "10", November: "11",
|
|
123
|
+
December: "12", Jan: "1", Feb: "2", Mar: "3", Apr: "4", Jun: "6",
|
|
124
|
+
Jul: "7", Aug: "8", Sep: "9", Sept: "9", Oct: "10", Nov: "11", Dec: "12",
|
|
125
|
+
};
|
|
126
|
+
export class IeeeDraft {
|
|
127
|
+
version;
|
|
128
|
+
revision;
|
|
129
|
+
year;
|
|
130
|
+
month;
|
|
131
|
+
day;
|
|
132
|
+
originalMonth;
|
|
133
|
+
commaBeforeMonth;
|
|
134
|
+
/** Distinguishes an explicit `false` from "not recorded" (Ruby's nil). */
|
|
135
|
+
commaBeforeMonthSet;
|
|
136
|
+
constructor(attrs) {
|
|
137
|
+
this.commaBeforeMonthSet = "comma_before_month" in attrs;
|
|
138
|
+
this.version = String(attrs["version"] ?? "");
|
|
139
|
+
this.revision = attrs["revision"];
|
|
140
|
+
this.year = attrs["year"];
|
|
141
|
+
this.originalMonth = attrs["month"];
|
|
142
|
+
this.month = attrs["month"] !== undefined
|
|
143
|
+
? DRAFT_MONTH_NAMES[String(attrs["month"])] ?? String(attrs["month"])
|
|
144
|
+
: undefined;
|
|
145
|
+
this.day = attrs["day"];
|
|
146
|
+
this.commaBeforeMonth = attrs["comma_before_month"] === true;
|
|
147
|
+
}
|
|
148
|
+
static parse(value) {
|
|
149
|
+
if (value === "")
|
|
150
|
+
return undefined;
|
|
151
|
+
let body = value;
|
|
152
|
+
if (body.startsWith("/D"))
|
|
153
|
+
body = body.slice(2);
|
|
154
|
+
else if (body.startsWith("/"))
|
|
155
|
+
body = body.slice(1);
|
|
156
|
+
else if (body.startsWith("D") && body.length > 1)
|
|
157
|
+
body = body.slice(1);
|
|
158
|
+
const monthAlt = Object.keys(DRAFT_MONTH_NAMES)
|
|
159
|
+
.sort((a, b) => b.length - a.length)
|
|
160
|
+
.map((m) => `${m.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.?`)
|
|
161
|
+
.join("|");
|
|
162
|
+
const suffix = new RegExp(`(?:(, | )(${monthAlt})(?: (\\d{1,2}))?(?:, | )| )((?:19|20)\\d{2}[a-z]{0,2})$`);
|
|
163
|
+
const m = suffix.exec(body);
|
|
164
|
+
if (m === null)
|
|
165
|
+
return new IeeeDraft({ version: body });
|
|
166
|
+
return new IeeeDraft({
|
|
167
|
+
version: body.slice(0, m.index),
|
|
168
|
+
month: m[2],
|
|
169
|
+
day: m[3],
|
|
170
|
+
year: m[4],
|
|
171
|
+
comma_before_month: m[1] === ", ",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
render() {
|
|
175
|
+
let result = `/D${this.version}`;
|
|
176
|
+
if (this.revision !== undefined)
|
|
177
|
+
result += `.${this.revision}`;
|
|
178
|
+
if (this.year !== undefined) {
|
|
179
|
+
const displayMonth = this.originalMonth;
|
|
180
|
+
if (displayMonth !== undefined) {
|
|
181
|
+
const useCommaBefore = this.commaBeforeMonthSet
|
|
182
|
+
? this.commaBeforeMonth
|
|
183
|
+
: displayMonth.length > 4 && displayMonth !== "Sept";
|
|
184
|
+
result += useCommaBefore ? `, ${displayMonth}` : ` ${displayMonth}`;
|
|
185
|
+
if (this.day !== undefined)
|
|
186
|
+
result += ` ${this.day}`;
|
|
187
|
+
result += displayMonth.length <= 4 || displayMonth === "Sept" ? ` ${this.year}` : `, ${this.year}`;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
result += ` ${this.year}`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// --- Wire helpers ------------------------------------------------------------
|
|
197
|
+
const typedStageWire = {
|
|
198
|
+
wire: "typed_stage",
|
|
199
|
+
to: "typed_stage",
|
|
200
|
+
toWire: (model) => (model["typed_stage"] instanceof IeeeTypedStage
|
|
201
|
+
? model["typed_stage"].toWire()
|
|
202
|
+
: undefined),
|
|
203
|
+
fromWire: (hash) => {
|
|
204
|
+
const value = hash["typed_stage"];
|
|
205
|
+
if (value === undefined || typeof value !== "object" || Array.isArray(value))
|
|
206
|
+
return undefined;
|
|
207
|
+
const rec = value;
|
|
208
|
+
const abbr = Array.isArray(rec["abbr"]) ? rec["abbr"].map(String) : [];
|
|
209
|
+
const match = TYPED_STAGES.find((ts) => ts.abbr.length === abbr.length && ts.abbr.every((a, i) => a === abbr[i]));
|
|
210
|
+
return match !== undefined ? new IeeeTypedStage(match) : undefined;
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
const draftWire = {
|
|
214
|
+
wire: "draft",
|
|
215
|
+
to: "draft",
|
|
216
|
+
toWire: (model) => {
|
|
217
|
+
const draft = model["draft"];
|
|
218
|
+
if (typeof draft !== "string" || draft === "")
|
|
219
|
+
return undefined;
|
|
220
|
+
return draft.startsWith("/") ? draft.slice(1) : draft;
|
|
221
|
+
},
|
|
222
|
+
fromWire: (hash) => {
|
|
223
|
+
const value = hash["draft"];
|
|
224
|
+
if (typeof value !== "string" || value === "")
|
|
225
|
+
return undefined;
|
|
226
|
+
return IeeeDraft.parse(value)?.render() ?? undefined;
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
const nestedIdWire = (attrName) => ({
|
|
230
|
+
wire: attrName,
|
|
231
|
+
to: attrName,
|
|
232
|
+
});
|
|
233
|
+
export const RELATIONSHIP_PREFIXES = {
|
|
234
|
+
revision_of: "Revision of",
|
|
235
|
+
amendment_to: "Amendment to",
|
|
236
|
+
corrigendum_to: "Corrigendum to",
|
|
237
|
+
incorporates: "incorporates",
|
|
238
|
+
adoption_of: "Adoption of",
|
|
239
|
+
supplement_to: "Supplement to",
|
|
240
|
+
draft_amendment_to: "Draft Amendment to",
|
|
241
|
+
draft_revision_of: "Draft Revision of",
|
|
242
|
+
reaffirmation_of: "Reaffirmation of",
|
|
243
|
+
redesignation_of: "Redesignation of",
|
|
244
|
+
supersedes: "Supersedes",
|
|
245
|
+
previously_designated_as: "Previously designated as",
|
|
246
|
+
includes: "Includes",
|
|
247
|
+
};
|
|
248
|
+
export class IeeeRelationship {
|
|
249
|
+
relationshipType;
|
|
250
|
+
relatedIds;
|
|
251
|
+
intermediateAmendments;
|
|
252
|
+
approvedAmendmentsFlag;
|
|
253
|
+
constructor(relationshipType, relatedIds, intermediateAmendments, approvedAmendmentsFlag = false) {
|
|
254
|
+
this.relationshipType = relationshipType;
|
|
255
|
+
this.relatedIds = relatedIds;
|
|
256
|
+
this.intermediateAmendments = intermediateAmendments;
|
|
257
|
+
this.approvedAmendmentsFlag = approvedAmendmentsFlag;
|
|
258
|
+
}
|
|
259
|
+
render() {
|
|
260
|
+
if (this.relatedIds.length === 0)
|
|
261
|
+
return "";
|
|
262
|
+
const prefix = RELATIONSHIP_PREFIXES[this.relationshipType] ?? this.relationshipType;
|
|
263
|
+
const ids = this.relatedIds.length === 1
|
|
264
|
+
? this.relatedIds[0].toHuman()
|
|
265
|
+
: this.relatedIds.length === 2
|
|
266
|
+
? `${this.relatedIds[0].toHuman()} and ${this.relatedIds[1].toHuman()}`
|
|
267
|
+
: `${this.relatedIds.slice(0, -1).map((i) => i.toHuman()).join(", ")}, and ${this.relatedIds[this.relatedIds.length - 1].toHuman()}`;
|
|
268
|
+
return `${prefix} ${ids}`;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// --- Compaction (hash transforms on toHash/fromHash) --------------------------
|
|
272
|
+
function walkHash(node, visit) {
|
|
273
|
+
if (Array.isArray(node)) {
|
|
274
|
+
for (const item of node)
|
|
275
|
+
walkHash(item, visit);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (node !== null && typeof node === "object") {
|
|
279
|
+
visit(node);
|
|
280
|
+
for (const value of Object.values(node)) {
|
|
281
|
+
walkHash(value, visit);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function collapseIeeeHash(node) {
|
|
286
|
+
walkHash(node, (h) => {
|
|
287
|
+
const ts = h["typed_stage"];
|
|
288
|
+
if (ts !== null && typeof ts === "object" && !Array.isArray(ts)) {
|
|
289
|
+
const sub = ts;
|
|
290
|
+
const abbr = Array.isArray(sub["abbr"]) ? sub["abbr"][0] : undefined;
|
|
291
|
+
if (typeof abbr === "string") {
|
|
292
|
+
const expected = SUB_HASH_FOR.get(abbr);
|
|
293
|
+
if (expected !== undefined &&
|
|
294
|
+
JSON.stringify(canonicalJsonKeyOrder(expected)) === JSON.stringify(canonicalJsonKeyOrder(sub))) {
|
|
295
|
+
delete h["typed_stage"];
|
|
296
|
+
h["stage"] = abbr;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const draft = h["draft"];
|
|
301
|
+
if (typeof draft === "string" && draft.startsWith("/")) {
|
|
302
|
+
h["draft"] = draft.slice(1);
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
function canonicalJsonKeyOrder(sub) {
|
|
307
|
+
return JSON.parse(JSON.stringify(sub, Object.keys(sub).sort()));
|
|
308
|
+
}
|
|
309
|
+
function expandIeeeHash(hash) {
|
|
310
|
+
const deep = (node) => {
|
|
311
|
+
if (Array.isArray(node))
|
|
312
|
+
return node.map(deep);
|
|
313
|
+
if (node !== null && typeof node === "object") {
|
|
314
|
+
const src = node;
|
|
315
|
+
const out = {};
|
|
316
|
+
for (const [k, v] of Object.entries(src))
|
|
317
|
+
out[k] = deep(v);
|
|
318
|
+
if (typeof out["stage"] === "string") {
|
|
319
|
+
const sub = SUB_HASH_FOR.get(out["stage"]);
|
|
320
|
+
if (sub !== undefined) {
|
|
321
|
+
delete out["stage"];
|
|
322
|
+
out["typed_stage"] = { ...sub };
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
return node;
|
|
328
|
+
};
|
|
329
|
+
return deep(hash);
|
|
330
|
+
}
|
|
331
|
+
// --- The identifier base -----------------------------------------------------
|
|
332
|
+
export class IeeeIdentifier extends BaseIdentifier {
|
|
333
|
+
static attributes = extendAttributes(BaseIdentifier, {
|
|
334
|
+
publisher: { type: "string", default: "IEEE" },
|
|
335
|
+
copublisher: { type: "string", collection: true, default: [] },
|
|
336
|
+
year: { type: "string" },
|
|
337
|
+
type: { type: "string", default: "Std" },
|
|
338
|
+
draft_status: { type: "string" },
|
|
339
|
+
draft: { type: "string" },
|
|
340
|
+
revision: { type: "string" },
|
|
341
|
+
edition: { type: "string" },
|
|
342
|
+
month: { type: "string" },
|
|
343
|
+
day: { type: "string" },
|
|
344
|
+
redline: { type: "boolean", default: false },
|
|
345
|
+
edition_month: { type: "string" },
|
|
346
|
+
space_before_draft: { type: "boolean", default: false },
|
|
347
|
+
typed_stage: { type: IeeeTypedStage },
|
|
348
|
+
parenthetical_content: { type: "string" },
|
|
349
|
+
nickname: { type: "string" },
|
|
350
|
+
adoption: { type: "string" },
|
|
351
|
+
amendment_to: { type: "string" },
|
|
352
|
+
note: { type: "string" },
|
|
353
|
+
iso_identifier: { type: "string" },
|
|
354
|
+
revision_of: { type: "string" },
|
|
355
|
+
ashrae_number: { type: "string" },
|
|
356
|
+
ashrae_year: { type: "string" },
|
|
357
|
+
crossref: { type: "string" },
|
|
358
|
+
reaffirmed: { type: "string" },
|
|
359
|
+
interpretation: { type: "boolean", default: false },
|
|
360
|
+
relationships: { type: "string", collection: true },
|
|
361
|
+
});
|
|
362
|
+
static mappings = keyValue({ wire: "publisher", to: "publisher" }, { wire: "copublisher", to: "copublisher" }, { wire: "year", to: "year" }, { wire: "type", to: "type" }, { wire: "draft_status", to: "draft_status" }, draftWire, { wire: "revision", to: "revision" }, { wire: "edition", to: "edition" }, { wire: "month", to: "month" }, { wire: "day", to: "day" }, { wire: "redline", to: "redline" }, { wire: "edition_month", to: "edition_month" }, { wire: "space_before_draft", to: "space_before_draft" }, typedStageWire, { wire: "parenthetical_content", to: "parenthetical_content" }, { wire: "nickname", to: "nickname" }, { wire: "adoption", to: "adoption" }, { wire: "amendment_to", to: "amendment_to" }, { wire: "note", to: "note" }, { wire: "iso_identifier", to: "iso_identifier" }, { wire: "revision_of", to: "revision_of" }, { wire: "ashrae_number", to: "ashrae_number" }, { wire: "ashrae_year", to: "ashrae_year" }, { wire: "crossref", to: "crossref" }, { wire: "reaffirmed", to: "reaffirmed" }, { wire: "interpretation", to: "interpretation" }, {
|
|
363
|
+
wire: "relationships",
|
|
364
|
+
to: "relationships",
|
|
365
|
+
toWire: (model) => {
|
|
366
|
+
const rel = model["relationships"];
|
|
367
|
+
if (rel === undefined || rel.length === 0)
|
|
368
|
+
return undefined;
|
|
369
|
+
return rel.map((r) => ({ relationship_type: r.relationshipType }));
|
|
370
|
+
},
|
|
371
|
+
fromWire: (hash) => {
|
|
372
|
+
const value = hash["relationships"];
|
|
373
|
+
if (!Array.isArray(value))
|
|
374
|
+
return undefined;
|
|
375
|
+
return value.map((r) => new IeeeRelationship(String(r["relationship_type"] ?? ""), [], []));
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
draftObjCache;
|
|
379
|
+
draftObject() {
|
|
380
|
+
if (this.draftObjCache !== undefined)
|
|
381
|
+
return this.draftObjCache;
|
|
382
|
+
if (this.draft === undefined || this.draft === "")
|
|
383
|
+
return undefined;
|
|
384
|
+
this.draftObjCache = IeeeDraft.parse(this.draft);
|
|
385
|
+
return this.draftObjCache;
|
|
386
|
+
}
|
|
387
|
+
get codeObj() {
|
|
388
|
+
return undefined;
|
|
389
|
+
}
|
|
390
|
+
root() {
|
|
391
|
+
return this;
|
|
392
|
+
}
|
|
393
|
+
yearForUrn() {
|
|
394
|
+
return this.year;
|
|
395
|
+
}
|
|
396
|
+
toHash() {
|
|
397
|
+
const hash = super.toHash();
|
|
398
|
+
collapseIeeeHash(hash);
|
|
399
|
+
return hash;
|
|
400
|
+
}
|
|
401
|
+
static fromHash(hash) {
|
|
402
|
+
return super.fromHash(expandIeeeHash(hash));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// --- render_base (the shared renderer core) ----------------------------------
|
|
406
|
+
export function renderIeeeBase(id) {
|
|
407
|
+
const parts = [];
|
|
408
|
+
if (id.copublisher !== undefined && id.copublisher.length > 0) {
|
|
409
|
+
parts.push([id.publisher, ...id.copublisher].join("/"));
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
parts.push(id.publisher);
|
|
413
|
+
}
|
|
414
|
+
if (id.draft_status !== undefined)
|
|
415
|
+
parts.push(id.draft_status);
|
|
416
|
+
const shouldRenderType = /^(IEEE|AIEE)/.test(id.publisher ?? "");
|
|
417
|
+
const stageObj = id.typed_stage;
|
|
418
|
+
if (shouldRenderType && !(stageObj?.projectStatus === true) &&
|
|
419
|
+
id.type !== undefined && id.type.trim() !== "" && id.type !== "P" &&
|
|
420
|
+
!/unapproved/i.test(id.draft_status ?? "")) {
|
|
421
|
+
let typeStr = id.type;
|
|
422
|
+
if (typeStr.startsWith("P"))
|
|
423
|
+
typeStr = typeStr.slice(1);
|
|
424
|
+
if (typeStr.trim() !== "")
|
|
425
|
+
parts.push(typeStr);
|
|
426
|
+
}
|
|
427
|
+
const codeObj = id.codeObj;
|
|
428
|
+
const draftObj = id.draftObject();
|
|
429
|
+
// An exactly-IEC/IEEE co-published reference drops its comma project
|
|
430
|
+
// dates (catalogue metadata, not identity); wider sets and
|
|
431
|
+
// space-separated dates print as spelled.
|
|
432
|
+
const iecIeeOnly = id.publisher === "IEC" && JSON.stringify(id.copublisher) === '["IEEE"]';
|
|
433
|
+
if (codeObj !== undefined) {
|
|
434
|
+
let result = codeObj.render();
|
|
435
|
+
// A draft-carrying ISO-led joint reference prints P-less.
|
|
436
|
+
if (id.publisher === "ISO" && draftObj !== undefined)
|
|
437
|
+
result = result.replace(/^P/, "");
|
|
438
|
+
if (stageObj?.projectStatus === true && shouldRenderType && !result.startsWith("P")) {
|
|
439
|
+
result = `P${result}`;
|
|
440
|
+
}
|
|
441
|
+
if (id.year !== undefined && draftObj === undefined && id.edition === undefined && id.month === undefined) {
|
|
442
|
+
result += `-${id.year}`;
|
|
443
|
+
}
|
|
444
|
+
if (id.revision !== undefined)
|
|
445
|
+
result += `Rev${id.revision}`;
|
|
446
|
+
if (draftObj !== undefined) {
|
|
447
|
+
let printed = draftObj.render();
|
|
448
|
+
if (iecIeeOnly) {
|
|
449
|
+
printed = printed.split(", ")[0];
|
|
450
|
+
}
|
|
451
|
+
else if (id.publisher === "IEEE" && (id.draft_status ?? "") === "") {
|
|
452
|
+
// The long comma form for dated project drafts; the
|
|
453
|
+
// unapproved-draft keeps its pinned single-comma form.
|
|
454
|
+
printed = printed.replace(/, ([A-Z][a-z]+) (\d{4})$/, ", $1, $2");
|
|
455
|
+
}
|
|
456
|
+
// A space-separated draft year with no print date trailing is the
|
|
457
|
+
// dash form ("…/D1-2006").
|
|
458
|
+
printed = printed.replace(/^(D\d+) (\d{4})$/, "$1-$2");
|
|
459
|
+
result += id.space_before_draft === true ? ` ${printed}` : printed;
|
|
460
|
+
}
|
|
461
|
+
if (id.interpretation === true)
|
|
462
|
+
result += "/INT";
|
|
463
|
+
if (id.ashrae_number !== undefined) {
|
|
464
|
+
result += `/ASHRAE Guideline ${id.ashrae_number}`;
|
|
465
|
+
if (id.ashrae_year !== undefined)
|
|
466
|
+
result += `-${id.ashrae_year}`;
|
|
467
|
+
}
|
|
468
|
+
if (id.crossref !== undefined)
|
|
469
|
+
result += id.crossref;
|
|
470
|
+
parts.push(result);
|
|
471
|
+
}
|
|
472
|
+
else if (shouldRenderType && stageObj?.projectStatus === true) {
|
|
473
|
+
parts.push("P");
|
|
474
|
+
}
|
|
475
|
+
if (id.edition !== undefined) {
|
|
476
|
+
let editionStr = `Edition ${id.edition}`;
|
|
477
|
+
if (id.year !== undefined) {
|
|
478
|
+
editionStr += ` ${id.year}`;
|
|
479
|
+
if (id.edition_month !== undefined)
|
|
480
|
+
editionStr += `-${id.edition_month}`;
|
|
481
|
+
}
|
|
482
|
+
parts.push(editionStr);
|
|
483
|
+
}
|
|
484
|
+
let result = parts.join(" ");
|
|
485
|
+
if (id.month !== undefined && !iecIeeOnly) {
|
|
486
|
+
result += `, ${id.month}`;
|
|
487
|
+
if (id.day !== undefined)
|
|
488
|
+
result += ` ${id.day}`;
|
|
489
|
+
if (id.year !== undefined && id.edition === undefined)
|
|
490
|
+
result += ` ${id.year}`;
|
|
491
|
+
}
|
|
492
|
+
const parentheticals = [];
|
|
493
|
+
if (id.reaffirmed !== undefined && id.reaffirmed.trim() !== "") {
|
|
494
|
+
parentheticals.push(`(R${id.reaffirmed})`);
|
|
495
|
+
}
|
|
496
|
+
if (id.parenthetical_content !== undefined) {
|
|
497
|
+
parentheticals.push(`(${id.parenthetical_content})`);
|
|
498
|
+
}
|
|
499
|
+
if (parentheticals.length > 0)
|
|
500
|
+
result += ` ${parentheticals.join(" ")}`;
|
|
501
|
+
if (id.nickname !== undefined && id.nickname.trim() !== "")
|
|
502
|
+
result += ` [${id.nickname}]`;
|
|
503
|
+
if (id.redline === true)
|
|
504
|
+
result += " - Redline";
|
|
505
|
+
return result;
|
|
506
|
+
}
|
|
507
|
+
// --- URN generator -----------------------------------------------------------
|
|
508
|
+
let SPECIAL_URN_OF = () => undefined;
|
|
509
|
+
let CODE_THROUGH_BASE = () => false;
|
|
510
|
+
class IeeeUrnGenerator extends BaseUrnGenerator {
|
|
511
|
+
generate() {
|
|
512
|
+
const id = this.identifier;
|
|
513
|
+
const parts = ["urn", "ieee"];
|
|
514
|
+
const special = this.specialType();
|
|
515
|
+
const push = (value) => {
|
|
516
|
+
if (value !== undefined)
|
|
517
|
+
parts.push(value);
|
|
518
|
+
};
|
|
519
|
+
push(this.publisherComponent());
|
|
520
|
+
push(special);
|
|
521
|
+
push(this.typeComponent());
|
|
522
|
+
push(this.codeComponent());
|
|
523
|
+
push(this.yearComponent());
|
|
524
|
+
push(this.draftComponent());
|
|
525
|
+
if (id.edition !== undefined)
|
|
526
|
+
push(`ed.${id.edition}`);
|
|
527
|
+
push(this.monthDayComponent());
|
|
528
|
+
if (id.draft_status !== undefined)
|
|
529
|
+
push(id.draft_status.toLowerCase().replaceAll(" ", "."));
|
|
530
|
+
if (special === undefined && id.redline === true)
|
|
531
|
+
push("redline");
|
|
532
|
+
if (special === undefined && id.interpretation === true)
|
|
533
|
+
push("int");
|
|
534
|
+
if (id.ashrae_number !== undefined) {
|
|
535
|
+
let ashrae = `ashrae.${id.ashrae_number}`;
|
|
536
|
+
if (id.ashrae_year !== undefined)
|
|
537
|
+
ashrae += `-${id.ashrae_year}`;
|
|
538
|
+
push(ashrae);
|
|
539
|
+
}
|
|
540
|
+
if (id.crossref !== undefined)
|
|
541
|
+
push(`xref.${id.crossref}`);
|
|
542
|
+
if (id.relationships !== undefined && id.relationships.length > 0) {
|
|
543
|
+
push(`rel.${id.relationships.map((r) => r.render()).join("/")}`);
|
|
544
|
+
}
|
|
545
|
+
if (id.revision_of !== undefined)
|
|
546
|
+
push(`revof.${id.revision_of}`);
|
|
547
|
+
if (id.amendment_to !== undefined)
|
|
548
|
+
push(`amdto.${id.amendment_to}`);
|
|
549
|
+
if (id.adoption !== undefined)
|
|
550
|
+
push(`adopt.${id.adoption}`);
|
|
551
|
+
if (id.reaffirmed !== undefined)
|
|
552
|
+
push(`reaff.${id.reaffirmed}`);
|
|
553
|
+
if (id.note !== undefined)
|
|
554
|
+
push(`note.${id.note}`);
|
|
555
|
+
if (id.nickname !== undefined)
|
|
556
|
+
push(`nick.${id.nickname}`);
|
|
557
|
+
return parts.join(":");
|
|
558
|
+
}
|
|
559
|
+
specialType() {
|
|
560
|
+
return SPECIAL_URN_OF(this.identifier);
|
|
561
|
+
}
|
|
562
|
+
publisherComponent() {
|
|
563
|
+
// Supplements delegate #publisher/#copublisher to their base (Ruby
|
|
564
|
+
// SupplementIdentifier); DualPublished derives publisher from BOTH
|
|
565
|
+
// members; MultiNumbered derives it from its primary.
|
|
566
|
+
const self = this.identifier;
|
|
567
|
+
const first = self["first_identifier"];
|
|
568
|
+
const second = self["second_identifier"];
|
|
569
|
+
const single = (self["ieee_identifier"] ?? self["primary_identifier"]);
|
|
570
|
+
const derived = first !== undefined && second !== undefined
|
|
571
|
+
? [first.publisher, second.publisher]
|
|
572
|
+
: undefined;
|
|
573
|
+
// The Ruby reference reads the publisher through the wrapper (an
|
|
574
|
+
// adopted IRE id namespaces "ire") but the copublisher list RAW off
|
|
575
|
+
// this identifier: an amendment over a joint base carries publisher
|
|
576
|
+
// "ISO" and no copublishers of its own, so its URN namespace is
|
|
577
|
+
// "iso", not the base's joint slug.
|
|
578
|
+
const wrapped = (self["base"] ?? single);
|
|
579
|
+
const pubSource = derived !== undefined || wrapped === undefined
|
|
580
|
+
? this.identifier
|
|
581
|
+
: wrapped;
|
|
582
|
+
const names = derived ?? (Array.isArray(pubSource.publisher) ? pubSource.publisher : [pubSource.publisher]);
|
|
583
|
+
const cleaned = names.map((p) => String(p).toLowerCase()).filter((p) => p !== "");
|
|
584
|
+
let pub = cleaned.length === 0 ? "ieee" : cleaned.join("-");
|
|
585
|
+
const rawCopub = this.identifier.copublisher;
|
|
586
|
+
if (rawCopub !== undefined && rawCopub.length > 0) {
|
|
587
|
+
pub = [pub, ...rawCopub.map((c) => String(c).toLowerCase())].join("-");
|
|
588
|
+
}
|
|
589
|
+
return pub;
|
|
590
|
+
}
|
|
591
|
+
typeComponent() {
|
|
592
|
+
const type = this.identifier.type;
|
|
593
|
+
if (type === undefined || type.trim() === "" || type === "Std")
|
|
594
|
+
return undefined;
|
|
595
|
+
return type.toLowerCase().replaceAll(" ", ".");
|
|
596
|
+
}
|
|
597
|
+
codeComponent() {
|
|
598
|
+
// Wrappers delegate code_obj to the identifier they wrap (Ruby
|
|
599
|
+
// AdoptedStandard/CsaDualPublished/MultiNumberedIdentifier).
|
|
600
|
+
const self = this.identifier;
|
|
601
|
+
// NB: NOT base — SupplementIdentifier delegates #code but leaves
|
|
602
|
+
// code_obj nil on the wrapper (identity-free corrigendum URNs) —
|
|
603
|
+
// except InterpretationIdentifier, whose override reaches the base.
|
|
604
|
+
const fallbacks = CODE_THROUGH_BASE(this.identifier)
|
|
605
|
+
? ["ieee_identifier", "primary_identifier", "first_identifier", "base"]
|
|
606
|
+
: ["ieee_identifier", "primary_identifier", "first_identifier"];
|
|
607
|
+
const wrapped = fallbacks.map((k) => self[k]).find((v) => v instanceof IeeeIdentifier);
|
|
608
|
+
return (wrapped ?? this.identifier).codeObj?.render();
|
|
609
|
+
}
|
|
610
|
+
yearComponent() {
|
|
611
|
+
const id = this.identifier;
|
|
612
|
+
if (id.year !== undefined)
|
|
613
|
+
return id.year;
|
|
614
|
+
const root = id.root();
|
|
615
|
+
return root === id ? undefined : root.yearForUrn();
|
|
616
|
+
}
|
|
617
|
+
draftComponent() {
|
|
618
|
+
const draftObj = this.identifier.draftObject();
|
|
619
|
+
return draftObj === undefined ? undefined : `draft.${draftObj.render()}`;
|
|
620
|
+
}
|
|
621
|
+
monthDayComponent() {
|
|
622
|
+
const parts = [];
|
|
623
|
+
const id = this.identifier;
|
|
624
|
+
if (id.month !== undefined)
|
|
625
|
+
parts.push(id.month);
|
|
626
|
+
if (id.day !== undefined)
|
|
627
|
+
parts.push(id.day);
|
|
628
|
+
return parts.length === 0 ? undefined : parts.join("-");
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const CODE_COLUMN_DEFS = {
|
|
632
|
+
number: { type: "string" },
|
|
633
|
+
prefix: { type: "string" },
|
|
634
|
+
parts: { type: "string", collection: true, default: [] },
|
|
635
|
+
separator: { type: "string" },
|
|
636
|
+
};
|
|
637
|
+
const CODE_COLUMN_MAPPINGS = keyValue({ wire: "number", to: "number" }, { wire: "prefix", to: "prefix" }, { wire: "parts", to: "parts" }, { wire: "separator", to: "separator" });
|
|
638
|
+
function ieeeClass(spec, opts = {}) {
|
|
639
|
+
const parentAttrs = () => opts.codeColumns === true
|
|
640
|
+
? extendAttributes(IeeeIdentifier, CODE_COLUMN_DEFS)
|
|
641
|
+
: IeeeIdentifier.attributes;
|
|
642
|
+
const parentMappings = () => opts.codeColumns === true
|
|
643
|
+
? [...IeeeIdentifier.mappings, ...CODE_COLUMN_MAPPINGS]
|
|
644
|
+
: [...IeeeIdentifier.mappings];
|
|
645
|
+
class IeeeConcrete extends IeeeIdentifier {
|
|
646
|
+
static polymorphicName = `pubid:ieee:${spec.kind}`;
|
|
647
|
+
static urnGenerator = IeeeUrnGenerator;
|
|
648
|
+
static get attributes() {
|
|
649
|
+
return opts.extraDefs === undefined
|
|
650
|
+
? parentAttrs()
|
|
651
|
+
: extendAttributes({ attributes: parentAttrs() }, opts.extraDefs);
|
|
652
|
+
}
|
|
653
|
+
static get mappings() {
|
|
654
|
+
const base = opts.extraMappings === undefined
|
|
655
|
+
? parentMappings()
|
|
656
|
+
: [...parentMappings(), ...opts.extraMappings];
|
|
657
|
+
return opts.wireDelete === undefined
|
|
658
|
+
? base
|
|
659
|
+
: base.filter((m) => !opts.wireDelete.keys.includes(m.wire));
|
|
660
|
+
}
|
|
661
|
+
// The UNFILTERED list: nested serialization keeps the derived keys
|
|
662
|
+
// the top-level wire deletes (mirrors lutaml's nested transform,
|
|
663
|
+
// which serializes through the reader methods).
|
|
664
|
+
static get mappingsNested() {
|
|
665
|
+
return opts.extraMappings === undefined
|
|
666
|
+
? parentMappings()
|
|
667
|
+
: [...parentMappings(), ...opts.extraMappings];
|
|
668
|
+
}
|
|
669
|
+
constructor(attrs = {}) {
|
|
670
|
+
super(attrs);
|
|
671
|
+
// Ruby lutaml materializes attribute defaults on every instance; the
|
|
672
|
+
// base constructor only assigns present keys, so fill scalar defaults
|
|
673
|
+
// the renderers read (publisher/type). toHash still drops them.
|
|
674
|
+
const self = this;
|
|
675
|
+
for (const [name, spec] of Object.entries(this.classAttributes())) {
|
|
676
|
+
if (self[name] === undefined && spec.default !== undefined && typeof spec.default !== "function") {
|
|
677
|
+
self[name] = spec.default;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
render() {
|
|
682
|
+
return this.renderBody();
|
|
683
|
+
}
|
|
684
|
+
toHuman() {
|
|
685
|
+
return this.render();
|
|
686
|
+
}
|
|
687
|
+
renderBody() {
|
|
688
|
+
return (opts.render ?? renderIeeeBase)(this);
|
|
689
|
+
}
|
|
690
|
+
get codeObj() {
|
|
691
|
+
// Only CodeNumber leaves carry code columns; on a supplement the
|
|
692
|
+
// `number` attribute is the ORDINAL (Ruby SupplementIdentifier#code
|
|
693
|
+
// delegates to base, code_obj stays nil).
|
|
694
|
+
if (opts.codeColumns !== true)
|
|
695
|
+
return undefined;
|
|
696
|
+
const self = this;
|
|
697
|
+
const number = self["number"];
|
|
698
|
+
if (typeof number !== "string" || number === "")
|
|
699
|
+
return undefined;
|
|
700
|
+
return new IeeeCode({
|
|
701
|
+
prefix: self["prefix"],
|
|
702
|
+
number,
|
|
703
|
+
parts: self["parts"],
|
|
704
|
+
original_separator: self["separator"],
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
root() {
|
|
708
|
+
return opts.rootOf !== undefined
|
|
709
|
+
? opts.rootOf(this)
|
|
710
|
+
: this;
|
|
711
|
+
}
|
|
712
|
+
yearForUrn() {
|
|
713
|
+
return opts.yearForUrnOf !== undefined
|
|
714
|
+
? opts.yearForUrnOf(this)
|
|
715
|
+
: this.year;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
registerType(IeeeConcrete);
|
|
719
|
+
if (opts.specialUrn !== undefined) {
|
|
720
|
+
const special = opts.specialUrn;
|
|
721
|
+
const prev = SPECIAL_URN_OF;
|
|
722
|
+
SPECIAL_URN_OF = (id) => {
|
|
723
|
+
if (id instanceof IeeeConcrete)
|
|
724
|
+
return special;
|
|
725
|
+
return prev(id);
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (opts.codeThroughBase === true) {
|
|
729
|
+
const prevCode = CODE_THROUGH_BASE;
|
|
730
|
+
CODE_THROUGH_BASE = (id) => (id instanceof IeeeConcrete ? true : prevCode(id));
|
|
731
|
+
}
|
|
732
|
+
return IeeeConcrete;
|
|
733
|
+
}
|
|
734
|
+
const childOf = (attrName) => (id) => id[attrName]?.root() ?? id;
|
|
735
|
+
const childYearOf = (attrName) => (id) => id[attrName]?.year;
|
|
736
|
+
// --- Supplements and wrappers -------------------------------------------------
|
|
737
|
+
export const SupplementBaseDefs = {
|
|
738
|
+
base: { type: IeeeIdentifier },
|
|
739
|
+
};
|
|
740
|
+
export const StandardClass = ieeeClass({ kind: "standard" }, { codeColumns: true });
|
|
741
|
+
export const ProjectDraftIdentifierClass = ieeeClass({ kind: "project-draft-identifier" }, { codeColumns: true });
|
|
742
|
+
export const SiStandardClass = ieeeClass({ kind: "si-standard" }, {
|
|
743
|
+
codeColumns: true,
|
|
744
|
+
specialUrn: "si",
|
|
745
|
+
render: (id) => {
|
|
746
|
+
const parts = ["IEEE/ASTM"];
|
|
747
|
+
const isPsi = (id.typed_stage?.abbr ?? []).includes("PSI");
|
|
748
|
+
parts.push(isPsi ? "PSI" : "SI");
|
|
749
|
+
const codeObj = id.codeObj;
|
|
750
|
+
let codePart = codeObj?.render() ?? "";
|
|
751
|
+
const draftObj = id.draftObject();
|
|
752
|
+
if (draftObj !== undefined)
|
|
753
|
+
codePart += `/D${draftObj.version}`;
|
|
754
|
+
if (codeObj !== undefined)
|
|
755
|
+
parts.push(codePart);
|
|
756
|
+
let result = "";
|
|
757
|
+
for (const part of parts) {
|
|
758
|
+
if (result === "" || part.startsWith("-") || part.startsWith(",")) {
|
|
759
|
+
result += part;
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
result += ` ${part}`;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (id.month !== undefined && id.year !== undefined)
|
|
766
|
+
result += `, ${id.month} ${id.year}`;
|
|
767
|
+
else if (id.year !== undefined)
|
|
768
|
+
result += `-${id.year}`;
|
|
769
|
+
return result;
|
|
770
|
+
},
|
|
771
|
+
});
|
|
772
|
+
export const CorrigendumClass = ieeeClass({ kind: "corrigendum" }, {
|
|
773
|
+
extraDefs: SupplementBaseDefs,
|
|
774
|
+
extraMappings: keyValue(nestedIdWire("base"), { wire: "number", to: "number" }),
|
|
775
|
+
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
776
|
+
render: (id) => {
|
|
777
|
+
const base = id["base"];
|
|
778
|
+
if (base === undefined)
|
|
779
|
+
return renderIeeeBase(id);
|
|
780
|
+
let result = base.toHuman();
|
|
781
|
+
result += "/Cor";
|
|
782
|
+
if (id.number !== undefined)
|
|
783
|
+
result += ". ";
|
|
784
|
+
if (id.number !== undefined)
|
|
785
|
+
result += id.number;
|
|
786
|
+
if (id.year !== undefined)
|
|
787
|
+
result += `-${id.year}`;
|
|
788
|
+
return result;
|
|
789
|
+
},
|
|
790
|
+
rootOf: childOf("base"),
|
|
791
|
+
});
|
|
792
|
+
export const AmendmentClass = ieeeClass({ kind: "amendment" }, {
|
|
793
|
+
extraDefs: SupplementBaseDefs,
|
|
794
|
+
extraMappings: keyValue(nestedIdWire("base"), { wire: "number", to: "number" }),
|
|
795
|
+
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
796
|
+
render: (id) => {
|
|
797
|
+
const base = id["base"];
|
|
798
|
+
if (base === undefined)
|
|
799
|
+
return renderIeeeBase(id);
|
|
800
|
+
let result = base.toHuman();
|
|
801
|
+
result += "/Amd";
|
|
802
|
+
if (id.number !== undefined)
|
|
803
|
+
result += ` ${id.number}`;
|
|
804
|
+
if (id.year !== undefined)
|
|
805
|
+
result += `-${id.year}`;
|
|
806
|
+
return result;
|
|
807
|
+
},
|
|
808
|
+
rootOf: childOf("base"),
|
|
809
|
+
});
|
|
810
|
+
export const InterpretationClass = ieeeClass({ kind: "interpretation-identifier" }, {
|
|
811
|
+
specialUrn: "interpretation",
|
|
812
|
+
codeThroughBase: true,
|
|
813
|
+
extraDefs: SupplementBaseDefs,
|
|
814
|
+
extraMappings: keyValue(nestedIdWire("base")),
|
|
815
|
+
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
816
|
+
render: (id) => {
|
|
817
|
+
const base = id["base"];
|
|
818
|
+
if (base === undefined)
|
|
819
|
+
return renderIeeeBase(id);
|
|
820
|
+
let result = base.toHuman();
|
|
821
|
+
result += "/INT";
|
|
822
|
+
if (id.year !== undefined)
|
|
823
|
+
result += `-${id.year}`;
|
|
824
|
+
return result;
|
|
825
|
+
},
|
|
826
|
+
rootOf: childOf("base"),
|
|
827
|
+
});
|
|
828
|
+
export const ConformanceClass = ieeeClass({ kind: "conformance-identifier" }, {
|
|
829
|
+
specialUrn: "conformance",
|
|
830
|
+
extraDefs: SupplementBaseDefs,
|
|
831
|
+
extraMappings: keyValue(nestedIdWire("base"), { wire: "number", to: "number" }),
|
|
832
|
+
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
833
|
+
render: (id) => {
|
|
834
|
+
const base = id["base"];
|
|
835
|
+
if (base === undefined)
|
|
836
|
+
return renderIeeeBase(id);
|
|
837
|
+
let result = base.toHuman();
|
|
838
|
+
if (id.number !== undefined)
|
|
839
|
+
result += `/Conformance${id.number}`;
|
|
840
|
+
if (id.year !== undefined)
|
|
841
|
+
result += `-${id.year}`;
|
|
842
|
+
return result;
|
|
843
|
+
},
|
|
844
|
+
rootOf: childOf("base"),
|
|
845
|
+
});
|
|
846
|
+
const DualDefs = {
|
|
847
|
+
first_identifier: { type: IeeeIdentifier },
|
|
848
|
+
second_identifier: { type: IeeeIdentifier },
|
|
849
|
+
};
|
|
850
|
+
export const DualPublishedClass = ieeeClass({ kind: "dual-published" }, {
|
|
851
|
+
extraDefs: DualDefs,
|
|
852
|
+
extraMappings: keyValue(nestedIdWire("first_identifier"), nestedIdWire("second_identifier")),
|
|
853
|
+
wireDelete: { keys: ["publisher"] },
|
|
854
|
+
render: (id) => `${id["first_identifier"].toHuman()} and ${id["second_identifier"].toHuman()}`,
|
|
855
|
+
rootOf: childOf("first_identifier"),
|
|
856
|
+
yearForUrnOf: childYearOf("first_identifier"),
|
|
857
|
+
});
|
|
858
|
+
export const DualIdentifierClass = ieeeClass({ kind: "dual-identifier" }, {
|
|
859
|
+
extraDefs: DualDefs,
|
|
860
|
+
extraMappings: keyValue(nestedIdWire("first_identifier"), nestedIdWire("second_identifier")),
|
|
861
|
+
render: (id) => `${id["first_identifier"].toHuman()} and ${id["second_identifier"].toHuman()}`,
|
|
862
|
+
});
|
|
863
|
+
export const ParentheticalClass = ieeeClass({ kind: "parenthetical-identifier" }, {
|
|
864
|
+
extraDefs: {
|
|
865
|
+
base: { type: IeeeIdentifier },
|
|
866
|
+
parenthetical_identifier: { type: IeeeIdentifier },
|
|
867
|
+
},
|
|
868
|
+
extraMappings: keyValue(nestedIdWire("base"), nestedIdWire("parenthetical_identifier")),
|
|
869
|
+
render: (id) => {
|
|
870
|
+
let result = id["base"].toHuman();
|
|
871
|
+
if (id["parenthetical_identifier"] !== undefined) {
|
|
872
|
+
result += ` (${id["parenthetical_identifier"].toHuman()})`;
|
|
873
|
+
}
|
|
874
|
+
return result;
|
|
875
|
+
},
|
|
876
|
+
rootOf: childOf("base"),
|
|
877
|
+
});
|
|
878
|
+
export const AdoptedStandardClass = ieeeClass({ kind: "adopted-standard" }, {
|
|
879
|
+
extraDefs: {
|
|
880
|
+
ieee_identifier: { type: IeeeIdentifier },
|
|
881
|
+
adopted_identifiers: { type: IeeeIdentifier, collection: true },
|
|
882
|
+
},
|
|
883
|
+
extraMappings: keyValue(nestedIdWire("ieee_identifier"), nestedIdWire("adopted_identifiers")),
|
|
884
|
+
wireDelete: { keys: ["publisher"] },
|
|
885
|
+
render: (id) => {
|
|
886
|
+
const ieee = id["ieee_identifier"];
|
|
887
|
+
let result = ieee.toHuman();
|
|
888
|
+
const adopted = id["adopted_identifiers"];
|
|
889
|
+
if (adopted !== undefined && adopted.length > 0) {
|
|
890
|
+
result += ` (${adopted.map((a) => a.toHuman()).join(" and ")})`;
|
|
891
|
+
}
|
|
892
|
+
return result;
|
|
893
|
+
},
|
|
894
|
+
rootOf: childOf("ieee_identifier"),
|
|
895
|
+
yearForUrnOf: childYearOf("ieee_identifier"),
|
|
896
|
+
});
|
|
897
|
+
export const CsaDualPublishedClass = ieeeClass({ kind: "csa-dual-published" }, {
|
|
898
|
+
extraDefs: {
|
|
899
|
+
ieee_identifier: { type: IeeeIdentifier },
|
|
900
|
+
csa_string: { type: "string" },
|
|
901
|
+
},
|
|
902
|
+
// The wrapper serializes its DELEGATED year/typed_stage (Ruby lutaml
|
|
903
|
+
// reads through the reader methods) — the builder copies them onto the
|
|
904
|
+
// wrapper instance. csa_identifier is runtime-only (never serialized).
|
|
905
|
+
extraMappings: keyValue(nestedIdWire("ieee_identifier")),
|
|
906
|
+
render: (id) => {
|
|
907
|
+
const ieee = id["ieee_identifier"];
|
|
908
|
+
let csaStr = String(id["csa_string"] ?? "");
|
|
909
|
+
if (!csaStr.startsWith("CSA") && !csaStr.startsWith("CAN/"))
|
|
910
|
+
csaStr = `CSA ${csaStr}`;
|
|
911
|
+
return `${ieee.toHuman()}/${csaStr}`;
|
|
912
|
+
},
|
|
913
|
+
rootOf: childOf("ieee_identifier"),
|
|
914
|
+
yearForUrnOf: childYearOf("ieee_identifier"),
|
|
915
|
+
});
|
|
916
|
+
export const MultiNumberedClass = ieeeClass({ kind: "multi-numbered-identifier" }, {
|
|
917
|
+
extraDefs: {
|
|
918
|
+
primary_identifier: { type: IeeeIdentifier },
|
|
919
|
+
secondary_identifier: { type: IeeeIdentifier },
|
|
920
|
+
},
|
|
921
|
+
extraMappings: keyValue(nestedIdWire("primary_identifier"), nestedIdWire("secondary_identifier")),
|
|
922
|
+
wireDelete: { keys: ["publisher", "year"] },
|
|
923
|
+
render: (id) => {
|
|
924
|
+
const primary = id["primary_identifier"];
|
|
925
|
+
const secondary = id["secondary_identifier"];
|
|
926
|
+
if (secondary === undefined)
|
|
927
|
+
return primary.toHuman();
|
|
928
|
+
const secondaryCode = secondary.codeObj?.render() ?? "";
|
|
929
|
+
if (secondaryCode.startsWith("C") && /^C\d+\./.test(secondaryCode)) {
|
|
930
|
+
return `${primary.toHuman()}/${secondaryCode}`;
|
|
931
|
+
}
|
|
932
|
+
return `${primary.toHuman()} and ${secondary.toHuman()}`;
|
|
933
|
+
},
|
|
934
|
+
rootOf: childOf("primary_identifier"),
|
|
935
|
+
});
|
|
936
|
+
export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
937
|
+
codeColumns: true,
|
|
938
|
+
extraDefs: {
|
|
939
|
+
publishers: { type: "string", collection: true },
|
|
940
|
+
lead_party: { type: "string" },
|
|
941
|
+
iso_stage: { type: "string" },
|
|
942
|
+
ieee_draft: { type: "string" },
|
|
943
|
+
},
|
|
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" }),
|
|
945
|
+
wireDelete: { keys: ["publisher", "copublisher"] },
|
|
946
|
+
render: (id) => {
|
|
947
|
+
const publishers = id["publishers"];
|
|
948
|
+
const leadParty = id["lead_party"];
|
|
949
|
+
const isoStage = id["iso_stage"];
|
|
950
|
+
const ieeeDraft = id["ieee_draft"];
|
|
951
|
+
const codeObj = id.codeObj;
|
|
952
|
+
// ISO-led renders the ISO format ALWAYS (the stage-less published
|
|
953
|
+
// form "ISO/IEC/IEEE 12207.2:2020" prints colon-year, no stage).
|
|
954
|
+
if (leadParty === "ISO") {
|
|
955
|
+
const parts = [];
|
|
956
|
+
if (publishers !== undefined && publishers.length > 0)
|
|
957
|
+
parts.push(publishers.join("/"));
|
|
958
|
+
if (id.typed_stage !== undefined) {
|
|
959
|
+
parts.push(id.typed_stage.record.iso_stage_equivalent ?? id.typed_stage.render());
|
|
960
|
+
}
|
|
961
|
+
else if (isoStage !== undefined) {
|
|
962
|
+
parts.push(isoStage);
|
|
963
|
+
}
|
|
964
|
+
let codeStr = codeObj?.render().replace(/^P/, "") ?? "";
|
|
965
|
+
if (codeStr !== "")
|
|
966
|
+
parts.push(codeStr);
|
|
967
|
+
let result = parts.join(" ");
|
|
968
|
+
if (id.year !== undefined)
|
|
969
|
+
result += `:${id.year}`;
|
|
970
|
+
return result;
|
|
971
|
+
}
|
|
972
|
+
// IEEE format
|
|
973
|
+
const parts = [];
|
|
974
|
+
if (publishers !== undefined && publishers.length > 0)
|
|
975
|
+
parts.push(publishers.join("/"));
|
|
976
|
+
let codeStr = codeObj?.render().replace(/^P/, "") ?? "";
|
|
977
|
+
if (id.typed_stage?.projectStatus === true || id.type === "P")
|
|
978
|
+
codeStr = `P${codeStr}`;
|
|
979
|
+
if (ieeeDraft !== undefined)
|
|
980
|
+
codeStr += `/${ieeeDraft}`;
|
|
981
|
+
else if (id.typed_stage?.ieeeDraftEquivalent !== undefined) {
|
|
982
|
+
codeStr += `/${id.typed_stage.ieeeDraftEquivalent}`;
|
|
983
|
+
}
|
|
984
|
+
if (codeStr !== "")
|
|
985
|
+
parts.push(codeStr);
|
|
986
|
+
let result = parts.join(" ");
|
|
987
|
+
if (id.year !== undefined)
|
|
988
|
+
result += `-${id.year}`;
|
|
989
|
+
return result;
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
export const IecIeeeCopublishedClass = ieeeClass({ kind: "iec-ieee-copublished" }, {
|
|
993
|
+
extraDefs: {
|
|
994
|
+
number: { type: "string" },
|
|
995
|
+
parts: { type: "string", collection: true, default: [] },
|
|
996
|
+
separators: { type: "string", collection: true, default: [] },
|
|
997
|
+
year_sep: { type: "string", default: "-" },
|
|
998
|
+
draft_info: { type: "string" },
|
|
999
|
+
iec_year: { type: "string" },
|
|
1000
|
+
date_info: { type: "string" },
|
|
1001
|
+
},
|
|
1002
|
+
extraMappings: keyValue({ wire: "number", to: "number" }, { wire: "parts", to: "parts" }, { wire: "separators", to: "separators" }, { wire: "year_sep", to: "year_sep" }, { wire: "draft_info", to: "draft_info" }, { wire: "iec_year", to: "iec_year" }, { wire: "date_info", to: "date_info" }),
|
|
1003
|
+
render: (id) => {
|
|
1004
|
+
let result = "IEC/IEEE";
|
|
1005
|
+
const number = id["number"];
|
|
1006
|
+
if (number !== undefined && number !== "") {
|
|
1007
|
+
const parts = id["parts"] ?? [];
|
|
1008
|
+
const separators = id["separators"] ?? [];
|
|
1009
|
+
let code = number;
|
|
1010
|
+
separators.forEach((sep, i) => {
|
|
1011
|
+
code += `${sep}${parts[i] ?? ""}`;
|
|
1012
|
+
});
|
|
1013
|
+
if (id.year !== undefined)
|
|
1014
|
+
code += `${id["year_sep"] ?? "-"}${id.year}`;
|
|
1015
|
+
result += ` ${code}`;
|
|
1016
|
+
}
|
|
1017
|
+
const draftInfo = id["draft_info"];
|
|
1018
|
+
if (draftInfo !== undefined)
|
|
1019
|
+
result += draftInfo;
|
|
1020
|
+
const iecYear = id["iec_year"];
|
|
1021
|
+
if (iecYear !== undefined)
|
|
1022
|
+
result += ` IEC:${iecYear}`;
|
|
1023
|
+
const dateInfo = id["date_info"];
|
|
1024
|
+
if (dateInfo !== undefined)
|
|
1025
|
+
result += ` ${dateInfo}`;
|
|
1026
|
+
return result;
|
|
1027
|
+
},
|
|
1028
|
+
});
|
|
1029
|
+
// --- AIEE / IRE / NESC -------------------------------------------------------
|
|
1030
|
+
export const AieeClass = ieeeClass({ kind: "aiee" }, {
|
|
1031
|
+
codeColumns: true,
|
|
1032
|
+
extraDefs: {
|
|
1033
|
+
publisher: { type: "string", default: "AIEE" },
|
|
1034
|
+
type: { type: "string", default: undefined },
|
|
1035
|
+
date_separator: { type: "string" },
|
|
1036
|
+
original_format: { type: "string" },
|
|
1037
|
+
},
|
|
1038
|
+
extraMappings: keyValue({ wire: "date_separator", to: "date_separator" }, { wire: "original_format", to: "original_format" }),
|
|
1039
|
+
render: (id) => {
|
|
1040
|
+
const result = [id.publisher];
|
|
1041
|
+
if (id.type !== undefined && id.type !== "")
|
|
1042
|
+
result.push(id.type);
|
|
1043
|
+
if (id.codeObj !== undefined)
|
|
1044
|
+
result.push(id.codeObj.render());
|
|
1045
|
+
let base = result.join(" ");
|
|
1046
|
+
const format = id["original_format"];
|
|
1047
|
+
if (id.year !== undefined) {
|
|
1048
|
+
const month = id.month;
|
|
1049
|
+
const dateSep = id["date_separator"];
|
|
1050
|
+
if (format === "short") {
|
|
1051
|
+
base += `-${id.year}`;
|
|
1052
|
+
}
|
|
1053
|
+
else if (format === "long" || month !== undefined || dateSep !== undefined) {
|
|
1054
|
+
const sep = dateSep ?? ",";
|
|
1055
|
+
base += `${sep} ${month !== undefined ? `${month} ` : ""}${id.year}`;
|
|
1056
|
+
}
|
|
1057
|
+
else {
|
|
1058
|
+
base += `-${id.year}`;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return base;
|
|
1062
|
+
},
|
|
1063
|
+
});
|
|
1064
|
+
export const IreClass = ieeeClass({ kind: "ire" }, {
|
|
1065
|
+
codeColumns: true,
|
|
1066
|
+
extraDefs: {
|
|
1067
|
+
publisher: { type: "string", default: "IRE" },
|
|
1068
|
+
type: { type: "string", default: undefined },
|
|
1069
|
+
},
|
|
1070
|
+
render: (id) => {
|
|
1071
|
+
const shortYear = (() => {
|
|
1072
|
+
if (id.year === undefined)
|
|
1073
|
+
return undefined;
|
|
1074
|
+
const value = Number.parseInt(id.year, 10);
|
|
1075
|
+
return String(value >= 1900 && value <= 1999 ? value - 1900 : value);
|
|
1076
|
+
})();
|
|
1077
|
+
const result = [shortYear, id.publisher, id.type, id.codeObj?.render()]
|
|
1078
|
+
.filter((p) => p !== undefined && p !== "");
|
|
1079
|
+
return result.join(" ");
|
|
1080
|
+
},
|
|
1081
|
+
});
|
|
1082
|
+
const NescDefs = {
|
|
1083
|
+
variant: { type: "string" },
|
|
1084
|
+
registered: { type: "boolean" },
|
|
1085
|
+
abbr_suffix: { type: "boolean" },
|
|
1086
|
+
abbr_suffix_registered: { type: "boolean" },
|
|
1087
|
+
};
|
|
1088
|
+
const NescMappings = keyValue({ wire: "variant", to: "variant" }, { wire: "registered", to: "registered" }, { wire: "abbr_suffix", to: "abbr_suffix" }, { wire: "abbr_suffix_registered", to: "abbr_suffix_registered" });
|
|
1089
|
+
export const NescEditionClass = ieeeClass({ kind: "nesc-edition" }, {
|
|
1090
|
+
codeColumns: true,
|
|
1091
|
+
extraDefs: NescDefs,
|
|
1092
|
+
extraMappings: NescMappings,
|
|
1093
|
+
render: (id) => ["IEEE Std", id.year, nescNamePortion(id)].filter((p) => p !== undefined).join(" "),
|
|
1094
|
+
});
|
|
1095
|
+
export const NescHandbookClass = ieeeClass({ kind: "nesc-handbook" }, {
|
|
1096
|
+
codeColumns: true,
|
|
1097
|
+
extraDefs: { ...NescDefs, edition: { type: "string", default: undefined } },
|
|
1098
|
+
extraMappings: NescMappings,
|
|
1099
|
+
render: (id) => {
|
|
1100
|
+
const abbr = id.registered === true ? "NESC(R)" : "NESC";
|
|
1101
|
+
const parts = [["IEEE Std", id.year, `${abbr} Handbook`].filter((p) => p !== undefined).join(" ")];
|
|
1102
|
+
if (id.edition !== undefined)
|
|
1103
|
+
parts.push(`, ${id.edition}`);
|
|
1104
|
+
return parts.join("");
|
|
1105
|
+
},
|
|
1106
|
+
});
|
|
1107
|
+
export const NescRedlineClass = ieeeClass({ kind: "nesc-redline" }, {
|
|
1108
|
+
codeColumns: true,
|
|
1109
|
+
extraDefs: NescDefs,
|
|
1110
|
+
extraMappings: NescMappings,
|
|
1111
|
+
render: (id) => [id.year, "NESC Redline"].filter((p) => p !== undefined).join(" "),
|
|
1112
|
+
});
|
|
1113
|
+
export const NescStandardClass = ieeeClass({ kind: "nesc-standard" }, {
|
|
1114
|
+
codeColumns: true,
|
|
1115
|
+
extraDefs: NescDefs,
|
|
1116
|
+
extraMappings: NescMappings,
|
|
1117
|
+
render: (id) => {
|
|
1118
|
+
let codePart = "C2";
|
|
1119
|
+
if (id.year !== undefined)
|
|
1120
|
+
codePart += `-${id.year}`;
|
|
1121
|
+
return `${codePart} National Electrical Safety Code`;
|
|
1122
|
+
},
|
|
1123
|
+
});
|
|
1124
|
+
export const NescDraftClass = ieeeClass({ kind: "nesc-draft" }, {
|
|
1125
|
+
codeColumns: true,
|
|
1126
|
+
extraDefs: NescDefs,
|
|
1127
|
+
extraMappings: NescMappings,
|
|
1128
|
+
render: (id) => {
|
|
1129
|
+
const parts = ["Draft National Electrical Safety Code"];
|
|
1130
|
+
if (id.month !== undefined && id.year !== undefined)
|
|
1131
|
+
parts.push(`, ${id.month} ${id.year}`);
|
|
1132
|
+
return parts.join("");
|
|
1133
|
+
},
|
|
1134
|
+
});
|
|
1135
|
+
function nescNamePortion(id) {
|
|
1136
|
+
let name = "National Electrical Safety Code";
|
|
1137
|
+
if (id["registered"] === true)
|
|
1138
|
+
name += "(R)";
|
|
1139
|
+
if (id["abbr_suffix"] === true) {
|
|
1140
|
+
let suffix = "NESC";
|
|
1141
|
+
if (id["abbr_suffix_registered"] === true)
|
|
1142
|
+
suffix += "(R)";
|
|
1143
|
+
name += ` (${suffix})`;
|
|
1144
|
+
}
|
|
1145
|
+
return name;
|
|
1146
|
+
}
|
|
1147
|
+
// The RedlinedStandard wrapper exists in Ruby but is unreachable (a redline
|
|
1148
|
+
// is a flat `redline: true` Standard); not registered.
|