@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,634 @@
|
|
|
1
|
+
import { parseGrammar } from "../../grammar/engine.js";
|
|
2
|
+
import { grammarImplementation } from "../index.js";
|
|
3
|
+
import { csaGrammar, normalizeCsa, csaPublisherPrefix } from "./grammar.js";
|
|
4
|
+
import { BundledClass, CanadianAdoptedClass, CecClass, CombinedClass, CsaAdoptedClass, CsaSingleIdentifier, PackageClass, SeriesClass, StandardClass, } from "./model.js";
|
|
5
|
+
/**
|
|
6
|
+
* Port of lib/pubid/csa/builder.rb + the Identifier.parse pre-parse
|
|
7
|
+
* logic (identifier.rb): CAN/, CAN3-, CSA-adoption, and PACKAGE
|
|
8
|
+
* wrappers; the parser's own normalization + prefix injection.
|
|
9
|
+
*/
|
|
10
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11
|
+
const strv = (v) => {
|
|
12
|
+
if (v === undefined || v === null)
|
|
13
|
+
return undefined;
|
|
14
|
+
if (Array.isArray(v)) {
|
|
15
|
+
const flat = v.flat(10);
|
|
16
|
+
const joined = flat.map(String).join("");
|
|
17
|
+
return joined.length > 0 ? joined : undefined;
|
|
18
|
+
}
|
|
19
|
+
const s = String(v).trim();
|
|
20
|
+
return s.length > 0 ? s : undefined;
|
|
21
|
+
};
|
|
22
|
+
function flatten(data) {
|
|
23
|
+
return Array.isArray(data) ? Object.assign({}, ...data) : data;
|
|
24
|
+
}
|
|
25
|
+
const ctor = (klass) => klass;
|
|
26
|
+
function tryForeign(flavor, raw) {
|
|
27
|
+
const impl = grammarImplementation(flavor);
|
|
28
|
+
if (impl === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
try {
|
|
31
|
+
return impl.parse(raw);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// --- Single identifiers (builder.rb build_single + friends) ---------------------------
|
|
38
|
+
function expandYear(yearStr, prefix) {
|
|
39
|
+
if (yearStr.length === 2) {
|
|
40
|
+
if (prefix === "M")
|
|
41
|
+
return `19${yearStr}`;
|
|
42
|
+
return Number(yearStr) < 50 ? `20${yearStr}` : `19${yearStr}`;
|
|
43
|
+
}
|
|
44
|
+
return yearStr;
|
|
45
|
+
}
|
|
46
|
+
function setReaffirmation(target, data) {
|
|
47
|
+
const self = target;
|
|
48
|
+
if (data["reaffirmation_4digit"] !== undefined) {
|
|
49
|
+
self["reaffirmation"] = strv(data["reaffirmation_4digit"]);
|
|
50
|
+
self["original_reaffirmation_4digit"] = true;
|
|
51
|
+
}
|
|
52
|
+
else if (data["reaffirmation_2digit"] !== undefined) {
|
|
53
|
+
const two = strv(data["reaffirmation_2digit"]) ?? "";
|
|
54
|
+
self["reaffirmation"] = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
55
|
+
self["original_reaffirmation_4digit"] = false;
|
|
56
|
+
}
|
|
57
|
+
else if (data["reaffirmation"] !== undefined) {
|
|
58
|
+
const raw = data["reaffirmation"];
|
|
59
|
+
self["reaffirmation"] = isObj(raw)
|
|
60
|
+
? strv(raw["year"])
|
|
61
|
+
: strv(raw);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function selectSingleClass(data) {
|
|
65
|
+
if (data["no_notation"] !== undefined && data["no_number"] !== undefined)
|
|
66
|
+
return CecClass;
|
|
67
|
+
if (data["series_type"] !== undefined)
|
|
68
|
+
return SeriesClass;
|
|
69
|
+
if (data["series"] !== undefined && strv(data["series"]) === "SERIES")
|
|
70
|
+
return SeriesClass;
|
|
71
|
+
return StandardClass;
|
|
72
|
+
}
|
|
73
|
+
function buildSingle(dataIn) {
|
|
74
|
+
const data = dataIn;
|
|
75
|
+
const identifier = new (ctor(selectSingleClass(data)))();
|
|
76
|
+
const self = identifier;
|
|
77
|
+
if (data["publisher_prefix"] !== undefined) {
|
|
78
|
+
self["publisher_prefix"] = strv(data["publisher_prefix"]);
|
|
79
|
+
}
|
|
80
|
+
else if (data["code"] !== undefined) {
|
|
81
|
+
self["code_only"] = true;
|
|
82
|
+
}
|
|
83
|
+
if (data["has_publisher"] !== undefined)
|
|
84
|
+
self["has_publisher"] = true;
|
|
85
|
+
if (data["code"] !== undefined && !(identifier instanceof CecClass)) {
|
|
86
|
+
const codeValue = strv(data["code"]) ?? "";
|
|
87
|
+
const m = !data["year"] ? /^(.+)-(\d{2})$/.exec(codeValue) : null;
|
|
88
|
+
if (m !== null) {
|
|
89
|
+
self["number"] = m[1];
|
|
90
|
+
self["year"] = `20${m[2]}`;
|
|
91
|
+
self["year_format"] = "dash";
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
self["number"] = codeValue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (identifier instanceof CecClass) {
|
|
98
|
+
if (data["code"] !== undefined && self["cec_part"] === undefined) {
|
|
99
|
+
self["cec_part"] = strv(data["code"]);
|
|
100
|
+
}
|
|
101
|
+
if (data["no_number"] !== undefined) {
|
|
102
|
+
self["no_number"] = strv(data["no_number"]);
|
|
103
|
+
}
|
|
104
|
+
if (self["cec_part"] !== undefined && self["no_number"] !== undefined) {
|
|
105
|
+
self["number"] = `${self["cec_part"]}-${self["no_number"]}`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (data["series_prefix"] !== undefined)
|
|
109
|
+
self["series_prefix"] = strv(data["series_prefix"]);
|
|
110
|
+
if (data["series"] !== undefined)
|
|
111
|
+
self["series"] = true;
|
|
112
|
+
const yearFormat = data["dash_format"] !== undefined
|
|
113
|
+
? "dash"
|
|
114
|
+
: "colon";
|
|
115
|
+
if (data["year"] !== undefined && self["year"] === undefined) {
|
|
116
|
+
const yearStr = strv(data["year"]) ?? "";
|
|
117
|
+
self["year"] = expandYear(yearStr, strv(data["year_prefix"]));
|
|
118
|
+
if (yearStr.length === 4)
|
|
119
|
+
self["original_year_4digit"] = true;
|
|
120
|
+
self["year_format"] = yearFormat;
|
|
121
|
+
}
|
|
122
|
+
if (data["year_prefix"] !== undefined) {
|
|
123
|
+
self["year_prefix"] = strv(data["year_prefix"]);
|
|
124
|
+
if (strv(data["year_prefix"]) === "F")
|
|
125
|
+
self["french"] = true;
|
|
126
|
+
}
|
|
127
|
+
if (data["french"] !== undefined)
|
|
128
|
+
self["french"] = true;
|
|
129
|
+
setReaffirmation(identifier, data);
|
|
130
|
+
if (data["package_portion"] !== undefined) {
|
|
131
|
+
self["package"] = strv(data["package_portion"]);
|
|
132
|
+
}
|
|
133
|
+
return identifier;
|
|
134
|
+
}
|
|
135
|
+
function buildSeries(dataIn) {
|
|
136
|
+
const data = dataIn;
|
|
137
|
+
const series = new (ctor(SeriesClass))();
|
|
138
|
+
const self = series;
|
|
139
|
+
self["series"] = true;
|
|
140
|
+
if (data["publisher_prefix"] !== undefined)
|
|
141
|
+
self["publisher_prefix"] = strv(data["publisher_prefix"]);
|
|
142
|
+
if (data["series_prefix"] !== undefined)
|
|
143
|
+
self["series_prefix"] = strv(data["series_prefix"]);
|
|
144
|
+
if (data["code"] !== undefined)
|
|
145
|
+
self["number"] = strv(data["code"]);
|
|
146
|
+
if (data["year"] !== undefined) {
|
|
147
|
+
const yearStr = strv(data["year"]) ?? "";
|
|
148
|
+
self["year"] = expandYear(yearStr, strv(data["year_prefix"]));
|
|
149
|
+
if (yearStr.length === 4)
|
|
150
|
+
self["original_year_4digit"] = true;
|
|
151
|
+
self["year_format"] = data["dash_format"] !== undefined ? "dash" : "colon";
|
|
152
|
+
}
|
|
153
|
+
if (data["year_prefix"] !== undefined)
|
|
154
|
+
self["year_prefix"] = strv(data["year_prefix"]);
|
|
155
|
+
setReaffirmation(series, data);
|
|
156
|
+
return series;
|
|
157
|
+
}
|
|
158
|
+
function buildCec(dataIn) {
|
|
159
|
+
const data = dataIn;
|
|
160
|
+
const cec = new (ctor(CecClass))();
|
|
161
|
+
const self = cec;
|
|
162
|
+
if (data["publisher_prefix"] !== undefined)
|
|
163
|
+
self["publisher_prefix"] = strv(data["publisher_prefix"]);
|
|
164
|
+
if (data["cec_part"] !== undefined)
|
|
165
|
+
self["cec_part"] = strv(data["cec_part"]);
|
|
166
|
+
if (data["no_number"] !== undefined)
|
|
167
|
+
self["no_number"] = strv(data["no_number"]);
|
|
168
|
+
if (self["cec_part"] !== undefined && self["no_number"] !== undefined) {
|
|
169
|
+
self["number"] = `${self["cec_part"]}-${self["no_number"]}`;
|
|
170
|
+
}
|
|
171
|
+
if (data["year"] !== undefined) {
|
|
172
|
+
const yearStr = strv(data["year"]) ?? "";
|
|
173
|
+
self["year"] = expandYear(yearStr, strv(data["year_prefix"]));
|
|
174
|
+
if (yearStr.length === 4)
|
|
175
|
+
self["original_year_4digit"] = true;
|
|
176
|
+
self["year_format"] = data["dash_format"] !== undefined ? "dash" : "colon";
|
|
177
|
+
}
|
|
178
|
+
if (data["year_prefix"] !== undefined) {
|
|
179
|
+
self["year_prefix"] = strv(data["year_prefix"]);
|
|
180
|
+
if (strv(data["year_prefix"]) === "F")
|
|
181
|
+
self["french"] = true;
|
|
182
|
+
}
|
|
183
|
+
if (data["french"] !== undefined)
|
|
184
|
+
self["french"] = true;
|
|
185
|
+
setReaffirmation(cec, data);
|
|
186
|
+
return cec;
|
|
187
|
+
}
|
|
188
|
+
// --- The builder dispatch ---------------------------------------------------------------
|
|
189
|
+
function buildTree(parsed) {
|
|
190
|
+
const data = parsed;
|
|
191
|
+
if (data["publisher_prefix"] !== undefined
|
|
192
|
+
&& ["CAN/CSA-", "CAN3-"].includes(strv(data["publisher_prefix"]) ?? "")) {
|
|
193
|
+
return buildCanadianAdopted(data);
|
|
194
|
+
}
|
|
195
|
+
if ("adoption_number" in data)
|
|
196
|
+
return buildAdoption(data);
|
|
197
|
+
if ("series_type" in data)
|
|
198
|
+
return buildSeries(parsed);
|
|
199
|
+
if ("cec_part" in data)
|
|
200
|
+
return buildCec(parsed);
|
|
201
|
+
if ("package_portion" in data)
|
|
202
|
+
return buildPackage(parsed);
|
|
203
|
+
if ("bundled_first" in data)
|
|
204
|
+
return buildBundled(data);
|
|
205
|
+
if (data["first"] !== undefined && data["second"] !== undefined)
|
|
206
|
+
return buildCombined(data);
|
|
207
|
+
return buildSingle(parsed);
|
|
208
|
+
}
|
|
209
|
+
function buildPackage(data) {
|
|
210
|
+
const baseData = { ...data };
|
|
211
|
+
delete baseData["package_portion"];
|
|
212
|
+
return new (ctor(PackageClass))({
|
|
213
|
+
base: buildSingle(baseData),
|
|
214
|
+
...(data["package_portion"] !== undefined
|
|
215
|
+
? { package_materials: strv(data["package_portion"]) }
|
|
216
|
+
: {}),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function parseAdoptionBase(adoptionOrg, baseStr) {
|
|
220
|
+
if (adoptionOrg.startsWith("ISO") || adoptionOrg.startsWith("CEI")) {
|
|
221
|
+
return tryForeign("iso", baseStr);
|
|
222
|
+
}
|
|
223
|
+
if (adoptionOrg.startsWith("IEC")) {
|
|
224
|
+
return tryForeign("iec", baseStr);
|
|
225
|
+
}
|
|
226
|
+
return tryForeign("iso", baseStr) ?? tryForeign("iec", baseStr);
|
|
227
|
+
}
|
|
228
|
+
function buildAdoption(data) {
|
|
229
|
+
let adoptionOrg = strv(data["adoption_org"]) ?? "";
|
|
230
|
+
const adoptionNumber = strv(data["adoption_number"]) ?? "";
|
|
231
|
+
const adoptionYear = strv(data["adoption_year"]) ?? "";
|
|
232
|
+
if (data["iso_type"] !== undefined)
|
|
233
|
+
adoptionOrg += ` ${strv(data["iso_type"])}`;
|
|
234
|
+
const yearSep = strv(data["adoption_year_sep"]) ?? ":";
|
|
235
|
+
const wrappedYear = adoptionYear.length === 2 ? `20${adoptionYear}` : adoptionYear;
|
|
236
|
+
let base;
|
|
237
|
+
if (data["adoption_amendment"] !== undefined) {
|
|
238
|
+
const baseStr = `${adoptionOrg} ${adoptionNumber}${yearSep}${wrappedYear}`;
|
|
239
|
+
const amendmentYear = strv(data["adoption_amendment_year"]) ?? "";
|
|
240
|
+
const wrappedAmendmentYear = amendmentYear.length === 2 ? `20${amendmentYear}` : amendmentYear;
|
|
241
|
+
const amendmentStr = `${baseStr}/Amd ${strv(data["adoption_amendment"])}:${wrappedAmendmentYear}`;
|
|
242
|
+
base = parseAdoptionBase(adoptionOrg, amendmentStr);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
let wrappedIdStr = `${adoptionOrg} ${adoptionNumber}${yearSep}${wrappedYear}`;
|
|
246
|
+
if (adoptionOrg === "CEI/IEC") {
|
|
247
|
+
wrappedIdStr = wrappedIdStr.replace("CEI/IEC", "IEC");
|
|
248
|
+
}
|
|
249
|
+
base = parseAdoptionBase(adoptionOrg, wrappedIdStr);
|
|
250
|
+
}
|
|
251
|
+
const self = { base };
|
|
252
|
+
if (data["reaffirmation_4digit"] !== undefined) {
|
|
253
|
+
self["reaffirmation"] = strv(data["reaffirmation_4digit"]);
|
|
254
|
+
}
|
|
255
|
+
else if (data["reaffirmation_2digit"] !== undefined) {
|
|
256
|
+
const two = strv(data["reaffirmation_2digit"]) ?? "";
|
|
257
|
+
self["reaffirmation"] = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
258
|
+
}
|
|
259
|
+
else if (data["reaffirmation"] !== undefined) {
|
|
260
|
+
const raw = data["reaffirmation"];
|
|
261
|
+
self["reaffirmation"] = isObj(raw) ? strv(raw["year"]) : strv(raw);
|
|
262
|
+
}
|
|
263
|
+
return new (ctor(CsaAdoptedClass))(self);
|
|
264
|
+
}
|
|
265
|
+
function buildCanadianAdopted(data) {
|
|
266
|
+
const originalPrefix = strv(data["publisher_prefix"]);
|
|
267
|
+
const wrappedData = { ...data };
|
|
268
|
+
delete wrappedData["publisher_prefix"];
|
|
269
|
+
let base;
|
|
270
|
+
if ("series_type" in wrappedData) {
|
|
271
|
+
base = buildSeries(wrappedData);
|
|
272
|
+
if (originalPrefix !== undefined) {
|
|
273
|
+
base["publisher_prefix"] = originalPrefix;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else if ("cec_part" in wrappedData) {
|
|
277
|
+
base = buildCec(wrappedData);
|
|
278
|
+
if (originalPrefix !== undefined) {
|
|
279
|
+
base["publisher_prefix"] = originalPrefix;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
base = buildSingle(wrappedData);
|
|
284
|
+
if (originalPrefix !== undefined) {
|
|
285
|
+
base["publisher_prefix"] = originalPrefix;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const self = { base };
|
|
289
|
+
if (data["reaffirmation_4digit"] !== undefined) {
|
|
290
|
+
self["reaffirmation"] = strv(data["reaffirmation_4digit"]);
|
|
291
|
+
}
|
|
292
|
+
else if (data["reaffirmation_2digit"] !== undefined) {
|
|
293
|
+
const two = strv(data["reaffirmation_2digit"]) ?? "";
|
|
294
|
+
self["reaffirmation"] = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
295
|
+
}
|
|
296
|
+
return new (ctor(CanadianAdoptedClass))(self);
|
|
297
|
+
}
|
|
298
|
+
function buildBundled(data) {
|
|
299
|
+
const base = buildSingle(flatten(data["base"]));
|
|
300
|
+
const portions = [flatten(data["bundled_first"])];
|
|
301
|
+
const rest = data["bundled_rest"];
|
|
302
|
+
if (rest !== undefined && (!Array.isArray(rest) || rest.length > 0)) {
|
|
303
|
+
const restArr = (Array.isArray(rest)
|
|
304
|
+
? rest.flat(10)
|
|
305
|
+
: [rest])
|
|
306
|
+
.filter((x) => isObj(x));
|
|
307
|
+
for (const portion of restArr) {
|
|
308
|
+
portions.push(flatten(portion));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const self = {
|
|
312
|
+
base,
|
|
313
|
+
bundled_with: portions.map((p) => buildSingle(p)),
|
|
314
|
+
};
|
|
315
|
+
if (data["reaffirmation_4digit"] !== undefined) {
|
|
316
|
+
self["reaffirmation"] = strv(data["reaffirmation_4digit"]);
|
|
317
|
+
self["original_reaffirmation_4digit"] = true;
|
|
318
|
+
}
|
|
319
|
+
else if (data["reaffirmation_2digit"] !== undefined) {
|
|
320
|
+
const two = strv(data["reaffirmation_2digit"]) ?? "";
|
|
321
|
+
self["reaffirmation"] = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
322
|
+
}
|
|
323
|
+
return new (ctor(BundledClass))(self);
|
|
324
|
+
}
|
|
325
|
+
function buildCombined(data) {
|
|
326
|
+
const parts = ["first", "second", "third"]
|
|
327
|
+
.map((key) => data[key])
|
|
328
|
+
.filter((v) => v !== undefined)
|
|
329
|
+
.map((v) => buildSingle(flatten(v)));
|
|
330
|
+
const self = {
|
|
331
|
+
identifiers: parts,
|
|
332
|
+
separator: data["comma_separator"] !== undefined ? ", " : "/",
|
|
333
|
+
};
|
|
334
|
+
if (data["reaffirmation_4digit"] !== undefined) {
|
|
335
|
+
self["reaffirmation"] = strv(data["reaffirmation_4digit"]);
|
|
336
|
+
self["original_reaffirmation_4digit"] = true;
|
|
337
|
+
}
|
|
338
|
+
else if (data["reaffirmation_2digit"] !== undefined) {
|
|
339
|
+
const two = strv(data["reaffirmation_2digit"]) ?? "";
|
|
340
|
+
self["reaffirmation"] = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
341
|
+
}
|
|
342
|
+
else if (data["reaffirmation"] !== undefined) {
|
|
343
|
+
self["reaffirmation"] = strv(data["reaffirmation"]);
|
|
344
|
+
}
|
|
345
|
+
if (data["package_portion"] !== undefined) {
|
|
346
|
+
self["package"] = strv(data["package_portion"]);
|
|
347
|
+
}
|
|
348
|
+
return new (ctor(CombinedClass))(self);
|
|
349
|
+
}
|
|
350
|
+
// --- The parser entry (parser.rb parse + prefix injection) -------------------------------
|
|
351
|
+
function injectPublisherPrefix(hash, prefix) {
|
|
352
|
+
const first = hash["first"];
|
|
353
|
+
if (isObj(first))
|
|
354
|
+
first["publisher_prefix"] = prefix;
|
|
355
|
+
const second = hash["second"];
|
|
356
|
+
if (isObj(second)
|
|
357
|
+
&& (hash["comma_separator"] !== undefined || second["has_publisher"] !== undefined)) {
|
|
358
|
+
second["publisher_prefix"] = prefix;
|
|
359
|
+
}
|
|
360
|
+
const third = hash["third"];
|
|
361
|
+
if (isObj(third) && third["has_publisher"] !== undefined) {
|
|
362
|
+
third["publisher_prefix"] = prefix;
|
|
363
|
+
}
|
|
364
|
+
const base = hash["base"];
|
|
365
|
+
if (isObj(base))
|
|
366
|
+
injectPublisherPrefix(base, prefix);
|
|
367
|
+
if (hash["first"] === undefined && hash["base"] === undefined && hash["bundled_first"] === undefined) {
|
|
368
|
+
hash["publisher_prefix"] = prefix;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function parseTree(input) {
|
|
372
|
+
const normalized = normalizeCsa(input);
|
|
373
|
+
const prefix = csaPublisherPrefix(normalized);
|
|
374
|
+
const tree = parseGrammar(csaGrammar, normalized);
|
|
375
|
+
const hash = flatten(tree);
|
|
376
|
+
if (prefix !== undefined)
|
|
377
|
+
injectPublisherPrefix(hash, prefix);
|
|
378
|
+
return hash;
|
|
379
|
+
}
|
|
380
|
+
// --- Identifier.parse (identifier.rb) ------------------------------------------------------
|
|
381
|
+
function tryParse(input) {
|
|
382
|
+
try {
|
|
383
|
+
return parseCsa(input);
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function extractReaffirmation(wrappedInput) {
|
|
390
|
+
const m = /\(R(\d{2,4})\)/.exec(wrappedInput);
|
|
391
|
+
if (m === null)
|
|
392
|
+
return { year: undefined, was4digit: false, rest: wrappedInput };
|
|
393
|
+
let year = m[1];
|
|
394
|
+
const was4digit = year.length === 4;
|
|
395
|
+
if (year.length === 2) {
|
|
396
|
+
year = Number(year) < 50 ? `20${year}` : `19${year}`;
|
|
397
|
+
}
|
|
398
|
+
const rest = wrappedInput.replace(/\s*\(R\d{2,4}\)/, "");
|
|
399
|
+
return { year, was4digit, rest };
|
|
400
|
+
}
|
|
401
|
+
function setPublisherPrefix(obj, prefix) {
|
|
402
|
+
const self = obj;
|
|
403
|
+
self["publisher_prefix"] = prefix;
|
|
404
|
+
const combined = self["identifiers"];
|
|
405
|
+
if (combined !== undefined) {
|
|
406
|
+
combined.forEach((part, index) => {
|
|
407
|
+
const partSelf = part;
|
|
408
|
+
if (index > 0 && partSelf["has_publisher"] !== true)
|
|
409
|
+
return;
|
|
410
|
+
partSelf["publisher_prefix"] = prefix;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
const base = self["base"];
|
|
414
|
+
if (base !== undefined && combined === undefined) {
|
|
415
|
+
setPublisherPrefix(base, prefix);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function parseExternalStandard(input) {
|
|
419
|
+
if (/^(ISO\/IEC|ISO|IEC|CEI|CEI\/IEC)\s/.test(input)) {
|
|
420
|
+
return tryForeign("iso", input.replace(/^CEI\/IEC/, "IEC"));
|
|
421
|
+
}
|
|
422
|
+
// The catalogue also prints the IWA designation without the ISO
|
|
423
|
+
// keyword ("CAN/CSA-IWA 18:17" beside "CAN/CSA-ISO IWA 18:17"); the
|
|
424
|
+
// ISO parser wants the ISO/ prefix.
|
|
425
|
+
if (/^IWA\s/.test(input)) {
|
|
426
|
+
return tryForeign("iso", input.replace(/^IWA\s/, "ISO/IWA "));
|
|
427
|
+
}
|
|
428
|
+
if (/^CISPR\s/.test(input)) {
|
|
429
|
+
return tryForeign("iec", input);
|
|
430
|
+
}
|
|
431
|
+
return undefined;
|
|
432
|
+
}
|
|
433
|
+
function parseCsa(input) {
|
|
434
|
+
if (input.startsWith("#")) {
|
|
435
|
+
throw new Error(`Not a CSA identifier (comment): ${input}`);
|
|
436
|
+
}
|
|
437
|
+
if (/^CSA (Communities|Group|Learning|OnDemand|Update)/.test(input)) {
|
|
438
|
+
throw new Error(`Not a CSA standard: ${input}`);
|
|
439
|
+
}
|
|
440
|
+
input = input.replaceAll("CEI/IEC", "IEC").replaceAll(/\bCEI\b/g, "IEC");
|
|
441
|
+
// CAN/ wrapper (Canadian adoption).
|
|
442
|
+
if (input.startsWith("CAN/")) {
|
|
443
|
+
const wrappedInput0 = input.replace(/^CAN\//, "");
|
|
444
|
+
if (wrappedInput0.includes("+")
|
|
445
|
+
|| (wrappedInput0.includes("/") && /\s+CSA-/.test(wrappedInput0))
|
|
446
|
+
|| (wrappedInput0.includes("/") && (wrappedInput0.match(/CSA-/g) ?? []).length > 1)) {
|
|
447
|
+
let normalized = wrappedInput0.replace(/^CSA-/, "CSA ");
|
|
448
|
+
normalized = normalized.replaceAll("CAN/CSA-", "CSA ").replaceAll("CAN3-", "CSA ");
|
|
449
|
+
normalized = normalized.replaceAll(/\s+/g, " ").trim();
|
|
450
|
+
const result = buildTree(parseTree(normalized));
|
|
451
|
+
setPublisherPrefix(result, "CAN/CSA-");
|
|
452
|
+
const rMatch = /\(R(\d{4})\)/.exec(wrappedInput0);
|
|
453
|
+
if (rMatch !== null) {
|
|
454
|
+
result["reaffirmation"] = rMatch[1];
|
|
455
|
+
}
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
const { year: reaffirmYear, was4digit, rest: stripped } = extractReaffirmation(wrappedInput0);
|
|
459
|
+
const originalPrefix = stripped.startsWith("CSA-")
|
|
460
|
+
? "CSA-"
|
|
461
|
+
: stripped.startsWith("CSA ")
|
|
462
|
+
? "CSA"
|
|
463
|
+
: undefined;
|
|
464
|
+
const normalized = stripped.replace(/^CSA-/, "CSA ");
|
|
465
|
+
const base = parseCsa(normalized);
|
|
466
|
+
const baseSelf = base;
|
|
467
|
+
// Only the single-document types and CsaAdopted declare
|
|
468
|
+
// publisher_prefix; the containers (Combined/Bundled/Package) keep
|
|
469
|
+
// what the recursive parse already injected.
|
|
470
|
+
if (base instanceof CsaSingleIdentifier || base instanceof CsaAdoptedClass) {
|
|
471
|
+
if (base instanceof SeriesClass) {
|
|
472
|
+
baseSelf["publisher_prefix"] = "CAN/CSA-";
|
|
473
|
+
}
|
|
474
|
+
else if (originalPrefix !== undefined) {
|
|
475
|
+
baseSelf["publisher_prefix"] = originalPrefix;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (reaffirmYear !== undefined) {
|
|
479
|
+
baseSelf["reaffirmation"] = reaffirmYear;
|
|
480
|
+
baseSelf["original_reaffirmation_4digit"] = was4digit;
|
|
481
|
+
}
|
|
482
|
+
return new (ctor(CanadianAdoptedClass))({
|
|
483
|
+
base,
|
|
484
|
+
...(reaffirmYear !== undefined ? { reaffirmation: reaffirmYear } : {}),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
// CAN3- wrapper (historical).
|
|
488
|
+
if (input.startsWith("CAN3-")) {
|
|
489
|
+
const wrapped0 = input.replace(/^CAN3-/, "CSA ");
|
|
490
|
+
const hasDashYear = /-\d{2}\b/.test(wrapped0);
|
|
491
|
+
const { year: reaffirmYear, was4digit, rest: stripped } = extractReaffirmation(wrapped0);
|
|
492
|
+
const base = parseCsa(stripped);
|
|
493
|
+
const baseSelf = base;
|
|
494
|
+
if (hasDashYear) {
|
|
495
|
+
baseSelf["year_format"] = "dash";
|
|
496
|
+
baseSelf["original_year_4digit"] = false;
|
|
497
|
+
}
|
|
498
|
+
if (base instanceof SeriesClass) {
|
|
499
|
+
baseSelf["publisher_prefix"] = "CAN3-";
|
|
500
|
+
if (reaffirmYear !== undefined) {
|
|
501
|
+
baseSelf["reaffirmation"] = reaffirmYear;
|
|
502
|
+
baseSelf["original_reaffirmation_4digit"] = was4digit;
|
|
503
|
+
}
|
|
504
|
+
return base;
|
|
505
|
+
}
|
|
506
|
+
baseSelf["publisher_prefix"] = "CAN3-";
|
|
507
|
+
if (reaffirmYear !== undefined) {
|
|
508
|
+
baseSelf["reaffirmation"] = reaffirmYear;
|
|
509
|
+
baseSelf["original_reaffirmation_4digit"] = was4digit;
|
|
510
|
+
}
|
|
511
|
+
return new (ctor(CanadianAdoptedClass))({
|
|
512
|
+
base,
|
|
513
|
+
...(reaffirmYear !== undefined ? { reaffirmation: reaffirmYear } : {}),
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
// CSA adoption of international standards. The catalogue also drops
|
|
517
|
+
// the ISO keyword from the IWA designation ("CSA IWA 18:17").
|
|
518
|
+
if (/^CSA (ISO\/IEC|CEI\/IEC|CISPR|IEC|CEI|ISO|IWA)\s/.test(input)) {
|
|
519
|
+
let wrapped = input.replace(/^CSA\s+/, "");
|
|
520
|
+
const { year: reaffirmYear, rest: stripped } = extractReaffirmation(wrapped);
|
|
521
|
+
wrapped = stripped;
|
|
522
|
+
const shortYear = /:(\d{2})\b/.exec(wrapped);
|
|
523
|
+
if (shortYear !== null) {
|
|
524
|
+
const two = shortYear[1];
|
|
525
|
+
const full = Number(two) < 50 ? `20${two}` : `19${two}`;
|
|
526
|
+
wrapped = wrapped.replace(new RegExp(`:${two}\\b`), `:${full}`);
|
|
527
|
+
}
|
|
528
|
+
wrapped = wrapped.replace(/\/A(\d+)([:/-])(\d{2,4})\b/g, (_m, num, sep, year) => {
|
|
529
|
+
const full = year.length === 2
|
|
530
|
+
? (Number(year) < 50 ? `20${year}` : `19${year}`)
|
|
531
|
+
: year;
|
|
532
|
+
return `/Amd ${num}${sep}${full}`;
|
|
533
|
+
});
|
|
534
|
+
const base = parseExternalStandard(wrapped);
|
|
535
|
+
if (base === undefined) {
|
|
536
|
+
throw new Error(`Unparseable adopted standard: ${input}`);
|
|
537
|
+
}
|
|
538
|
+
return new (ctor(CsaAdoptedClass))({
|
|
539
|
+
base,
|
|
540
|
+
...(reaffirmYear !== undefined ? { reaffirmation: reaffirmYear } : {}),
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
// Package identifiers.
|
|
544
|
+
if (/\sPACKAGE\b/i.test(input)) {
|
|
545
|
+
let baseInput;
|
|
546
|
+
let packageMaterials;
|
|
547
|
+
let materialsAfter = true;
|
|
548
|
+
const after = /\sPACKAGE\s+[A-Z]/i.exec(input);
|
|
549
|
+
const yearThen = /:(\d{2,4})(\s+[^P]+)\s+PACKAGE/i.exec(input);
|
|
550
|
+
if (after !== null) {
|
|
551
|
+
const idx = input.search(/\s+PACKAGE\s+/i);
|
|
552
|
+
baseInput = input.slice(0, idx).trim();
|
|
553
|
+
packageMaterials = input.slice(input.indexOf("PACKAGE", idx) + "PACKAGE".length).trim() === ""
|
|
554
|
+
? ""
|
|
555
|
+
: input.slice(idx).replace(/^\s+PACKAGE\s+/i, "").trim();
|
|
556
|
+
materialsAfter = true;
|
|
557
|
+
}
|
|
558
|
+
else if (yearThen !== null) {
|
|
559
|
+
const yearMatch = /:\d{2,4}/.exec(input);
|
|
560
|
+
if (yearMatch !== null) {
|
|
561
|
+
if (/,\s+CSA/.test(input)) {
|
|
562
|
+
const combinedMatch = /^(.+?)(\s+&[^P]+)\s+PACKAGE$/i.exec(input);
|
|
563
|
+
if (combinedMatch !== null) {
|
|
564
|
+
baseInput = combinedMatch[1].trim();
|
|
565
|
+
packageMaterials = `${combinedMatch[2].trim()} Package`;
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
baseInput = input.slice(0, yearMatch.index + yearMatch[0].length);
|
|
569
|
+
packageMaterials = input.slice(yearMatch.index + yearMatch[0].length).trim();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
baseInput = input.slice(0, yearMatch.index + yearMatch[0].length).trim();
|
|
574
|
+
packageMaterials = input.slice(yearMatch.index + yearMatch[0].length).trim();
|
|
575
|
+
}
|
|
576
|
+
materialsAfter = false;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
const trailing = /^(.+?)\s+PACKAGE\s*$/i.exec(input);
|
|
581
|
+
if (trailing !== null) {
|
|
582
|
+
baseInput = trailing[1].trim();
|
|
583
|
+
packageMaterials = "";
|
|
584
|
+
materialsAfter = true;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (baseInput === undefined || baseInput === "") {
|
|
588
|
+
// Fallback: parse incrementally.
|
|
589
|
+
const tokens = input.split(/\s+/);
|
|
590
|
+
let acc = "";
|
|
591
|
+
for (const token of tokens) {
|
|
592
|
+
if (/^PACKAGE$/i.test(token))
|
|
593
|
+
break;
|
|
594
|
+
const testInput = acc === "" ? token : `${acc} ${token}`;
|
|
595
|
+
if (tryParse(testInput) === undefined)
|
|
596
|
+
break;
|
|
597
|
+
acc = testInput;
|
|
598
|
+
}
|
|
599
|
+
baseInput = acc;
|
|
600
|
+
if (baseInput !== "" && baseInput.length < input.length) {
|
|
601
|
+
const materialsInput = input.slice(baseInput.length).trim();
|
|
602
|
+
packageMaterials = materialsInput.replace(/\s+PACKAGE\s*$/i, "").trim();
|
|
603
|
+
materialsAfter = packageMaterials !== "";
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (baseInput === undefined || baseInput === "") {
|
|
607
|
+
throw new Error(`Unparseable package base: ${input}`);
|
|
608
|
+
}
|
|
609
|
+
const base = parseCsa(baseInput);
|
|
610
|
+
return new (ctor(PackageClass))({
|
|
611
|
+
base,
|
|
612
|
+
package_keyword: "PACKAGE",
|
|
613
|
+
...(packageMaterials !== undefined && packageMaterials !== ""
|
|
614
|
+
? { package_materials: packageMaterials }
|
|
615
|
+
: {}),
|
|
616
|
+
materials_after_keyword: materialsAfter,
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
// Plain path with parser-level normalization and prefix injection.
|
|
620
|
+
const hasDashYear = /-\d{2}\b/.test(input);
|
|
621
|
+
const result = buildTree(parseTree(input));
|
|
622
|
+
const self = result;
|
|
623
|
+
if (hasDashYear && self["year_format"] === undefined) {
|
|
624
|
+
self["year_format"] = "dash";
|
|
625
|
+
}
|
|
626
|
+
return result;
|
|
627
|
+
}
|
|
628
|
+
export function csaGrammarImplementation() {
|
|
629
|
+
return {
|
|
630
|
+
parse(input) {
|
|
631
|
+
return parseCsa(input);
|
|
632
|
+
},
|
|
633
|
+
};
|
|
634
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseIdentifier } from "../../model/identifier.js";
|
|
2
|
+
import type { IdentifierStatic } from "../../model/identifier.js";
|
|
3
|
+
import { type AttributeTable, type FieldMapping } from "../../model/attribute.js";
|
|
4
|
+
export declare abstract class CsaIdentifier extends BaseIdentifier {
|
|
5
|
+
root(): CsaIdentifier;
|
|
6
|
+
}
|
|
7
|
+
export declare abstract class CsaSingleIdentifier extends CsaIdentifier {
|
|
8
|
+
static attributes: AttributeTable;
|
|
9
|
+
static mappings: FieldMapping[];
|
|
10
|
+
readonly number: string | undefined;
|
|
11
|
+
readonly no_number: string | undefined;
|
|
12
|
+
readonly year: string | undefined;
|
|
13
|
+
readonly year_format: string | undefined;
|
|
14
|
+
readonly year_prefix: string | undefined;
|
|
15
|
+
readonly original_year_4digit: boolean | undefined;
|
|
16
|
+
readonly french: boolean | undefined;
|
|
17
|
+
readonly reaffirmation: string | undefined;
|
|
18
|
+
readonly original_reaffirmation_4digit: boolean | undefined;
|
|
19
|
+
readonly has_publisher: boolean | undefined;
|
|
20
|
+
readonly series_prefix: string | undefined;
|
|
21
|
+
readonly series: boolean | undefined;
|
|
22
|
+
readonly package: string | undefined;
|
|
23
|
+
readonly publisher_prefix: string | undefined;
|
|
24
|
+
readonly code_only: boolean | undefined;
|
|
25
|
+
}
|
|
26
|
+
export declare const StandardClass: IdentifierStatic;
|
|
27
|
+
export declare const SeriesClass: IdentifierStatic;
|
|
28
|
+
export declare const CecClass: IdentifierStatic;
|
|
29
|
+
export declare const CanadianAdoptedClass: IdentifierStatic;
|
|
30
|
+
export declare const CsaAdoptedClass: IdentifierStatic;
|
|
31
|
+
export declare const PackageClass: IdentifierStatic;
|
|
32
|
+
export declare const BundledClass: IdentifierStatic;
|
|
33
|
+
export declare const CombinedClass: IdentifierStatic;
|