reamkit 1.30.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 (147) hide show
  1. package/README.md +70 -24
  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 +4 -1
  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/crypto/offcrypto.js +1 -1
  10. package/dist/esm/core/document-model/index.d.ts +1 -1
  11. package/dist/esm/core/document-model/types.d.ts +175 -0
  12. package/dist/esm/core/drawingml/chart-geometry.d.ts +21 -8
  13. package/dist/esm/core/drawingml/chart-geometry.js +198 -108
  14. package/dist/esm/core/drawingml/chart-parser.js +73 -2
  15. package/dist/esm/core/drawingml/colors.d.ts +6 -0
  16. package/dist/esm/core/drawingml/colors.js +23 -3
  17. package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
  18. package/dist/esm/core/drawingml/shape-render.js +4 -2
  19. package/dist/esm/core/font/index.d.ts +2 -0
  20. package/dist/esm/core/font/measure.d.ts +9 -0
  21. package/dist/esm/core/font/measure.js +9 -1
  22. package/dist/esm/core/font/ttf-build.d.ts +113 -0
  23. package/dist/esm/core/font/ttf-build.js +1224 -0
  24. package/dist/esm/core/font/ttf-subset.d.ts +19 -0
  25. package/dist/esm/core/font/ttf-subset.js +14 -1
  26. package/dist/esm/core/fonts/families.js +4 -2
  27. package/dist/esm/core/fonts/provider.d.ts +17 -0
  28. package/dist/esm/core/fonts/provider.js +27 -2
  29. package/dist/esm/core/fonts/remote-fonts.js +8 -1
  30. package/dist/esm/core/fonts/scripts.js +4 -2
  31. package/dist/esm/core/ir/flow.d.ts +77 -1
  32. package/dist/esm/core/ir/sheet.d.ts +43 -0
  33. package/dist/esm/core/number-format.js +16 -11
  34. package/dist/esm/core/numbering/index.d.ts +1 -1
  35. package/dist/esm/core/numbering/state.d.ts +11 -1
  36. package/dist/esm/core/numbering/state.js +10 -1
  37. package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
  38. package/dist/esm/core/spreadsheet-model/types.d.ts +96 -0
  39. package/dist/esm/core/style-cascade/resolver.js +39 -6
  40. package/dist/esm/core/style-cascade/types.d.ts +19 -1
  41. package/dist/esm/core/style-cascade/types.js +3 -0
  42. package/dist/esm/excel/column-bands.d.ts +39 -6
  43. package/dist/esm/excel/column-bands.js +41 -17
  44. package/dist/esm/excel/comments-parser.js +19 -0
  45. package/dist/esm/excel/conditional-format.d.ts +7 -3
  46. package/dist/esm/excel/conditional-format.js +77 -39
  47. package/dist/esm/excel/formula/context.d.ts +18 -0
  48. package/dist/esm/excel/formula/eval.js +51 -0
  49. package/dist/esm/excel/formula/index.d.ts +2 -2
  50. package/dist/esm/excel/formula/lexer.d.ts +1 -1
  51. package/dist/esm/excel/formula/lexer.js +41 -0
  52. package/dist/esm/excel/formula/parser.d.ts +25 -0
  53. package/dist/esm/excel/formula/parser.js +95 -0
  54. package/dist/esm/excel/print-model.d.ts +38 -1
  55. package/dist/esm/excel/print-model.js +522 -80
  56. package/dist/esm/excel/shared-strings-parser.d.ts +9 -0
  57. package/dist/esm/excel/shared-strings-parser.js +11 -1
  58. package/dist/esm/excel/sheet-drawing.d.ts +38 -2
  59. package/dist/esm/excel/sheet-drawing.js +47 -13
  60. package/dist/esm/excel/sheet-shape-parser.d.ts +6 -2
  61. package/dist/esm/excel/sheet-shape-parser.js +18 -6
  62. package/dist/esm/excel/sheet-to-flow.d.ts +17 -0
  63. package/dist/esm/excel/sheet-to-flow.js +434 -47
  64. package/dist/esm/excel/styles-parser.d.ts +9 -0
  65. package/dist/esm/excel/styles-parser.js +80 -26
  66. package/dist/esm/excel/table-parser.js +5 -0
  67. package/dist/esm/excel/table-style-presets.d.ts +26 -0
  68. package/dist/esm/excel/table-style-presets.js +1555 -0
  69. package/dist/esm/excel/table-style.d.ts +13 -0
  70. package/dist/esm/excel/table-style.js +75 -0
  71. package/dist/esm/excel/tint.d.ts +10 -0
  72. package/dist/esm/excel/tint.js +75 -0
  73. package/dist/esm/excel/vml-drawing.d.ts +41 -3
  74. package/dist/esm/excel/vml-drawing.js +143 -10
  75. package/dist/esm/excel/worksheet-parser.js +89 -15
  76. package/dist/esm/excel/xls/biff-reader.js +10 -2
  77. package/dist/esm/excel/xlsx-reader.js +195 -14
  78. package/dist/esm/excel/xlsx-writer.js +8 -7
  79. package/dist/esm/html/html-writer.js +202 -20
  80. package/dist/esm/index.d.ts +2 -2
  81. package/dist/esm/layout/fit-pages.d.ts +11 -0
  82. package/dist/esm/layout/fit-pages.js +86 -0
  83. package/dist/esm/layout/line-paint.d.ts +58 -0
  84. package/dist/esm/layout/line-paint.js +107 -0
  85. package/dist/esm/layout/page-doc.d.ts +61 -3
  86. package/dist/esm/layout/page-doc.js +141 -1
  87. package/dist/esm/layout/styled-layout.d.ts +55 -7
  88. package/dist/esm/layout/styled-layout.js +1154 -169
  89. package/dist/esm/layout/turned-section.d.ts +38 -0
  90. package/dist/esm/layout/turned-section.js +205 -0
  91. package/dist/esm/markdown/markdown-writer.js +17 -6
  92. package/dist/esm/pdf/styled-page-emitter.js +114 -60
  93. package/dist/esm/pdf/styled-page-renderer.js +1 -1
  94. package/dist/esm/pdf-reader/cff-outline.d.ts +27 -0
  95. package/dist/esm/pdf-reader/cff-outline.js +169 -21
  96. package/dist/esm/pdf-reader/content.d.ts +53 -0
  97. package/dist/esm/pdf-reader/content.js +9 -1
  98. package/dist/esm/pdf-reader/display.d.ts +36 -0
  99. package/dist/esm/pdf-reader/display.js +66 -1
  100. package/dist/esm/pdf-reader/document.js +5 -1
  101. package/dist/esm/pdf-reader/embedded-fonts.d.ts +2 -1
  102. package/dist/esm/pdf-reader/embedded-fonts.js +32 -2
  103. package/dist/esm/pdf-reader/encodings.d.ts +8 -0
  104. package/dist/esm/pdf-reader/encodings.js +25 -3
  105. package/dist/esm/pdf-reader/face-outlines.d.ts +78 -0
  106. package/dist/esm/pdf-reader/face-outlines.js +362 -0
  107. package/dist/esm/pdf-reader/figures.d.ts +52 -0
  108. package/dist/esm/pdf-reader/figures.js +433 -0
  109. package/dist/esm/pdf-reader/flow-build.d.ts +131 -5
  110. package/dist/esm/pdf-reader/flow-build.js +345 -26
  111. package/dist/esm/pdf-reader/font.js +321 -36
  112. package/dist/esm/pdf-reader/glyf-outline.d.ts +33 -0
  113. package/dist/esm/pdf-reader/glyf-outline.js +135 -1
  114. package/dist/esm/pdf-reader/glyph-names.js +154 -1
  115. package/dist/esm/pdf-reader/layout.d.ts +93 -0
  116. package/dist/esm/pdf-reader/layout.js +1703 -214
  117. package/dist/esm/pdf-reader/page-numbers.d.ts +53 -0
  118. package/dist/esm/pdf-reader/page-numbers.js +167 -0
  119. package/dist/esm/pdf-reader/tagged.js +182 -23
  120. package/dist/esm/pdf-reader/text.d.ts +6 -3
  121. package/dist/esm/pdf-reader/text.js +98 -9
  122. package/dist/esm/pdf-reader/type1-outline.d.ts +11 -0
  123. package/dist/esm/pdf-reader/type1-outline.js +63 -8
  124. package/dist/esm/pdf-reader/vector.js +71 -1
  125. package/dist/esm/svg/svg-text.d.ts +58 -0
  126. package/dist/esm/svg/svg-text.js +322 -0
  127. package/dist/esm/svg/svg-writer.js +135 -71
  128. package/dist/esm/word/doc/doc-reader.js +6 -2
  129. package/dist/esm/word/doc/doc-text.d.ts +6 -0
  130. package/dist/esm/word/doc/doc-text.js +19 -1
  131. package/dist/esm/word/document-parser.d.ts +2 -2
  132. package/dist/esm/word/document-parser.js +11 -1
  133. package/dist/esm/word/docx-reader.js +5 -3
  134. package/dist/esm/word/docx-writer.js +218 -23
  135. package/dist/esm/word/drawing-parser.d.ts +5 -3
  136. package/dist/esm/word/drawing-parser.js +49 -8
  137. package/dist/esm/word/font-embed.d.ts +30 -0
  138. package/dist/esm/word/font-embed.js +173 -0
  139. package/dist/esm/word/font-table.d.ts +10 -0
  140. package/dist/esm/word/font-table.js +13 -1
  141. package/dist/esm/word/index.js +1 -1
  142. package/dist/esm/word/numbering-parser.d.ts +3 -1
  143. package/dist/esm/word/numbering-parser.js +2 -1
  144. package/dist/esm/word/paragraph-properties.d.ts +7 -6
  145. package/dist/esm/word/paragraph-properties.js +14 -2
  146. package/dist/esm/word/run-properties.js +26 -0
  147. package/package.json +12 -3
package/README.md CHANGED
@@ -27,10 +27,12 @@ Runtime dependencies are minimal: `fflate` (ZIP/Deflate) and `fast-xml-parser`.
27
27
  ## Usage
28
28
 
29
29
  Parse once into the format-neutral interlayer, convert to any target. The
30
- format (docx/xlsx) is sniffed from the bytes; no fonts to wire up — an open
30
+ format is sniffed from the bytes; no fonts to wire up — an open
31
31
  metric-compatible substitute font (Arimo for sans, Tinos for serif, Cousine for
32
32
  monospace, plus Carlito/Caladea for Calibri/Cambria — the same families LibreOffice
33
- substitutes) is fetched automatically based on the document's referenced fonts:
33
+ substitutes) is fetched automatically based on the document's referenced fonts,
34
+ with a Noto face for the Japanese, Korean, Chinese, Arabic, Hebrew or Thai text
35
+ the document holds:
34
36
 
35
37
  ```ts
36
38
  import { Ream } from 'reamkit';
@@ -38,7 +40,7 @@ import { Ream } from 'reamkit';
38
40
  // e.g. from an <input type="file"> or a fetch() — anything that yields bytes.
39
41
  const bytes = new Uint8Array(await file.arrayBuffer());
40
42
 
41
- const doc = Ream.parse(bytes); // docx, xlsx, pptx or pdf — sniffed
43
+ const doc = Ream.parse(bytes); // docx, xlsx, pptx, pdf, doc, xls or ppt — sniffed
42
44
  const pdf = await doc.convert('pdf'); // async — fetches a font if needed
43
45
  const svg = await doc.convert('svg'); // same parse, different target
44
46
  const html = await doc.convert('html'); // flowed HTML — needs no fonts at all
@@ -57,6 +59,13 @@ and `doc.convertWithReport(...)` returns `{ bytes, losses }` (pass
57
59
  are plain `Uint8Array`s, so wiring this to files, the network, or disk is up
58
60
  to you.
59
61
 
62
+ An encrypted source opens with its password — a PDF's user password, or an
63
+ Office package's (MS-OFFCRYPTO, Agile and Standard):
64
+
65
+ ```ts
66
+ const doc = Ream.parse(bytes, { password: 'secret' });
67
+ ```
68
+
60
69
  ### Bring your own fonts (no network)
61
70
 
62
71
  To embed specific fonts — or to avoid the network entirely — pass the font
@@ -139,7 +148,7 @@ rendering — inspect or analyze it without converting:
139
148
 
140
149
  ```ts
141
150
  const doc = Ream.parse(bytes);
142
- doc.format; // 'docx' | 'xlsx' | 'pptx' | 'pdf'
151
+ doc.format; // 'docx' | 'xlsx' | 'pptx' | 'pdf' | 'doc' | 'xls' | 'ppt'
143
152
  doc.flow.body; // paragraphs / tables / images / charts …
144
153
  doc.losses; // read-time losses
145
154
  ```
@@ -157,7 +166,9 @@ const pdf = await doc.convert('pdf', { fonts, hyphenator });
157
166
  `convert` accepts (beyond the above): `info` (PDF `/Info` metadata — also read
158
167
  automatically from the document's `docProps/core.xml`), `attachments`
159
168
  (PDF/A-3 associated files), `tagged` (logical structure without full PDF/A),
160
- `pageWidth`/`pageHeight`/margins overrides.
169
+ `encrypt` (AES-256 with a user and an owner password and the permissions a
170
+ reader keeps: printing, copying, modifying, …), `pageWidth`/`pageHeight`/margins
171
+ overrides.
161
172
 
162
173
  ### Lower-level APIs
163
174
 
@@ -166,6 +177,9 @@ automatically from the document's `docProps/core.xml`), `attachments`
166
177
  keeping unused formats out of your bundle); `layoutStyledDocument` produces the
167
178
  frozen page model (`PageItem` pages in a top-left `Pt` frame) the page-based
168
179
  writers consume (`docxWriter` works from the flow model, before layout).
180
+ - `createConverter({ readers })` — a converter over a reader registry of your
181
+ own: `detect` names the reader that recognises the bytes, and `convert` reads
182
+ and converts them in one call, returning `{ bytes, losses }`.
169
183
  - `renderStyledPdf` drives the layout engine directly; the typed document
170
184
  model is on the `reamkit/document-model` subpath.
171
185
 
@@ -187,27 +201,59 @@ encryption, digital signatures (PKCS#7/ECDSA/PAdES/RFC 3161), SVG page
187
201
  preview, flowed HTML export, and **docx + xlsx output** (write WordprocessingML
188
202
  / SpreadsheetML back out, incl. round-trips). Reads OOXML Transitional and Strict.
189
203
 
204
+ A Word document is laid out by Word's own rules, each measured in Word: a line
205
+ as tall as Word sets its faces, two paragraphs standing the larger of their
206
+ spacings apart rather than the sum, widow and orphan control, a heading kept with
207
+ what it heads, table borders that take the room they are wide, a Word 2010
208
+ table placed by its first cell's text, and sections whose lines run down the
209
+ sheet.
210
+
211
+ A workbook is drawn the way Excel draws it, each rule checked against Excel's
212
+ own PDF: columns in the Normal font's digit as Excel counts it, a table in the
213
+ style it names, a theme colour's tint to the digit, a sheet that reads from the
214
+ right turned round, the notes it shows beside their cells, its drawings over
215
+ the cells and cut where its pages are, a chart's axes scaled and crossed where
216
+ Excel puts them. As HTML a workbook comes out as Excel's window shows it —
217
+ every tab, its gridlines, a noted cell flagged with the note on hover — and as
218
+ SVG as pictures of its sheets, each whole, its text drawn from the faces' own
219
+ outlines.
220
+
190
221
  **Reads PDF, too.** `Ream.parse` accepts a PDF and reconstructs a `FlowDoc` — a
191
222
  tagged PDF from its structure tree (headings, tables, lists, reading order), an
192
- untagged one heuristically from glyph positions (lines, paragraphs, headings,
193
- and a clean two-column split). It lifts back the text (via each font's
194
- `/ToUnicode`, or the embedded program's own `cmap` where there is none, or the
195
- glyph names its `/Encoding` states — which is all a PDF from TeX gives), the
196
- font programs themselves, raster images (JPEG verbatim; PNG/Flate/LZW/CCITT-fax
197
- and **JBIG2** decoded and re-encoded), `/Link` hyperlinks, form-XObject content,
198
- annotation appearances (drawing one itself where the file supplies none),
199
- colour set through a named space — device, CIE (`CalGray`, `Lab`) or a
200
- `Separation`/`DeviceN` run through its own tint transform — and the page's
201
- artwork: filled / stroked / gradient shapes, clipping paths, tiling patterns,
202
- stencil image masks, constant alpha, and the Type 3 glyphs that are drawings
203
- rather than letters. It honours the layers a file turns off (§8.11 optional
204
- content) and the box it says to show (`/CropBox`), and it decides for itself
205
- whether a file is a document to re-flow or a page to keep — a paper is mostly
206
- lines, a form is mostly marks — and there is nothing to configure: a caller
207
- cannot know which of the two it was handed. It reads modern compressed files (cross-reference
208
- + object streams) and encrypted ones (RC4 / AES — the user password is passed to
209
- `Ream.parse(bytes, { password })`, defaulting to the permissions-only case); a
210
- filter it does not carry can be handed to it through
223
+ untagged one from where its glyphs stand: lines and paragraphs at the page's own
224
+ pitch, with their indents and alignment; headings and list items; columns of
225
+ any number, breaking and balancing where the page does; tables ruled or set out
226
+ on stops, within a column or across them; code listings; figures, a drawing and
227
+ the labels set on it kept as one group; the hanging entries of an index; and a
228
+ heading's bar as its shading. Running heads and feet become headers and footers,
229
+ their numbers PAGE fields counted in the page's own numerals — a book's roman
230
+ front matter, and a foot of its own for each side of its spreads.
231
+
232
+ It lifts back the text (via each font's `/ToUnicode`, or the embedded program's
233
+ own `cmap` where there is none, or the glyph names its `/Encoding` states — which
234
+ is all a PDF from TeX gives, its Greek and mathematics included) and the font
235
+ programs themselves: written to `.docx`, each face the page drew with travels
236
+ with the document, rebuilt as TrueType with the page's own advances, kerning and
237
+ ligatures, and embedded where its licence (OS/2 `fsType`) allows — so a line
238
+ breaks where the page broke it, on a machine that has none of its fonts. Raster
239
+ images come back (JPEG verbatim, a CMYK one re-coloured; PNG/Flate/LZW/CCITT-fax
240
+ and **JBIG2** decoded and re-encoded), with `/Link` hyperlinks, form-XObject
241
+ content, annotation and form appearances (drawing one itself where the file
242
+ supplies none), colour set through a named space — device, CIE (`CalGray`,
243
+ `CalRGB`, `Lab`), ICC-based, or a `Separation`/`DeviceN` run through its own
244
+ tint transform — and the page's artwork: filled / stroked / gradient shapes,
245
+ dashes and caps, clipping paths, tiling patterns, stencil image masks, opacity,
246
+ and the Type 3 glyphs that are drawings rather than letters.
247
+
248
+ It honours the layers a file turns off (§8.11 optional content), the box it says
249
+ to show (`/CropBox`) and the way it turns a page (`/Rotate` — a page whose words
250
+ run down its sheet comes back as a section set that way), and it decides for
251
+ itself whether a file is a document to re-flow or a page to keep — a paper is
252
+ mostly lines, a form is mostly marks — and there is nothing to configure: a
253
+ caller cannot know which of the two it was handed. It reads modern compressed
254
+ files (cross-reference + object streams) and encrypted ones (RC4 / AES — the
255
+ user password is passed to `Ream.parse(bytes, { password })`, defaulting to the
256
+ permissions-only case); a filter it does not carry can be handed to it through
211
257
  `Ream.parse(bytes, { filters })`.
212
258
 
213
259
  A form or a drawing is not a reflowable document, so the reader keeps it as a
@@ -36,6 +36,16 @@ export declare function analyzeString(text: string, dir?: Direction): StringBidi
36
36
  * or Arabic presentation-form ranges.
37
37
  */
38
38
  export declare function hasBidiCharacters(text: string): boolean;
39
+ /**
40
+ * The direction of a string's first strong character (UAX #9 P2): `rtl` for
41
+ * an `R` or `AL` one, `ltr` for an `L` one, undefined when it has none — a
42
+ * number, punctuation, a blank. This is what an application means by a
43
+ * "context" reading order.
44
+ *
45
+ * @param text The string to scan.
46
+ * @returns The direction its first strong character sets, if any.
47
+ */
48
+ export declare function firstStrongDirection(text: string): 'ltr' | 'rtl' | undefined;
39
49
  /**
40
50
  * Reverse a string by code point (so surrogate pairs stay intact). Used to emit
41
51
  * an RTL run's glyphs in visual (right-to-left) order, since our glyph placement
@@ -1,4 +1,4 @@
1
- import "./char-types.js";
1
+ import { bidiClass } from "./char-types.js";
2
2
  import { computeBidi } from "./algorithm.js";
3
3
  import "./segments.js";
4
4
  //#region src/core/bidi/index.ts
@@ -39,6 +39,22 @@ function hasBidiCharacters(text) {
39
39
  return false;
40
40
  }
41
41
  /**
42
+ * The direction of a string's first strong character (UAX #9 P2): `rtl` for
43
+ * an `R` or `AL` one, `ltr` for an `L` one, undefined when it has none — a
44
+ * number, punctuation, a blank. This is what an application means by a
45
+ * "context" reading order.
46
+ *
47
+ * @param text The string to scan.
48
+ * @returns The direction its first strong character sets, if any.
49
+ */
50
+ function firstStrongDirection(text) {
51
+ for (const ch of text) {
52
+ const cls = bidiClass(ch.codePointAt(0));
53
+ if (cls === "L") return "ltr";
54
+ if (cls === "R" || cls === "AL") return "rtl";
55
+ }
56
+ }
57
+ /**
42
58
  * Reverse a string by code point (so surrogate pairs stay intact). Used to emit
43
59
  * an RTL run's glyphs in visual (right-to-left) order, since our glyph placement
44
60
  * advances left-to-right.
@@ -50,4 +66,4 @@ function reverseByCodePoint(text) {
50
66
  return [...text].reverse().join("");
51
67
  }
52
68
  //#endregion
53
- export { analyzeString, hasBidiCharacters, reverseByCodePoint };
69
+ export { analyzeString, firstStrongDirection, hasBidiCharacters, reverseByCodePoint };
@@ -11,6 +11,7 @@ import { projectSheetDoc } from "../../excel/sheet-to-flow.js";
11
11
  import { xlsxReader } from "../../excel/xlsx-reader.js";
12
12
  import { chainProviders } from "../fonts/provider.js";
13
13
  import { flowRenderOptions } from "./project.js";
14
+ import { layoutSheetImages } from "./sheet-images.js";
14
15
  import { writeDocx } from "../../word/docx-writer.js";
15
16
  import { writeXlsx } from "../../excel/xlsx-writer.js";
16
17
  import { writeHtml } from "../../html/html-writer.js";
@@ -78,7 +79,10 @@ function createConverter(opts = {}) {
78
79
  };
79
80
  }
80
81
  if (to === "html") {
81
- const { doc: flow, losses: readLosses } = readToFlow(reader, bytes, rest.now ? { now: rest.now } : void 0);
82
+ const { doc: flow, losses: readLosses } = readToFlow(reader, bytes, {
83
+ ...rest.now ? { now: rest.now } : {},
84
+ screen: true
85
+ });
82
86
  losses.push(...readLosses);
83
87
  const html = writeHtml(flow);
84
88
  losses.push(...html.losses);
@@ -123,10 +127,11 @@ function createConverter(opts = {}) {
123
127
  if (to === "svg") {
124
128
  const fonts = conv.fonts ?? (conv.fontBytes ? { regular: conv.fontBytes } : void 0);
125
129
  if (!fonts) throw new Error("to: 'svg' requires options.fonts/fontBytes or fontProviders");
126
- const { doc: flow } = readToFlow(reader, bytes, rest.now ? { now: rest.now } : void 0);
127
- const svg = writeSvg(layoutStyledDocument(flow.body, {
128
- registry: FontRegistry.fromBytes(fonts),
129
- ...flowRenderOptions(flow)
130
+ const { doc } = reader.read(bytes);
131
+ const registry = FontRegistry.fromBytes(fonts);
132
+ const svg = writeSvg(doc.kind === "sheet" ? layoutSheetImages(doc, { registry }, rest.now ? { now: rest.now } : {}) : layoutStyledDocument(doc.body, {
133
+ registry,
134
+ ...flowRenderOptions(doc)
130
135
  }));
131
136
  losses.push(...svg.losses);
132
137
  if (strict && losses.length > 0) throw new ConversionLossError(losses[0]);
@@ -28,7 +28,10 @@ function flowRenderOptions(flow) {
28
28
  ...flow.doNotExpandShiftReturn ? { doNotExpandShiftReturn: true } : {},
29
29
  ...flow.pageBackgroundColorHex ? { pageBackgroundColorHex: flow.pageBackgroundColorHex } : {},
30
30
  ...flow.pageBackgroundFill ? { pageBackgroundFill: flow.pageBackgroundFill } : {},
31
- ...flow.gutterAtTop ? { gutterAtTop: true } : {}
31
+ ...flow.gutterAtTop ? { gutterAtTop: true } : {},
32
+ ...flow.typesetBy ? { typesetBy: flow.typesetBy } : {},
33
+ ...flow.floatsOverText ? { floatsOverText: true } : {},
34
+ ...flow.compatibilityMode !== void 0 ? { compatibilityMode: flow.compatibilityMode } : {}
32
35
  };
33
36
  }
34
37
  //#endregion
@@ -9,6 +9,7 @@ import { renderStyledPdf, renderStyledPdfEncrypted } from "../../pdf/styled-page
9
9
  import "../../pdf/index.js";
10
10
  import { projectSheetDoc } from "../../excel/sheet-to-flow.js";
11
11
  import { flowRenderOptions } from "./project.js";
12
+ import { layoutSheetImages } from "./sheet-images.js";
12
13
  import { writeDocx } from "../../word/docx-writer.js";
13
14
  import { writeXlsx } from "../../excel/xlsx-writer.js";
14
15
  import { writeHtml } from "../../html/html-writer.js";
@@ -128,7 +129,11 @@ var Ream = class Ream {
128
129
  ...options.fileName ? { fileName: options.fileName } : {}
129
130
  }) : this.flow;
130
131
  if (to === "html") {
131
- const html = writeHtml(flow);
132
+ const html = writeHtml(this.sheet ? projectSheetDoc(this.sheet, {
133
+ ...options.now ? { now: options.now } : {},
134
+ ...options.fileName ? { fileName: options.fileName } : {},
135
+ screen: true
136
+ }) : flow);
132
137
  losses.push(...html.losses);
133
138
  this.enforceStrict(options, losses);
134
139
  return {
@@ -173,15 +178,21 @@ var Ream = class Ream {
173
178
  }
174
179
  const { fonts, registriesByFamily } = await this.resolveFonts(options, losses, flow);
175
180
  const registry = FontRegistry.fromBytes(fonts);
176
- const paginated = this.sheet ? projectSheetDoc(this.sheet, {
181
+ const sheetOptions = {
177
182
  ...options.now ? { now: options.now } : {},
178
183
  ...options.fileName ? { fileName: options.fileName } : {},
179
184
  digitWidthPt: createFontMeasure(registry.resolveByStyle(false, false).parsed).textWidthPt("0", DEFAULT_WORKBOOK_FONT_PT)
180
- }) : flow;
185
+ };
186
+ const { fonts: _a, fontBytes: _b, fontFamily: _c, fontFetch: _d, fontProviders: _e, strict: _f, embedSource, signature, info: callerInfo, attachments: callerAttachments, ...renderOptions } = options;
181
187
  if (to === "svg") {
182
- const svg = writeSvg(layoutStyledDocument(paginated.body, {
188
+ const faces = {
183
189
  registry,
184
- ...flowRenderOptions(paginated)
190
+ ...registriesByFamily ? { registriesByFamily } : {}
191
+ };
192
+ const svg = writeSvg(this.sheet ? layoutSheetImages(this.sheet, faces, sheetOptions, renderOptions) : layoutStyledDocument(flow.body, {
193
+ ...faces,
194
+ ...flowRenderOptions(flow),
195
+ ...renderOptions
185
196
  }));
186
197
  losses.push(...svg.losses);
187
198
  this.enforceStrict(options, losses);
@@ -190,7 +201,7 @@ var Ream = class Ream {
190
201
  losses
191
202
  };
192
203
  }
193
- const { fonts: _a, fontBytes: _b, fontFamily: _c, fontFetch: _d, fontProviders: _e, strict: _f, embedSource, signature, info: callerInfo, attachments: callerAttachments, ...renderOptions } = options;
204
+ const paginated = this.sheet ? projectSheetDoc(this.sheet, sheetOptions) : flow;
194
205
  const info = paginated.info || callerInfo ? {
195
206
  ...paginated.info,
196
207
  ...callerInfo
@@ -0,0 +1,17 @@
1
+ import { SheetDoc } from '../ir/sheet.js';
2
+ import { ProjectSheetOptions } from '../../excel/sheet-to-flow.js';
3
+ import { LaidOutDocument } from '../../layout/page-doc.js';
4
+ import { StyledRenderOptions } from '../../pdf/index.js';
5
+ /**
6
+ * Lay a workbook out as images of its sheets: the screen projection, one page a
7
+ * sheet with room for all of it, each page then cut to its content.
8
+ *
9
+ * @param sheet The workbook.
10
+ * @param faces The faces the sheets are measured and drawn in: the registry,
11
+ * and one per family where the document names several.
12
+ * @param options The projection's other knobs (reference date, file name, the
13
+ * render face's digit width).
14
+ * @param render The caller's own layout options, over the document's.
15
+ * @returns One page per visible sheet, each as large as what it holds.
16
+ */
17
+ export declare function layoutSheetImages(sheet: SheetDoc, faces: Pick<StyledRenderOptions, 'registry' | 'registriesByFamily'>, options?: Omit<ProjectSheetOptions, 'screen' | 'wholeSheetPages'>, render?: Partial<StyledRenderOptions>): LaidOutDocument;
@@ -0,0 +1,33 @@
1
+ import { layoutStyledDocument } from "../../layout/styled-layout.js";
2
+ import { projectSheetDoc } from "../../excel/sheet-to-flow.js";
3
+ import { flowRenderOptions } from "./project.js";
4
+ import { fitPagesToContent } from "../../layout/fit-pages.js";
5
+ //#region src/core/converter/sheet-images.ts
6
+ /** The room kept past a sheet's content, as the layout keeps it before it. */
7
+ var SHEET_IMAGE_PAD_PT = 2;
8
+ /**
9
+ * Lay a workbook out as images of its sheets: the screen projection, one page a
10
+ * sheet with room for all of it, each page then cut to its content.
11
+ *
12
+ * @param sheet The workbook.
13
+ * @param faces The faces the sheets are measured and drawn in: the registry,
14
+ * and one per family where the document names several.
15
+ * @param options The projection's other knobs (reference date, file name, the
16
+ * render face's digit width).
17
+ * @param render The caller's own layout options, over the document's.
18
+ * @returns One page per visible sheet, each as large as what it holds.
19
+ */
20
+ function layoutSheetImages(sheet, faces, options = {}, render = {}) {
21
+ const flow = projectSheetDoc(sheet, {
22
+ ...options,
23
+ screen: true,
24
+ wholeSheetPages: true
25
+ });
26
+ return fitPagesToContent(layoutStyledDocument(flow.body, {
27
+ ...faces,
28
+ ...flowRenderOptions(flow),
29
+ ...render
30
+ }), SHEET_IMAGE_PAD_PT);
31
+ }
32
+ //#endregion
33
+ export { layoutSheetImages };
@@ -1,5 +1,5 @@
1
- import { openCfb } from "../ole/cfb.js";
2
1
  import { aesCbcDecrypt, aesEcbDecrypt, sha1, sha256, sha384, sha512 } from "./primitives.js";
2
+ import { openCfb } from "../ole/cfb.js";
3
3
  //#region src/core/crypto/offcrypto.ts
4
4
  /** Thrown when the bytes are encrypted and the password does not open them. */
5
5
  var WrongPasswordError = class extends Error {
@@ -5,4 +5,4 @@
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
- export type { AbstractNumbering, Alignment, Border, BorderStyle, BodyElement, Comment, CellBorders, CellMerge, DocumentInfo, CellMargins, CellProperties, CellShading, CellDataBar, CellIcon, CellIconShape, CellSparkline, Chart, ChartBlock, ChartDataPoint, ChartLineStyle, ChartMarker, ChartMarkerSymbol, ChartSeries, ChartType, CustomGeometry, CustomPathCmd, DocumentModel, FontFamilyMap, HeaderFooterReference, HeaderFooterType, ImageBlock, ImageCrop, InlineImage, MathAccent, MathBar, MathDelimiter, MathEqArray, MathFraction, MathFunc, MathGroupChr, MathLimit, MathMatrix, MathNary, MathNode, MathRadical, MathRow, MathRun, MathScript, Numbering, NumberingFormat, NumberingInstance, NumberingLevel, PictureBullet, PictureOutline, NumberingReference, PageMargins, PageSize, Paragraph, ParagraphProperties, FrameProperties, RelativeSize, TabStop, Run, RunProperties, TextOutline, RowConditionalFormat, RowProperties, Section, FloatAnchor, SectionColumns, SectionProperties, ShapeBlock, ShapeShadow, ShapeDash, ShapeFill, ShapeFillKind, ShapeGeometry, ShapeGroupChild, ShapeLine, LineEnd, ShapeTextBody, ShapeTransform, Style, StyleSheet, StyleType, Table, TableCell, TableLook, TableProperties, TableStyleCondition, TableStyleConditionType, TableStyleLayer, TableRow, UnderlineStyle, VerticalAlign, } from './types.js';
8
+ export type { AbstractNumbering, Alignment, Border, BorderStyle, BodyElement, Comment, CellBorders, CellMerge, DocumentInfo, CellMargins, CellProperties, CellShading, CellDataBar, CellIcon, CellNoteFlag, CellIconShape, CellSparkline, Chart, ChartBlock, ChartDataPoint, ChartLineStyle, ChartMarker, ChartMarkerSymbol, ChartSeries, ChartType, CustomGeometry, CustomPathCmd, DocumentModel, FontFamilyMap, HeaderFooterReference, HeaderFooterType, ImageBlock, ImageCrop, InlineImage, MathAccent, MathBar, MathDelimiter, MathEqArray, MathFraction, MathFunc, MathGroupChr, MathLimit, MathMatrix, MathNary, MathNode, MathRadical, MathRow, MathRun, MathScript, Numbering, NumberingFormat, NumberingInstance, NumberingLevel, PictureBullet, PictureOutline, NumberingReference, PageMargins, PageSize, Paragraph, ParagraphProperties, FrameProperties, RelativeSize, TabStop, Run, RunProperties, TextOutline, Ligatures, RowConditionalFormat, RowProperties, Section, FloatAnchor, SectionColumns, SectionProperties, ShapeBlock, ShapeShadow, ShapeDash, ShapeFill, ShapeFillKind, ShapeGeometry, ShapeGroupChild, ShapeLine, LineEnd, ShapeTextBody, ShapeTransform, Style, StyleSheet, StyleType, Table, TableCell, TableLook, TableOverlay, TableProperties, TableStyleCondition, TableStyleConditionType, TableStyleLayer, TableRow, UnderlineStyle, VerticalAlign, } from './types.js';