@pubid/pubid 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifact/corpus.json.gz +0 -0
- package/dist/flavors/ieee/index.js +136 -19
- package/dist/flavors/ieee/model.js +90 -34
- package/dist/flavors/ieee/preprocessor.js +46 -1
- package/package.json +2 -2
- package/vendor/parg/adobe.json +1 -1
- package/vendor/parg/aiee.json +1 -1
- package/vendor/parg/amca.json +1 -1
- package/vendor/parg/ansi.json +1 -1
- package/vendor/parg/api.json +1 -1
- package/vendor/parg/ashrae.json +1 -1
- package/vendor/parg/asme.json +1 -1
- package/vendor/parg/astm.json +1 -1
- package/vendor/parg/bipm.json +1 -1
- package/vendor/parg/bsi.json +1 -1
- package/vendor/parg/calconnect.json +1 -1
- package/vendor/parg/ccsds.json +1 -1
- package/vendor/parg/cen_cenelec.json +1 -1
- package/vendor/parg/cie.json +1 -1
- package/vendor/parg/csa.json +1 -1
- package/vendor/parg/doi.json +1 -1
- package/vendor/parg/easc.json +1 -1
- package/vendor/parg/ecma.json +1 -1
- package/vendor/parg/etsi.json +1 -1
- package/vendor/parg/evs.json +1 -1
- package/vendor/parg/gb.json +1 -1
- package/vendor/parg/gost.json +1 -1
- package/vendor/parg/iala.json +1 -1
- package/vendor/parg/iana.json +1 -1
- package/vendor/parg/idf.json +1 -1
- package/vendor/parg/iec.json +1 -1
- package/vendor/parg/ieee.json +1 -1
- package/vendor/parg/ietf.json +1 -1
- package/vendor/parg/ire.json +1 -1
- package/vendor/parg/isbn.json +1 -1
- package/vendor/parg/iso.json +1 -1
- package/vendor/parg/itu.json +1 -1
- package/vendor/parg/jcgm.json +1 -1
- package/vendor/parg/jis.json +1 -1
- package/vendor/parg/nesc.json +1 -1
- package/vendor/parg/nist.json +1 -1
- package/vendor/parg/oasis.json +1 -1
- package/vendor/parg/ogc.json +1 -1
- package/vendor/parg/oiml.json +1 -1
- package/vendor/parg/omg.json +1 -1
- package/vendor/parg/parg.json +1 -1
- package/vendor/parg/plateau.json +1 -1
- package/vendor/parg/sae.json +1 -1
- package/vendor/parg/tgpp.json +1 -1
- package/vendor/parg/un.json +1 -1
- package/vendor/parg/w3c.json +1 -1
- package/vendor/parg/xsf.json +1 -1
package/artifact/corpus.json.gz
CHANGED
|
Binary file
|
|
@@ -119,7 +119,7 @@ class IeeeBuilder {
|
|
|
119
119
|
}
|
|
120
120
|
const dash = drafts.find((e) => isObj(e) && e["dash_year"] !== undefined) ??
|
|
121
121
|
(d["dash_year"] !== undefined ? d : undefined);
|
|
122
|
-
if (dash === undefined
|
|
122
|
+
if (dash === undefined)
|
|
123
123
|
return;
|
|
124
124
|
const objs = drafts.filter(isObj);
|
|
125
125
|
const joined = objs
|
|
@@ -151,7 +151,7 @@ class IeeeBuilder {
|
|
|
151
151
|
delete dash["dash_year"];
|
|
152
152
|
delete dash["dash_month"];
|
|
153
153
|
}
|
|
154
|
-
else {
|
|
154
|
+
else if (d["year"] === undefined) {
|
|
155
155
|
d["year"] = dashYear;
|
|
156
156
|
d["month"] = dm;
|
|
157
157
|
}
|
|
@@ -163,7 +163,7 @@ class IeeeBuilder {
|
|
|
163
163
|
delete dash["dash_year"];
|
|
164
164
|
delete dash["dash_month"];
|
|
165
165
|
}
|
|
166
|
-
else {
|
|
166
|
+
else if (d["year"] === undefined) {
|
|
167
167
|
d["year"] = dashYear;
|
|
168
168
|
d["month"] = extractValue(dashMonth);
|
|
169
169
|
}
|
|
@@ -339,6 +339,10 @@ class IeeeBuilder {
|
|
|
339
339
|
}
|
|
340
340
|
if (typeValue === undefined && this.originalInput !== "" && /ANSI\s+P/.test(this.originalInput)) {
|
|
341
341
|
typeValue = "P";
|
|
342
|
+
// The P is identity on a non-IEEE-led publisher too (the C1
|
|
343
|
+
// ruling): record the marker so the render prepends it —
|
|
344
|
+
// "ANSI PN42.34/D9a, 2015" round-trips.
|
|
345
|
+
attributes["project_marker"] = true;
|
|
342
346
|
}
|
|
343
347
|
if (codeStr !== undefined && codeStr.startsWith("P") && this.originalInput.includes("/CSA")) {
|
|
344
348
|
const pubData = parsed["publishers"] !== undefined ? asHash(parsed["publishers"]) : undefined;
|
|
@@ -480,7 +484,10 @@ class IeeeBuilder {
|
|
|
480
484
|
const dv = draftData["draft_version"];
|
|
481
485
|
const version = Array.isArray(dv) ? dv.map((v) => extractValue(v) ?? "").join("") : extractValue(dv);
|
|
482
486
|
if (version !== undefined) {
|
|
483
|
-
|
|
487
|
+
// relaton's hyphenated "/D-2" spelling captures the dash inside
|
|
488
|
+
// draft_version; the stage registry keys on "D2". A date-embedded
|
|
489
|
+
// version ("3-2017-07") keys on its leading ordinal.
|
|
490
|
+
const draftAbbr = `D${version.replace(/^-/, "").replace(/-\d{4}(-\d{2})?$/, "")}`;
|
|
484
491
|
const stage = locateStage(draftAbbr);
|
|
485
492
|
if (stage !== undefined && stage.abbr.includes(draftAbbr))
|
|
486
493
|
return draftAbbr;
|
|
@@ -532,6 +539,15 @@ class IeeeBuilder {
|
|
|
532
539
|
revision = extractValue(draftData["revision"]);
|
|
533
540
|
isoStage = extractValue(draftData["draft_iso_stage"]);
|
|
534
541
|
isoIteration = extractValue(draftData["draft_iso_iteration"]);
|
|
542
|
+
// FDIS/CDV/… are ISO/IEC stage tokens, not draft ordinals (C1
|
|
543
|
+
// ruling, testsuite#2). "/DDIS" and "/DFDIS" are hallucinated
|
|
544
|
+
// concatenations — the designator D does not merge onto a stage
|
|
545
|
+
// word. The draft of a stage rides the iso_stage slot, which
|
|
546
|
+
// Draft#to_s renders as the D= designator face ("…/D=DIS-2020").
|
|
547
|
+
if (version !== undefined && /^(FDIS|FCD|CDV|DIS|CD|WD|PWI|NP)$/.test(version)) {
|
|
548
|
+
isoStage = version;
|
|
549
|
+
version = undefined;
|
|
550
|
+
}
|
|
535
551
|
month = extractValue(draftData["month"]);
|
|
536
552
|
year = extractValue(draftData["year"]);
|
|
537
553
|
// The apostrophe-year catalogue convention ("P1484.20.1/D7,
|
|
@@ -567,7 +583,8 @@ class IeeeBuilder {
|
|
|
567
583
|
month = year = day = undefined;
|
|
568
584
|
}
|
|
569
585
|
}
|
|
570
|
-
if (version !== undefined ||
|
|
586
|
+
if (version !== undefined || isoStage !== undefined ||
|
|
587
|
+
(isObj(draftData) && draftData["draft_iso_stage"] !== undefined)) {
|
|
571
588
|
const draftObj = new IeeeDraft({
|
|
572
589
|
version,
|
|
573
590
|
revision,
|
|
@@ -821,6 +838,15 @@ class IeeeBuilder {
|
|
|
821
838
|
const codeParts = [];
|
|
822
839
|
if (parsed["part"] !== undefined)
|
|
823
840
|
codeParts.push(extractValue(parsed["part"]) ?? "");
|
|
841
|
+
// The part/subpart captures carry their printed separator
|
|
842
|
+
// (separator-in-capture); the subpart rides after the part
|
|
843
|
+
// ("P65700.19.03", "60079-30-2" — the reference's joint code
|
|
844
|
+
// assembly).
|
|
845
|
+
if (parsed["subpart"] !== undefined) {
|
|
846
|
+
const subs = Array.isArray(parsed["subpart"]) ? parsed["subpart"] : [parsed["subpart"]];
|
|
847
|
+
for (const sp of subs)
|
|
848
|
+
codeParts.push(extractValue(sp) ?? "");
|
|
849
|
+
}
|
|
824
850
|
let codeStr = extractValue(parsed["number"]);
|
|
825
851
|
if (codeStr !== undefined && codeParts.length > 0) {
|
|
826
852
|
// The ISO/IEC label's part may be dash-joined ("8802-9") - keep the
|
|
@@ -859,6 +885,39 @@ class IeeeBuilder {
|
|
|
859
885
|
if (attributes["month"] === undefined)
|
|
860
886
|
attributes["month"] = extractValue(parsed["draft_month"]);
|
|
861
887
|
}
|
|
888
|
+
// The IEEE-led tail word-stage ("IEEE/ISO/IEC P15026-3/CD,
|
|
889
|
+
// December 2021") composes the D= designator with the glued
|
|
890
|
+
// 6-digit date — the identity its D= twin spelling parses to (the
|
|
891
|
+
// corpus canonical: joint-development, lead IEEE, stage P). The
|
|
892
|
+
// ISO-led lists converge to the published-Std identity (the issue
|
|
893
|
+
// #216 semantics). The zero-width printed_month_year capture
|
|
894
|
+
// carries "" — truthy in the reference (nil-check), falsy in JS:
|
|
895
|
+
// test presence, not truth.
|
|
896
|
+
if (parsed["tail_iso_stage"] !== undefined &&
|
|
897
|
+
parsed["printed_month_year"] !== undefined &&
|
|
898
|
+
parsed["part"] !== undefined) {
|
|
899
|
+
const stage = extractValue(parsed["tail_iso_stage"]);
|
|
900
|
+
const year = extractValue(parsed["year"]) ?? "";
|
|
901
|
+
const monthName = (extractValue(parsed["month"]) ?? "").replace(/\.$/, "");
|
|
902
|
+
const monthNum = DRAFT_MONTH_NAMES[monthName];
|
|
903
|
+
if (stage !== undefined && monthNum !== undefined) {
|
|
904
|
+
attributes["ieee_draft"] = `D=${stage}-${year}${monthNum.padStart(2, "0")}`;
|
|
905
|
+
parsed["year"] = undefined;
|
|
906
|
+
parsed["month"] = undefined;
|
|
907
|
+
parsed["printed_month_year"] = undefined;
|
|
908
|
+
delete attributes["year"];
|
|
909
|
+
delete attributes["month"];
|
|
910
|
+
// The ISO-led lists converge to the published-Std identity; the
|
|
911
|
+
// IEEE-led lists stay the live project draft (stage P).
|
|
912
|
+
if (attributes["publisher"] !== "IEEE") {
|
|
913
|
+
parsed["iso_published"] = { value: "" };
|
|
914
|
+
const stdRecord = locateStage("Std");
|
|
915
|
+
if (stdRecord !== undefined) {
|
|
916
|
+
attributes["typed_stage"] = new IeeeTypedStage(stdRecord);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
862
921
|
if (parsed["edition"] !== undefined)
|
|
863
922
|
attributes["edition"] = extractValue(parsed["edition"]);
|
|
864
923
|
if (parsed["edition_month"] !== undefined) {
|
|
@@ -874,13 +933,28 @@ class IeeeBuilder {
|
|
|
874
933
|
// the ISO face, which prints the date from the identity slots
|
|
875
934
|
// (", March 2017", pubid#216).
|
|
876
935
|
if (parsed["draft_month"] !== undefined && parsed["iso_stage"] === undefined) {
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
936
|
+
const dm = extractValue(parsed["draft_month"]) ?? "";
|
|
937
|
+
const dy = extractValue(parsed["draft_year"]) ?? "";
|
|
938
|
+
const monthNum = DRAFT_MONTH_NAMES[dm.replace(/\.$/, "")];
|
|
939
|
+
if (JSON.stringify(attributes["publishers"]) === JSON.stringify(["IEEE", "CSA"]) &&
|
|
940
|
+
monthNum !== undefined && dy !== "") {
|
|
941
|
+
// The joint IEEE/CSA drafts glue their date into the
|
|
942
|
+
// designator with the month numeric (pubid ruling
|
|
943
|
+
// 2026-10-14: no comma dates on these rows).
|
|
944
|
+
const glued = new IeeeDraft({
|
|
945
|
+
version: `${draftVer}-${dy}-${monthNum.padStart(2, "0")}`,
|
|
946
|
+
});
|
|
947
|
+
attributes["draft"] = glued.render();
|
|
948
|
+
}
|
|
949
|
+
else {
|
|
950
|
+
const draftObj = new IeeeDraft({
|
|
951
|
+
version: draftVer,
|
|
952
|
+
month: dm === "" ? undefined : dm,
|
|
953
|
+
year: dy === "" ? undefined : dy,
|
|
954
|
+
comma_before_month: true,
|
|
955
|
+
});
|
|
956
|
+
attributes["draft"] = draftObj.render();
|
|
957
|
+
}
|
|
884
958
|
if (parsed["year"] === undefined)
|
|
885
959
|
delete attributes["year"];
|
|
886
960
|
if (parsed["month"] === undefined)
|
|
@@ -895,6 +969,21 @@ class IeeeBuilder {
|
|
|
895
969
|
if (parsed["year"] === undefined)
|
|
896
970
|
delete attributes["year"];
|
|
897
971
|
}
|
|
972
|
+
else if (JSON.stringify(attributes["publishers"]) === JSON.stringify(["IEEE", "CSA"]) &&
|
|
973
|
+
parsed["iso_stage"] === undefined &&
|
|
974
|
+
/^(19|20)\d\d$/.test(extractValue(parsed["year"]) ?? "") &&
|
|
975
|
+
/^\d{1,2}$/.test(extractValue(parsed["month"]) ?? "")) {
|
|
976
|
+
// The glued face re-parses with the date in the identity
|
|
977
|
+
// slots ("D2-2016-09" -> year/month + a bare D2): it
|
|
978
|
+
// normalizes back onto the draft-embedded date so the
|
|
979
|
+
// round trip closes on the CSA canonical.
|
|
980
|
+
const glued = new IeeeDraft({
|
|
981
|
+
version: `${draftVer}-${extractValue(parsed["year"])}-${extractValue(parsed["month"])}`,
|
|
982
|
+
});
|
|
983
|
+
attributes["draft"] = glued.render();
|
|
984
|
+
delete attributes["year"];
|
|
985
|
+
delete attributes["month"];
|
|
986
|
+
}
|
|
898
987
|
else {
|
|
899
988
|
attributes["ieee_draft"] = `D${draftVer}`;
|
|
900
989
|
}
|
|
@@ -941,9 +1030,10 @@ class IeeeBuilder {
|
|
|
941
1030
|
jointDraft += `.${extractValue(parsed["draft_iso_iteration"])}`;
|
|
942
1031
|
}
|
|
943
1032
|
if (parsed["draft_stage_year"] !== undefined) {
|
|
944
|
-
// The capture carries its separator (":2020"
|
|
945
|
-
// #471 separator-in-capture rule)
|
|
946
|
-
|
|
1033
|
+
// The capture carries its separator verbatim (":2020" /
|
|
1034
|
+
// "-201112" - the #471 separator-in-capture rule): the ruby
|
|
1035
|
+
// builder appends it raw, so the face keeps the printed form.
|
|
1036
|
+
jointDraft += extractValue(parsed["draft_stage_year"]) ?? "";
|
|
947
1037
|
}
|
|
948
1038
|
attributes["ieee_draft"] = jointDraft;
|
|
949
1039
|
}
|
|
@@ -1035,9 +1125,22 @@ class IeeeBuilder {
|
|
|
1035
1125
|
else {
|
|
1036
1126
|
attributes["lead_party"] = "IEEE";
|
|
1037
1127
|
attributes["type"] = "P";
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
attributes["
|
|
1128
|
+
if ((parsed["draft_iso_stage"] !== undefined ||
|
|
1129
|
+
parsed["tail_iso_stage"] !== undefined) &&
|
|
1130
|
+
attributes["publisher"] === "ISO") {
|
|
1131
|
+
// The ISO-led D= designator (the issue #216 convergence) is
|
|
1132
|
+
// the stage-tracked draft of a published standard - the typed
|
|
1133
|
+
// stage reads Std/published.
|
|
1134
|
+
const stdRecord = locateStage("Std");
|
|
1135
|
+
if (stdRecord !== undefined) {
|
|
1136
|
+
attributes["typed_stage"] = new IeeeTypedStage(stdRecord);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
else {
|
|
1140
|
+
const record = locateStage("P");
|
|
1141
|
+
if (record !== undefined)
|
|
1142
|
+
attributes["typed_stage"] = new IeeeTypedStage(record);
|
|
1143
|
+
}
|
|
1041
1144
|
}
|
|
1042
1145
|
// A plain IEEE-designator draft on joint publishers ("/D8, June
|
|
1043
1146
|
// 2010") carries no ISO stage machinery: it builds as the project
|
|
@@ -1049,9 +1152,23 @@ class IeeeBuilder {
|
|
|
1049
1152
|
parsed["amd_number"] === undefined) {
|
|
1050
1153
|
const pubs = (attributes["publishers"] ?? []);
|
|
1051
1154
|
const projectAttrs = {
|
|
1052
|
-
code: attributes["code"],
|
|
1053
1155
|
draft: attributes["draft"],
|
|
1054
1156
|
};
|
|
1157
|
+
// The comma-year tail rides the draft verbatim ("D4, 2019" — the
|
|
1158
|
+
// reference keeps the comma face on the joint project drafts; the
|
|
1159
|
+
// year never promotes to the identity slots).
|
|
1160
|
+
// The code columns (number/parts/separator/prefix) are the
|
|
1161
|
+
// ProjectDraft render/hash face; the spelled P is the project
|
|
1162
|
+
// marker (identity), whatever the lead publisher.
|
|
1163
|
+
for (const k of ["number", "prefix", "parts", "separator"]) {
|
|
1164
|
+
// A "P" prefix is the project marker itself (the generic path
|
|
1165
|
+
// deletes it on the strip) - it must not ride the code columns.
|
|
1166
|
+
if (attributes[k] !== undefined && !(k === "prefix" && attributes[k] === "P")) {
|
|
1167
|
+
projectAttrs[k] = attributes[k];
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
if (parsed["project_marker"] !== undefined)
|
|
1171
|
+
projectAttrs["project_marker"] = true;
|
|
1055
1172
|
if (pubs.length > 0) {
|
|
1056
1173
|
projectAttrs["publisher"] = pubs[0];
|
|
1057
1174
|
if (pubs.length > 1)
|
|
@@ -186,8 +186,11 @@ export class IeeeDraft {
|
|
|
186
186
|
// The compound stage suffix (docs/IEEE-DRAFT-STAGES.md §1.3):
|
|
187
187
|
// "=DIS.3" is canonical - D (draft) = DIS (the stage), iteration 3.
|
|
188
188
|
// "=DDIS.3", "=DDIS3", "=DDIS-3" (the stage echoed with its own D)
|
|
189
|
-
// are accepted aliases. Captures [stage, iteration].
|
|
190
|
-
|
|
189
|
+
// are accepted aliases. Captures [stage, iteration]. The iteration
|
|
190
|
+
// ordinal stays short (one or two digits): a glued D= date
|
|
191
|
+
// ("-201908", the pubid#203 convention) must ride the version body
|
|
192
|
+
// verbatim, not fold into the iteration slot.
|
|
193
|
+
const compound = /=D?(PWI|NP|WD|CDV|FDIS|DIS|CD)(?:[.-]?(\d{1,2}[a-z]?))?$/;
|
|
191
194
|
let isoStage;
|
|
192
195
|
let isoIteration;
|
|
193
196
|
const cm = compound.exec(body);
|
|
@@ -200,7 +203,7 @@ export class IeeeDraft {
|
|
|
200
203
|
.sort((a, b) => b.length - a.length)
|
|
201
204
|
.map((m) => `${m.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.?`)
|
|
202
205
|
.join("|");
|
|
203
|
-
const suffix = new RegExp(`(?:(, | )(${monthAlt})(?: (\\d{1,2}))?(?:, | )| )((?:19|20)\\d{2}[a-z]{0,2})$`);
|
|
206
|
+
const suffix = new RegExp(`(?:(, | )(${monthAlt})(?: (\\d{1,2}))?(?:, | )|, | )((?:19|20)\\d{2}[a-z]{0,2})$`);
|
|
204
207
|
const m = suffix.exec(body);
|
|
205
208
|
if (m === null) {
|
|
206
209
|
return new IeeeDraft({ version: body, iso_stage: isoStage, iso_iteration: isoIteration });
|
|
@@ -216,7 +219,7 @@ export class IeeeDraft {
|
|
|
216
219
|
});
|
|
217
220
|
}
|
|
218
221
|
render() {
|
|
219
|
-
let result = `/D${this.version}`;
|
|
222
|
+
let result = `/D${this.version ?? ""}`;
|
|
220
223
|
if (this.isoStage !== undefined)
|
|
221
224
|
result += `=${this.isoStage}`;
|
|
222
225
|
if (this.isoStage !== undefined && this.isoIteration !== undefined) {
|
|
@@ -225,6 +228,15 @@ export class IeeeDraft {
|
|
|
225
228
|
if (this.revision !== undefined)
|
|
226
229
|
result += `.${this.revision}`;
|
|
227
230
|
if (this.year !== undefined) {
|
|
231
|
+
if (this.isoStage !== undefined) {
|
|
232
|
+
// The D= designator face dash-joins its date in IEEE's
|
|
233
|
+
// convention: the year, and a draft month rides the
|
|
234
|
+
// designator zero-padded ("D=FDIS-201008", pubid#203).
|
|
235
|
+
result += `-${this.year}`;
|
|
236
|
+
if (this.month !== undefined)
|
|
237
|
+
result += this.month.padStart(2, "0");
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
228
240
|
const displayMonth = this.originalMonth;
|
|
229
241
|
if (displayMonth !== undefined) {
|
|
230
242
|
const useCommaBefore = this.commaBeforeMonthSet
|
|
@@ -236,7 +248,10 @@ export class IeeeDraft {
|
|
|
236
248
|
result += displayMonth.length <= 4 || displayMonth === "Sept" ? ` ${this.year}` : `, ${this.year}`;
|
|
237
249
|
}
|
|
238
250
|
else {
|
|
239
|
-
|
|
251
|
+
// The year-only date joins with its comma - the grammar's
|
|
252
|
+
// comma-year draft tail (pubid-grammar 17244fc) - so the
|
|
253
|
+
// render re-parses through the same clause.
|
|
254
|
+
result += `, ${this.year}`;
|
|
240
255
|
}
|
|
241
256
|
}
|
|
242
257
|
return result;
|
|
@@ -515,7 +530,8 @@ export function renderIeeeBase(id) {
|
|
|
515
530
|
// spelling ("IEEE P15026.1, 05 2014" renders "P15026.1-2014-05").
|
|
516
531
|
const yearOnCode = id.year !== undefined && id.edition === undefined &&
|
|
517
532
|
(id.month === undefined || gluedMonth) &&
|
|
518
|
-
(draftObj === undefined || draftObj.year !== undefined
|
|
533
|
+
(draftObj === undefined || draftObj.year !== undefined ||
|
|
534
|
+
(draftObj.version ?? "").match(/-\d{4}-\d{2}$/) !== null);
|
|
519
535
|
if (yearOnCode) {
|
|
520
536
|
result += `-${id.year}`;
|
|
521
537
|
}
|
|
@@ -575,7 +591,8 @@ export function renderIeeeBase(id) {
|
|
|
575
591
|
result += ` ${id.year}`;
|
|
576
592
|
}
|
|
577
593
|
else if (id.year !== undefined && draftObj !== undefined && id.edition === undefined &&
|
|
578
|
-
draftObj?.year === undefined &&
|
|
594
|
+
draftObj?.year === undefined &&
|
|
595
|
+
(draftObj.version ?? "").match(/-\d{4}-\d{2}$/) === null && !iecIeeOnly) {
|
|
579
596
|
// A year-only date trailing the draft ("ANSI N42.34/D9a, 2015")
|
|
580
597
|
// keeps its comma form instead of being silently dropped; a year
|
|
581
598
|
// whose draft carries its own date dash-attached to the code above
|
|
@@ -882,8 +899,12 @@ export const ProjectDraftIdentifierClass = ieeeClass({ kind: "project-draft-iden
|
|
|
882
899
|
codeColumns: true,
|
|
883
900
|
extraDefs: {
|
|
884
901
|
project_marker: { type: "boolean", default: false },
|
|
902
|
+
// The ISO-led joint project drafts carry the designator as the
|
|
903
|
+
// stage ("ISO/IEC/IEEE P42010/D4, 2019" - stage D4), the same
|
|
904
|
+
// key the ruby identity serializes.
|
|
905
|
+
stage: { type: "string" },
|
|
885
906
|
},
|
|
886
|
-
extraMappings: keyValue({ wire: "project_marker", to: "project_marker" }),
|
|
907
|
+
extraMappings: keyValue({ wire: "project_marker", to: "project_marker" }, { wire: "stage", to: "stage" }),
|
|
887
908
|
});
|
|
888
909
|
export const SiStandardClass = ieeeClass({ kind: "si-standard" }, {
|
|
889
910
|
codeColumns: true,
|
|
@@ -1102,28 +1123,35 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1102
1123
|
const isoStage = id["iso_stage"];
|
|
1103
1124
|
const ieeeDraft = id["ieee_draft"];
|
|
1104
1125
|
const codeObj = id.codeObj;
|
|
1105
|
-
// ISO-led renders the ISO format
|
|
1126
|
+
// ISO-led renders the ISO format (the stage-less published
|
|
1106
1127
|
// form "ISO/IEC/IEEE 12207.2:2020" prints colon-year, no stage).
|
|
1107
1128
|
// IEEE semantics: P = project (a draft); no P = a standard. The
|
|
1108
1129
|
// P-state is identity-bearing and prints as spelled - it is never
|
|
1109
1130
|
// added or stripped here.
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1131
|
+
// A stage-tracked D= designator is IEEE draft notation — its
|
|
1132
|
+
// canonical face is the designator spelling (§1.3 spelling 7),
|
|
1133
|
+
// whatever the lead party (the reference's canonical_format).
|
|
1134
|
+
if (leadParty === "ISO" && !(ieeeDraft ?? "").startsWith("D=")) {
|
|
1135
|
+
// The stage word is the ISO format's own position convention —
|
|
1136
|
+
// it prints whenever the identifier carries one, as stored,
|
|
1137
|
+
// iteration included ("DIS2", "CD4" — the lossless face,
|
|
1138
|
+
// pubid#477). A stage-tracked D= designator decomposes into its
|
|
1139
|
+
// stage word and date ("D=CD-2020" → "CD", 2020); the P project
|
|
1140
|
+
// stage is IEEE convention and never prints here.
|
|
1141
|
+
let stageWord = isoStage ?? "";
|
|
1142
|
+
let draftYear;
|
|
1143
|
+
if (stageWord === "" && ieeeDraft !== undefined) {
|
|
1144
|
+
const decomposed = /^D=([A-Z]+)(?:\.(\d+[a-z]?))?(?:[-:](\d{4}))?$/.exec(ieeeDraft);
|
|
1145
|
+
if (decomposed !== null) {
|
|
1146
|
+
stageWord = decomposed[1] ?? "";
|
|
1147
|
+
draftYear = decomposed[3];
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1116
1150
|
const parts = [];
|
|
1117
1151
|
if (publishers !== undefined && publishers.length > 0)
|
|
1118
1152
|
parts.push(publishers.join("/"));
|
|
1119
|
-
if (
|
|
1120
|
-
|
|
1121
|
-
parts.push(id.typed_stage.record.iso_stage_equivalent ?? id.typed_stage.render());
|
|
1122
|
-
}
|
|
1123
|
-
else if (isoStage !== undefined) {
|
|
1124
|
-
parts.push(isoStage);
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1153
|
+
if (stageWord !== "")
|
|
1154
|
+
parts.push(stageWord);
|
|
1127
1155
|
let codeStr = codeObj?.render() ?? "";
|
|
1128
1156
|
// A P-prefixed joint project prints its parts dot-joined on the
|
|
1129
1157
|
// ISO face ("ISO/IEEE DIS P15500.1"), whatever separator the
|
|
@@ -1132,15 +1160,23 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1132
1160
|
codeStr = codeStr.replaceAll("-", ".");
|
|
1133
1161
|
if (codeStr !== "")
|
|
1134
1162
|
parts.push(codeStr);
|
|
1163
|
+
// The ISO-face date, in the spelling that parses back to the
|
|
1164
|
+
// same year and month: the colon year (":2018"); a numeric
|
|
1165
|
+
// month glued with dashes ("-2018-05"); a text month as
|
|
1166
|
+
// ", February 2015".
|
|
1135
1167
|
let result = parts.join(" ");
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1168
|
+
const dateYear = id.year ?? draftYear;
|
|
1169
|
+
if (dateYear !== undefined) {
|
|
1170
|
+
if (id.month === undefined) {
|
|
1171
|
+
result += `:${dateYear}`;
|
|
1172
|
+
}
|
|
1173
|
+
else if (/^\d+$/.test(id.month)) {
|
|
1174
|
+
result += `-${dateYear}-${id.month.padStart(2, "0")}`;
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
result += `, ${id.month} ${dateYear}`;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1144
1180
|
const marker = id["parenthetical_content"];
|
|
1145
1181
|
if (marker !== undefined && /^[A-Z](?:\s*[/&]\s*[A-Z])*$/.test(marker)) {
|
|
1146
1182
|
result += ` (${marker})`;
|
|
@@ -1158,16 +1194,36 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1158
1194
|
// The P-state prints as spelled (P = project draft; no P =
|
|
1159
1195
|
// standard). Never added or stripped.
|
|
1160
1196
|
let codeStr = codeObj?.render() ?? "";
|
|
1161
|
-
|
|
1197
|
+
let designatorCarriesYear = false;
|
|
1198
|
+
if (ieeeDraft !== undefined && ieeeDraft.startsWith("D=") && id.year !== undefined) {
|
|
1199
|
+
// The ordinal-less stage draft's canonical face (the
|
|
1200
|
+
// UpdateCodes rewrite): the publication year colon-joins the
|
|
1201
|
+
// code and the designator trails — "P16326:2017/D=WD.5".
|
|
1202
|
+
codeStr += `:${id.year}`;
|
|
1203
|
+
codeStr += `/${ieeeDraft}`;
|
|
1204
|
+
designatorCarriesYear = true;
|
|
1205
|
+
}
|
|
1206
|
+
else if (ieeeDraft !== undefined) {
|
|
1162
1207
|
codeStr += `/${ieeeDraft}`;
|
|
1163
|
-
|
|
1208
|
+
}
|
|
1209
|
+
else if (isoStage !== undefined) {
|
|
1210
|
+
// The ordinal-less stage draft: an iteration glued onto the
|
|
1211
|
+
// printed word ("CD2") renders in the doctrine's ".iter" slot
|
|
1212
|
+
// ("D=CD.2" — docs/IEEE-DRAFT-STAGES.md §1.3).
|
|
1213
|
+
const glued = /([A-Z]+?)(\d+)/.exec(isoStage);
|
|
1214
|
+
codeStr += glued !== null ? `/D=${glued[1]}.${glued[2]}` : `/D=${isoStage}`;
|
|
1215
|
+
}
|
|
1216
|
+
else if (id.typed_stage?.ieeeDraftEquivalent !== undefined &&
|
|
1217
|
+
!codeStr.startsWith(id.typed_stage.ieeeDraftEquivalent)) {
|
|
1164
1218
|
codeStr += `/${id.typed_stage.ieeeDraftEquivalent}`;
|
|
1165
1219
|
}
|
|
1166
1220
|
if (codeStr !== "")
|
|
1167
1221
|
parts.push(codeStr);
|
|
1168
1222
|
let result = parts.join(" ");
|
|
1169
|
-
if (id.year !== undefined
|
|
1223
|
+
if (id.year !== undefined && !designatorCarriesYear &&
|
|
1224
|
+
!(ieeeDraft ?? "").endsWith(`-${id.year}`)) {
|
|
1170
1225
|
result += `-${id.year}`;
|
|
1226
|
+
}
|
|
1171
1227
|
if (id.redline === true)
|
|
1172
1228
|
result += " - Redline";
|
|
1173
1229
|
return result;
|
|
@@ -259,6 +259,47 @@ function normalizeRevisionNotation(input) {
|
|
|
259
259
|
cleaned = cleaned.replace(/(\/D-?[0-9A-Za-z.]+)\s+[Rr][Ee][Vv]\s*(\d+)/, "$1/R-$2");
|
|
260
260
|
cleaned = cleaned.replace(/[-/_.]?\s?[Rr][Ee][Vv][-\s]?(\d+)(\/D-?[0-9A-Za-z.]+)/, "$2/R-$1");
|
|
261
261
|
cleaned = cleaned.replace(/(\d)[-._]?\s?[Rr][Ee][Vv]\s*(\d+)\s*$/, "$1/R-$2");
|
|
262
|
+
// The joint IEEE/CSA catalogue spells the type word before the
|
|
263
|
+
// project number ("IEEE/CSA Draft P844.1/D2, Sept, 2016"): the P
|
|
264
|
+
// already carries the project semantics (docs/IEEE-DRAFT-STAGES.md
|
|
265
|
+
// §1.1), so the redundant word drops and the joint route parses.
|
|
266
|
+
cleaned = cleaned.replace(/IEEE\/CSA Draft (P[A-Z0-9])/g, "IEEE/CSA $1");
|
|
267
|
+
// The same redundant word rides the wider joint lists
|
|
268
|
+
// ("IEEE//ISO/IEC Draft P29119-2/D=DIS-201112"); the crawl also
|
|
269
|
+
// doubles the publisher slash (the 2026-10-14 ruling: the list
|
|
270
|
+
// normalizes to single slashes). Drop the word and collapse the
|
|
271
|
+
// slash before the joint route sees either - scoped to the D=
|
|
272
|
+
// stage-draft tail (the doubled-D and stage-month tails route
|
|
273
|
+
// elsewhere until the grammar carries them).
|
|
274
|
+
cleaned = cleaned.replace(/((?:IEEE|ISO|IEC)(?:\/(?:IEEE|ISO|IEC|CSA))+)\s+Draft\s+(P[A-Z0-9][A-Z0-9.-]*\/D=[A-Z])/g, "$1 $2");
|
|
275
|
+
cleaned = cleaned.replace(/(IEEE|ISO|IEC)\/\//g, "$1/");
|
|
276
|
+
// The lettered REV spellings glue to the number ("P1310Rev3") or
|
|
277
|
+
// carry an after-word separator ("REV.ma", "REV-ma"); the rev rules
|
|
278
|
+
// read a space or a bare word, so the boundary normalizes (the
|
|
279
|
+
// render keeps the glued face). The before-word separator the Rev
|
|
280
|
+
// doctrine carries ("-REVmc") is untouched.
|
|
281
|
+
cleaned = cleaned.replace(/(REV|Rev|rev)[.\-](?=[A-Za-z])/g, "$1");
|
|
282
|
+
cleaned = cleaned.replace(/(\d)(REV|Rev|rev)/g, "$1 $2");
|
|
283
|
+
// The corrigendum's own draft rides before the ordinal in the house
|
|
284
|
+
// order ("PC37.101-2006/D2, 2007/Cor. 1"): the catalogue spellings
|
|
285
|
+
// ".../Cor 1, D4, July 2015" and ".../Cor 1-201x/D5, April 2012"
|
|
286
|
+
// re-order into it, with the draft's date glued -YYYY-MM (pubid
|
|
287
|
+
// ruling 2026-10-14: no comma dates).
|
|
288
|
+
const COR_MONTHS = {
|
|
289
|
+
January: "01", February: "02", March: "03", April: "04", May: "05",
|
|
290
|
+
June: "06", July: "07", August: "08", September: "09", Sept: "09",
|
|
291
|
+
October: "10", November: "11", December: "12", Jan: "01", Feb: "02",
|
|
292
|
+
Mar: "03", Apr: "04", Jun: "06", Jul: "07", Aug: "08", Sep: "09",
|
|
293
|
+
Oct: "10", Nov: "11", Dec: "12",
|
|
294
|
+
};
|
|
295
|
+
cleaned = cleaned.replace(/\/Cor(?:rigendum)? (\d+(?:-[0-9xX]{4})?)\/(D[A-Z0-9][^,]*), ([A-Za-z]+) (\d{4})/g, (_m, cor, draft, mon, year) => {
|
|
296
|
+
const month = COR_MONTHS[mon.charAt(0).toUpperCase() + mon.slice(1).toLowerCase()];
|
|
297
|
+
return month === undefined ? _m : `/${draft}-${year}-${month}/Cor. ${cor}`;
|
|
298
|
+
});
|
|
299
|
+
cleaned = cleaned.replace(/\/Cor(?:rigendum)? (\d+), (D[A-Z0-9][^,]*), ([A-Za-z]+) (\d{4})/g, (_m, cor, draft, mon, year) => {
|
|
300
|
+
const month = COR_MONTHS[mon.charAt(0).toUpperCase() + mon.slice(1).toLowerCase()];
|
|
301
|
+
return month === undefined ? _m : `/${draft}-${year}-${month}/Cor. ${cor}`;
|
|
302
|
+
});
|
|
262
303
|
// Lettered inline revisions are IDENTITY (pubid ruling 2026-10-14):
|
|
263
304
|
// the grammar captures them natively with their separator; the former
|
|
264
305
|
// strip rewrite here dropped the letters and is gone.
|
|
@@ -376,7 +417,11 @@ export function preprocessIeee(input) {
|
|
|
376
417
|
cleaned = cleaned.replace(/^(ISO\/IEC \d+[-.]\d*)\s*:\s*(\d{4})/, "$1:$2");
|
|
377
418
|
cleaned = cleaned.replace(/^(ISO\/IEC \d+)\s*:\s*(\d{4})/, "$1:$2");
|
|
378
419
|
cleaned = cleaned.replace(/^(IEC\/IEEE P[\w.-]+)_D/, "$1/D");
|
|
379
|
-
|
|
420
|
+
// Scoped: the D= stage-draft rows keep the IEEE-led list (the ruby
|
|
421
|
+
// ieee_format routes them with the input publisher order and lead
|
|
422
|
+
// IEEE - "IEEE/ISO/IEC P29119-2/D=DIS-201112"); the other IEEE/ISO/IEC
|
|
423
|
+
// spellings print the ISO-led face.
|
|
424
|
+
cleaned = cleaned.replace(/^IEEE\/ISO\/IEC\s+(?!P[\w.-]+\/D=)(P[\w.-]+)/, "ISO/IEC/IEEE $1");
|
|
380
425
|
cleaned = cleaned.replace(/^IEEE\/IEC\/ISO\s+(P[\w.-]+)/, "IEC/ISO/IEEE $1");
|
|
381
426
|
cleaned = cleaned.replace(/^(IEEE\/IEC P[\w.-]+)\s+D(\d)/, "$1/D$2");
|
|
382
427
|
cleaned = cleaned.replace(/^(IEEE\/IEC P[\w.-]+)\s+(CDV|FDIS|CD|DIS|ED\d)/, "$1/$2");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubid/pubid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "TypeScript PubID identifiers: resolution, normalization and canonical hashes for every identifier in the pubid-testsuite corpus (41 standards bodies), with a conformance runner mirroring the Ruby reference",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"artifact": "tsc -p tsconfig.json && node scripts/build-artifact.mjs"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"parsanol": "^0.10.
|
|
20
|
+
"parsanol": "^0.10.4",
|
|
21
21
|
"yaml": "^2.5.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
package/vendor/parg/adobe.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"bindings":null,"version":"0.1.0","grammar":"PubidAdobe","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":48}},{"Entity":{"atom":30}},{"Entity":{"atom":9}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":" "}},{"Str":{"pattern":"TN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":7,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[3,4,6,8]}},{"Entity":{"atom":24}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Technical"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Note"}},{"Entity":{"atom":5}},{"Repetition":{"atom":16,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"#"}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":5}},{"Repetition":{"atom":20,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[17,19,21]}},{"Repetition":{"atom":22,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[11,12,13,14,15,23]}},{"Entity":{"atom":29}},{"Str":{"pattern":"ATN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":27,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[26,28]}},{"Alternative":{"atoms":[2,10,25]}},{"Entity":{"atom":32}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":31,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":33}},{"Entity":{"atom":36}},{"Str":{"pattern":"."}},{"Entity":{"atom":42}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[_]"}},{"Alternative":{"atoms":[38,39,40,41]}},{"Repetition":{"atom":37,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"slug","atom":43}},{"Sequence":{"atoms":[35,44]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,34,46]}},{"Named":{"name":"tech_note","atom":47}},{"Entity":{"atom":53}},{"Entity":{"atom":32}},{"Repetition":{"atom":50,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":51}},{"Named":{"name":"tech_note_bare","atom":52}},{"Entity":{"atom":87}},{"Str":{"pattern":"Adobe Publication "}},{"Repetition":{"atom":55,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":86}},{"Entity":{"atom":82}},{"Entity":{"atom":75}},{"Entity":{"atom":69}},{"Entity":{"atom":62}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":61,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":67}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[65,66]}},{"Repetition":{"atom":64,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[63,68]}},{"Entity":{"atom":71}},{"Str":{"pattern":"-"}},{"Entity":{"atom":69}},{"Sequence":{"atoms":[70,72]}},{"Repetition":{"atom":73,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[60,74]}},{"Named":{"name":"slug","atom":59}},{"Entity":{"atom":71}},{"Entity":{"atom":32}},{"Repetition":{"atom":78,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"version","atom":79}},{"Sequence":{"atoms":[76,77,80]}},{"Named":{"name":"publication_version","atom":81}},{"Entity":{"atom":85}},{"Entity":{"atom":75}},{"Named":{"name":"slug","atom":84}},{"Alternative":{"atoms":[58,83]}},{"Sequence":{"atoms":[56,57]}},{"Alternative":{"atoms":[0,49,54]}}],"root":88},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule tech_note_prefix: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule publication_slug_or_version: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"Adobe TN 15","expect":{}},{"entry":"identifier","kind":"accept","input":"ATN 30","expect":{}},{"entry":"identifier","kind":"accept","input":"Adobe Technical Note #12","expect":{}},{"entry":"identifier","kind":"reject","input":"###","expect":{}}],"docs":{},"source":"# Port of lib/pubid/adobe/parser.rb: tech notes (Adobe TN 5014, legacy\n# \"Adobe Technical Note #5014\", ATN5014, bare 5014) and publications\n# (adobe-glyph-list, adobe-japan1-7 with the version split tried first).\n\ngrammar PubidAdobe version \"0.1.0\" {\n tech_note_tn_prefix = \"Adobe\" space \"TN\" [space]\n tech_note_long_prefix = \"Adobe\" space \"Technical\" space \"Note\" [[space] [\"#\"] [space]]\n tech_note_atn_prefix = \"ATN\" [space]\n tech_note_prefix = tech_note_tn_prefix / tech_note_long_prefix / tech_note_atn_prefix\n # Capture precedence: (*rep) as name wraps the whole repetition, so a\n # digit run joins to one string instead of re-keying every character;\n # slug is captured exactly once (the bare form) or as a sibling of\n # version inside the publication_version capture.\n tech_note = (tech_note_prefix (1*digit) as number [(dot (1*slug_char) as slug)]) as tech_note\n bare_number = ((1*digit) as number) as tech_note_bare\n slug_segment = 1*lower1 *lowerd\n slug_text = slug_segment *(dash slug_segment)\n slug_inner = (slug_text) as slug\n publication_with_version = ((slug_text) as slug dash (1*digit) as version) as publication_version\n publication_slug_or_version = publication_with_version / slug_inner\n publication = [\"Adobe Publication \"] publication_slug_or_version\n identifier = tech_note / bare_number / publication\n slug_char = %x41-5A / %x61-7A / %x30-39 / %x5F\n lower1 = %x61-7A\n lowerd = %x61-7A / %x30-39\n digit = %x30-39\n space = \" \"\n dot = \".\"\n dash = \"-\"\n entry identifier: identifier\n\n test {\n accept \"Adobe TN 15\"\n accept \"ATN 30\"\n accept \"Adobe Technical Note #12\"\n reject \"###\"\n }\n}\n","checksum":"sha256:
|
|
1
|
+
{"bindings":null,"version":"0.1.0","grammar":"PubidAdobe","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":48}},{"Entity":{"atom":30}},{"Entity":{"atom":9}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":" "}},{"Str":{"pattern":"TN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":7,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[3,4,6,8]}},{"Entity":{"atom":24}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Technical"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Note"}},{"Entity":{"atom":5}},{"Repetition":{"atom":16,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"#"}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":5}},{"Repetition":{"atom":20,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[17,19,21]}},{"Repetition":{"atom":22,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[11,12,13,14,15,23]}},{"Entity":{"atom":29}},{"Str":{"pattern":"ATN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":27,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[26,28]}},{"Alternative":{"atoms":[2,10,25]}},{"Entity":{"atom":32}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":31,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":33}},{"Entity":{"atom":36}},{"Str":{"pattern":"."}},{"Entity":{"atom":42}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[_]"}},{"Alternative":{"atoms":[38,39,40,41]}},{"Repetition":{"atom":37,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"slug","atom":43}},{"Sequence":{"atoms":[35,44]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,34,46]}},{"Named":{"name":"tech_note","atom":47}},{"Entity":{"atom":53}},{"Entity":{"atom":32}},{"Repetition":{"atom":50,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":51}},{"Named":{"name":"tech_note_bare","atom":52}},{"Entity":{"atom":87}},{"Str":{"pattern":"Adobe Publication "}},{"Repetition":{"atom":55,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":86}},{"Entity":{"atom":82}},{"Entity":{"atom":75}},{"Entity":{"atom":69}},{"Entity":{"atom":62}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":61,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":67}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[65,66]}},{"Repetition":{"atom":64,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[63,68]}},{"Entity":{"atom":71}},{"Str":{"pattern":"-"}},{"Entity":{"atom":69}},{"Sequence":{"atoms":[70,72]}},{"Repetition":{"atom":73,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[60,74]}},{"Named":{"name":"slug","atom":59}},{"Entity":{"atom":71}},{"Entity":{"atom":32}},{"Repetition":{"atom":78,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"version","atom":79}},{"Sequence":{"atoms":[76,77,80]}},{"Named":{"name":"publication_version","atom":81}},{"Entity":{"atom":85}},{"Entity":{"atom":75}},{"Named":{"name":"slug","atom":84}},{"Alternative":{"atoms":[58,83]}},{"Sequence":{"atoms":[56,57]}},{"Alternative":{"atoms":[0,49,54]}}],"root":88},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule tech_note_prefix: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule publication_slug_or_version: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"Adobe TN 15","expect":{}},{"entry":"identifier","kind":"accept","input":"ATN 30","expect":{}},{"entry":"identifier","kind":"accept","input":"Adobe Technical Note #12","expect":{}},{"entry":"identifier","kind":"reject","input":"###","expect":{}}],"docs":{},"source":"# Port of lib/pubid/adobe/parser.rb: tech notes (Adobe TN 5014, legacy\n# \"Adobe Technical Note #5014\", ATN5014, bare 5014) and publications\n# (adobe-glyph-list, adobe-japan1-7 with the version split tried first).\n\ngrammar PubidAdobe version \"0.1.0\" {\n tech_note_tn_prefix = \"Adobe\" space \"TN\" [space]\n tech_note_long_prefix = \"Adobe\" space \"Technical\" space \"Note\" [[space] [\"#\"] [space]]\n tech_note_atn_prefix = \"ATN\" [space]\n tech_note_prefix = tech_note_tn_prefix / tech_note_long_prefix / tech_note_atn_prefix\n # Capture precedence: (*rep) as name wraps the whole repetition, so a\n # digit run joins to one string instead of re-keying every character;\n # slug is captured exactly once (the bare form) or as a sibling of\n # version inside the publication_version capture.\n tech_note = (tech_note_prefix (1*digit) as number [(dot (1*slug_char) as slug)]) as tech_note\n bare_number = ((1*digit) as number) as tech_note_bare\n slug_segment = 1*lower1 *lowerd\n slug_text = slug_segment *(dash slug_segment)\n slug_inner = (slug_text) as slug\n publication_with_version = ((slug_text) as slug dash (1*digit) as version) as publication_version\n publication_slug_or_version = publication_with_version / slug_inner\n publication = [\"Adobe Publication \"] publication_slug_or_version\n identifier = tech_note / bare_number / publication\n slug_char = %x41-5A / %x61-7A / %x30-39 / %x5F\n lower1 = %x61-7A\n lowerd = %x61-7A / %x30-39\n digit = %x30-39\n space = \" \"\n dot = \".\"\n dash = \"-\"\n entry identifier: identifier\n\n test {\n accept \"Adobe TN 15\"\n accept \"ATN 30\"\n accept \"Adobe Technical Note #12\"\n reject \"###\"\n }\n}\n","source_hash":"bba8ad76fa85bcbf6363b8bfa1502a76a050fa4ca87bcf5a8bfd14a19cab9f5e","compiler_version":"1.3.93","checksum":"sha256:cef9c127759ddb05f7bd725d9bc923b6207c099dbd8a8e73ec4ae84101040361"}
|