@pubid/pubid 0.1.8 → 0.1.10
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/cen_cenelec/grammar.js +10 -4
- package/dist/flavors/cen_cenelec/index.js +20 -1
- package/dist/flavors/cen_cenelec/model.d.ts +1 -0
- package/dist/flavors/cen_cenelec/model.js +4 -1
- package/dist/flavors/evs/grammar.js +53 -7
- package/dist/flavors/evs/index.js +74 -7
- package/dist/flavors/evs/model.d.ts +37 -1
- package/dist/flavors/evs/model.js +173 -11
- package/dist/flavors/ieee/artifact_tree.d.ts +2 -0
- package/dist/flavors/ieee/artifact_tree.js +36 -0
- package/dist/flavors/ieee/grammar.js +99 -19
- package/dist/flavors/ieee/index.js +353 -18
- package/dist/flavors/ieee/model.d.ts +5 -0
- package/dist/flavors/ieee/model.js +132 -20
- package/dist/flavors/ieee/preprocessor.js +28 -6
- package/dist/flavors/nist/grammar.js +18 -9
- package/dist/flavors/nist/index.js +16 -7
- package/dist/flavors/nist/preprocessor.js +9 -1
- package/dist/parg/runtime.d.ts +25 -0
- package/dist/parg/runtime.js +76 -0
- package/dist/parg/suite.d.ts +4 -0
- package/dist/parg/suite.js +14 -0
- package/dist/urn/parsers.js +7 -0
- package/package.json +6 -4
- package/vendor/parg/adobe.json +1 -0
- package/vendor/parg/aiee.json +1 -0
- package/vendor/parg/amca.json +1 -0
- package/vendor/parg/ansi.json +1 -0
- package/vendor/parg/api.json +1 -0
- package/vendor/parg/ashrae.json +1 -0
- package/vendor/parg/asme.json +1 -0
- package/vendor/parg/astm.json +1 -0
- package/vendor/parg/bipm.json +1 -0
- package/vendor/parg/bsi.json +1 -0
- package/vendor/parg/calconnect.json +1 -0
- package/vendor/parg/ccsds.json +1 -0
- package/vendor/parg/cen_cenelec.json +1 -0
- package/vendor/parg/cie.json +1 -0
- package/vendor/parg/csa.json +1 -0
- package/vendor/parg/doi.json +1 -0
- package/vendor/parg/easc.json +1 -0
- package/vendor/parg/ecma.json +1 -0
- package/vendor/parg/etsi.json +1 -0
- package/vendor/parg/evs.json +1 -0
- package/vendor/parg/gb.json +1 -0
- package/vendor/parg/gost.json +1 -0
- package/vendor/parg/iala.json +1 -0
- package/vendor/parg/iana.json +1 -0
- package/vendor/parg/idf.json +1 -0
- package/vendor/parg/iec.json +1 -0
- package/vendor/parg/ieee.json +1 -0
- package/vendor/parg/ietf.json +1 -0
- package/vendor/parg/ire.json +1 -0
- package/vendor/parg/isbn.json +1 -0
- package/vendor/parg/iso.json +1 -0
- package/vendor/parg/itu.json +1 -0
- package/vendor/parg/jcgm.json +1 -0
- package/vendor/parg/jis.json +1 -0
- package/vendor/parg/nesc.json +1 -0
- package/vendor/parg/nist.json +1 -0
- package/vendor/parg/oasis.json +1 -0
- package/vendor/parg/ogc.json +1 -0
- package/vendor/parg/oiml.json +1 -0
- package/vendor/parg/omg.json +1 -0
- package/vendor/parg/parg.json +1 -0
- package/vendor/parg/plateau.json +1 -0
- package/vendor/parg/sae.json +1 -0
- package/vendor/parg/tgpp.json +1 -0
- package/vendor/parg/un.json +1 -0
- package/vendor/parg/w3c.json +1 -0
- package/vendor/parg/xsf.json +1 -0
- package/dist/pg/runtime.d.ts +0 -85
- package/dist/pg/runtime.js +0 -170
- package/dist/pg/suite.d.ts +0 -20
- package/dist/pg/suite.js +0 -90
|
@@ -117,7 +117,16 @@ export class IeeeCode {
|
|
|
117
117
|
return result;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
|
|
120
|
+
// Canonical month spelling (mirrors the gem's CANONICAL_ABBREVIATIONS):
|
|
121
|
+
// full names normalize onto the crawl abbreviation, and "September"
|
|
122
|
+
// keeps its IEEE "Sept" form — the 3-letter "Sep" folds onto it, so
|
|
123
|
+
// every spelling of September renders and hashes alike.
|
|
124
|
+
const DRAFT_MONTH_CANONICAL = {
|
|
125
|
+
January: "Jan", February: "Feb", March: "Mar", April: "Apr",
|
|
126
|
+
June: "Jun", July: "Jul", August: "Aug", September: "Sept",
|
|
127
|
+
October: "Oct", November: "Nov", December: "Dec", Sep: "Sept",
|
|
128
|
+
};
|
|
129
|
+
export const DRAFT_MONTH_NAMES = {
|
|
121
130
|
January: "1", February: "2", March: "3", April: "4", May: "5", June: "6",
|
|
122
131
|
July: "7", August: "8", September: "9", October: "10", November: "11",
|
|
123
132
|
December: "12", Jan: "1", Feb: "2", Mar: "3", Apr: "4", Jun: "6",
|
|
@@ -139,12 +148,27 @@ export class IeeeDraft {
|
|
|
139
148
|
this.commaBeforeMonthSet = "comma_before_month" in attrs;
|
|
140
149
|
this.version = String(attrs["version"] ?? "");
|
|
141
150
|
this.revision = attrs["revision"];
|
|
142
|
-
this.isoStage = attrs["iso_stage"];
|
|
143
151
|
this.isoIteration = attrs["iso_iteration"];
|
|
152
|
+
// The grammar's ordered alternation captures the stage WITH its
|
|
153
|
+
// draft-marker D when the spelling doubles it ("=DDIS"): the marker
|
|
154
|
+
// is notation, the stage is the bare ISO/IEC token (the reference's
|
|
155
|
+
// Draft constructor strips it).
|
|
156
|
+
let stage = attrs["iso_stage"];
|
|
157
|
+
if (stage !== undefined && stage.startsWith("D") &&
|
|
158
|
+
["PWI", "NP", "WD", "CD", "CDV", "DIS", "FDIS"].includes(stage.slice(1))) {
|
|
159
|
+
stage = stage.slice(1);
|
|
160
|
+
}
|
|
161
|
+
this.isoStage = stage;
|
|
144
162
|
this.year = attrs["year"];
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
163
|
+
// Canonical month spelling: the crawl abbreviation ("September" →
|
|
164
|
+
// "Sept"); the 3-letter "Sep" folds onto the IEEE "Sept" form, so
|
|
165
|
+
// every spelling of September renders — and hashes — alike.
|
|
166
|
+
const rawMonth = attrs["month"];
|
|
167
|
+
this.originalMonth = rawMonth !== undefined
|
|
168
|
+
? DRAFT_MONTH_CANONICAL[rawMonth.replace(/\.$/, "")] ?? rawMonth
|
|
169
|
+
: undefined;
|
|
170
|
+
this.month = rawMonth !== undefined
|
|
171
|
+
? DRAFT_MONTH_NAMES[String(this.originalMonth)] ?? String(this.originalMonth)
|
|
148
172
|
: undefined;
|
|
149
173
|
this.day = attrs["day"];
|
|
150
174
|
this.commaBeforeMonth = attrs["comma_before_month"] === true;
|
|
@@ -363,10 +387,17 @@ export class IeeeIdentifier extends BaseIdentifier {
|
|
|
363
387
|
draft_status: { type: "string" },
|
|
364
388
|
draft: { type: "string" },
|
|
365
389
|
revision: { type: "string" },
|
|
390
|
+
rev_sep: { type: "string" },
|
|
391
|
+
rev_bare: { type: "boolean" },
|
|
366
392
|
edition: { type: "string" },
|
|
367
393
|
month: { type: "string" },
|
|
368
394
|
day: { type: "string" },
|
|
369
395
|
redline: { type: "boolean", default: false },
|
|
396
|
+
// Provenance (gem#520): the month arrived glued to the identity year
|
|
397
|
+
// on the code ("ANSI/IEEE 21-1976-11") rather than as a trailing
|
|
398
|
+
// print date. The render keys on the month being numeric; this
|
|
399
|
+
// records how it arrived.
|
|
400
|
+
month_glued: { type: "boolean", default: false },
|
|
370
401
|
edition_month: { type: "string" },
|
|
371
402
|
space_before_draft: { type: "boolean", default: false },
|
|
372
403
|
typed_stage: { type: IeeeTypedStage },
|
|
@@ -384,7 +415,7 @@ export class IeeeIdentifier extends BaseIdentifier {
|
|
|
384
415
|
interpretation: { type: "boolean", default: false },
|
|
385
416
|
relationships: { type: "string", collection: true },
|
|
386
417
|
});
|
|
387
|
-
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" }, {
|
|
418
|
+
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: "rev_sep", to: "rev_sep" }, { wire: "rev_bare", to: "rev_bare" }, { wire: "edition", to: "edition" }, { wire: "month", to: "month" }, { wire: "day", to: "day" }, { wire: "redline", to: "redline" }, { wire: "month_glued", to: "month_glued" }, { 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" }, {
|
|
388
419
|
wire: "relationships",
|
|
389
420
|
to: "relationships",
|
|
390
421
|
toWire: (model) => {
|
|
@@ -446,6 +477,12 @@ export function renderIeeeBase(id) {
|
|
|
446
477
|
let typeStr = id.type;
|
|
447
478
|
if (typeStr.startsWith("P"))
|
|
448
479
|
typeStr = typeStr.slice(1);
|
|
480
|
+
// A draft carries the word Draft alone in every face (the C2
|
|
481
|
+
// ruling): Std/Standard never renders on a draft - a status-less
|
|
482
|
+
// draft ("IEEE Draft Std P802.3/D2.0") renders "IEEE Draft
|
|
483
|
+
// P802.3/D2.0".
|
|
484
|
+
if (id.draft !== undefined && id.draft_status === undefined)
|
|
485
|
+
typeStr = "Draft";
|
|
449
486
|
if (typeStr.trim() !== "")
|
|
450
487
|
parts.push(typeStr);
|
|
451
488
|
}
|
|
@@ -455,6 +492,8 @@ export function renderIeeeBase(id) {
|
|
|
455
492
|
// dates (catalogue metadata, not identity); wider sets and
|
|
456
493
|
// space-separated dates print as spelled.
|
|
457
494
|
const iecIeeOnly = id.publisher === "IEC" && JSON.stringify(id.copublisher) === '["IEEE"]';
|
|
495
|
+
// Short format = numeric month (glued face); the comma face is a month name.
|
|
496
|
+
const gluedMonth = /^\d{1,2}$/.test(id.month ?? "");
|
|
458
497
|
if (codeObj !== undefined) {
|
|
459
498
|
let result = codeObj.render();
|
|
460
499
|
// Prepend P if this is a project AND code doesn't already have P.
|
|
@@ -467,11 +506,30 @@ export function renderIeeeBase(id) {
|
|
|
467
506
|
!result.startsWith("P")) {
|
|
468
507
|
result = `P${result}`;
|
|
469
508
|
}
|
|
470
|
-
|
|
509
|
+
// A base year dash-attaches to the code when nothing else carries
|
|
510
|
+
// it: no edition, no identity-month date - and either no draft at
|
|
511
|
+
// all, or a draft that carries its OWN date (the draft+corrigendum
|
|
512
|
+
// family: "PC37.09-1999/D7.2, Nov 2006").
|
|
513
|
+
// A numeric identity month is the SHORT format: the year stays on
|
|
514
|
+
// the code and the month dash-joins after it, whatever the input
|
|
515
|
+
// spelling ("IEEE P15026.1, 05 2014" renders "P15026.1-2014-05").
|
|
516
|
+
const yearOnCode = id.year !== undefined && id.edition === undefined &&
|
|
517
|
+
(id.month === undefined || gluedMonth) &&
|
|
518
|
+
(draftObj === undefined || draftObj.year !== undefined ||
|
|
519
|
+
(draftObj.version ?? "").match(/-\d{4}-\d{2}$/) !== null);
|
|
520
|
+
if (yearOnCode) {
|
|
471
521
|
result += `-${id.year}`;
|
|
472
522
|
}
|
|
523
|
+
if (gluedMonth && id.month !== undefined) {
|
|
524
|
+
result += `-${id.month}`;
|
|
525
|
+
}
|
|
526
|
+
// The lettered revision keeps its printed separator ("P802.11-REVmc"
|
|
527
|
+
// renders "P802.11-Revmc"); the bare word with no id still prints
|
|
528
|
+
// "Rev" (pubid ruling 2026-10-14).
|
|
473
529
|
if (id.revision !== undefined)
|
|
474
|
-
result +=
|
|
530
|
+
result += `${id.rev_sep ?? ""}Rev${id.revision}`;
|
|
531
|
+
if (id.rev_bare === true)
|
|
532
|
+
result += `${id.rev_sep ?? ""}Rev`;
|
|
475
533
|
if (draftObj !== undefined) {
|
|
476
534
|
let printed = draftObj.render();
|
|
477
535
|
// The draft designator carries its date on every lead
|
|
@@ -510,13 +568,22 @@ export function renderIeeeBase(id) {
|
|
|
510
568
|
parts.push(editionStr);
|
|
511
569
|
}
|
|
512
570
|
let result = parts.join(" ");
|
|
513
|
-
if (id.month !== undefined && !iecIeeOnly) {
|
|
571
|
+
if (id.month !== undefined && !gluedMonth && !iecIeeOnly) {
|
|
514
572
|
result += `, ${id.month}`;
|
|
515
573
|
if (id.day !== undefined)
|
|
516
574
|
result += ` ${id.day}`;
|
|
517
575
|
if (id.year !== undefined && id.edition === undefined)
|
|
518
576
|
result += ` ${id.year}`;
|
|
519
577
|
}
|
|
578
|
+
else if (id.year !== undefined && draftObj !== undefined && id.edition === undefined &&
|
|
579
|
+
draftObj?.year === undefined &&
|
|
580
|
+
(draftObj.version ?? "").match(/-\d{4}-\d{2}$/) === null && !iecIeeOnly) {
|
|
581
|
+
// A year-only date trailing the draft ("ANSI N42.34/D9a, 2015")
|
|
582
|
+
// keeps its comma form instead of being silently dropped; a year
|
|
583
|
+
// whose draft carries its own date dash-attached to the code above
|
|
584
|
+
// and never repeats.
|
|
585
|
+
result += `, ${id.year}`;
|
|
586
|
+
}
|
|
520
587
|
const parentheticals = [];
|
|
521
588
|
if (id.reaffirmed !== undefined && id.reaffirmed.trim() !== "") {
|
|
522
589
|
parentheticals.push(`(R${id.reaffirmed})`);
|
|
@@ -559,6 +626,13 @@ class IeeeUrnGenerator extends BaseUrnGenerator {
|
|
|
559
626
|
push("redline");
|
|
560
627
|
if (special === undefined && id.interpretation === true)
|
|
561
628
|
push("int");
|
|
629
|
+
// A NESC preprint is a draft-stage document distinct from the
|
|
630
|
+
// published edition it precedes — without this component it would
|
|
631
|
+
// share the edition's URN (urn:ieee:ieee:C2:2012).
|
|
632
|
+
if (id.constructor.polymorphicName ===
|
|
633
|
+
"pubid:ieee:nesc-preprint") {
|
|
634
|
+
push("preprint");
|
|
635
|
+
}
|
|
562
636
|
if (id.ashrae_number !== undefined) {
|
|
563
637
|
let ashrae = `ashrae.${id.ashrae_number}`;
|
|
564
638
|
if (id.ashrae_year !== undefined)
|
|
@@ -836,8 +910,14 @@ export const SiStandardClass = ieeeClass({ kind: "si-standard" }, {
|
|
|
836
910
|
result += ` ${part}`;
|
|
837
911
|
}
|
|
838
912
|
}
|
|
839
|
-
if (id.month !== undefined && id.year !== undefined)
|
|
840
|
-
|
|
913
|
+
if (id.month !== undefined && id.year !== undefined) {
|
|
914
|
+
// Short format (numeric month) renders glued; the comma marks a
|
|
915
|
+
// month name (the long format).
|
|
916
|
+
if (/^\d{1,2}$/.test(id.month))
|
|
917
|
+
result += `-${id.year}-${id.month}`;
|
|
918
|
+
else
|
|
919
|
+
result += `, ${id.month} ${id.year}`;
|
|
920
|
+
}
|
|
841
921
|
else if (id.year !== undefined)
|
|
842
922
|
result += `-${id.year}`;
|
|
843
923
|
return result;
|
|
@@ -1030,16 +1110,28 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1030
1110
|
// P-state is identity-bearing and prints as spelled - it is never
|
|
1031
1111
|
// added or stripped here.
|
|
1032
1112
|
if (leadParty === "ISO") {
|
|
1113
|
+
// A D= designator row ("P26511/D8=DDIS.3") prints the designator
|
|
1114
|
+
// after the code, not the stage as a word; only genuine stage
|
|
1115
|
+
// rows print the stage position.
|
|
1116
|
+
const designatorDraft = id["ieee_draft"];
|
|
1117
|
+
const printsDesignator = designatorDraft !== undefined && /^D\d*=/.test(designatorDraft);
|
|
1033
1118
|
const parts = [];
|
|
1034
1119
|
if (publishers !== undefined && publishers.length > 0)
|
|
1035
1120
|
parts.push(publishers.join("/"));
|
|
1036
|
-
if (
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1121
|
+
if (!printsDesignator) {
|
|
1122
|
+
if (id.typed_stage !== undefined) {
|
|
1123
|
+
parts.push(id.typed_stage.record.iso_stage_equivalent ?? id.typed_stage.render());
|
|
1124
|
+
}
|
|
1125
|
+
else if (isoStage !== undefined) {
|
|
1126
|
+
parts.push(isoStage);
|
|
1127
|
+
}
|
|
1041
1128
|
}
|
|
1042
|
-
|
|
1129
|
+
let codeStr = codeObj?.render() ?? "";
|
|
1130
|
+
// A P-prefixed joint project prints its parts dot-joined on the
|
|
1131
|
+
// ISO face ("ISO/IEEE DIS P15500.1"), whatever separator the
|
|
1132
|
+
// parse captured ("IEC/IEEE FDIS P60214-2-2018(E)" aliases in).
|
|
1133
|
+
if (codeStr.startsWith("P"))
|
|
1134
|
+
codeStr = codeStr.replaceAll("-", ".");
|
|
1043
1135
|
if (codeStr !== "")
|
|
1044
1136
|
parts.push(codeStr);
|
|
1045
1137
|
let result = parts.join(" ");
|
|
@@ -1049,12 +1141,16 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1049
1141
|
// the ISO-led print; only the bare language/edition marker ("(E)")
|
|
1050
1142
|
// prints - a relationship narrative is metadata, not identity.
|
|
1051
1143
|
const jointDraft = id["ieee_draft"];
|
|
1052
|
-
if (jointDraft !== undefined && jointDraft
|
|
1144
|
+
if (jointDraft !== undefined && /^D\d*=/.test(jointDraft))
|
|
1053
1145
|
result += `/${jointDraft}`;
|
|
1054
1146
|
const marker = id["parenthetical_content"];
|
|
1055
1147
|
if (marker !== undefined && /^[A-Z](?:\s*[/&]\s*[A-Z])*$/.test(marker)) {
|
|
1056
1148
|
result += ` (${marker})`;
|
|
1057
1149
|
}
|
|
1150
|
+
// The joint ISO-print redline is a distinct document (pubid#215):
|
|
1151
|
+
// "15289:2015(E) - Redline".
|
|
1152
|
+
if (id.redline === true)
|
|
1153
|
+
result += " - Redline";
|
|
1058
1154
|
return result;
|
|
1059
1155
|
}
|
|
1060
1156
|
// IEEE format
|
|
@@ -1074,6 +1170,8 @@ export const JointDevelopmentClass = ieeeClass({ kind: "joint-development" }, {
|
|
|
1074
1170
|
let result = parts.join(" ");
|
|
1075
1171
|
if (id.year !== undefined)
|
|
1076
1172
|
result += `-${id.year}`;
|
|
1173
|
+
if (id.redline === true)
|
|
1174
|
+
result += " - Redline";
|
|
1077
1175
|
return result;
|
|
1078
1176
|
},
|
|
1079
1177
|
});
|
|
@@ -1215,11 +1313,25 @@ export const NescDraftClass = ieeeClass({ kind: "nesc-draft" }, {
|
|
|
1215
1313
|
extraMappings: NescMappings,
|
|
1216
1314
|
render: (id) => {
|
|
1217
1315
|
const parts = ["Draft National Electrical Safety Code"];
|
|
1218
|
-
if (id.month !== undefined && id.year !== undefined)
|
|
1219
|
-
|
|
1316
|
+
if (id.month !== undefined && id.year !== undefined) {
|
|
1317
|
+
if (/^\d{1,2}$/.test(id.month))
|
|
1318
|
+
parts.push(` ${id.number}-${id.year}-${id.month}`);
|
|
1319
|
+
else
|
|
1320
|
+
parts.push(`, ${id.month} ${id.year}`);
|
|
1321
|
+
}
|
|
1220
1322
|
return parts.join("");
|
|
1221
1323
|
},
|
|
1222
1324
|
});
|
|
1325
|
+
// The NESC's own term for its pre-edition drafts: a draft STAGE of the
|
|
1326
|
+
// C2 code, not a variant. Canonical spelling is dotted and prefixed;
|
|
1327
|
+
// the dash, catalogue slash-tail and verbose proposal spellings are
|
|
1328
|
+
// aliases.
|
|
1329
|
+
export const NescPreprintClass = ieeeClass({ kind: "nesc-preprint" }, {
|
|
1330
|
+
codeColumns: true,
|
|
1331
|
+
extraDefs: NescDefs,
|
|
1332
|
+
extraMappings: NescMappings,
|
|
1333
|
+
render: (id) => `IEEE Std ${["C2", id.year, "Preprint"].filter((p) => p !== undefined).join(".")}`,
|
|
1334
|
+
});
|
|
1223
1335
|
function nescNamePortion(id) {
|
|
1224
1336
|
let name = "National Electrical Safety Code";
|
|
1225
1337
|
if (id["registered"] === true)
|
|
@@ -259,9 +259,34 @@ 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
|
-
//
|
|
263
|
-
|
|
264
|
-
|
|
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 corrigendum's own draft rides before the ordinal in the house
|
|
268
|
+
// order ("PC37.101-2006/D2, 2007/Cor. 1"): the catalogue spellings
|
|
269
|
+
// ".../Cor 1, D4, July 2015" and ".../Cor 1-201x/D5, April 2012"
|
|
270
|
+
// re-order into it, with the draft's date glued -YYYY-MM (pubid
|
|
271
|
+
// ruling 2026-10-14: no comma dates).
|
|
272
|
+
const COR_MONTHS = {
|
|
273
|
+
January: "01", February: "02", March: "03", April: "04", May: "05",
|
|
274
|
+
June: "06", July: "07", August: "08", September: "09", Sept: "09",
|
|
275
|
+
October: "10", November: "11", December: "12", Jan: "01", Feb: "02",
|
|
276
|
+
Mar: "03", Apr: "04", Jun: "06", Jul: "07", Aug: "08", Sep: "09",
|
|
277
|
+
Oct: "10", Nov: "11", Dec: "12",
|
|
278
|
+
};
|
|
279
|
+
cleaned = cleaned.replace(/\/Cor(?:rigendum)? (\d+(?:-[0-9xX]{4})?)\/(D[A-Z0-9][^,]*), ([A-Za-z]+) (\d{4})/g, (_m, cor, draft, mon, year) => {
|
|
280
|
+
const month = COR_MONTHS[mon.charAt(0).toUpperCase() + mon.slice(1).toLowerCase()];
|
|
281
|
+
return month === undefined ? _m : `/${draft}-${year}-${month}/Cor. ${cor}`;
|
|
282
|
+
});
|
|
283
|
+
cleaned = cleaned.replace(/\/Cor(?:rigendum)? (\d+), (D[A-Z0-9][^,]*), ([A-Za-z]+) (\d{4})/g, (_m, cor, draft, mon, year) => {
|
|
284
|
+
const month = COR_MONTHS[mon.charAt(0).toUpperCase() + mon.slice(1).toLowerCase()];
|
|
285
|
+
return month === undefined ? _m : `/${draft}-${year}-${month}/Cor. ${cor}`;
|
|
286
|
+
});
|
|
287
|
+
// Lettered inline revisions are IDENTITY (pubid ruling 2026-10-14):
|
|
288
|
+
// the grammar captures them natively with their separator; the former
|
|
289
|
+
// strip rewrite here dropped the letters and is gone.
|
|
265
290
|
return cleaned;
|
|
266
291
|
}
|
|
267
292
|
function normalizeJointStageSpellings(input) {
|
|
@@ -271,7 +296,6 @@ function normalizeJointStageSpellings(input) {
|
|
|
271
296
|
const num = "(P?\\d+(?:[.-]\\d+)?)";
|
|
272
297
|
const tail = "(,? (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Sept|Oct|Nov|Dec)[a-z]* \\d{4}|$|-\\d{4}(?:-\\d\\d)?)";
|
|
273
298
|
cleaned = cleaned.replace(/(\d)_D(\d)/g, "$1/D$2");
|
|
274
|
-
cleaned = cleaned.replace(/,(?=[A-Za-z])/, ", ");
|
|
275
299
|
cleaned = cleaned.replace(new RegExp(`^${pubs}${num}/(D[\\d.]+)/ ?${stage}\\b`), "$1$4 $2/$3");
|
|
276
300
|
cleaned = cleaned.replace(new RegExp(`^${pubs}${num}/ ${stage}${tail}`), "$1$3 $2$4");
|
|
277
301
|
cleaned = cleaned.replace(new RegExp(`^${pubs}${num}/${stage} (\\d{4})\\b`), "$1$3 $2-$4");
|
|
@@ -287,7 +311,6 @@ function normalizeJointStageSpellings(input) {
|
|
|
287
311
|
// The Parser.parse cleaning pipeline, in Ruby order.
|
|
288
312
|
export function preprocessIeee(input) {
|
|
289
313
|
let cleaned = input.replace(/\.pdf$/i, "");
|
|
290
|
-
cleaned = cleaned.replace(/_(FDIS|CDV|CD|DIS|WD|PWI|NP)/g, "/$1");
|
|
291
314
|
cleaned = cleaned.replace(/\s+/g, " ");
|
|
292
315
|
cleaned = cleaned.replace(/\b(ISO\/IEC\/IEEE|IEEE\/ISO\/IEC|IEEE\/IEC\/ISO|ISO\/IEEE|IEC\/IEEE|IEEE\/IEC|ISO\/IEC)\/ ?(FDIS|FCD|CDV|DIS\d?|CD\d?|WD|PWI|NP)\b/g, "$1 $2");
|
|
293
316
|
cleaned = normalizeRevisionNotation(cleaned);
|
|
@@ -363,7 +386,6 @@ export function preprocessIeee(input) {
|
|
|
363
386
|
if (/^(\d+[-.]\d+)\/D\d+/.test(cleaned)) {
|
|
364
387
|
cleaned = `IEEE P${cleaned}`;
|
|
365
388
|
}
|
|
366
|
-
cleaned = cleaned.replace(/\/Preprint\b/g, "");
|
|
367
389
|
cleaned = cleaned.replaceAll("Proposed Revision of", "Revision of");
|
|
368
390
|
cleaned = cleaned.replace(/\bammended\b/gi, "amended");
|
|
369
391
|
cleaned = cleaned.replace(/(\/INT|\/Cor\s+\d+-\d{4})\./g, "$1");
|
|
@@ -70,8 +70,14 @@ function buildRules() {
|
|
|
70
70
|
rule("simple_series", () => literalAlternation(SIMPLE_SERIES).as("series"));
|
|
71
71
|
rule("number_suffix", () => str("U")
|
|
72
72
|
.then(lowerLetter)
|
|
73
|
-
.or(
|
|
74
|
-
|
|
73
|
+
.or(
|
|
74
|
+
// An "r" directly followed by a digit is the revision marker
|
|
75
|
+
// (pubid#170), not a suffix — leave it for the edition rules.
|
|
76
|
+
str("r")
|
|
77
|
+
.then(digit)
|
|
78
|
+
.absent()
|
|
79
|
+
.then(letter, literalAlternation([
|
|
80
|
+
"ec", "ndex", "ndx", "nsert", "rrata", "raft", "pp", "s", "t",
|
|
75
81
|
"hi", "iet", "ort", "r", "p",
|
|
76
82
|
]).absent(), digits.maybe())));
|
|
77
83
|
rule("digits_with_suffix", () => digits.then(ref(rules, "number_suffix").then(digit.absent()).maybe()));
|
|
@@ -105,20 +111,23 @@ function buildRules() {
|
|
|
105
111
|
.absent()
|
|
106
112
|
.then(str("draft").absent(), (digits
|
|
107
113
|
.then(literalAlternation(["supp", "sup"]), digit.absent(), letter.absent())
|
|
108
|
-
.or(digits.then(str("r"), digits, str("U"), lowerLetter), digits.then(str("r"), digits, letter), digits.as("number_only").then(str("r"), digits.as("edition_id")), digits.then(str("_"), digits, dash, digits, upperLetter.maybe()), lowerLetter.then(dash, digits), digits.then(str("pt"), digits, dash.absent()), digits.then(upperLetter), digits
|
|
114
|
+
.or(digits.then(str("r"), digits, str("U"), lowerLetter), digits.then(str("r"), digits, letter), digits.as("number_only").then(str("r"), digits.then(dot.then(digits).maybe()).as("edition_id")), digits.then(str("_"), digits, dash, digits, upperLetter.maybe()), lowerLetter.then(dash, digits), digits.then(str("pt"), digits, dash.absent()), digits.then(upperLetter), digits
|
|
109
115
|
.as("number_only")
|
|
110
116
|
.then(str("r"), letter.as("letter"))
|
|
111
|
-
.as("revision_letter"), str("r").then(letter).as("revision_letter_suffix"), str("r")
|
|
117
|
+
.as("revision_letter"), str("r").then(letter).as("revision_letter_suffix"), str("r")
|
|
118
|
+
.then(digits.then(dot.then(digits).maybe()).as("edition_id"))
|
|
119
|
+
.as("revision_simple"), str("NCNR"), str("PERMIS"), str("BFRL"), upperLetter.repeat(1, 3), rules["digits_with_suffix"]
|
|
112
120
|
.then(dash.then(monthAbbrev(), digits, slash).absent()), lowerLetter.then(digit.absent()))).as("second_number")));
|
|
121
|
+
const dottedDigits = () => digits.then(dot.then(digits).maybe());
|
|
113
122
|
const editionInner = () => space
|
|
114
123
|
.maybe()
|
|
115
|
-
.then(str("e"),
|
|
124
|
+
.then(str("e"), dottedDigits().as("edition_id"))
|
|
116
125
|
.as("edition_e")
|
|
117
126
|
.or(space
|
|
118
|
-
.then(str("r"),
|
|
119
|
-
.as("edition_r_with_space_letter"), space.then(str("r"),
|
|
120
|
-
.then(
|
|
121
|
-
.as("edition_r_no_space_letter"), str("r").then(
|
|
127
|
+
.then(str("r"), dottedDigits().as("edition_id"), letter.as("edition_letter"))
|
|
128
|
+
.as("edition_r_with_space_letter"), space.then(str("r"), dottedDigits().as("edition_id")).as("edition_r_with_space"), str("r")
|
|
129
|
+
.then(dottedDigits().as("edition_id"), letter.as("edition_letter"))
|
|
130
|
+
.as("edition_r_no_space_letter"), str("r").then(dottedDigits().as("edition_id")).as("edition_r_no_space"), space
|
|
122
131
|
.maybe()
|
|
123
132
|
.then(str("rev"), space.maybe(), digits.as("edition_id"))
|
|
124
133
|
.as("edition_rev"), dash.then(match("[1-9]").as("edition_id"), digit.absent()).as("edition_historical"), dash
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { PubidRuntime, toBuilderTree } from "../../parg/runtime.js";
|
|
2
|
+
// The grammar runtime is the baked PARG artifact (pubid-grammar
|
|
3
|
+
// artifacts/nist.json via the parsanol engine) — the same artifact the
|
|
4
|
+
// gem runs, so grammar changes land once and this port cannot drift.
|
|
5
|
+
// Only the preprocessor, builder and model are ported code.
|
|
6
|
+
let cachedNistRuntime;
|
|
7
|
+
function cachedRuntime(input) {
|
|
8
|
+
cachedNistRuntime ??= PubidRuntime.load("nist");
|
|
9
|
+
return cachedNistRuntime.parseShape(input);
|
|
10
|
+
}
|
|
3
11
|
import { preprocessNist } from "./preprocessor.js";
|
|
4
12
|
import { NIST_CLASSES, NistCode, NistEdition, NistPart, NistStage, NistSupplement, NistTranslation, NistUpdate, NistVersion, NistVolume, SP_SUBSERIES, seriesPolicy, } from "./model.js";
|
|
5
13
|
/**
|
|
@@ -1238,11 +1246,12 @@ export function nistGrammarImplementation() {
|
|
|
1238
1246
|
return {
|
|
1239
1247
|
parse(input) {
|
|
1240
1248
|
const { cleaned, format } = preprocessNist(input);
|
|
1241
|
-
const
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1249
|
+
const base = cleaned.replace(/\s*\(all parts\)\s*$/, "");
|
|
1250
|
+
const tree = toBuilderTree(cachedRuntime(base));
|
|
1251
|
+
const marked = base !== cleaned
|
|
1252
|
+
? { ...tree, all_parts: true }
|
|
1253
|
+
: tree;
|
|
1254
|
+
return builder.build(marked, format);
|
|
1246
1255
|
},
|
|
1247
1256
|
};
|
|
1248
1257
|
}
|
|
@@ -192,8 +192,16 @@ export function preprocessNist(input) {
|
|
|
192
192
|
cleaned = cleaned.replace(/(\d)(v\d+[a-z]-[a-z])/g, "$1 $2");
|
|
193
193
|
cleaned = cleaned.replace(/(\d)(v\d+[A-Z])/g, "$1 $2");
|
|
194
194
|
cleaned = cleaned.replace(/(v\d+)([A-Z])-([A-Z])/g, (_m, v, a, b) => `${v}${a}-${b.toLowerCase()}`);
|
|
195
|
-
// normalize_edition_year_suffix
|
|
195
|
+
// normalize_edition_year_suffix — a dotted minor after the dot stays
|
|
196
|
+
// attached (pubid#170): "2006ed.1" → "e2006.1", never "e20061".
|
|
197
|
+
cleaned = cleaned.replace(/(\d{4})ed\.(\d+)/g, "e$1.$2");
|
|
196
198
|
cleaned = cleaned.replace(/(\d{4})ed\./g, "e$1");
|
|
199
|
+
// normalize_glued_dotted_edition — a glued dotted e-edition needs the
|
|
200
|
+
// space the spaced form has (pubid#170): "800-53e2.1" → "800-53 e2.1".
|
|
201
|
+
// The minor is 1-2 digits; a 4-digit tail is the additional-text year of
|
|
202
|
+
// "NBS CIRC 11e2.1915", which keeps its existing tree. Dot-less "800-53e2"
|
|
203
|
+
// keeps its number-bound tree.
|
|
204
|
+
cleaned = cleaned.replace(/(\d)e(\d+\.\d{1,2})(?!\d)/g, "$1 e$2");
|
|
197
205
|
// normalize_revision_with_letter
|
|
198
206
|
cleaned = cleaned.replace(/(\d+)(r\d{1,2})([a-z])(?=-|[A-Z]|$)/g, (_m, n, r, l) => `${n}${r}${l.toUpperCase()}`);
|
|
199
207
|
cleaned = cleaned.replace(/(\d+)(r\d{1,2})(?![a-zA-Z])(?=[A-Z]|-(?=[A-Z])|\/(?:upd|errata|insert))/g, "$1 $2");
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PargRuntime as EngineRuntime } from "parsanol";
|
|
2
|
+
export type { FieldRequirement, EntrySchema, Schema } from "parsanol";
|
|
3
|
+
export { PargRuntime } from "parsanol";
|
|
4
|
+
/** The artifacts directory: PARG_ARTIFACT_DIR, else the sibling
|
|
5
|
+
* pubid-grammar checkout of the pubid workspace, else the vendored copy
|
|
6
|
+
* shipped in the published package (refreshed by `npm run artifact`). */
|
|
7
|
+
export declare function artifactsDir(): string;
|
|
8
|
+
/** The pubid flavor runtime: loads baked artifacts from the workspace. */
|
|
9
|
+
export declare class PubidRuntime extends EngineRuntime {
|
|
10
|
+
static artifactsDir(): string;
|
|
11
|
+
static load(grammar: string, entry?: string): EngineRuntime;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The artifact emits capture leaves ({value, line, column, offset,
|
|
15
|
+
* length}) and a top-level sequence of capture hashes. This mirrors the
|
|
16
|
+
* gem's Pubid::Parg::Backend.to_builder_hash: scalarize leaves, fold the
|
|
17
|
+
* top-level list into one hash (last key wins — parslet's sequence fold).
|
|
18
|
+
*/
|
|
19
|
+
export declare function toBuilderTree(shape: unknown): unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Strip the shape metadata an artifact parse carries (offset/line/column
|
|
22
|
+
* wrappers) down to the plain string/array capture tree the builders
|
|
23
|
+
* consume — the same tree shape the hand-written grammars produced.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeShape(node: unknown): unknown;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//! The PARG artifact runtime for pubid: a thin adapter over the
|
|
2
|
+
//! published `parsanol` npm package (the wasm engine), adding the
|
|
3
|
+
//! pubid-workspace artifacts directory convention. No grammar code and
|
|
4
|
+
//! no vendored engine copy live in this repo; the baked artifact is
|
|
5
|
+
//! the contract and the engine ships from the registry.
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { PargRuntime as EngineRuntime } from "parsanol";
|
|
10
|
+
export { PargRuntime } from "parsanol";
|
|
11
|
+
/** Walk up from this module to the package root (which holds package.json). */
|
|
12
|
+
function packageRoot() {
|
|
13
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
for (; !existsSync(join(dir, "package.json")); dir = dirname(dir)) {
|
|
15
|
+
if (dir === dirname(dir))
|
|
16
|
+
throw new Error("package.json not found above the parg runtime");
|
|
17
|
+
}
|
|
18
|
+
return dir;
|
|
19
|
+
}
|
|
20
|
+
/** The artifacts directory: PARG_ARTIFACT_DIR, else the sibling
|
|
21
|
+
* pubid-grammar checkout of the pubid workspace, else the vendored copy
|
|
22
|
+
* shipped in the published package (refreshed by `npm run artifact`). */
|
|
23
|
+
export function artifactsDir() {
|
|
24
|
+
const env = process.env.PARG_ARTIFACT_DIR;
|
|
25
|
+
if (env)
|
|
26
|
+
return env;
|
|
27
|
+
const sibling = join(packageRoot(), "..", "pubid-grammar", "artifacts");
|
|
28
|
+
if (existsSync(sibling))
|
|
29
|
+
return sibling;
|
|
30
|
+
return join(packageRoot(), "vendor", "parg");
|
|
31
|
+
}
|
|
32
|
+
/** The pubid flavor runtime: loads baked artifacts from the workspace. */
|
|
33
|
+
export class PubidRuntime extends EngineRuntime {
|
|
34
|
+
static artifactsDir() {
|
|
35
|
+
return artifactsDir();
|
|
36
|
+
}
|
|
37
|
+
static load(grammar, entry) {
|
|
38
|
+
return EngineRuntime.fromFile(join(artifactsDir(), `${grammar}.json`), entry);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The artifact emits capture leaves ({value, line, column, offset,
|
|
43
|
+
* length}) and a top-level sequence of capture hashes. This mirrors the
|
|
44
|
+
* gem's Pubid::Parg::Backend.to_builder_hash: scalarize leaves, fold the
|
|
45
|
+
* top-level list into one hash (last key wins — parslet's sequence fold).
|
|
46
|
+
*/
|
|
47
|
+
export function toBuilderTree(shape) {
|
|
48
|
+
const normalized = normalizeShape(shape);
|
|
49
|
+
if (Array.isArray(normalized) &&
|
|
50
|
+
normalized.length > 0 &&
|
|
51
|
+
normalized.every((n) => typeof n === "object" && n !== null && !Array.isArray(n))) {
|
|
52
|
+
return Object.assign({}, ...normalized);
|
|
53
|
+
}
|
|
54
|
+
return normalized;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Strip the shape metadata an artifact parse carries (offset/line/column
|
|
58
|
+
* wrappers) down to the plain string/array capture tree the builders
|
|
59
|
+
* consume — the same tree shape the hand-written grammars produced.
|
|
60
|
+
*/
|
|
61
|
+
export function normalizeShape(node) {
|
|
62
|
+
if (Array.isArray(node))
|
|
63
|
+
return node.map(normalizeShape);
|
|
64
|
+
if (typeof node === "object" && node !== null) {
|
|
65
|
+
const rec = node;
|
|
66
|
+
if (typeof rec["value"] === "string" && Object.keys(rec).length >= 1 &&
|
|
67
|
+
"offset" in rec) {
|
|
68
|
+
return rec["value"];
|
|
69
|
+
}
|
|
70
|
+
const out = {};
|
|
71
|
+
for (const [k, v] of Object.entries(rec))
|
|
72
|
+
out[k] = normalizeShape(v);
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
return node;
|
|
76
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { loadSuites, readSuite, runSuite, type Suite, type SuiteTest, type TestKind, } from "parsanol/suite";
|
|
2
|
+
export { PubidRuntime } from "./runtime.js";
|
|
3
|
+
/** The suites directory: PARG_SUITES_DIR, else beside the artifacts. */
|
|
4
|
+
export declare function suitesDir(): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//! pgtest suite runner: re-exports the engine suite machinery from the
|
|
2
|
+
//! published `parsanol` package; only the suites directory convention
|
|
3
|
+
//! (sibling pubid-grammar checkout) is pubid-specific.
|
|
4
|
+
export { loadSuites, readSuite, runSuite, } from "parsanol/suite";
|
|
5
|
+
export { PubidRuntime } from "./runtime.js";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { artifactsDir } from "./runtime.js";
|
|
8
|
+
/** The suites directory: PARG_SUITES_DIR, else beside the artifacts. */
|
|
9
|
+
export function suitesDir() {
|
|
10
|
+
const env = process.env.PARG_SUITES_DIR;
|
|
11
|
+
if (env)
|
|
12
|
+
return env;
|
|
13
|
+
return join(artifactsDir(), "..", "suites");
|
|
14
|
+
}
|
package/dist/urn/parsers.js
CHANGED
|
@@ -552,6 +552,13 @@ export const URN_PARSERS = {
|
|
|
552
552
|
const parts = splitParts(body);
|
|
553
553
|
const [, code, year] = parts;
|
|
554
554
|
let text = `IEEE Std ${code}`;
|
|
555
|
+
// A "-YYYY-MM" tail is a dated reference (year + numeric month),
|
|
556
|
+
// mirroring the gem's urn parser; it re-parses through the
|
|
557
|
+
// trailing-month-year clause so the render prints "21, 11 1976"
|
|
558
|
+
// like the reference.
|
|
559
|
+
const dated = /^(.*)-(\d{4})-(\d{2})$/.exec(text);
|
|
560
|
+
if (dated)
|
|
561
|
+
return parse(`${dated[1]}, ${dated[3]} ${dated[2]}`);
|
|
555
562
|
if (year)
|
|
556
563
|
text += `-${year}`;
|
|
557
564
|
return parse(text);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubid/pubid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
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,15 +17,17 @@
|
|
|
17
17
|
"artifact": "tsc -p tsconfig.json && node scripts/build-artifact.mjs"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"parsanol": "^0.10.3",
|
|
20
21
|
"yaml": "^2.5.0"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"
|
|
24
|
-
"
|
|
24
|
+
"@types/node": "^20.14.0",
|
|
25
|
+
"typescript": "^5.6.0"
|
|
25
26
|
},
|
|
26
27
|
"files": [
|
|
27
28
|
"dist",
|
|
28
|
-
"artifact"
|
|
29
|
+
"artifact",
|
|
30
|
+
"vendor/parg"
|
|
29
31
|
],
|
|
30
32
|
"keywords": [
|
|
31
33
|
"pubid",
|
|
@@ -0,0 +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:38e8488c3da1c0f4a36fe2f63d87fee551d9317c5dae62f56972da1efe842a52"}
|