reamkit 1.31.0 → 1.32.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.
Files changed (83) hide show
  1. package/README.md +10 -0
  2. package/dist/esm/core/bidi/index.d.ts +10 -0
  3. package/dist/esm/core/bidi/index.js +18 -2
  4. package/dist/esm/core/converter/facade.js +10 -5
  5. package/dist/esm/core/converter/project.js +1 -0
  6. package/dist/esm/core/converter/ream.js +17 -6
  7. package/dist/esm/core/converter/sheet-images.d.ts +17 -0
  8. package/dist/esm/core/converter/sheet-images.js +33 -0
  9. package/dist/esm/core/document-model/index.d.ts +1 -1
  10. package/dist/esm/core/document-model/types.d.ts +112 -0
  11. package/dist/esm/core/drawingml/chart-geometry.d.ts +21 -8
  12. package/dist/esm/core/drawingml/chart-geometry.js +198 -108
  13. package/dist/esm/core/drawingml/chart-parser.js +73 -2
  14. package/dist/esm/core/drawingml/colors.d.ts +6 -0
  15. package/dist/esm/core/drawingml/colors.js +23 -3
  16. package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
  17. package/dist/esm/core/drawingml/shape-render.js +4 -2
  18. package/dist/esm/core/font/measure.d.ts +9 -0
  19. package/dist/esm/core/font/measure.js +9 -1
  20. package/dist/esm/core/fonts/families.js +4 -2
  21. package/dist/esm/core/fonts/scripts.js +4 -2
  22. package/dist/esm/core/ir/flow.d.ts +6 -0
  23. package/dist/esm/core/ir/sheet.d.ts +43 -0
  24. package/dist/esm/core/number-format.js +16 -11
  25. package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
  26. package/dist/esm/core/spreadsheet-model/types.d.ts +96 -0
  27. package/dist/esm/core/style-cascade/resolver.js +4 -2
  28. package/dist/esm/excel/column-bands.d.ts +39 -6
  29. package/dist/esm/excel/column-bands.js +41 -17
  30. package/dist/esm/excel/comments-parser.js +19 -0
  31. package/dist/esm/excel/conditional-format.d.ts +7 -3
  32. package/dist/esm/excel/conditional-format.js +77 -39
  33. package/dist/esm/excel/formula/context.d.ts +18 -0
  34. package/dist/esm/excel/formula/eval.js +51 -0
  35. package/dist/esm/excel/formula/index.d.ts +2 -2
  36. package/dist/esm/excel/formula/lexer.d.ts +1 -1
  37. package/dist/esm/excel/formula/lexer.js +41 -0
  38. package/dist/esm/excel/formula/parser.d.ts +25 -0
  39. package/dist/esm/excel/formula/parser.js +95 -0
  40. package/dist/esm/excel/print-model.d.ts +38 -1
  41. package/dist/esm/excel/print-model.js +522 -80
  42. package/dist/esm/excel/shared-strings-parser.d.ts +9 -0
  43. package/dist/esm/excel/shared-strings-parser.js +11 -1
  44. package/dist/esm/excel/sheet-drawing.d.ts +38 -2
  45. package/dist/esm/excel/sheet-drawing.js +47 -13
  46. package/dist/esm/excel/sheet-shape-parser.d.ts +6 -2
  47. package/dist/esm/excel/sheet-shape-parser.js +18 -6
  48. package/dist/esm/excel/sheet-to-flow.d.ts +17 -0
  49. package/dist/esm/excel/sheet-to-flow.js +434 -47
  50. package/dist/esm/excel/styles-parser.d.ts +9 -0
  51. package/dist/esm/excel/styles-parser.js +80 -26
  52. package/dist/esm/excel/table-parser.js +5 -0
  53. package/dist/esm/excel/table-style-presets.d.ts +26 -0
  54. package/dist/esm/excel/table-style-presets.js +1555 -0
  55. package/dist/esm/excel/table-style.d.ts +13 -0
  56. package/dist/esm/excel/table-style.js +75 -0
  57. package/dist/esm/excel/tint.d.ts +10 -0
  58. package/dist/esm/excel/tint.js +75 -0
  59. package/dist/esm/excel/vml-drawing.d.ts +41 -3
  60. package/dist/esm/excel/vml-drawing.js +143 -10
  61. package/dist/esm/excel/worksheet-parser.js +89 -15
  62. package/dist/esm/excel/xls/biff-reader.js +10 -2
  63. package/dist/esm/excel/xlsx-reader.js +195 -14
  64. package/dist/esm/excel/xlsx-writer.js +8 -7
  65. package/dist/esm/html/html-writer.js +202 -20
  66. package/dist/esm/layout/fit-pages.d.ts +11 -0
  67. package/dist/esm/layout/fit-pages.js +86 -0
  68. package/dist/esm/layout/line-paint.d.ts +58 -0
  69. package/dist/esm/layout/line-paint.js +107 -0
  70. package/dist/esm/layout/page-doc.d.ts +51 -0
  71. package/dist/esm/layout/page-doc.js +141 -1
  72. package/dist/esm/layout/styled-layout.d.ts +7 -0
  73. package/dist/esm/layout/styled-layout.js +274 -51
  74. package/dist/esm/layout/turned-section.js +14 -2
  75. package/dist/esm/markdown/markdown-writer.js +17 -6
  76. package/dist/esm/pdf/styled-page-emitter.js +49 -71
  77. package/dist/esm/pdf/styled-page-renderer.js +1 -1
  78. package/dist/esm/pdf-reader/font.js +3 -3
  79. package/dist/esm/svg/svg-text.d.ts +58 -0
  80. package/dist/esm/svg/svg-text.js +322 -0
  81. package/dist/esm/svg/svg-writer.js +135 -71
  82. package/dist/esm/word/docx-writer.js +11 -2
  83. package/package.json +5 -1
@@ -17,3 +17,12 @@ export interface SharedStrings {
17
17
  * cell limit (32 767 chars).
18
18
  */
19
19
  export declare function parseSharedStrings(data: Uint8Array): SharedStrings;
20
+ /**
21
+ * §18.4.7 `<rPr>` — a run's own font properties (NOT a cellXf index): bold,
22
+ * italic, underline, strike, colour (rgb), size, vertical alignment and face.
23
+ * Shared with the comments part, whose `<text>` is the same rich string.
24
+ *
25
+ * @param text The run's text.
26
+ * @param rPr The parsed `<rPr>` node, if the run has one.
27
+ */
28
+ export declare function richRun(text: string, rPr: unknown): SheetRichRun;
@@ -83,6 +83,14 @@ function extractSi(si) {
83
83
  runs: anyFormatting && runs.length > 0 ? runs : void 0
84
84
  };
85
85
  }
86
+ /**
87
+ * §18.4.7 `<rPr>` — a run's own font properties (NOT a cellXf index): bold,
88
+ * italic, underline, strike, colour (rgb), size, vertical alignment and face.
89
+ * Shared with the comments part, whose `<text>` is the same rich string.
90
+ *
91
+ * @param text The run's text.
92
+ * @param rPr The parsed `<rPr>` node, if the run has one.
93
+ */
86
94
  function richRun(text, rPr) {
87
95
  const p = rPr && typeof rPr === "object" ? rPr : void 0;
88
96
  if (!p) return { text };
@@ -97,6 +105,8 @@ function richRun(text, rPr) {
97
105
  if (sz !== void 0) out.sizePt = sz;
98
106
  const vert = attrStr(p["vertAlign"], "val");
99
107
  if (vert === "superscript" || vert === "subscript") out.vertAlign = vert;
108
+ const face = attrStr(p["rFont"], "val");
109
+ if (face) out.fontName = face;
100
110
  return out;
101
111
  }
102
112
  function has(p, key) {
@@ -132,4 +142,4 @@ function textOf(node) {
132
142
  return "";
133
143
  }
134
144
  //#endregion
135
- export { parseSharedStrings };
145
+ export { parseSharedStrings, richRun };
@@ -19,6 +19,11 @@ export interface SheetChartRef {
19
19
  readonly yPt: number;
20
20
  /** Anchor top row (0-based) — used only to order charts on the sheet. */
21
21
  readonly anchorRow: number;
22
+ /**
23
+ * §20.5.2.3 `<xdr:clientData fPrintsWithSheet="0">` — on the sheet, not on
24
+ * its paper: the window shows it, a print leaves it out.
25
+ */
26
+ readonly screenOnly?: true;
22
27
  }
23
28
  /**
24
29
  * §20.5.2.1 `xdr:pic` — a picture anchored over the grid. The reader reads the
@@ -34,6 +39,11 @@ export interface SheetPicture {
34
39
  readonly yPt: number;
35
40
  /** Anchor top row (0-based) — used only to order pictures on the sheet. */
36
41
  readonly anchorRow: number;
42
+ /**
43
+ * §20.5.2.3 `<xdr:clientData fPrintsWithSheet="0">` — on the sheet, not on
44
+ * its paper: the window shows it, a print leaves it out.
45
+ */
46
+ readonly screenOnly?: true;
37
47
  }
38
48
  /** Both kinds of anchored frame the drawing yields, anchor-ordered. */
39
49
  export interface SheetDrawing {
@@ -50,15 +60,41 @@ export interface SheetDrawing {
50
60
  * @param drawingPartPath The drawing part path, for resolving its relationships.
51
61
  * @param pkg The OPC package, used to resolve relId → part path.
52
62
  * @param worksheet The host worksheet, for the column/row track geometry.
63
+ * @param colUnitTwips The unit its columns are measured in (columnUnitTwips).
64
+ */
65
+ export declare function parseSheetDrawing(drawingXml: Uint8Array, drawingPartPath: string, pkg: OpcPackage, worksheet: ParsedWorksheet, colUnitTwips?: number): SheetDrawing;
66
+ /**
67
+ * §20.5.2.3 `<xdr:clientData fPrintsWithSheet>` — whether the drawing prints
68
+ * with the sheet, which it does unless this says otherwise. A template's tip
69
+ * for whoever fills it in says otherwise: simple-monthly-budget.xlsx keeps a
70
+ * "Need to add more entries?" box under its table for the window only, and
71
+ * printed it ran past the bottom margin of a page LibreOffice prints without.
72
+ *
73
+ * @param clientData The anchor's parsed `<xdr:clientData>`, if any.
53
74
  */
54
- export declare function parseSheetDrawing(drawingXml: Uint8Array, drawingPartPath: string, pkg: OpcPackage, worksheet: ParsedWorksheet): SheetDrawing;
75
+ export declare function printsWithSheet(clientData: unknown): boolean;
76
+ /**
77
+ * Whether a drawing anchored here starts ON the sheet. A cell offset cannot be
78
+ * negative in anything Excel writes, and a drawing that begins before the
79
+ * sheet's own corner is one LibreOffice does not import at all (its drawing
80
+ * fragment keeps only an anchor rectangle at X ≥ 0, Y ≥ 0). tdf66668.xlsx is
81
+ * LibreOffice's own export of a sheet that reads from the right: each of its
82
+ * 24 notes left behind a white box the size of the whole sheet at a negative
83
+ * offset, and drawn they buried every value under them.
84
+ */
85
+ export declare function onTheSheet(xPt: number, yPt: number): boolean;
55
86
  /**
56
87
  * Build a `col → width-in-points` accessor: a `<col>` override (Excel "chars")
57
88
  * where present, else the default — the same conversions the print model uses.
58
89
  * Exported so the sheet-shape parser (E-SHEET W2) sizes shape anchors with the same
59
90
  * track geometry.
91
+ *
92
+ * @param ws The sheet.
93
+ * @param unitTwips The unit its columns are measured in — the grid's own
94
+ * (columnUnitTwips), or Excel's 7px digit.
95
+ * @returns The accessor.
60
96
  */
61
- export declare function makeColWidthPt(ws: ParsedWorksheet): (col: number) => number;
97
+ export declare function makeColWidthPt(ws: ParsedWorksheet, unitTwips?: number): (col: number) => number;
62
98
  /**
63
99
  * Build a `row → height-in-points` accessor: the explicit row height where present,
64
100
  * else the default. Pairs with {@link makeColWidthPt} for the anchor track geometry.
@@ -1,5 +1,5 @@
1
1
  import { emuToPt } from "../core/ir/units.js";
2
- import { columnTwips } from "./print-model.js";
2
+ import { columnTwips, defaultColumnTwips } from "./print-model.js";
3
3
  import { XMLParser } from "fast-xml-parser";
4
4
  //#region src/excel/sheet-drawing.ts
5
5
  var CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
@@ -21,15 +21,16 @@ var TWIPS_PER_PT = 20;
21
21
  * @param drawingPartPath The drawing part path, for resolving its relationships.
22
22
  * @param pkg The OPC package, used to resolve relId → part path.
23
23
  * @param worksheet The host worksheet, for the column/row track geometry.
24
+ * @param colUnitTwips The unit its columns are measured in (columnUnitTwips).
24
25
  */
25
- function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
26
+ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet, colUnitTwips) {
26
27
  const root = parser.parse(new TextDecoder().decode(drawingXml))["wsDr"];
27
28
  if (!root || typeof root !== "object") return {
28
29
  charts: [],
29
30
  pictures: []
30
31
  };
31
32
  const rootObj = root;
32
- const colWidthPt = makeColWidthPt(worksheet);
33
+ const colWidthPt = makeColWidthPt(worksheet, colUnitTwips);
33
34
  const rowHeightPt = makeRowHeightPt(worksheet);
34
35
  const rels = pkg.getPartRelationships(drawingPartPath);
35
36
  const partPathOf = (relId) => {
@@ -70,6 +71,8 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
70
71
  const posNode = posRaw && typeof posRaw === "object" ? posRaw : void 0;
71
72
  const xPt = posNode ? emuToPt(num(posNode["@_x"]) ?? 0) : from ? spanPt(0, 0, from.col, from.colOffPt, colWidthPt) : 0;
72
73
  const yPt = posNode ? emuToPt(num(posNode["@_y"]) ?? 0) : from ? spanPt(0, 0, from.row, from.rowOffPt, rowHeightPt) : 0;
74
+ if (!onTheSheet(xPt, yPt)) continue;
75
+ const screenOnly = !printsWithSheet(a["clientData"]) ? { screenOnly: true } : {};
73
76
  if (chartRelId) {
74
77
  const path = partPathOf(chartRelId);
75
78
  if (path) charts.push({
@@ -78,7 +81,8 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
78
81
  heightPt,
79
82
  xPt,
80
83
  yPt,
81
- anchorRow
84
+ anchorRow,
85
+ ...screenOnly
82
86
  });
83
87
  } else if (picRelId) {
84
88
  const path = partPathOf(picRelId);
@@ -88,7 +92,8 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
88
92
  heightPt,
89
93
  xPt,
90
94
  yPt,
91
- anchorRow
95
+ anchorRow,
96
+ ...screenOnly
92
97
  });
93
98
  }
94
99
  }
@@ -99,6 +104,20 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
99
104
  pictures
100
105
  };
101
106
  }
107
+ /**
108
+ * §20.5.2.3 `<xdr:clientData fPrintsWithSheet>` — whether the drawing prints
109
+ * with the sheet, which it does unless this says otherwise. A template's tip
110
+ * for whoever fills it in says otherwise: simple-monthly-budget.xlsx keeps a
111
+ * "Need to add more entries?" box under its table for the window only, and
112
+ * printed it ran past the bottom margin of a page LibreOffice prints without.
113
+ *
114
+ * @param clientData The anchor's parsed `<xdr:clientData>`, if any.
115
+ */
116
+ function printsWithSheet(clientData) {
117
+ if (!clientData || typeof clientData !== "object") return true;
118
+ const flag = clientData["@_fPrintsWithSheet"];
119
+ return flag !== "0" && flag !== "false";
120
+ }
102
121
  function isHiddenDrawing(anchor, kind) {
103
122
  const node = anchor[kind];
104
123
  if (!node || typeof node !== "object") return false;
@@ -152,18 +171,33 @@ function spanPt(from, fromOffPt, to, toOffPt, trackPt) {
152
171
  return span - fromOffPt + toOffPt;
153
172
  }
154
173
  /**
174
+ * Whether a drawing anchored here starts ON the sheet. A cell offset cannot be
175
+ * negative in anything Excel writes, and a drawing that begins before the
176
+ * sheet's own corner is one LibreOffice does not import at all (its drawing
177
+ * fragment keeps only an anchor rectangle at X ≥ 0, Y ≥ 0). tdf66668.xlsx is
178
+ * LibreOffice's own export of a sheet that reads from the right: each of its
179
+ * 24 notes left behind a white box the size of the whole sheet at a negative
180
+ * offset, and drawn they buried every value under them.
181
+ */
182
+ function onTheSheet(xPt, yPt) {
183
+ return xPt >= 0 && yPt >= 0;
184
+ }
185
+ /**
155
186
  * Build a `col → width-in-points` accessor: a `<col>` override (Excel "chars")
156
187
  * where present, else the default — the same conversions the print model uses.
157
188
  * Exported so the sheet-shape parser (E-SHEET W2) sizes shape anchors with the same
158
189
  * track geometry.
190
+ *
191
+ * @param ws The sheet.
192
+ * @param unitTwips The unit its columns are measured in — the grid's own
193
+ * (columnUnitTwips), or Excel's 7px digit.
194
+ * @returns The accessor.
159
195
  */
160
- function makeColWidthPt(ws) {
161
- const widthPt = (chars) => columnTwips(chars, 105) / TWIPS_PER_PT;
196
+ function makeColWidthPt(ws, unitTwips = 105) {
197
+ const widthPt = (chars) => columnTwips(chars, unitTwips) / TWIPS_PER_PT;
162
198
  return (col) => {
163
- for (const c of ws.columns) if (col >= c.min - 1 && col <= c.max - 1) return widthPt(c.widthChars);
164
- if (ws.defaultColWidthChars !== void 0) return widthPt(ws.defaultColWidthChars);
165
- if (ws.baseColWidthChars !== void 0) return (columnTwips(ws.baseColWidthChars, 105) + 150) / TWIPS_PER_PT;
166
- return 960 / TWIPS_PER_PT;
199
+ for (const c of ws.columns) if (col >= c.min - 1 && col <= c.max - 1) return c.hidden ? 0 : widthPt(c.widthChars);
200
+ return defaultColumnTwips(ws, unitTwips) / TWIPS_PER_PT;
167
201
  };
168
202
  }
169
203
  /**
@@ -172,7 +206,7 @@ function makeColWidthPt(ws) {
172
206
  */
173
207
  function makeRowHeightPt(ws) {
174
208
  return (row) => {
175
- for (const r of ws.rowHeights) if (r.row === row) return r.heightPt;
209
+ for (const r of ws.rowHeights) if (r.row === row) return r.hidden === true ? 0 : r.heightPt;
176
210
  return ws.defaultRowHeightPt ?? 300 / TWIPS_PER_PT;
177
211
  };
178
212
  }
@@ -187,4 +221,4 @@ function asArray(v) {
187
221
  return Array.isArray(v) ? v : v !== void 0 ? [v] : [];
188
222
  }
189
223
  //#endregion
190
- export { makeColWidthPt, makeRowHeightPt, parseSheetDrawing };
224
+ export { makeColWidthPt, makeRowHeightPt, onTheSheet, parseSheetDrawing, printsWithSheet };
@@ -19,8 +19,11 @@ import { PoNode } from '../core/po-helpers.js';
19
19
  * `<a:fillRef idx>` indexes for a gallery-styled fill.
20
20
  * @param themeEffectStyles The theme's `a:effectStyleLst` nodes, which an
21
21
  * `<a:effectRef idx>` indexes for a gallery-styled shadow.
22
+ * @param screenOnly Collects the shapes whose anchor does not print with the
23
+ * sheet (§20.5.2.3 `fPrintsWithSheet="0"`).
24
+ * @param colUnitTwips The unit the sheet's columns are measured in (columnUnitTwips).
22
25
  */
23
- export declare function parseSheetShapes(drawingXml: Uint8Array, worksheet: ParsedWorksheet, colors: ColorResolver, themeLineWidths?: ReadonlyArray<number>, themeFillStyles?: ReadonlyArray<PoNode>, themeEffectStyles?: ReadonlyArray<PoNode>): Array<ShapeBlock>;
26
+ export declare function parseSheetShapes(drawingXml: Uint8Array, worksheet: ParsedWorksheet, colors: ColorResolver, themeLineWidths?: ReadonlyArray<number>, themeFillStyles?: ReadonlyArray<PoNode>, themeEffectStyles?: ReadonlyArray<PoNode>, screenOnly?: Set<ShapeBlock>, colUnitTwips?: number): Array<ShapeBlock>;
24
27
  /**
25
28
  * The boxes the diagram frames of a drawing occupy, in document order.
26
29
  *
@@ -31,9 +34,10 @@ export declare function parseSheetShapes(drawingXml: Uint8Array, worksheet: Pars
31
34
  *
32
35
  * @param drawingXml The drawing part bytes.
33
36
  * @param worksheet The host worksheet, for the column/row track geometry.
37
+ * @param colUnitTwips The unit its columns are measured in (columnUnitTwips).
34
38
  * @returns One box per diagram frame, in the order the drawing writes them.
35
39
  */
36
- export declare function parseDiagramFrames(drawingXml: Uint8Array, worksheet: ParsedWorksheet): Array<AnchorBox>;
40
+ export declare function parseDiagramFrames(drawingXml: Uint8Array, worksheet: ParsedWorksheet, colUnitTwips?: number): Array<AnchorBox>;
37
41
  /**
38
42
  * Parse the fallback drawing of a SmartArt diagram (§ MS-ODRAWXML 2.1
39
43
  * `dsp:drawing`) into the shapes it lays out.
@@ -4,7 +4,7 @@ import { placeholderColors, resolveColorNode } from "../core/drawingml/colors.js
4
4
  import { parseFill, parseLine, parseShadow, parseXfrm, shadowFromOuterShdw } from "../word/drawing-parser.js";
5
5
  import { parseGeometry, parseTxBody } from "../pptx/slide-parser.js";
6
6
  import { parseXml } from "../pptx/pptx-reader.js";
7
- import { makeColWidthPt, makeRowHeightPt } from "./sheet-drawing.js";
7
+ import { makeColWidthPt, makeRowHeightPt, onTheSheet, printsWithSheet } from "./sheet-drawing.js";
8
8
  //#region src/excel/sheet-shape-parser.ts
9
9
  var ANCHOR_KINDS = [
10
10
  "xdr:twoCellAnchor",
@@ -87,17 +87,22 @@ function buildShape(sp, box, ns, colors, themeLineWidths, themeFillStyles, theme
87
87
  * `<a:fillRef idx>` indexes for a gallery-styled fill.
88
88
  * @param themeEffectStyles The theme's `a:effectStyleLst` nodes, which an
89
89
  * `<a:effectRef idx>` indexes for a gallery-styled shadow.
90
+ * @param screenOnly Collects the shapes whose anchor does not print with the
91
+ * sheet (§20.5.2.3 `fPrintsWithSheet="0"`).
92
+ * @param colUnitTwips The unit the sheet's columns are measured in (columnUnitTwips).
90
93
  */
91
- function parseSheetShapes(drawingXml, worksheet, colors, themeLineWidths = [], themeFillStyles = [], themeEffectStyles = []) {
94
+ function parseSheetShapes(drawingXml, worksheet, colors, themeLineWidths = [], themeFillStyles = [], themeEffectStyles = [], screenOnly, colUnitTwips) {
92
95
  const wsDr = parseXml(drawingXml).find((n) => poIs(n, "xdr:wsDr"));
93
96
  if (!wsDr) return [];
94
- const colWidthPt = makeColWidthPt(worksheet);
97
+ const colWidthPt = makeColWidthPt(worksheet, colUnitTwips);
95
98
  const rowHeightPt = makeRowHeightPt(worksheet);
96
99
  const shapes = [];
97
100
  for (const anchor of poChildren(wsDr)) {
98
101
  if (!ANCHOR_KINDS.some((k) => poIs(anchor, k))) continue;
99
102
  const anchored = anchorBox(anchor, colWidthPt, rowHeightPt);
100
103
  if (!anchored) continue;
104
+ const clientData = poChildren(anchor).find((c) => poIs(c, "xdr:clientData"));
105
+ const printing = printsWithSheet(clientData ? { "@_fPrintsWithSheet": poAttr(clientData, "fPrintsWithSheet") } : void 0);
101
106
  const placed = [];
102
107
  const direct = poChildren(anchor).find((c) => poIs(c, "xdr:sp"));
103
108
  if (direct) placed.push({
@@ -111,11 +116,13 @@ function parseSheetShapes(drawingXml, worksheet, colors, themeLineWidths = [], t
111
116
  if (!shape) continue;
112
117
  shapes.push({
113
118
  shape,
114
- anchorRow: box.anchorRow
119
+ anchorRow: box.anchorRow,
120
+ screenOnly: !printing
115
121
  });
116
122
  }
117
123
  }
118
124
  shapes.sort((a, b) => a.anchorRow - b.anchorRow);
125
+ for (const s of shapes) if (s.screenOnly) screenOnly?.add(s.shape);
119
126
  return shapes.map((s) => s.shape);
120
127
  }
121
128
  /**
@@ -128,12 +135,13 @@ function parseSheetShapes(drawingXml, worksheet, colors, themeLineWidths = [], t
128
135
  *
129
136
  * @param drawingXml The drawing part bytes.
130
137
  * @param worksheet The host worksheet, for the column/row track geometry.
138
+ * @param colUnitTwips The unit its columns are measured in (columnUnitTwips).
131
139
  * @returns One box per diagram frame, in the order the drawing writes them.
132
140
  */
133
- function parseDiagramFrames(drawingXml, worksheet) {
141
+ function parseDiagramFrames(drawingXml, worksheet, colUnitTwips) {
134
142
  const wsDr = parseXml(drawingXml).find((n) => poIs(n, "xdr:wsDr"));
135
143
  if (!wsDr) return [];
136
- const colWidthPt = makeColWidthPt(worksheet);
144
+ const colWidthPt = makeColWidthPt(worksheet, colUnitTwips);
137
145
  const rowHeightPt = makeRowHeightPt(worksheet);
138
146
  const out = [];
139
147
  for (const anchor of poChildren(wsDr)) {
@@ -442,6 +450,10 @@ function withStyleTextColor(text, sp, ns, colors) {
442
450
  };
443
451
  }
444
452
  function anchorBox(anchor, colWidthPt, rowHeightPt) {
453
+ const box = anchorBoxAnywhere(anchor, colWidthPt, rowHeightPt);
454
+ return box && onTheSheet(box.xPt, box.yPt) ? box : void 0;
455
+ }
456
+ function anchorBoxAnywhere(anchor, colWidthPt, rowHeightPt) {
445
457
  const from = marker(poChildren(anchor).find((c) => poIs(c, "xdr:from")));
446
458
  if (poIs(anchor, "xdr:twoCellAnchor")) {
447
459
  const to = marker(poChildren(anchor).find((c) => poIs(c, "xdr:to")));
@@ -52,6 +52,23 @@ export interface ProjectSheetOptions {
52
52
  * which is which; markdown asks for this, and gets `# Sheet1`.
53
53
  */
54
54
  readonly sheetHeadings?: boolean;
55
+ /**
56
+ * Project for a SCREEN rather than for paper: each sheet as Excel shows it in
57
+ * its window, not as it prints. One table a sheet with all of its columns —
58
+ * no column bands, no print scale, no print area or repeated titles, no page
59
+ * breaks — its drawings where they are anchored, every visible tab including
60
+ * an empty one, and each sheet a section that names its tab
61
+ * ({@link Section.sheet}). Headers and footers are print furniture and are
62
+ * left out. A flowed target that shows the workbook, HTML, asks for this.
63
+ */
64
+ readonly screen?: boolean;
65
+ /**
66
+ * With {@link screen}: each sheet on a page of its own with room for all of
67
+ * it — no paper and no margins but a sliver — for a target that draws a
68
+ * sheet as an image of itself and then cuts the page down to what was drawn
69
+ * on it (`fitPagesToContent`). The SVG target asks for this.
70
+ */
71
+ readonly wholeSheetPages?: boolean;
55
72
  }
56
73
  /**
57
74
  * Project a {@link SheetDoc} into a {@link FlowDoc} (E-SHEET SA2): each grid sheet