rtf-codec 1.1.2 → 2.1.0

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/README.md CHANGED
@@ -141,21 +141,21 @@ Two places where the two models genuinely differ in shape, rather than merely in
141
141
 
142
142
  Each of these is reported through a diagnostic rather than dropped silently — see [Diagnostics](#diagnostics).
143
143
 
144
- | Construct | Why |
145
- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
146
- | Headers, footers, footnotes, endnotes, annotations | `ContentDocument`'s flat form has no page-furniture or note position for them. A footnote's real home is `document-schema.js`'s tree-only `definitions` table, which a codec producing the flat form cannot reach. |
147
- | Content controls | **RTF 1.9.1 specifies none.** It predates OOXML's `w:sdt`: its "Custom XML Tags" (`\xmlopen`/`\xmlclose`) are a bare namespace/name tag with no type, lock, alias or value, and `\*\datastore` is an opaque blob whose "format ... is unknown to RTF" by the spec's own words. |
148
- | Form fields (`\*\formfield`, with a `FORMTEXT`/`FORMCHECKBOX`/`FORMDROPDOWN` instruction) | RTF's own nearest analogue to a content control, and a real `contentControl` mapping -- `ooxml.js` maps docx's legacy `w:ffData` twin onto exactly that kind. Not mapped yet: it needs the field machinery to hand the control its instruction and cached result. |
149
- | East Asian DBCS code pages (932, 936, 949, 950, 1361) | Each needs a ~20k-entry table and its own lead-byte state machine. A document declaring one decodes through cp1252 and says so. |
150
- | Code page 42 (`SYMBOL_CHARSET`) | Not an encoding: its bytes are glyph indices into whichever symbol font the run names, so there is no correct Unicode for them without that font's own cmap. |
151
- | Metafile and bitmap pictures (`\wmetafileN`, `\emfblip`, `\dibitmapN`, `\wbitmapN`, `\macpict`) | `ContentImageBlock` carries PNG and JPEG only. |
152
- | A picture with no stated size | `ContentImageBlock` requires a positive width and height, and deriving them from the payload would need an image decoder this package deliberately does not carry. |
153
- | Nested tables (`\nestcell`/`\nestrow`) | Read as ordinary cell content; the inner table's own structure is not reconstructed. |
154
- | Embedded objects (`\object`), drawing objects (`\do`, `\shp`) | Dropped. Writing one would need the OLE container this package does not build. |
155
- | Superscript/subscript (`\super`, `\sub`, `\upN`, `\dnN`), character scaling, kerning, background colour | **A schema gap, not an RTF one.** `ContentRun` carries no vertical-alignment field at all -- `epub-codec` reports the identical gap for its own `<sub>`/`<sup>`, and `ooxml.js`'s docx reader has no `w:vertAlign` handling either. Closing it is a change to `document-schema.js` and every codec that would then carry it, not to this one. |
156
- | Right-to-left text (`\rtlch`, `\ltrch`, `\rtlpar`, `\rtlrow`, `\rtldoc`) | The same shape of gap: no `ContentDocument` field carries text direction, at any of the four scopes RTF states it at. |
157
- | Cell vertical alignment (`\clvertalt`/`\clvertalc`/`\clvertalb`), diagonal cell borders (`\cldglu`/`\cldgll`), `\clshdngN` | `ContentTableCell` carries per-side borders and one background colour and nothing else -- a diagonal rule is not a side, and a shading percentage is a pattern rather than a colour. |
158
- | A bookmark whose two halves straddle a table cell wall | `document-schema.js` ratifies this as a drop rather than a shape to repair: each block list is its own bracket scope, and pairing across two of them would need the marker ids its contract deliberately refuses. |
144
+ | Construct | Why |
145
+ | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
146
+ | Headers, footers, footnotes, endnotes, annotations | `ContentDocument`'s flat form has no page-furniture or note position for them. A footnote's real home is `document-schema.js`'s tree-only `definitions` table, which a codec producing the flat form cannot reach. |
147
+ | Content controls | **RTF 1.9.1 specifies none.** It predates OOXML's `w:sdt`: its "Custom XML Tags" (`\xmlopen`/`\xmlclose`) are a bare namespace/name tag with no type, lock, alias or value, and `\*\datastore` is an opaque blob whose "format ... is unknown to RTF" by the spec's own words. |
148
+ | Form fields (`\*\formfield`, with a `FORMTEXT`/`FORMCHECKBOX`/`FORMDROPDOWN` instruction) | RTF's own nearest analogue to a content control, and a real `contentControl` mapping -- `ooxml.js` maps docx's legacy `w:ffData` twin onto exactly that kind. Not mapped yet: it needs the field machinery to hand the control its instruction and cached result. |
149
+ | East Asian DBCS code pages (932, 936, 949, 950, 1361) | Each needs a ~20k-entry table and its own lead-byte state machine. A document declaring one decodes through cp1252 and says so. |
150
+ | Code page 42 (`SYMBOL_CHARSET`) | Not an encoding: its bytes are glyph indices into whichever symbol font the run names, so there is no correct Unicode for them without that font's own cmap. |
151
+ | Metafile and bitmap pictures (`\wmetafileN`, `\emfblip`, `\dibitmapN`, `\wbitmapN`, `\macpict`) | `ContentImageBlock` carries PNG and JPEG only. |
152
+ | A picture with no stated size | `ContentImageBlock` requires a positive width and height, and deriving them from the payload would need an image decoder this package deliberately does not carry. |
153
+ | Nested tables (`\nestcell`/`\nestrow`) | Read as ordinary cell content; the inner table's own structure is not reconstructed. |
154
+ | Embedded objects (`\object`), drawing objects (`\do`, `\shp`) | Dropped. Writing one would need the OLE container this package does not build. |
155
+ | Superscript/subscript (`\super`, `\sub`, `\upN`, `\dnN`), character scaling, kerning, background colour | **A schema gap, not an RTF one.** `ContentRun` carries no vertical-alignment field at all -- `epub-codec` reports the identical gap for its own `<sub>`/`<sup>`, and `ooxml.js`'s docx reader has no `w:vertAlign` handling either. Closing it is a change to `document-schema.js` and every codec that would then carry it, not to this one. |
156
+ | Right-to-left text (`\rtlch`, `\ltrch`, `\rtlpar`, `\rtlrow`, `\rtldoc`) | The same shape of gap: no `ContentDocument` field carries text direction, at any of the four scopes RTF states it at. |
157
+ | Cell vertical alignment (`\clvertalt`/`\clvertalc`/`\clvertalb`), diagonal cell borders (`\cldglu`/`\cldgll`), `\clshdngN` | `ContentTableCell.borders` has no diagonal member, so a diagonal rule is not a side; `\clshdngN`'s own shading percentage names a genuine two-colour pattern fill, which `document-schema.js`'s `ContentCellFill` can now express (ExaDev/documents.js#951) but this package does not yet resolve either `\clcbpatN`'s own foreground colour or `\clshdngN`'s percentage into one -- `\clcbpatN`'s background colour alone still reads and writes as a `'solid'` fill. |
158
+ | A bookmark whose two halves straddle a table cell wall | `document-schema.js` ratifies this as a drop rather than a shape to repair: each block list is its own bracket scope, and pairing across two of them would need the marker ids its contract deliberately refuses. |
159
159
 
160
160
  ## Diagnostics
161
161
 
package/dist/codec.d.cts CHANGED
@@ -595,7 +595,7 @@ declare const rtfCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Arr
595
595
  kind: z.ZodLiteral<"drawing">;
596
596
  }, z.core.$strip>, z.ZodObject<{
597
597
  children: z.ZodArray<z.ZodObject<{
598
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
598
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
599
599
  starMath: z.ZodOptional<z.ZodString>;
600
600
  presentation: z.ZodOptional<z.ZodObject<{
601
601
  latex: z.ZodString;
@@ -1113,11 +1113,80 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1113
1113
  }, z.core.$strip>>>;
1114
1114
  colSpan: z.ZodOptional<z.ZodNumber>;
1115
1115
  rowSpan: z.ZodOptional<z.ZodNumber>;
1116
- background: z.ZodOptional<z.ZodObject<{
1117
- r: z.ZodNumber;
1118
- g: z.ZodNumber;
1119
- b: z.ZodNumber;
1120
- }, z.core.$strip>>;
1116
+ background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1117
+ kind: z.ZodLiteral<"solid">;
1118
+ color: z.ZodObject<{
1119
+ r: z.ZodNumber;
1120
+ g: z.ZodNumber;
1121
+ b: z.ZodNumber;
1122
+ }, z.core.$strip>;
1123
+ }, z.core.$strip>, z.ZodObject<{
1124
+ kind: z.ZodLiteral<"pattern">;
1125
+ patternType: z.ZodEnum<{
1126
+ percent5: "percent5";
1127
+ percent10: "percent10";
1128
+ percent12: "percent12";
1129
+ percent15: "percent15";
1130
+ percent20: "percent20";
1131
+ percent25: "percent25";
1132
+ percent30: "percent30";
1133
+ percent35: "percent35";
1134
+ percent37: "percent37";
1135
+ percent40: "percent40";
1136
+ percent45: "percent45";
1137
+ percent50: "percent50";
1138
+ percent55: "percent55";
1139
+ percent60: "percent60";
1140
+ percent62: "percent62";
1141
+ percent65: "percent65";
1142
+ percent70: "percent70";
1143
+ percent75: "percent75";
1144
+ percent80: "percent80";
1145
+ percent85: "percent85";
1146
+ percent87: "percent87";
1147
+ percent90: "percent90";
1148
+ percent95: "percent95";
1149
+ horizontalStripe: "horizontalStripe";
1150
+ verticalStripe: "verticalStripe";
1151
+ diagonalStripe: "diagonalStripe";
1152
+ reverseDiagonalStripe: "reverseDiagonalStripe";
1153
+ horizontalCross: "horizontalCross";
1154
+ diagonalCross: "diagonalCross";
1155
+ thinHorizontalStripe: "thinHorizontalStripe";
1156
+ thinVerticalStripe: "thinVerticalStripe";
1157
+ thinDiagonalStripe: "thinDiagonalStripe";
1158
+ thinReverseDiagonalStripe: "thinReverseDiagonalStripe";
1159
+ thinHorizontalCross: "thinHorizontalCross";
1160
+ thinDiagonalCross: "thinDiagonalCross";
1161
+ mediumGray: "mediumGray";
1162
+ darkGray: "darkGray";
1163
+ lightGray: "lightGray";
1164
+ darkHorizontal: "darkHorizontal";
1165
+ darkVertical: "darkVertical";
1166
+ darkDown: "darkDown";
1167
+ darkUp: "darkUp";
1168
+ darkGrid: "darkGrid";
1169
+ darkTrellis: "darkTrellis";
1170
+ lightHorizontal: "lightHorizontal";
1171
+ lightVertical: "lightVertical";
1172
+ lightDown: "lightDown";
1173
+ lightUp: "lightUp";
1174
+ lightGrid: "lightGrid";
1175
+ lightTrellis: "lightTrellis";
1176
+ gray125: "gray125";
1177
+ gray0625: "gray0625";
1178
+ }>;
1179
+ foregroundColor: z.ZodOptional<z.ZodObject<{
1180
+ r: z.ZodNumber;
1181
+ g: z.ZodNumber;
1182
+ b: z.ZodNumber;
1183
+ }, z.core.$strip>>;
1184
+ backgroundColor: z.ZodOptional<z.ZodObject<{
1185
+ r: z.ZodNumber;
1186
+ g: z.ZodNumber;
1187
+ b: z.ZodNumber;
1188
+ }, z.core.$strip>>;
1189
+ }, z.core.$strip>], "kind">>;
1121
1190
  borders: z.ZodOptional<z.ZodObject<{
1122
1191
  left: z.ZodOptional<z.ZodObject<{
1123
1192
  color: z.ZodObject<{
@@ -1356,10 +1425,10 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1356
1425
  endColumn: z.ZodNumber;
1357
1426
  }, z.core.$strip>>;
1358
1427
  type: z.ZodEnum<{
1359
- decimal: "decimal";
1360
- list: "list";
1361
1428
  date: "date";
1362
1429
  custom: "custom";
1430
+ decimal: "decimal";
1431
+ list: "list";
1363
1432
  time: "time";
1364
1433
  whole: "whole";
1365
1434
  textLength: "textLength";
@@ -2439,7 +2508,7 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
2439
2508
  }, z.core.$strip>;
2440
2509
  }, z.core.$strip>, z.ZodObject<{
2441
2510
  formula: z.ZodObject<{
2442
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
2511
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
2443
2512
  starMath: z.ZodOptional<z.ZodString>;
2444
2513
  presentation: z.ZodOptional<z.ZodObject<{
2445
2514
  latex: z.ZodString;
package/dist/codec.d.ts CHANGED
@@ -595,7 +595,7 @@ declare const rtfCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Arr
595
595
  kind: z.ZodLiteral<"drawing">;
596
596
  }, z.core.$strip>, z.ZodObject<{
597
597
  children: z.ZodArray<z.ZodObject<{
598
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
598
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
599
599
  starMath: z.ZodOptional<z.ZodString>;
600
600
  presentation: z.ZodOptional<z.ZodObject<{
601
601
  latex: z.ZodString;
@@ -1113,11 +1113,80 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1113
1113
  }, z.core.$strip>>>;
1114
1114
  colSpan: z.ZodOptional<z.ZodNumber>;
1115
1115
  rowSpan: z.ZodOptional<z.ZodNumber>;
1116
- background: z.ZodOptional<z.ZodObject<{
1117
- r: z.ZodNumber;
1118
- g: z.ZodNumber;
1119
- b: z.ZodNumber;
1120
- }, z.core.$strip>>;
1116
+ background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1117
+ kind: z.ZodLiteral<"solid">;
1118
+ color: z.ZodObject<{
1119
+ r: z.ZodNumber;
1120
+ g: z.ZodNumber;
1121
+ b: z.ZodNumber;
1122
+ }, z.core.$strip>;
1123
+ }, z.core.$strip>, z.ZodObject<{
1124
+ kind: z.ZodLiteral<"pattern">;
1125
+ patternType: z.ZodEnum<{
1126
+ percent5: "percent5";
1127
+ percent10: "percent10";
1128
+ percent12: "percent12";
1129
+ percent15: "percent15";
1130
+ percent20: "percent20";
1131
+ percent25: "percent25";
1132
+ percent30: "percent30";
1133
+ percent35: "percent35";
1134
+ percent37: "percent37";
1135
+ percent40: "percent40";
1136
+ percent45: "percent45";
1137
+ percent50: "percent50";
1138
+ percent55: "percent55";
1139
+ percent60: "percent60";
1140
+ percent62: "percent62";
1141
+ percent65: "percent65";
1142
+ percent70: "percent70";
1143
+ percent75: "percent75";
1144
+ percent80: "percent80";
1145
+ percent85: "percent85";
1146
+ percent87: "percent87";
1147
+ percent90: "percent90";
1148
+ percent95: "percent95";
1149
+ horizontalStripe: "horizontalStripe";
1150
+ verticalStripe: "verticalStripe";
1151
+ diagonalStripe: "diagonalStripe";
1152
+ reverseDiagonalStripe: "reverseDiagonalStripe";
1153
+ horizontalCross: "horizontalCross";
1154
+ diagonalCross: "diagonalCross";
1155
+ thinHorizontalStripe: "thinHorizontalStripe";
1156
+ thinVerticalStripe: "thinVerticalStripe";
1157
+ thinDiagonalStripe: "thinDiagonalStripe";
1158
+ thinReverseDiagonalStripe: "thinReverseDiagonalStripe";
1159
+ thinHorizontalCross: "thinHorizontalCross";
1160
+ thinDiagonalCross: "thinDiagonalCross";
1161
+ mediumGray: "mediumGray";
1162
+ darkGray: "darkGray";
1163
+ lightGray: "lightGray";
1164
+ darkHorizontal: "darkHorizontal";
1165
+ darkVertical: "darkVertical";
1166
+ darkDown: "darkDown";
1167
+ darkUp: "darkUp";
1168
+ darkGrid: "darkGrid";
1169
+ darkTrellis: "darkTrellis";
1170
+ lightHorizontal: "lightHorizontal";
1171
+ lightVertical: "lightVertical";
1172
+ lightDown: "lightDown";
1173
+ lightUp: "lightUp";
1174
+ lightGrid: "lightGrid";
1175
+ lightTrellis: "lightTrellis";
1176
+ gray125: "gray125";
1177
+ gray0625: "gray0625";
1178
+ }>;
1179
+ foregroundColor: z.ZodOptional<z.ZodObject<{
1180
+ r: z.ZodNumber;
1181
+ g: z.ZodNumber;
1182
+ b: z.ZodNumber;
1183
+ }, z.core.$strip>>;
1184
+ backgroundColor: z.ZodOptional<z.ZodObject<{
1185
+ r: z.ZodNumber;
1186
+ g: z.ZodNumber;
1187
+ b: z.ZodNumber;
1188
+ }, z.core.$strip>>;
1189
+ }, z.core.$strip>], "kind">>;
1121
1190
  borders: z.ZodOptional<z.ZodObject<{
1122
1191
  left: z.ZodOptional<z.ZodObject<{
1123
1192
  color: z.ZodObject<{
@@ -1356,10 +1425,10 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
1356
1425
  endColumn: z.ZodNumber;
1357
1426
  }, z.core.$strip>>;
1358
1427
  type: z.ZodEnum<{
1359
- decimal: "decimal";
1360
- list: "list";
1361
1428
  date: "date";
1362
1429
  custom: "custom";
1430
+ decimal: "decimal";
1431
+ list: "list";
1363
1432
  time: "time";
1364
1433
  whole: "whole";
1365
1434
  textLength: "textLength";
@@ -2439,7 +2508,7 @@ declare const rtfContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, U
2439
2508
  }, z.core.$strip>;
2440
2509
  }, z.core.$strip>, z.ZodObject<{
2441
2510
  formula: z.ZodObject<{
2442
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
2511
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
2443
2512
  starMath: z.ZodOptional<z.ZodString>;
2444
2513
  presentation: z.ZodOptional<z.ZodObject<{
2445
2514
  latex: z.ZodString;
package/dist/read.cjs CHANGED
@@ -513,12 +513,15 @@ var ContentBuilder = class {
513
513
  rowSpan += 1;
514
514
  }
515
515
  const borders = this.resolveBorders(definition);
516
- const background = definition?.backgroundIndex === void 0 ? void 0 : this.header.colors[definition.backgroundIndex];
516
+ const backgroundColor = definition?.backgroundIndex === void 0 ? void 0 : this.header.colors[definition.backgroundIndex];
517
517
  return {
518
518
  blocks: cell.blocks,
519
519
  ...colSpan > 1 ? { colSpan } : {},
520
520
  ...rowSpan > 1 ? { rowSpan } : {},
521
- ...background === void 0 ? {} : { background },
521
+ ...backgroundColor === void 0 ? {} : { background: {
522
+ kind: "solid",
523
+ color: backgroundColor
524
+ } },
522
525
  ...borders === void 0 ? {} : { borders }
523
526
  };
524
527
  }) }));
package/dist/read.js CHANGED
@@ -512,12 +512,15 @@ var ContentBuilder = class {
512
512
  rowSpan += 1;
513
513
  }
514
514
  const borders = this.resolveBorders(definition);
515
- const background = definition?.backgroundIndex === void 0 ? void 0 : this.header.colors[definition.backgroundIndex];
515
+ const backgroundColor = definition?.backgroundIndex === void 0 ? void 0 : this.header.colors[definition.backgroundIndex];
516
516
  return {
517
517
  blocks: cell.blocks,
518
518
  ...colSpan > 1 ? { colSpan } : {},
519
519
  ...rowSpan > 1 ? { rowSpan } : {},
520
- ...background === void 0 ? {} : { background },
520
+ ...backgroundColor === void 0 ? {} : { background: {
521
+ kind: "solid",
522
+ color: backgroundColor
523
+ } },
521
524
  ...borders === void 0 ? {} : { borders }
522
525
  };
523
526
  }) }));
package/dist/write.cjs CHANGED
@@ -73,7 +73,7 @@ function collectTables(document) {
73
73
  return;
74
74
  }
75
75
  if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) {
76
- noteColor(cell.background);
76
+ noteColor(cell.background === void 0 ? void 0 : (0, document_schema_js.resolveCellFillColor)(cell.background));
77
77
  for (const side of CELL_BORDER_ORDER) noteColor(cell.borders?.[side]?.color);
78
78
  for (const inner of cell.blocks) noteBlock(inner);
79
79
  }
@@ -459,8 +459,9 @@ var RtfWriter = class {
459
459
  const border = borders[side];
460
460
  if (border !== void 0) out += require_cell_format.borderControlWords(side, border, colorIndexOf(border.color, this.tables.colors));
461
461
  }
462
- if (cell.background !== void 0) {
463
- const index = colorIndexOf(cell.background, this.tables.colors);
462
+ const cellBackgroundColor = cell.background === void 0 ? void 0 : (0, document_schema_js.resolveCellFillColor)(cell.background);
463
+ if (cellBackgroundColor !== void 0) {
464
+ const index = colorIndexOf(cellBackgroundColor, this.tables.colors);
464
465
  if (index !== void 0) out += `\\clcbpat${String(index)}`;
465
466
  }
466
467
  return `${out}\\cellx${String(rightTwips)}`;
package/dist/write.js CHANGED
@@ -4,7 +4,7 @@ import { pointsToHalfPoints, pointsToTwips } from "./units.js";
4
4
  import { borderControlWords } from "./cell-format.js";
5
5
  import { bookmarkResidueControlWords, dttmFromIso, isBookmarkAnchor } from "./constructs.js";
6
6
  import { parseRtfListNumId } from "./list-id.js";
7
- import { clampHeadingLevel, colorToRgbHex, flattenTree } from "document-schema.js";
7
+ import { clampHeadingLevel, colorToRgbHex, flattenTree, resolveCellFillColor } from "document-schema.js";
8
8
  //#region src/write.ts
9
9
  const LEVEL_NUMBER_FORMAT_BULLET = 23;
10
10
  const LEVEL_NUMBER_FORMAT_ARABIC = 0;
@@ -72,7 +72,7 @@ function collectTables(document) {
72
72
  return;
73
73
  }
74
74
  if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) {
75
- noteColor(cell.background);
75
+ noteColor(cell.background === void 0 ? void 0 : resolveCellFillColor(cell.background));
76
76
  for (const side of CELL_BORDER_ORDER) noteColor(cell.borders?.[side]?.color);
77
77
  for (const inner of cell.blocks) noteBlock(inner);
78
78
  }
@@ -458,8 +458,9 @@ var RtfWriter = class {
458
458
  const border = borders[side];
459
459
  if (border !== void 0) out += borderControlWords(side, border, colorIndexOf(border.color, this.tables.colors));
460
460
  }
461
- if (cell.background !== void 0) {
462
- const index = colorIndexOf(cell.background, this.tables.colors);
461
+ const cellBackgroundColor = cell.background === void 0 ? void 0 : resolveCellFillColor(cell.background);
462
+ if (cellBackgroundColor !== void 0) {
463
+ const index = colorIndexOf(cellBackgroundColor, this.tables.colors);
463
464
  if (index !== void 0) out += `\\clcbpat${String(index)}`;
464
465
  }
465
466
  return `${out}\\cellx${String(rightTwips)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rtf-codec",
3
- "version": "1.1.2",
3
+ "version": "2.1.0",
4
4
  "description": "Hand-written Rich Text Format (RTF 1.9.1) reader and writer against the shared document-schema.js content pivot.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -62,6 +62,8 @@
62
62
  "test:watch": "vitest --project unit",
63
63
  "test:coverage": "turbo run _test:coverage",
64
64
  "_test:coverage": "vitest run --project unit --coverage",
65
+ "test:mutation": "turbo run _test:mutation",
66
+ "_test:mutation": "stryker run stryker.config.mjs",
65
67
  "test:smoke": "turbo run _test:smoke",
66
68
  "_test:smoke": "vitest run --project smoke",
67
69
  "prepare": "husky",
@@ -78,16 +80,20 @@
78
80
  "license": "MIT",
79
81
  "packageManager": "pnpm@11.6.0",
80
82
  "dependencies": {
81
- "document-schema.js": "^5.6.0",
83
+ "document-schema.js": "^6.1.0",
82
84
  "zod": "^4.4.3"
83
85
  },
84
86
  "devDependencies": {
85
87
  "@arethetypeswrong/cli": "^0.18.5",
86
88
  "@cloudflare/vitest-pool-workers": "^0.21.2",
89
+ "@stryker-mutator/core": "^10.0.0",
90
+ "@stryker-mutator/typescript-checker": "^10.0.0",
91
+ "@stryker-mutator/vitest-runner": "^10.0.0",
87
92
  "@types/node": "^26.1.1",
88
93
  "@vitest/coverage-v8": "^4.1.10",
89
94
  "eslint": "^10.8.0",
90
95
  "husky": "^9.1.7",
96
+ "jiti": "2.7.0",
91
97
  "publint": "^0.3.21",
92
98
  "semantic-release": "^25.0.8",
93
99
  "tsdown": "^0.22.13",