@pubid/pubid 0.1.9 → 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.
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 || d["year"] !== 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
  }
@@ -874,13 +874,28 @@ class IeeeBuilder {
874
874
  // the ISO face, which prints the date from the identity slots
875
875
  // (", March 2017", pubid#216).
876
876
  if (parsed["draft_month"] !== undefined && parsed["iso_stage"] === undefined) {
877
- const draftObj = new IeeeDraft({
878
- version: draftVer,
879
- month: extractValue(parsed["draft_month"]),
880
- year: extractValue(parsed["draft_year"]),
881
- comma_before_month: true,
882
- });
883
- attributes["draft"] = draftObj.render();
877
+ const dm = extractValue(parsed["draft_month"]) ?? "";
878
+ const dy = extractValue(parsed["draft_year"]) ?? "";
879
+ const monthNum = DRAFT_MONTH_NAMES[dm.replace(/\.$/, "")];
880
+ if (JSON.stringify(attributes["publishers"]) === JSON.stringify(["IEEE", "CSA"]) &&
881
+ monthNum !== undefined && dy !== "") {
882
+ // The joint IEEE/CSA drafts glue their date into the
883
+ // designator with the month numeric (pubid ruling
884
+ // 2026-10-14: no comma dates on these rows).
885
+ const glued = new IeeeDraft({
886
+ version: `${draftVer}-${dy}-${monthNum.padStart(2, "0")}`,
887
+ });
888
+ attributes["draft"] = glued.render();
889
+ }
890
+ else {
891
+ const draftObj = new IeeeDraft({
892
+ version: draftVer,
893
+ month: dm === "" ? undefined : dm,
894
+ year: dy === "" ? undefined : dy,
895
+ comma_before_month: true,
896
+ });
897
+ attributes["draft"] = draftObj.render();
898
+ }
884
899
  if (parsed["year"] === undefined)
885
900
  delete attributes["year"];
886
901
  if (parsed["month"] === undefined)
@@ -895,6 +910,21 @@ class IeeeBuilder {
895
910
  if (parsed["year"] === undefined)
896
911
  delete attributes["year"];
897
912
  }
913
+ else if (JSON.stringify(attributes["publishers"]) === JSON.stringify(["IEEE", "CSA"]) &&
914
+ parsed["iso_stage"] === undefined &&
915
+ /^(19|20)\d\d$/.test(extractValue(parsed["year"]) ?? "") &&
916
+ /^\d{1,2}$/.test(extractValue(parsed["month"]) ?? "")) {
917
+ // The glued face re-parses with the date in the identity
918
+ // slots ("D2-2016-09" -> year/month + a bare D2): it
919
+ // normalizes back onto the draft-embedded date so the
920
+ // round trip closes on the CSA canonical.
921
+ const glued = new IeeeDraft({
922
+ version: `${draftVer}-${extractValue(parsed["year"])}-${extractValue(parsed["month"])}`,
923
+ });
924
+ attributes["draft"] = glued.render();
925
+ delete attributes["year"];
926
+ delete attributes["month"];
927
+ }
898
928
  else {
899
929
  attributes["ieee_draft"] = `D${draftVer}`;
900
930
  }
@@ -1049,9 +1079,20 @@ class IeeeBuilder {
1049
1079
  parsed["amd_number"] === undefined) {
1050
1080
  const pubs = (attributes["publishers"] ?? []);
1051
1081
  const projectAttrs = {
1052
- code: attributes["code"],
1053
1082
  draft: attributes["draft"],
1054
1083
  };
1084
+ // The code columns (number/parts/separator/prefix) are the
1085
+ // ProjectDraft render/hash face; the spelled P is the project
1086
+ // marker (identity), whatever the lead publisher.
1087
+ for (const k of ["number", "prefix", "parts", "separator"]) {
1088
+ // A "P" prefix is the project marker itself (the generic path
1089
+ // deletes it on the strip) - it must not ride the code columns.
1090
+ if (attributes[k] !== undefined && !(k === "prefix" && attributes[k] === "P")) {
1091
+ projectAttrs[k] = attributes[k];
1092
+ }
1093
+ }
1094
+ if (parsed["project_marker"] !== undefined)
1095
+ projectAttrs["project_marker"] = true;
1055
1096
  if (pubs.length > 0) {
1056
1097
  projectAttrs["publisher"] = pubs[0];
1057
1098
  if (pubs.length > 1)
@@ -515,7 +515,8 @@ export function renderIeeeBase(id) {
515
515
  // spelling ("IEEE P15026.1, 05 2014" renders "P15026.1-2014-05").
516
516
  const yearOnCode = id.year !== undefined && id.edition === undefined &&
517
517
  (id.month === undefined || gluedMonth) &&
518
- (draftObj === undefined || draftObj.year !== undefined);
518
+ (draftObj === undefined || draftObj.year !== undefined ||
519
+ (draftObj.version ?? "").match(/-\d{4}-\d{2}$/) !== null);
519
520
  if (yearOnCode) {
520
521
  result += `-${id.year}`;
521
522
  }
@@ -575,7 +576,8 @@ export function renderIeeeBase(id) {
575
576
  result += ` ${id.year}`;
576
577
  }
577
578
  else if (id.year !== undefined && draftObj !== undefined && id.edition === undefined &&
578
- draftObj?.year === undefined && !iecIeeOnly) {
579
+ draftObj?.year === undefined &&
580
+ (draftObj.version ?? "").match(/-\d{4}-\d{2}$/) === null && !iecIeeOnly) {
579
581
  // A year-only date trailing the draft ("ANSI N42.34/D9a, 2015")
580
582
  // keeps its comma form instead of being silently dropped; a year
581
583
  // whose draft carries its own date dash-attached to the code above
@@ -259,6 +259,31 @@ 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 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
+ });
262
287
  // Lettered inline revisions are IDENTITY (pubid ruling 2026-10-14):
263
288
  // the grammar captures them natively with their separator; the former
264
289
  // strip rewrite here dropped the letters and is gone.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pubid/pubid",
3
- "version": "0.1.9",
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",