reamkit 1.14.0 → 1.15.1
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 +34 -8
- package/dist/esm/core/converter/facade.d.ts +8 -1
- package/dist/esm/core/converter/facade.js +34 -8
- package/dist/esm/core/converter/ream.d.ts +1 -0
- package/dist/esm/core/converter/ream.js +13 -8
- package/dist/esm/core/ir/features.d.ts +1 -0
- package/dist/esm/core/ir/features.js +1 -0
- package/dist/esm/core/ir/sheet.d.ts +7 -0
- package/dist/esm/core/ole/cfb.d.ts +19 -0
- package/dist/esm/core/ole/cfb.js +188 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +20 -1
- package/dist/esm/excel/activex-parser.d.ts +9 -0
- package/dist/esm/excel/activex-parser.js +188 -0
- package/dist/esm/excel/conditional-format.d.ts +4 -2
- package/dist/esm/excel/conditional-format.js +138 -4
- package/dist/esm/excel/formula/context.d.ts +11 -0
- package/dist/esm/excel/formula/dates.d.ts +11 -0
- package/dist/esm/excel/formula/dates.js +46 -0
- package/dist/esm/excel/formula/eval.d.ts +11 -0
- package/dist/esm/excel/formula/eval.js +196 -0
- package/dist/esm/excel/formula/functions.d.ts +7 -0
- package/dist/esm/excel/formula/functions.js +1359 -0
- package/dist/esm/excel/formula/index.d.ts +14 -0
- package/dist/esm/excel/formula/index.js +17 -0
- package/dist/esm/excel/formula/lexer.d.ts +8 -0
- package/dist/esm/excel/formula/lexer.js +163 -0
- package/dist/esm/excel/formula/parser.d.ts +57 -0
- package/dist/esm/excel/formula/parser.js +274 -0
- package/dist/esm/excel/formula/value.d.ts +52 -0
- package/dist/esm/excel/formula/value.js +102 -0
- package/dist/esm/excel/number-format.d.ts +2 -0
- package/dist/esm/excel/number-format.js +5 -1
- package/dist/esm/excel/print-model.d.ts +3 -0
- package/dist/esm/excel/print-model.js +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +4 -1
- package/dist/esm/excel/sheet-to-flow.js +46 -2
- package/dist/esm/excel/worksheet-parser.js +66 -0
- package/dist/esm/excel/xls/biff-chart.d.ts +8 -0
- package/dist/esm/excel/xls/biff-chart.js +121 -0
- package/dist/esm/excel/xls/biff-reader.d.ts +4 -0
- package/dist/esm/excel/xls/biff-reader.js +1418 -0
- package/dist/esm/excel/xls/biff-styles.d.ts +8 -0
- package/dist/esm/excel/xls/biff-styles.js +299 -0
- package/dist/esm/excel/xls/escher.d.ts +24 -0
- package/dist/esm/excel/xls/escher.js +171 -0
- package/dist/esm/excel/xls/xls-reader.d.ts +3 -0
- package/dist/esm/excel/xls/xls-reader.js +30 -0
- package/dist/esm/excel/xlsx-reader.d.ts +2 -1
- package/dist/esm/excel/xlsx-reader.js +28 -3
- package/dist/esm/excel/xlsx-to-pdf.d.ts +1 -0
- package/dist/esm/excel/xlsx-to-pdf.js +2 -2
- package/dist/esm/excel/xlsx-writer.js +2 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +4 -2
- package/dist/esm/pdf-reader/flow-build.js +25 -2
- package/dist/esm/pdf-reader/layout.js +2 -2
- package/dist/esm/pdf-reader/tagged.js +2 -2
- package/dist/esm/pptx/ppt/ppt-reader.d.ts +4 -0
- package/dist/esm/pptx/ppt/ppt-reader.js +337 -0
- package/dist/esm/pptx/ppt/ppt-text.d.ts +69 -0
- package/dist/esm/pptx/ppt/ppt-text.js +756 -0
- package/dist/esm/pptx/pptx-reader.js +16 -1
- package/dist/esm/word/doc/doc-reader.d.ts +4 -0
- package/dist/esm/word/doc/doc-reader.js +427 -0
- package/dist/esm/word/doc/doc-text.d.ts +83 -0
- package/dist/esm/word/doc/doc-text.js +731 -0
- package/package.json +1 -1
|
@@ -124,14 +124,37 @@ function shapeBlock(v) {
|
|
|
124
124
|
}
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function sectionFromPdfPages(pages) {
|
|
128
|
+
const box = pages[0]?.mediaBox;
|
|
129
|
+
if (!box) return void 0;
|
|
130
|
+
const width = Math.abs(box[2] - box[0]);
|
|
131
|
+
const height = Math.abs(box[3] - box[1]);
|
|
132
|
+
if (!(width > 0 && height > 0)) return void 0;
|
|
133
|
+
return {
|
|
134
|
+
pageSize: {
|
|
135
|
+
width: pt(width),
|
|
136
|
+
height: pt(height),
|
|
137
|
+
orientation: width > height ? "landscape" : "portrait"
|
|
138
|
+
},
|
|
139
|
+
margins: {
|
|
140
|
+
top: pt(0),
|
|
141
|
+
right: pt(0),
|
|
142
|
+
bottom: pt(0),
|
|
143
|
+
left: pt(0)
|
|
144
|
+
},
|
|
145
|
+
headers: [],
|
|
146
|
+
footers: []
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function buildFlowDoc(body, resources = new ResourceStore(), section) {
|
|
128
150
|
return {
|
|
129
151
|
kind: "flow",
|
|
130
152
|
body: resolveBodyStyles([...body], EMPTY_STYLE_SHEET),
|
|
131
153
|
sections: [],
|
|
154
|
+
...section ? { section } : {},
|
|
132
155
|
styles: EMPTY_STYLE_SHEET,
|
|
133
156
|
resources
|
|
134
157
|
};
|
|
135
158
|
}
|
|
136
159
|
//#endregion
|
|
137
|
-
export { buildFlowDoc, dedupeLosses, imageBlock, paragraphBlock, paragraphFromRuns, shapeBlock };
|
|
160
|
+
export { buildFlowDoc, dedupeLosses, imageBlock, paragraphBlock, paragraphFromRuns, sectionFromPdfPages, shapeBlock };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResourceStore } from "../core/ir/resources.js";
|
|
2
|
-
import { buildFlowDoc, dedupeLosses, imageBlock, paragraphFromRuns, shapeBlock } from "./flow-build.js";
|
|
2
|
+
import { buildFlowDoc, dedupeLosses, imageBlock, paragraphFromRuns, sectionFromPdfPages, shapeBlock } from "./flow-build.js";
|
|
3
3
|
import { collectPageImages } from "./images.js";
|
|
4
4
|
import { extractPageText } from "./text.js";
|
|
5
5
|
import { collectPageVectors } from "./vector.js";
|
|
@@ -45,7 +45,7 @@ function reconstructByLayout(file) {
|
|
|
45
45
|
for (const block of blocks) body.push(block.el);
|
|
46
46
|
});
|
|
47
47
|
return {
|
|
48
|
-
doc: buildFlowDoc(body, resources),
|
|
48
|
+
doc: buildFlowDoc(body, resources, sectionFromPdfPages(pages)),
|
|
49
49
|
losses: dedupeLosses(losses)
|
|
50
50
|
};
|
|
51
51
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pt } from "../core/ir/units.js";
|
|
2
2
|
import { ResourceStore } from "../core/ir/resources.js";
|
|
3
|
-
import { buildFlowDoc, dedupeLosses, imageBlock, paragraphBlock, paragraphFromRuns } from "./flow-build.js";
|
|
3
|
+
import { buildFlowDoc, dedupeLosses, imageBlock, paragraphBlock, paragraphFromRuns, sectionFromPdfPages } from "./flow-build.js";
|
|
4
4
|
import { collectPageImages } from "./images.js";
|
|
5
5
|
import { extractPageText } from "./text.js";
|
|
6
6
|
import { readStructTree } from "./struct-tree.js";
|
|
@@ -126,7 +126,7 @@ function reconstructTaggedPdf(file) {
|
|
|
126
126
|
for (const { img } of orphans) body.push(imageBlock(img, resources));
|
|
127
127
|
if (body.length === 0) return void 0;
|
|
128
128
|
return {
|
|
129
|
-
doc: buildFlowDoc(body, resources),
|
|
129
|
+
doc: buildFlowDoc(body, resources, sectionFromPdfPages(pages)),
|
|
130
130
|
losses: imageLosses
|
|
131
131
|
};
|
|
132
132
|
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { pt } from "../../core/ir/units.js";
|
|
2
|
+
import { ResourceStore } from "../../core/ir/resources.js";
|
|
3
|
+
import { FEATURES } from "../../core/ir/features.js";
|
|
4
|
+
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../../core/style-cascade/resolver.js";
|
|
5
|
+
import "../../core/style-cascade/index.js";
|
|
6
|
+
import { isCfb, openCfb } from "../../core/ole/cfb.js";
|
|
7
|
+
import { extractPptContent, paragraphText } from "./ppt-text.js";
|
|
8
|
+
//#region src/pptx/ppt/ppt-reader.ts
|
|
9
|
+
var ZERO_WIDTH_SPACE = "";
|
|
10
|
+
var DEFAULT_SLIDE_W = 720;
|
|
11
|
+
var DEFAULT_SLIDE_H = 540;
|
|
12
|
+
var SLIDE_MARGIN = 36;
|
|
13
|
+
var LEVEL_INDENT_PT = 18;
|
|
14
|
+
function looksLikePpt(bytes) {
|
|
15
|
+
if (!isCfb(bytes)) return false;
|
|
16
|
+
try {
|
|
17
|
+
return openCfb(bytes).hasStream("PowerPoint Document");
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
var PPT_TEXT_LOSS = {
|
|
23
|
+
severity: "degraded",
|
|
24
|
+
feature: FEATURES.text,
|
|
25
|
+
detail: "legacy .ppt: each slide's text (with run formatting — bold/italic/underline/size/colour — and paragraph alignment/indent), embedded images, per-shape placement and decorative autoshapes (preset or exact freeform geometry with literal, scheme- or system-resolved fill/line colours) are read into one page per slide (re-save as .pptx for full fidelity)"
|
|
26
|
+
};
|
|
27
|
+
var PPT_ENCRYPTED_LOSS = {
|
|
28
|
+
severity: "dropped",
|
|
29
|
+
feature: FEATURES.text,
|
|
30
|
+
detail: "legacy .ppt is encrypted/obfuscated — its text cannot be read"
|
|
31
|
+
};
|
|
32
|
+
function readPpt(bytes) {
|
|
33
|
+
const content = extractPptContent(bytes);
|
|
34
|
+
const width = pt(content.slideWidthPt ?? DEFAULT_SLIDE_W);
|
|
35
|
+
const height = pt(content.slideHeightPt ?? DEFAULT_SLIDE_H);
|
|
36
|
+
const resources = new ResourceStore();
|
|
37
|
+
return {
|
|
38
|
+
doc: {
|
|
39
|
+
kind: "flow",
|
|
40
|
+
body: resolveBodyStyles(buildBody(content, resources), EMPTY_STYLE_SHEET),
|
|
41
|
+
sections: [],
|
|
42
|
+
section: {
|
|
43
|
+
pageSize: {
|
|
44
|
+
width,
|
|
45
|
+
height
|
|
46
|
+
},
|
|
47
|
+
margins: {
|
|
48
|
+
top: pt(SLIDE_MARGIN),
|
|
49
|
+
right: pt(SLIDE_MARGIN),
|
|
50
|
+
bottom: pt(SLIDE_MARGIN),
|
|
51
|
+
left: pt(SLIDE_MARGIN)
|
|
52
|
+
},
|
|
53
|
+
headers: [],
|
|
54
|
+
footers: []
|
|
55
|
+
},
|
|
56
|
+
styles: EMPTY_STYLE_SHEET,
|
|
57
|
+
resources
|
|
58
|
+
},
|
|
59
|
+
losses: [content.encrypted ? PPT_ENCRYPTED_LOSS : PPT_TEXT_LOSS]
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function buildBody(content, resources) {
|
|
63
|
+
const body = [];
|
|
64
|
+
content.slides.forEach((slide, slideIndex) => {
|
|
65
|
+
const inFlowParas = [];
|
|
66
|
+
const inFlowImages = [];
|
|
67
|
+
const floats = [];
|
|
68
|
+
for (const shape of slide.shapes) if (shape.rectPt) {
|
|
69
|
+
if (shape.paragraphs?.some((p) => paragraphText(p).length > 0)) floats.push(positionedTextShape(shape.rectPt, shape.paragraphs));
|
|
70
|
+
if (shape.image) {
|
|
71
|
+
const block = positionedImage(shape.rectPt, shape.image, resources);
|
|
72
|
+
if (block) floats.push(block);
|
|
73
|
+
}
|
|
74
|
+
if (shape.autoShape) floats.push(positionedAutoShape(shape.rectPt, shape.autoShape));
|
|
75
|
+
} else {
|
|
76
|
+
for (const para of shape.paragraphs ?? []) if (paragraphText(para).length > 0) inFlowParas.push(flowParagraph(para));
|
|
77
|
+
if (shape.image) {
|
|
78
|
+
const block = inFlowImage(shape.image, resources);
|
|
79
|
+
if (block) inFlowImages.push(block);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
pushSlide(body, [...inFlowParas, ...inFlowImages], floats, slideIndex > 0);
|
|
83
|
+
});
|
|
84
|
+
if (body.length === 0) body.push(anchorParagraph(false));
|
|
85
|
+
return body;
|
|
86
|
+
}
|
|
87
|
+
function pushSlide(body, inFlow, floats, breakBefore) {
|
|
88
|
+
if (inFlow.length === 0 && floats.length === 0) {
|
|
89
|
+
body.push(anchorParagraph(breakBefore));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (inFlow.length > 0) {
|
|
93
|
+
const first = inFlow[0];
|
|
94
|
+
if (breakBefore && first.kind === "paragraph") inFlow[0] = {
|
|
95
|
+
kind: "paragraph",
|
|
96
|
+
paragraph: {
|
|
97
|
+
...first.paragraph,
|
|
98
|
+
properties: {
|
|
99
|
+
...first.paragraph.properties,
|
|
100
|
+
pageBreakBefore: true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
else if (breakBefore) body.push(anchorParagraph(true));
|
|
105
|
+
body.push(...inFlow);
|
|
106
|
+
} else body.push(anchorParagraph(breakBefore));
|
|
107
|
+
body.push(...floats);
|
|
108
|
+
}
|
|
109
|
+
function flowParagraph(para) {
|
|
110
|
+
return {
|
|
111
|
+
kind: "paragraph",
|
|
112
|
+
paragraph: {
|
|
113
|
+
properties: toParaProperties(para, false),
|
|
114
|
+
runs: para.runs.map(toRun)
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function floatAt(rect) {
|
|
119
|
+
return {
|
|
120
|
+
wrap: "none",
|
|
121
|
+
posH: {
|
|
122
|
+
relativeFrom: "page",
|
|
123
|
+
offsetPt: pt(rect.x)
|
|
124
|
+
},
|
|
125
|
+
posV: {
|
|
126
|
+
relativeFrom: "page",
|
|
127
|
+
offsetPt: pt(rect.y)
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function positionedTextShape(rect, paragraphs) {
|
|
132
|
+
return {
|
|
133
|
+
kind: "shape",
|
|
134
|
+
shape: {
|
|
135
|
+
float: floatAt(rect),
|
|
136
|
+
width: pt(rect.w),
|
|
137
|
+
height: pt(rect.h),
|
|
138
|
+
geometry: {
|
|
139
|
+
kind: "preset",
|
|
140
|
+
preset: "rect",
|
|
141
|
+
adjust: /* @__PURE__ */ new Map()
|
|
142
|
+
},
|
|
143
|
+
fill: { kind: "none" },
|
|
144
|
+
text: {
|
|
145
|
+
content: paragraphs.filter((p) => paragraphText(p).length > 0).map(flowParagraph),
|
|
146
|
+
anchor: "t"
|
|
147
|
+
},
|
|
148
|
+
paragraphProperties: {}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function positionedImage(rect, image, resources) {
|
|
153
|
+
if (!imagePixelSize(image.bytes)) return void 0;
|
|
154
|
+
return {
|
|
155
|
+
kind: "image",
|
|
156
|
+
image: {
|
|
157
|
+
float: floatAt(rect),
|
|
158
|
+
resource: resources.put(image.bytes),
|
|
159
|
+
width: pt(rect.w),
|
|
160
|
+
height: pt(rect.h),
|
|
161
|
+
paragraphProperties: {}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
var SHAPE_PRESETS = new Map([
|
|
166
|
+
[1, "rect"],
|
|
167
|
+
[2, "roundRect"],
|
|
168
|
+
[3, "ellipse"],
|
|
169
|
+
[4, "diamond"],
|
|
170
|
+
[5, "triangle"],
|
|
171
|
+
[6, "rtTriangle"],
|
|
172
|
+
[7, "parallelogram"],
|
|
173
|
+
[8, "trapezoid"],
|
|
174
|
+
[9, "hexagon"],
|
|
175
|
+
[10, "octagon"],
|
|
176
|
+
[13, "line"],
|
|
177
|
+
[20, "line"]
|
|
178
|
+
]);
|
|
179
|
+
function isLineShape(shapeType) {
|
|
180
|
+
return shapeType === 13 || shapeType >= 20 && shapeType <= 49;
|
|
181
|
+
}
|
|
182
|
+
function toCustomGeometry(g) {
|
|
183
|
+
const commands = g.commands.map((c) => c.kind === "move" ? {
|
|
184
|
+
cmd: "move",
|
|
185
|
+
x: c.x,
|
|
186
|
+
y: c.y
|
|
187
|
+
} : c.kind === "line" ? {
|
|
188
|
+
cmd: "line",
|
|
189
|
+
x: c.x,
|
|
190
|
+
y: c.y
|
|
191
|
+
} : c.kind === "cubic" ? {
|
|
192
|
+
cmd: "cubic",
|
|
193
|
+
x1: c.x1,
|
|
194
|
+
y1: c.y1,
|
|
195
|
+
x2: c.x2,
|
|
196
|
+
y2: c.y2,
|
|
197
|
+
x: c.x,
|
|
198
|
+
y: c.y
|
|
199
|
+
} : { cmd: "close" });
|
|
200
|
+
return {
|
|
201
|
+
pathWidth: g.pathWidth,
|
|
202
|
+
pathHeight: g.pathHeight,
|
|
203
|
+
commands
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function positionedAutoShape(rect, auto) {
|
|
207
|
+
const line = isLineShape(auto.shapeType);
|
|
208
|
+
const fill = auto.fillColorHex && !line ? {
|
|
209
|
+
kind: "solid",
|
|
210
|
+
colorHex: auto.fillColorHex
|
|
211
|
+
} : { kind: "none" };
|
|
212
|
+
const stroke = auto.lineColorHex ? {
|
|
213
|
+
colorHex: auto.lineColorHex,
|
|
214
|
+
fill: "solid"
|
|
215
|
+
} : line ? { fill: "solid" } : void 0;
|
|
216
|
+
return {
|
|
217
|
+
kind: "shape",
|
|
218
|
+
shape: {
|
|
219
|
+
float: floatAt(rect),
|
|
220
|
+
width: pt(rect.w),
|
|
221
|
+
height: pt(rect.h),
|
|
222
|
+
geometry: auto.geometry ? {
|
|
223
|
+
kind: "custom",
|
|
224
|
+
custom: toCustomGeometry(auto.geometry)
|
|
225
|
+
} : {
|
|
226
|
+
kind: "preset",
|
|
227
|
+
preset: SHAPE_PRESETS.get(auto.shapeType) ?? "rect",
|
|
228
|
+
adjust: /* @__PURE__ */ new Map()
|
|
229
|
+
},
|
|
230
|
+
fill,
|
|
231
|
+
...stroke ? { line: stroke } : {},
|
|
232
|
+
paragraphProperties: {}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function inFlowImage(image, resources) {
|
|
237
|
+
const size = imagePixelSize(image.bytes);
|
|
238
|
+
if (!size) return void 0;
|
|
239
|
+
return {
|
|
240
|
+
kind: "image",
|
|
241
|
+
image: {
|
|
242
|
+
resource: resources.put(image.bytes),
|
|
243
|
+
width: pt(size.w * .75),
|
|
244
|
+
height: pt(size.h * .75),
|
|
245
|
+
paragraphProperties: {}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function imagePixelSize(d) {
|
|
250
|
+
if (d.length >= 24 && d[0] === 137 && d[1] === 80 && d[2] === 78 && d[3] === 71) {
|
|
251
|
+
const w = u32be(d, 16);
|
|
252
|
+
const h = u32be(d, 20);
|
|
253
|
+
return w > 0 && h > 0 ? {
|
|
254
|
+
w,
|
|
255
|
+
h
|
|
256
|
+
} : void 0;
|
|
257
|
+
}
|
|
258
|
+
if (d.length >= 4 && d[0] === 255 && d[1] === 216) {
|
|
259
|
+
let off = 2;
|
|
260
|
+
while (off + 9 < d.length) {
|
|
261
|
+
if (d[off] !== 255) {
|
|
262
|
+
off++;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
const marker = d[off + 1];
|
|
266
|
+
if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
|
|
267
|
+
const h = d[off + 5] << 8 | d[off + 6];
|
|
268
|
+
const w = d[off + 7] << 8 | d[off + 8];
|
|
269
|
+
return w > 0 && h > 0 ? {
|
|
270
|
+
w,
|
|
271
|
+
h
|
|
272
|
+
} : void 0;
|
|
273
|
+
}
|
|
274
|
+
const len = d[off + 2] << 8 | d[off + 3];
|
|
275
|
+
if (len < 2) break;
|
|
276
|
+
off += 2 + len;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function u32be(d, o) {
|
|
281
|
+
return (d[o] << 24 | d[o + 1] << 16 | d[o + 2] << 8 | d[o + 3]) >>> 0;
|
|
282
|
+
}
|
|
283
|
+
function toRun(r) {
|
|
284
|
+
const underline = r.underline ? "single" : void 0;
|
|
285
|
+
const properties = {
|
|
286
|
+
...r.bold ? { bold: true } : {},
|
|
287
|
+
...r.italic ? { italic: true } : {},
|
|
288
|
+
...underline ? { underline } : {},
|
|
289
|
+
...r.sizePt ? { fontSizePt: pt(r.sizePt) } : {},
|
|
290
|
+
...r.colorHex ? { colorHex: r.colorHex } : {}
|
|
291
|
+
};
|
|
292
|
+
return {
|
|
293
|
+
text: r.text,
|
|
294
|
+
properties
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function toParaProperties(p, breakBefore) {
|
|
298
|
+
const alignment = p.align !== void 0 ? alignmentFrom(p.align) : void 0;
|
|
299
|
+
const level = p.level ?? 0;
|
|
300
|
+
return {
|
|
301
|
+
...breakBefore ? { pageBreakBefore: true } : {},
|
|
302
|
+
...alignment ? { alignment } : {},
|
|
303
|
+
...level > 0 ? { indentLeft: pt(level * LEVEL_INDENT_PT) } : {}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function alignmentFrom(a) {
|
|
307
|
+
switch (a) {
|
|
308
|
+
case 1: return "center";
|
|
309
|
+
case 2: return "right";
|
|
310
|
+
case 3:
|
|
311
|
+
case 6: return "both";
|
|
312
|
+
case 4:
|
|
313
|
+
case 5: return "distribute";
|
|
314
|
+
default: return;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function anchorParagraph(breakBefore) {
|
|
318
|
+
return {
|
|
319
|
+
kind: "paragraph",
|
|
320
|
+
paragraph: {
|
|
321
|
+
properties: breakBefore ? { pageBreakBefore: true } : {},
|
|
322
|
+
runs: [{
|
|
323
|
+
text: ZERO_WIDTH_SPACE,
|
|
324
|
+
properties: {}
|
|
325
|
+
}]
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
var pptReader = {
|
|
330
|
+
id: "ppt",
|
|
331
|
+
produces: "flow",
|
|
332
|
+
supports: new Set([FEATURES.text]),
|
|
333
|
+
sniff: looksLikePpt,
|
|
334
|
+
read: (bytes) => readPpt(bytes)
|
|
335
|
+
};
|
|
336
|
+
//#endregion
|
|
337
|
+
export { pptReader };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface PptRun {
|
|
2
|
+
readonly text: string;
|
|
3
|
+
readonly bold?: boolean;
|
|
4
|
+
readonly italic?: boolean;
|
|
5
|
+
readonly underline?: boolean;
|
|
6
|
+
readonly sizePt?: number;
|
|
7
|
+
readonly colorHex?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PptParagraph {
|
|
10
|
+
readonly runs: ReadonlyArray<PptRun>;
|
|
11
|
+
readonly align?: number;
|
|
12
|
+
readonly level?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PptImage {
|
|
15
|
+
readonly bytes: Uint8Array;
|
|
16
|
+
}
|
|
17
|
+
export interface PptRect {
|
|
18
|
+
readonly x: number;
|
|
19
|
+
readonly y: number;
|
|
20
|
+
readonly w: number;
|
|
21
|
+
readonly h: number;
|
|
22
|
+
}
|
|
23
|
+
export type PptPathCmd = {
|
|
24
|
+
readonly kind: 'move';
|
|
25
|
+
readonly x: number;
|
|
26
|
+
readonly y: number;
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: 'line';
|
|
29
|
+
readonly x: number;
|
|
30
|
+
readonly y: number;
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: 'cubic';
|
|
33
|
+
readonly x1: number;
|
|
34
|
+
readonly y1: number;
|
|
35
|
+
readonly x2: number;
|
|
36
|
+
readonly y2: number;
|
|
37
|
+
readonly x: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: 'close';
|
|
41
|
+
};
|
|
42
|
+
export interface PptCustomGeometry {
|
|
43
|
+
readonly pathWidth: number;
|
|
44
|
+
readonly pathHeight: number;
|
|
45
|
+
readonly commands: ReadonlyArray<PptPathCmd>;
|
|
46
|
+
}
|
|
47
|
+
export interface PptAutoShape {
|
|
48
|
+
readonly shapeType: number;
|
|
49
|
+
readonly fillColorHex?: string;
|
|
50
|
+
readonly lineColorHex?: string;
|
|
51
|
+
readonly geometry?: PptCustomGeometry;
|
|
52
|
+
}
|
|
53
|
+
export interface PptShape {
|
|
54
|
+
readonly rectPt?: PptRect;
|
|
55
|
+
readonly paragraphs?: ReadonlyArray<PptParagraph>;
|
|
56
|
+
readonly image?: PptImage;
|
|
57
|
+
readonly autoShape?: PptAutoShape;
|
|
58
|
+
}
|
|
59
|
+
export interface PptSlide {
|
|
60
|
+
readonly shapes: ReadonlyArray<PptShape>;
|
|
61
|
+
}
|
|
62
|
+
export interface PptContent {
|
|
63
|
+
readonly slides: ReadonlyArray<PptSlide>;
|
|
64
|
+
readonly slideWidthPt?: number;
|
|
65
|
+
readonly slideHeightPt?: number;
|
|
66
|
+
readonly encrypted: boolean;
|
|
67
|
+
}
|
|
68
|
+
export declare function extractPptContent(bytes: Uint8Array): PptContent;
|
|
69
|
+
export declare function paragraphText(p: PptParagraph): string;
|