reamkit 1.7.0 → 1.10.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 +21 -3
- package/dist/esm/core/converter/facade.js +2 -0
- package/dist/esm/core/converter/ream.d.ts +1 -0
- package/dist/esm/core/converter/ream.js +2 -1
- package/dist/esm/core/document-model/types.d.ts +3 -1
- package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
- package/dist/esm/core/drawingml/shape-render.js +27 -1
- package/dist/esm/core/vector.d.ts +10 -0
- package/dist/esm/html/html-writer.js +4 -2
- package/dist/esm/layout/styled-layout.js +5 -2
- package/dist/esm/pdf/shading.d.ts +12 -0
- package/dist/esm/pdf/shading.js +152 -0
- package/dist/esm/pdf/styled-page-emitter.js +29 -4
- package/dist/esm/pdf/vector-graphics.d.ts +1 -1
- package/dist/esm/pdf/vector-graphics.js +5 -3
- package/dist/esm/pdf-reader/ccitt.d.ts +15 -0
- package/dist/esm/pdf-reader/ccitt.js +394 -0
- package/dist/esm/pdf-reader/content.d.ts +6 -2
- package/dist/esm/pdf-reader/content.js +54 -13
- package/dist/esm/pdf-reader/decrypt.d.ts +1 -1
- package/dist/esm/pdf-reader/decrypt.js +20 -8
- package/dist/esm/pdf-reader/document.d.ts +1 -1
- package/dist/esm/pdf-reader/document.js +4 -4
- package/dist/esm/pdf-reader/flow-build.js +17 -6
- package/dist/esm/pdf-reader/image-decode.js +115 -7
- package/dist/esm/pdf-reader/layout.js +45 -7
- package/dist/esm/pdf-reader/reader.d.ts +1 -1
- package/dist/esm/pdf-reader/reader.js +5 -5
- package/dist/esm/pdf-reader/shading.d.ts +3 -0
- package/dist/esm/pdf-reader/shading.js +147 -0
- package/dist/esm/pdf-reader/text.js +47 -13
- package/dist/esm/pdf-reader/vector.d.ts +5 -1
- package/dist/esm/pdf-reader/vector.js +15 -6
- package/dist/esm/pptx/placeholder-cascade.d.ts +9 -0
- package/dist/esm/pptx/placeholder-cascade.js +77 -0
- package/dist/esm/pptx/pptx-reader.d.ts +4 -0
- package/dist/esm/pptx/pptx-reader.js +213 -0
- package/dist/esm/pptx/slide-parser.d.ts +18 -0
- package/dist/esm/pptx/slide-parser.js +359 -0
- package/dist/esm/pptx/sp-helpers.d.ts +17 -0
- package/dist/esm/pptx/sp-helpers.js +60 -0
- package/dist/esm/svg/svg-writer.js +12 -5
- package/dist/esm/word/docx-writer.js +8 -1
- package/dist/esm/word/drawing-parser.d.ts +4 -0
- package/dist/esm/word/drawing-parser.js +29 -18
- package/package.json +4 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FEATURES } from "../core/ir/features.js";
|
|
2
2
|
import { svgPathData } from "../core/vector.js";
|
|
3
|
+
import { gradientSvgDef } from "../core/drawingml/shape-render.js";
|
|
3
4
|
import { paintPlan } from "../layout/page-doc.js";
|
|
4
5
|
import { toBase64 } from "../core/bytes.js";
|
|
5
6
|
//#region src/svg/svg-writer.ts
|
|
@@ -12,10 +13,11 @@ function writeSvg(laid, opts = {}) {
|
|
|
12
13
|
const parts = [];
|
|
13
14
|
parts.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${fmt(width)}" height="${fmt(height)}" viewBox="0 0 ${fmt(width)} ${fmt(height)}">`);
|
|
14
15
|
let yOffset = 0;
|
|
16
|
+
const idc = { n: 0 };
|
|
15
17
|
laid.pages.forEach((page, i) => {
|
|
16
18
|
parts.push(`<g transform="translate(0 ${fmt(yOffset)})" data-page="${i + 1}">`);
|
|
17
19
|
parts.push(`<rect x="0" y="0" width="${fmt(page.width)}" height="${fmt(page.height)}" fill="#ffffff" stroke="#cccccc"/>`);
|
|
18
|
-
emitPage(parts, page, laid, losses);
|
|
20
|
+
emitPage(parts, page, laid, losses, idc);
|
|
19
21
|
parts.push("</g>");
|
|
20
22
|
yOffset += page.height + gap;
|
|
21
23
|
});
|
|
@@ -36,7 +38,7 @@ var svgWriter = {
|
|
|
36
38
|
]),
|
|
37
39
|
write: (doc, opts) => writeSvg(doc, opts ?? {})
|
|
38
40
|
};
|
|
39
|
-
function emitPage(out, page, laid, losses) {
|
|
41
|
+
function emitPage(out, page, laid, losses, idc) {
|
|
40
42
|
const plan = paintPlan(page.commands);
|
|
41
43
|
for (const f of plan.fills) out.push(`<rect x="${fmt(f.x)}" y="${fmt(f.y)}" width="${fmt(f.width)}" height="${fmt(f.height)}" fill="#${f.fillColorHex}"/>`);
|
|
42
44
|
for (const img of plan.images) {
|
|
@@ -71,7 +73,7 @@ function emitPage(out, page, laid, losses) {
|
|
|
71
73
|
];
|
|
72
74
|
out.push(`<line x1="${fmt(ax)}" y1="${fmt(ay)}" x2="${fmt(bx)}" y2="${fmt(by)}" stroke="#${b.borderColorHex}" stroke-width="${fmt(b.borderSizePt)}"/>`);
|
|
73
75
|
}
|
|
74
|
-
for (const sh of plan.shapes) emitShape(out, sh.shape);
|
|
76
|
+
for (const sh of plan.shapes) emitShape(out, sh.shape, idc);
|
|
75
77
|
for (const t of plan.lines) emitTextLine(out, t, losses);
|
|
76
78
|
}
|
|
77
79
|
function emitTextLine(out, item, losses) {
|
|
@@ -95,10 +97,15 @@ function emitTextLine(out, item, losses) {
|
|
|
95
97
|
x += tok.widthPt;
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
|
-
function emitShape(out, shape) {
|
|
100
|
+
function emitShape(out, shape, idc) {
|
|
99
101
|
const [a, b, c, d, e, f] = shape.transform;
|
|
100
102
|
const transform = `matrix(${fmt(a)} ${fmt(b)} ${fmt(c)} ${fmt(d)} ${fmt(e)} ${fmt(f)})`;
|
|
101
|
-
|
|
103
|
+
let fill;
|
|
104
|
+
if (shape.fillGradient) {
|
|
105
|
+
const id = `grad${idc.n++}`;
|
|
106
|
+
out.push(gradientSvgDef(id, shape.fillGradient));
|
|
107
|
+
fill = `url(#${id})`;
|
|
108
|
+
} else fill = shape.fillColorHex ? `#${shape.fillColorHex}` : "none";
|
|
102
109
|
const stroke = shape.stroke ? ` stroke="#${shape.stroke.colorHex}" stroke-width="${fmt(shape.stroke.widthPt)}"` : "";
|
|
103
110
|
for (const path of shape.paths) {
|
|
104
111
|
const d2 = pathData(path.segments);
|
|
@@ -359,7 +359,14 @@ function geomXml(g) {
|
|
|
359
359
|
return `<a:prstGeom prst="${escapeAttr(g.preset ?? "rect")}"><a:avLst>${gds}</a:avLst></a:prstGeom>`;
|
|
360
360
|
}
|
|
361
361
|
function fillXml(f) {
|
|
362
|
-
|
|
362
|
+
if (f.kind === "solid" && f.colorHex) return `<a:solidFill><a:srgbClr val="${f.colorHex}"/></a:solidFill>`;
|
|
363
|
+
if (f.kind === "gradient" && f.gradient) return gradFillXml(f.gradient);
|
|
364
|
+
return "<a:noFill/>";
|
|
365
|
+
}
|
|
366
|
+
function gradFillXml(g) {
|
|
367
|
+
return `<a:gradFill><a:gsLst>${g.stops.map((s) => {
|
|
368
|
+
return `<a:gs pos="${Math.round(Math.max(0, Math.min(1, s.offset)) * 1e5)}"><a:srgbClr val="${s.colorHex}"/></a:gs>`;
|
|
369
|
+
}).join("")}</a:gsLst>${g.kind === "radial" ? "<a:path path=\"circle\"/>" : `<a:lin ang="${Math.round(((g.angle ?? 0) % 360 + 360) % 360 * 6e4)}" scaled="1"/>`}</a:gradFill>`;
|
|
363
370
|
}
|
|
364
371
|
function lineXml(l) {
|
|
365
372
|
const w = l.width !== void 0 ? ` w="${Math.round(l.width * EMU_PER_PT)}"` : "";
|
|
@@ -36,3 +36,7 @@ export declare function resolveMc(altContent: PoNode): ReadonlyArray<PoNode>;
|
|
|
36
36
|
export declare function expandMcChildren(children: ReadonlyArray<PoNode>): Array<PoNode>;
|
|
37
37
|
export declare function parseDrawing(drawing: PoNode, resolveColor: ColorResolver, parseBody?: ParseBody): DrawingContent | null;
|
|
38
38
|
export declare function parseVmlPicture(node: PoNode): DrawingContent | null;
|
|
39
|
+
export declare function parsePrstGeom(prst: PoNode): ShapeGeometry;
|
|
40
|
+
export declare function parseCustGeom(cust: PoNode): ShapeGeometry;
|
|
41
|
+
export declare function parseFill(spPr: PoNode, resolveColor: ColorResolver): ShapeFill;
|
|
42
|
+
export declare function parseLine(spPr: PoNode, resolveColor: ColorResolver): ShapeLine | undefined;
|
|
@@ -353,10 +353,10 @@ function parseFill(spPr, resolveColor) {
|
|
|
353
353
|
} : { kind: "none" };
|
|
354
354
|
}
|
|
355
355
|
if (poIs(child, "a:gradFill")) {
|
|
356
|
-
const
|
|
357
|
-
return
|
|
358
|
-
kind: "
|
|
359
|
-
|
|
356
|
+
const gradient = parseGradient(child, resolveColor);
|
|
357
|
+
return gradient ? {
|
|
358
|
+
kind: "gradient",
|
|
359
|
+
gradient
|
|
360
360
|
} : { kind: "none" };
|
|
361
361
|
}
|
|
362
362
|
}
|
|
@@ -404,13 +404,10 @@ function colorFromContainer(parent, resolveColor) {
|
|
|
404
404
|
if (hex) return hex;
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
|
-
function
|
|
407
|
+
function parseGradient(grad, resolveColor) {
|
|
408
408
|
const gsLst = poChildren(grad).find((c) => poIs(c, "a:gsLst"));
|
|
409
409
|
if (!gsLst) return void 0;
|
|
410
|
-
|
|
411
|
-
let g = 0;
|
|
412
|
-
let b = 0;
|
|
413
|
-
let n = 0;
|
|
410
|
+
const stops = [];
|
|
414
411
|
for (const gs of poChildren(gsLst)) {
|
|
415
412
|
if (!poIs(gs, "a:gs")) continue;
|
|
416
413
|
let hex;
|
|
@@ -419,15 +416,29 @@ function colorFromGradient(grad, resolveColor) {
|
|
|
419
416
|
if (hex) break;
|
|
420
417
|
}
|
|
421
418
|
if (!hex) continue;
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
419
|
+
const pos = poIntAttr(gs, "pos");
|
|
420
|
+
const offset = pos !== void 0 ? clampUnit(pos / 1e5) : stops.length === 0 ? 0 : 1;
|
|
421
|
+
stops.push({
|
|
422
|
+
offset,
|
|
423
|
+
colorHex: hex
|
|
424
|
+
});
|
|
427
425
|
}
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
426
|
+
if (stops.length === 0) return void 0;
|
|
427
|
+
stops.sort((a, b) => a.offset - b.offset);
|
|
428
|
+
if (poChildren(grad).some((c) => poIs(c, "a:path"))) return {
|
|
429
|
+
kind: "radial",
|
|
430
|
+
stops
|
|
431
|
+
};
|
|
432
|
+
const lin = poChildren(grad).find((c) => poIs(c, "a:lin"));
|
|
433
|
+
const ang = lin ? poIntAttr(lin, "ang") : void 0;
|
|
434
|
+
return {
|
|
435
|
+
kind: "linear",
|
|
436
|
+
angle: ang !== void 0 ? ang / 6e4 % 360 : 0,
|
|
437
|
+
stops
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function clampUnit(x) {
|
|
441
|
+
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
431
442
|
}
|
|
432
443
|
//#endregion
|
|
433
|
-
export { expandMcChildren, parseDrawing, parseVmlPicture };
|
|
444
|
+
export { expandMcChildren, parseCustGeom, parseDrawing, parseFill, parseLine, parsePrstGeom, parseVmlPicture };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reamkit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Ream — convert DOCX, XLSX and PDF to PDF, SVG, HTML, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
|
|
3
|
+
"version": "1.10.0",
|
|
4
|
+
"description": "Ream — convert DOCX, XLSX, PPTX and PDF to PDF, SVG, HTML, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alex Krassavin <info@reamkit.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"keywords": [
|
|
39
39
|
"docx",
|
|
40
40
|
"xlsx",
|
|
41
|
+
"pptx",
|
|
41
42
|
"pdf",
|
|
42
43
|
"ooxml",
|
|
43
44
|
"ecma-376",
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"office",
|
|
47
48
|
"word",
|
|
48
49
|
"excel",
|
|
50
|
+
"powerpoint",
|
|
49
51
|
"converter"
|
|
50
52
|
],
|
|
51
53
|
"scripts": {
|