reamkit 1.23.0 → 1.25.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 +22 -11
- package/dist/esm/core/bmp.d.ts +33 -0
- package/dist/esm/core/bmp.js +276 -0
- package/dist/esm/core/converter/facade.d.ts +3 -3
- package/dist/esm/core/converter/facade.js +12 -0
- package/dist/esm/core/converter/ream.d.ts +48 -4
- package/dist/esm/core/converter/ream.js +25 -4
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +54 -0
- package/dist/esm/core/drawingml/chart-geometry.js +3 -2
- package/dist/esm/core/drawingml/diagram/colors.d.ts +52 -0
- package/dist/esm/core/drawingml/diagram/colors.js +125 -0
- package/dist/esm/core/drawingml/diagram/data-model.d.ts +47 -0
- package/dist/esm/core/drawingml/diagram/data-model.js +119 -0
- package/dist/esm/core/drawingml/diagram/layout-engine.d.ts +46 -0
- package/dist/esm/core/drawingml/diagram/layout-engine.js +948 -0
- package/dist/esm/core/drawingml/diagram/run.d.ts +37 -0
- package/dist/esm/core/drawingml/diagram/run.js +50 -0
- package/dist/esm/core/drawingml/diagram/to-drawing.d.ts +16 -0
- package/dist/esm/core/drawingml/diagram/to-drawing.js +86 -0
- package/dist/esm/core/drawingml/preset-geometry.js +116 -6
- package/dist/esm/core/drawingml/text-warp.d.ts +58 -0
- package/dist/esm/core/drawingml/text-warp.js +355 -0
- package/dist/esm/core/drawingml/theme-parser.js +9 -3
- package/dist/esm/core/font/measure.d.ts +12 -0
- package/dist/esm/core/font/measure.js +36 -0
- package/dist/esm/core/images.d.ts +30 -2
- package/dist/esm/core/images.js +121 -5
- package/dist/esm/core/metafile/emf.js +144 -16
- package/dist/esm/core/metafile/picture.d.ts +49 -0
- package/dist/esm/core/metafile/picture.js +70 -1
- package/dist/esm/core/metafile/wmf.js +53 -4
- package/dist/esm/core/ole/escher-blip.js +11 -1
- package/dist/esm/core/outline.d.ts +17 -0
- package/dist/esm/core/outline.js +30 -0
- package/dist/esm/core/style-cascade/resolver.js +1 -0
- package/dist/esm/core/style-cascade/types.d.ts +3 -1
- package/dist/esm/excel/print-model.js +2 -2
- package/dist/esm/excel/sheet-drawing.js +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +10 -0
- package/dist/esm/excel/sheet-to-flow.js +30 -3
- package/dist/esm/html/html-writer.js +5 -3
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/layout/page-doc.d.ts +35 -0
- package/dist/esm/layout/page-doc.js +14 -1
- package/dist/esm/layout/styled-layout.js +217 -30
- package/dist/esm/markdown/markdown-writer.d.ts +41 -0
- package/dist/esm/markdown/markdown-writer.js +733 -0
- package/dist/esm/pdf/shading.js +8 -6
- package/dist/esm/pdf/styled-page-emitter.js +62 -4
- package/dist/esm/pdf/vector-graphics.js +1 -1
- package/dist/esm/pdf-reader/annots.d.ts +24 -0
- package/dist/esm/pdf-reader/annots.js +126 -0
- package/dist/esm/pdf-reader/content.d.ts +131 -5
- package/dist/esm/pdf-reader/content.js +169 -12
- package/dist/esm/pdf-reader/display.d.ts +56 -0
- package/dist/esm/pdf-reader/display.js +162 -0
- package/dist/esm/pdf-reader/document.d.ts +36 -1
- package/dist/esm/pdf-reader/document.js +92 -25
- package/dist/esm/pdf-reader/embedded-fonts.d.ts +31 -0
- package/dist/esm/pdf-reader/embedded-fonts.js +94 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +61 -6
- package/dist/esm/pdf-reader/flow-build.js +128 -22
- package/dist/esm/pdf-reader/font.js +185 -4
- package/dist/esm/pdf-reader/image-decode.js +56 -5
- package/dist/esm/pdf-reader/images.d.ts +6 -0
- package/dist/esm/pdf-reader/images.js +25 -5
- package/dist/esm/pdf-reader/jpeg.d.ts +18 -0
- package/dist/esm/pdf-reader/jpeg.js +419 -0
- package/dist/esm/pdf-reader/layout.d.ts +1 -1
- package/dist/esm/pdf-reader/layout.js +221 -32
- package/dist/esm/pdf-reader/pattern-tint.d.ts +17 -0
- package/dist/esm/pdf-reader/pattern-tint.js +181 -0
- package/dist/esm/pdf-reader/reader.d.ts +9 -1
- package/dist/esm/pdf-reader/reader.js +22 -6
- package/dist/esm/pdf-reader/shading.d.ts +14 -0
- package/dist/esm/pdf-reader/shading.js +27 -1
- package/dist/esm/pdf-reader/tagged.js +156 -17
- package/dist/esm/pdf-reader/text.d.ts +13 -1
- package/dist/esm/pdf-reader/text.js +70 -3
- package/dist/esm/pdf-reader/vector.d.ts +25 -1
- package/dist/esm/pdf-reader/vector.js +168 -12
- package/dist/esm/pptx/ppt/ppt-reader.js +95 -27
- package/dist/esm/pptx/ppt/ppt-text.d.ts +41 -0
- package/dist/esm/pptx/ppt/ppt-text.js +327 -37
- package/dist/esm/pptx/pptx-reader.js +90 -10
- package/dist/esm/pptx/slide-parser.d.ts +4 -1
- package/dist/esm/pptx/slide-parser.js +104 -13
- package/dist/esm/pptx/sp-helpers.d.ts +7 -3
- package/dist/esm/pptx/sp-helpers.js +45 -7
- package/dist/esm/pptx/table-style.d.ts +7 -0
- package/dist/esm/pptx/table-style.js +59 -7
- package/dist/esm/svg/svg-writer.js +1 -0
- package/dist/esm/word/document-parser.d.ts +4 -1
- package/dist/esm/word/document-parser.js +4 -1
- package/dist/esm/word/docx-reader.js +26 -13
- package/dist/esm/word/docx-writer.js +15 -1
- package/dist/esm/word/drawing-parser.d.ts +20 -0
- package/dist/esm/word/drawing-parser.js +44 -5
- package/dist/esm/word/table-parser.js +3 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pt } from "../../core/ir/units.js";
|
|
2
2
|
import { ResourceStore } from "../../core/ir/resources.js";
|
|
3
3
|
import { FEATURES } from "../../core/ir/features.js";
|
|
4
|
+
import { knockOutColor } from "../../core/images.js";
|
|
4
5
|
import { isEmf } from "../../core/metafile/emf.js";
|
|
5
6
|
import { isWmf } from "../../core/metafile/wmf.js";
|
|
6
7
|
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../../core/style-cascade/resolver.js";
|
|
@@ -136,8 +137,9 @@ function bulletedRuns(para) {
|
|
|
136
137
|
const runs = para.runs.map(toRun);
|
|
137
138
|
if (para.bullet === void 0) return runs;
|
|
138
139
|
const { bold: _b, italic: _i, ...rest } = runs[0]?.properties ?? {};
|
|
140
|
+
const gap = hangs(para) ? " " : " ";
|
|
139
141
|
return [{
|
|
140
|
-
text: `${para.bullet}
|
|
142
|
+
text: `${para.bullet}${gap}`,
|
|
141
143
|
properties: rest
|
|
142
144
|
}, ...runs];
|
|
143
145
|
}
|
|
@@ -175,16 +177,13 @@ function backdropFill(bg, resources) {
|
|
|
175
177
|
if (bg.image) return {
|
|
176
178
|
kind: "picture",
|
|
177
179
|
imageResource: resources.put(bg.image.bytes),
|
|
178
|
-
...bg.imageTiled ? {
|
|
180
|
+
...bg.imageTiled ? {
|
|
181
|
+
tiled: true,
|
|
182
|
+
tileFromCentre: true
|
|
183
|
+
} : {}
|
|
179
184
|
};
|
|
180
185
|
if (bg.gradient) {
|
|
181
|
-
const stops =
|
|
182
|
-
offset: 0,
|
|
183
|
-
colorHex: bg.gradient.fromHex
|
|
184
|
-
}, {
|
|
185
|
-
offset: 1,
|
|
186
|
-
colorHex: bg.gradient.toHex
|
|
187
|
-
}];
|
|
186
|
+
const stops = gradientStops(bg.gradient);
|
|
188
187
|
return {
|
|
189
188
|
kind: "gradient",
|
|
190
189
|
gradient: bg.gradient.radial ? {
|
|
@@ -242,9 +241,10 @@ function positionedImage(rect, image, resources) {
|
|
|
242
241
|
kind: "image",
|
|
243
242
|
image: {
|
|
244
243
|
float: floatAt(rect),
|
|
245
|
-
resource: resources.put(image
|
|
244
|
+
resource: resources.put(drawnBytes(image)),
|
|
246
245
|
width: pt(rect.w),
|
|
247
246
|
height: pt(rect.h),
|
|
247
|
+
...image.crop ? { crop: image.crop } : {},
|
|
248
248
|
paragraphProperties: {}
|
|
249
249
|
}
|
|
250
250
|
};
|
|
@@ -290,34 +290,72 @@ function toCustomGeometry(g) {
|
|
|
290
290
|
commands
|
|
291
291
|
};
|
|
292
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* §2.3.7.6 `fillFocus` — the stops a shaded fill's two colours make.
|
|
295
|
+
*
|
|
296
|
+
* A focus of zero is the plain ramp everyone expects: the first colour at one
|
|
297
|
+
* end, the second at the other. Any other value means the sweep runs OUT from
|
|
298
|
+
* one of them — a focus of 50 puts the first colour halfway along with the
|
|
299
|
+
* second at BOTH ends, which is what 23884's every slide asks for and why its
|
|
300
|
+
* background read as a flat wash into violet where the reference is blue
|
|
301
|
+
* across the middle and dark only at the corners.
|
|
302
|
+
*
|
|
303
|
+
* @param g The gradient as the `.ppt` states it.
|
|
304
|
+
* @returns The stops, in order.
|
|
305
|
+
*/
|
|
306
|
+
function gradientStops(g) {
|
|
307
|
+
const focus = g.focusPct ?? 0;
|
|
308
|
+
if (focus === 0) return [{
|
|
309
|
+
offset: 0,
|
|
310
|
+
colorHex: g.fromHex
|
|
311
|
+
}, {
|
|
312
|
+
offset: 1,
|
|
313
|
+
colorHex: g.toHex
|
|
314
|
+
}];
|
|
315
|
+
if (Math.abs(focus) >= 100) return [{
|
|
316
|
+
offset: 0,
|
|
317
|
+
colorHex: g.toHex
|
|
318
|
+
}, {
|
|
319
|
+
offset: 1,
|
|
320
|
+
colorHex: g.fromHex
|
|
321
|
+
}];
|
|
322
|
+
const peak = focus > 0 ? g.fromHex : g.toHex;
|
|
323
|
+
const ends = focus > 0 ? g.toHex : g.fromHex;
|
|
324
|
+
const at = focus > 0 ? focus / 100 : 1 + focus / 100;
|
|
325
|
+
return [
|
|
326
|
+
{
|
|
327
|
+
offset: 0,
|
|
328
|
+
colorHex: ends
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
offset: at,
|
|
332
|
+
colorHex: peak
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
offset: 1,
|
|
336
|
+
colorHex: ends
|
|
337
|
+
}
|
|
338
|
+
];
|
|
339
|
+
}
|
|
293
340
|
function positionedAutoShape(rect, auto, resources) {
|
|
294
341
|
const line = isLineShape(auto.shapeType);
|
|
295
342
|
const fill = line ? { kind: "none" } : auto.image ? {
|
|
296
343
|
kind: "picture",
|
|
297
344
|
imageResource: resources.put(auto.image.bytes),
|
|
298
|
-
...auto.imageTiled ? {
|
|
345
|
+
...auto.imageTiled ? {
|
|
346
|
+
tiled: true,
|
|
347
|
+
tileFromCentre: true
|
|
348
|
+
} : {},
|
|
299
349
|
...auto.tileSizePt ? { tileSizePt: auto.tileSizePt } : {}
|
|
300
350
|
} : auto.gradient ? {
|
|
301
351
|
kind: "gradient",
|
|
302
352
|
gradient: auto.gradient.radial ? {
|
|
303
353
|
kind: "radial",
|
|
304
|
-
stops:
|
|
305
|
-
offset: 0,
|
|
306
|
-
colorHex: auto.gradient.fromHex
|
|
307
|
-
}, {
|
|
308
|
-
offset: 1,
|
|
309
|
-
colorHex: auto.gradient.toHex
|
|
310
|
-
}]
|
|
354
|
+
stops: gradientStops(auto.gradient)
|
|
311
355
|
} : {
|
|
312
356
|
kind: "linear",
|
|
313
357
|
angle: auto.gradient.angleDeg,
|
|
314
|
-
stops:
|
|
315
|
-
offset: 0,
|
|
316
|
-
colorHex: auto.gradient.fromHex
|
|
317
|
-
}, {
|
|
318
|
-
offset: 1,
|
|
319
|
-
colorHex: auto.gradient.toHex
|
|
320
|
-
}]
|
|
358
|
+
stops: gradientStops(auto.gradient)
|
|
321
359
|
}
|
|
322
360
|
} : auto.fillColorHex ? {
|
|
323
361
|
kind: "solid",
|
|
@@ -353,13 +391,30 @@ function inFlowImage(image, resources) {
|
|
|
353
391
|
return {
|
|
354
392
|
kind: "image",
|
|
355
393
|
image: {
|
|
356
|
-
resource: resources.put(image
|
|
394
|
+
resource: resources.put(drawnBytes(image)),
|
|
357
395
|
width: pt(size.w * .75),
|
|
358
396
|
height: pt(size.h * .75),
|
|
397
|
+
...image.crop ? { crop: image.crop } : {},
|
|
359
398
|
paragraphProperties: {}
|
|
360
399
|
}
|
|
361
400
|
};
|
|
362
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* The bytes a picture is actually DRAWN from.
|
|
404
|
+
*
|
|
405
|
+
* §2.3.23 `pictureTransparent` names a colour the picture is drawn without, and
|
|
406
|
+
* a raster carries no alpha channel to say so — so the knock-out is baked into
|
|
407
|
+
* bytes of its own. The resource store hashes content, so two shapes knocking
|
|
408
|
+
* different colours out of the same blip stay two resources by themselves, and
|
|
409
|
+
* one that knocks out nothing keeps the bytes it arrived with.
|
|
410
|
+
*
|
|
411
|
+
* @param image The picture as the shape states it.
|
|
412
|
+
* @returns The bytes to store, knocked out where the shape asks for it.
|
|
413
|
+
*/
|
|
414
|
+
function drawnBytes(image) {
|
|
415
|
+
if (image.transparentHex === void 0 || isMetafile(image.bytes)) return image.bytes;
|
|
416
|
+
return knockOutColor(image.bytes, image.transparentHex) ?? image.bytes;
|
|
417
|
+
}
|
|
363
418
|
function isMetafile(d) {
|
|
364
419
|
return isEmf(d) || isWmf(d);
|
|
365
420
|
}
|
|
@@ -418,12 +473,25 @@ function toRun(r) {
|
|
|
418
473
|
function toParaProperties(p, breakBefore) {
|
|
419
474
|
const alignment = p.align !== void 0 ? alignmentFrom(p.align) : void 0;
|
|
420
475
|
const level = p.level ?? 0;
|
|
476
|
+
const leftPt = p.leftMarginPt ?? (level > 0 ? level * LEVEL_INDENT_PT : void 0);
|
|
477
|
+
const firstPt = p.indentPt !== void 0 ? p.indentPt - (leftPt ?? 0) : void 0;
|
|
421
478
|
return {
|
|
422
479
|
...breakBefore ? { pageBreakBefore: true } : {},
|
|
423
480
|
...alignment ? { alignment } : {},
|
|
424
|
-
...
|
|
481
|
+
...leftPt !== void 0 ? { indentLeft: pt(leftPt) } : {},
|
|
482
|
+
...firstPt !== void 0 && firstPt !== 0 ? { indentFirstLine: pt(firstPt) } : {},
|
|
483
|
+
...p.spaceBeforePt !== void 0 ? { spacingBefore: pt(p.spaceBeforePt) } : {},
|
|
484
|
+
...p.spaceAfterPt !== void 0 ? { spacingAfter: pt(p.spaceAfterPt) } : {},
|
|
485
|
+
...p.lineSpacing !== void 0 && p.lineSpacing > 0 ? {
|
|
486
|
+
spacingLineRule: "auto",
|
|
487
|
+
spacingLine: pt(p.lineSpacing / 100 * 12)
|
|
488
|
+
} : {}
|
|
425
489
|
};
|
|
426
490
|
}
|
|
491
|
+
/** Whether the paragraph's first line starts LEFT of its body — a hanging bullet. */
|
|
492
|
+
function hangs(p) {
|
|
493
|
+
return p.indentPt !== void 0 && p.leftMarginPt !== void 0 && p.indentPt < p.leftMarginPt;
|
|
494
|
+
}
|
|
427
495
|
function alignmentFrom(a) {
|
|
428
496
|
switch (a) {
|
|
429
497
|
case 1: return "center";
|
|
@@ -28,6 +28,18 @@ export interface PptParagraph {
|
|
|
28
28
|
* carries none.
|
|
29
29
|
*/
|
|
30
30
|
readonly bullet?: string;
|
|
31
|
+
/**
|
|
32
|
+
* §2.9.20 `leftMargin` — where the paragraph's BODY sits, in points from the
|
|
33
|
+
* text box's own left edge.
|
|
34
|
+
*/
|
|
35
|
+
readonly leftMarginPt?: number;
|
|
36
|
+
/** §2.9.20 `indent` — where its FIRST line starts. Left of the body ⇒ hanging. */
|
|
37
|
+
readonly indentPt?: number;
|
|
38
|
+
/** §2.9.32 `lineSpacing`, as a PERCENTAGE of the line's height — 100 is single. */
|
|
39
|
+
readonly lineSpacing?: number;
|
|
40
|
+
/** §2.9.32 `spaceBefore` / `spaceAfter`, in points. */
|
|
41
|
+
readonly spaceBeforePt?: number;
|
|
42
|
+
readonly spaceAfterPt?: number;
|
|
31
43
|
}
|
|
32
44
|
/**
|
|
33
45
|
* An embedded picture referenced by a slide shape — the raw image bytes pulled
|
|
@@ -35,6 +47,22 @@ export interface PptParagraph {
|
|
|
35
47
|
*/
|
|
36
48
|
export interface PptImage {
|
|
37
49
|
readonly bytes: Uint8Array;
|
|
50
|
+
/**
|
|
51
|
+
* §2.3.23 `cropFrom*` — the fraction of each edge of the SOURCE cut away
|
|
52
|
+
* before it is fitted to the shape's box. Absent ⇒ the whole picture.
|
|
53
|
+
*/
|
|
54
|
+
readonly crop?: {
|
|
55
|
+
readonly left: number;
|
|
56
|
+
readonly top: number;
|
|
57
|
+
readonly right: number;
|
|
58
|
+
readonly bottom: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* §2.3.23 `pictureTransparent` — the colour the picture is drawn WITHOUT,
|
|
62
|
+
* 6-hex and no leading `#`. Clip art of this age states its ground here
|
|
63
|
+
* rather than carrying an alpha channel.
|
|
64
|
+
*/
|
|
65
|
+
readonly transparentHex?: string;
|
|
38
66
|
}
|
|
39
67
|
/** A shape's rectangle on the slide, in points (from the OfficeArtClientAnchor). */
|
|
40
68
|
export interface PptRect {
|
|
@@ -99,6 +127,12 @@ export interface PptAutoShape {
|
|
|
99
127
|
readonly toHex: string;
|
|
100
128
|
readonly angleDeg: number;
|
|
101
129
|
readonly radial: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* §2.3.7.6 `fillFocus` — where along the sweep the FIRST colour peaks, as a
|
|
132
|
+
* percentage. Zero is a plain ramp; 50 puts it in the middle with the
|
|
133
|
+
* second colour at both ends, which is a different picture entirely.
|
|
134
|
+
*/
|
|
135
|
+
readonly focusPct?: number;
|
|
102
136
|
};
|
|
103
137
|
/**
|
|
104
138
|
* §2.3.7.1 MSOFILLTYPE 3 — a picture stretched over the shape, its blip named
|
|
@@ -138,6 +172,13 @@ export interface PptShape {
|
|
|
138
172
|
* of them would carry "Click to edit Master title style".
|
|
139
173
|
*/
|
|
140
174
|
readonly placeholder?: boolean;
|
|
175
|
+
/**
|
|
176
|
+
* §2.9.51 `OEPlaceholderAtom.placeholderId` — WHICH placeholder it is. The
|
|
177
|
+
* three a master keeps for the slide's furniture — 7 the date, 8 the slide
|
|
178
|
+
* number, 9 the footer — are the only ones whose text does not live in the
|
|
179
|
+
* shape at all (§2.4.15).
|
|
180
|
+
*/
|
|
181
|
+
readonly placeholderId?: number;
|
|
141
182
|
readonly paragraphs?: ReadonlyArray<PptParagraph>;
|
|
142
183
|
readonly image?: PptImage;
|
|
143
184
|
readonly autoShape?: PptAutoShape;
|