ppt-codec 1.5.0 → 1.7.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 +91 -75
- package/dist/base64.cjs +48 -0
- package/dist/base64.d.cts +5 -0
- package/dist/base64.d.ts +5 -0
- package/dist/base64.js +46 -0
- package/dist/diagnostics-CqxAnubw.d.cts +16 -0
- package/dist/diagnostics-CqxAnubw.d.ts +16 -0
- package/dist/diagnostics.cjs +11 -0
- package/dist/diagnostics.d.cts +2 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +9 -0
- package/dist/document/color-scheme.cjs +4 -0
- package/dist/document/color-scheme.d.cts +2 -1
- package/dist/document/color-scheme.d.ts +2 -1
- package/dist/document/color-scheme.js +4 -1
- package/dist/document/master-write.cjs +21 -16
- package/dist/document/master-write.d.cts +2 -1
- package/dist/document/master-write.d.ts +2 -1
- package/dist/document/master-write.js +21 -16
- package/dist/document/notes-write.cjs +15 -7
- package/dist/document/notes-write.d.cts +2 -1
- package/dist/document/notes-write.d.ts +2 -1
- package/dist/document/notes-write.js +15 -7
- package/dist/document/notes.cjs +4 -3
- package/dist/document/notes.js +4 -3
- package/dist/drawing/blips.cjs +81 -0
- package/dist/drawing/blips.d.cts +16 -0
- package/dist/drawing/blips.d.ts +16 -0
- package/dist/drawing/blips.js +77 -0
- package/dist/drawing/properties.cjs +102 -0
- package/dist/drawing/properties.d.cts +29 -0
- package/dist/drawing/properties.d.ts +29 -0
- package/dist/drawing/properties.js +87 -0
- package/dist/drawing/shapes-write.cjs +234 -17
- package/dist/drawing/shapes-write.d.cts +16 -4
- package/dist/drawing/shapes-write.d.ts +16 -4
- package/dist/drawing/shapes-write.js +237 -19
- package/dist/drawing/shapes.cjs +34 -4
- package/dist/drawing/shapes.d.cts +11 -2
- package/dist/drawing/shapes.d.ts +11 -2
- package/dist/drawing/shapes.js +35 -5
- package/dist/index.cjs +48 -3
- package/dist/index.d.cts +12 -8
- package/dist/index.d.ts +12 -8
- package/dist/index.js +11 -7
- package/dist/ole/embedded-write.cjs +66 -0
- package/dist/ole/embedded-write.d.cts +12 -0
- package/dist/ole/embedded-write.d.ts +12 -0
- package/dist/ole/embedded-write.js +63 -0
- package/dist/ole/embedded.cjs +66 -0
- package/dist/ole/embedded.d.cts +12 -0
- package/dist/ole/embedded.d.ts +12 -0
- package/dist/ole/embedded.js +63 -0
- package/dist/read.cjs +145 -22
- package/dist/read.d.cts +13 -5
- package/dist/read.d.ts +13 -5
- package/dist/read.js +148 -26
- package/dist/record/types.cjs +28 -0
- package/dist/record/types.d.cts +15 -1
- package/dist/record/types.d.ts +15 -1
- package/dist/record/types.js +15 -1
- package/dist/stream/current-user.cjs +1 -0
- package/dist/stream/current-user.d.cts +2 -1
- package/dist/stream/current-user.d.ts +2 -1
- package/dist/stream/current-user.js +1 -1
- package/dist/units.cjs +10 -0
- package/dist/units.d.cts +4 -1
- package/dist/units.d.ts +4 -1
- package/dist/units.js +8 -1
- package/dist/write.cjs +137 -38
- package/dist/write.d.cts +14 -5
- package/dist/write.d.ts +14 -5
- package/dist/write.js +137 -38
- package/package.json +2 -1
package/dist/write.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { base64ToBytes } from "./base64.js";
|
|
1
2
|
import { PptUnsupportedContentError } from "./errors.js";
|
|
2
3
|
import { RT_Document, RT_Slide } from "./record/types.js";
|
|
3
4
|
import { collectFontFamilies } from "./content-write.js";
|
|
5
|
+
import { NOOP_PPT_DIAGNOSTIC_SINK } from "./diagnostics.js";
|
|
4
6
|
import { concatBytes, writeContainer } from "./record/write.js";
|
|
5
7
|
import { writeDocumentAtom } from "./document/document-atom-write.js";
|
|
6
8
|
import { writeEnvironment } from "./document/fonts-write.js";
|
|
7
|
-
import {
|
|
9
|
+
import { isBlipFormat, writeDrawingGroupContainer } from "./drawing/blips.js";
|
|
8
10
|
import { CURRENT_USER_STREAM, POWERPOINT_DOCUMENT_STREAM, SUMMARY_INFORMATION_STREAM } from "./read.js";
|
|
11
|
+
import { writeSlideDrawing } from "./drawing/shapes-write.js";
|
|
9
12
|
import { writeMainMaster, writeMasterListWithText, writeSlideAtomForSlide } from "./document/master-write.js";
|
|
10
13
|
import { writeNotesListWithText } from "./document/notes-list-write.js";
|
|
11
14
|
import { writeNotesContainer } from "./document/notes-write.js";
|
|
@@ -13,6 +16,7 @@ import { writeSlideListWithText } from "./document/slide-list-write.js";
|
|
|
13
16
|
import { layoutMetadataToSummaryInformation as layoutMetadataToSummaryInformation$1 } from "./metadata.js";
|
|
14
17
|
import { writeCurrentUserAtom } from "./stream/current-user-write.js";
|
|
15
18
|
import { writePersistDirectoryAtom, writeUserEditAtom } from "./stream/persist-write.js";
|
|
19
|
+
import { writeExObjListContainer, writeExOleObjStg, writeOleClientData } from "./ole/embedded-write.js";
|
|
16
20
|
import { hasSummaryInformationFields, writeCompoundFile, writeSummaryInformationStream } from "archive-codec";
|
|
17
21
|
import { flattenTree } from "document-schema.js";
|
|
18
22
|
//#region src/write.ts
|
|
@@ -31,65 +35,160 @@ function requireOneSlideSize(slides) {
|
|
|
31
35
|
for (const slide of slides) if (slide.size.widthPt !== first.widthPt || slide.size.heightPt !== first.heightPt) throw new PptUnsupportedContentError(`ppt-codec's writer cannot express per-slide sizes: slide sizes ${JSON.stringify(first)} and ${JSON.stringify(slide.size)} both appear, but [MS-PPT]'s DocumentAtom states exactly one slide size for the whole presentation`);
|
|
32
36
|
return first;
|
|
33
37
|
}
|
|
34
|
-
function writeSlideContainer(shapes, notesIdRef,
|
|
35
|
-
|
|
38
|
+
function writeSlideContainer(shapes, notesIdRef, context, clientDataFor) {
|
|
39
|
+
const drawing = writeSlideDrawing(shapes.map((shape) => ({
|
|
40
|
+
shape,
|
|
41
|
+
clientData: clientDataFor(shape)
|
|
42
|
+
})), context);
|
|
43
|
+
return {
|
|
44
|
+
bytes: writeContainer(RT_Slide, [writeSlideAtomForSlide(notesIdRef), drawing.bytes]),
|
|
45
|
+
shapeCount: drawing.shapeCount,
|
|
46
|
+
maxSpid: drawing.maxSpid
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function planOleEmbeds(slides, serialise, firstPersistId) {
|
|
50
|
+
const embeds = [];
|
|
51
|
+
const persistObjects = [];
|
|
52
|
+
const clientDataByShape = /* @__PURE__ */ new Map();
|
|
53
|
+
if (serialise !== void 0) for (const slide of slides) for (const shape of slide.shapes) {
|
|
54
|
+
const embedBlock = shape.blocks.find((block) => block.kind === "embeddedObject");
|
|
55
|
+
if (embedBlock === void 0) continue;
|
|
56
|
+
const storageBytes = serialise(embedBlock.document);
|
|
57
|
+
if (storageBytes === void 0) continue;
|
|
58
|
+
const exObjId = embeds.length + 1;
|
|
59
|
+
const persistId = firstPersistId + persistObjects.length;
|
|
60
|
+
embeds.push({
|
|
61
|
+
exObjId,
|
|
62
|
+
persistIdRef: persistId,
|
|
63
|
+
objectKind: embedBlock.objectKind
|
|
64
|
+
});
|
|
65
|
+
persistObjects.push({
|
|
66
|
+
persistId,
|
|
67
|
+
bytes: writeExOleObjStg(storageBytes)
|
|
68
|
+
});
|
|
69
|
+
clientDataByShape.set(shape, writeOleClientData(exObjId));
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
embeds,
|
|
73
|
+
persistObjects,
|
|
74
|
+
clientDataFor: (shape) => clientDataByShape.get(shape)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function planBlipStore(slides) {
|
|
78
|
+
const blips = [];
|
|
79
|
+
const pibByKey = /* @__PURE__ */ new Map();
|
|
80
|
+
for (const slide of slides) for (const shape of slide.shapes) for (const block of shape.blocks) {
|
|
81
|
+
if (block.kind !== "image" || !isBlipFormat(block.format)) continue;
|
|
82
|
+
const key = `${block.format}:${block.base64}`;
|
|
83
|
+
if (!pibByKey.has(key)) {
|
|
84
|
+
pibByKey.set(key, blips.length + 1);
|
|
85
|
+
blips.push({
|
|
86
|
+
format: block.format,
|
|
87
|
+
bytes: base64ToBytes(block.base64)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
blips,
|
|
93
|
+
pibOf: (image) => {
|
|
94
|
+
const pib = pibByKey.get(`${image.format}:${image.base64}`);
|
|
95
|
+
if (pib === void 0) throw new PptUnsupportedContentError("internal error: an image block reached the drawing writer without first being collected into the document's blip store");
|
|
96
|
+
return pib;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
36
99
|
}
|
|
37
|
-
function writePptStreams(document) {
|
|
100
|
+
function writePptStreams(document, options = {}) {
|
|
101
|
+
options.signal?.throwIfAborted();
|
|
38
102
|
const { slides } = document;
|
|
39
103
|
const size = requireOneSlideSize(slides);
|
|
104
|
+
const sink = options.sink ?? NOOP_PPT_DIAGNOSTIC_SINK;
|
|
40
105
|
const fontNames = collectFontFamilies(slides.map((slide) => slide.shapes.flatMap((shape) => shape.blocks)));
|
|
41
106
|
const fontIndexOf = (family) => {
|
|
42
107
|
const index = fontNames.indexOf(family);
|
|
43
108
|
if (index === -1) throw new PptUnsupportedContentError(`font family '${family}' was not collected into the document's font table before writing`);
|
|
44
109
|
return index;
|
|
45
110
|
};
|
|
111
|
+
const store = planBlipStore(slides);
|
|
112
|
+
const strict = options.onUnwritableBlock === "throw";
|
|
113
|
+
const contextFor = (location) => ({
|
|
114
|
+
fontIndexOf,
|
|
115
|
+
blipIndexOf: store.pibOf,
|
|
116
|
+
sink,
|
|
117
|
+
strict,
|
|
118
|
+
location
|
|
119
|
+
});
|
|
46
120
|
const slidePersistRefs = slides.map((_slide, index) => ({
|
|
47
121
|
persistIdRef: FIRST_SLIDE_PERSIST_ID + index,
|
|
48
122
|
slideId: FIRST_SLIDE_ID + index
|
|
49
123
|
}));
|
|
124
|
+
const notesIdRefs = slides.map((slide, index) => slide.notes.length === 0 ? NO_NOTES_ID_REF : FIRST_NOTES_ID + slides.slice(0, index).filter((earlier) => earlier.notes.length > 0).length);
|
|
125
|
+
const notesCount = notesIdRefs.filter((id) => id !== NO_NOTES_ID_REF).length;
|
|
126
|
+
const oleEmbeds = planOleEmbeds(slides, options.serialiseEmbeddedObject, FIRST_SLIDE_PERSIST_ID + slides.length + notesCount);
|
|
127
|
+
let shapeCount = 0;
|
|
128
|
+
let maxSpid = 0;
|
|
129
|
+
let drawingCount = 0;
|
|
130
|
+
const account = (drawing) => {
|
|
131
|
+
shapeCount += drawing.shapeCount;
|
|
132
|
+
maxSpid = Math.max(maxSpid, drawing.maxSpid);
|
|
133
|
+
drawingCount += 1;
|
|
134
|
+
};
|
|
135
|
+
const mainMaster = writeMainMaster(size, contextFor("the main master"));
|
|
136
|
+
account(mainMaster);
|
|
137
|
+
const slideContainers = slides.map((slide, index) => {
|
|
138
|
+
const ref = slidePersistRefs[index];
|
|
139
|
+
const notesIdRef = notesIdRefs[index];
|
|
140
|
+
if (ref === void 0 || notesIdRef === void 0) throw new PptUnsupportedContentError("internal error: slide persist reference missing for a slide being written");
|
|
141
|
+
const container = writeSlideContainer(slide.shapes, notesIdRef, contextFor(`slide ${index + 1}`), oleEmbeds.clientDataFor);
|
|
142
|
+
account(container);
|
|
143
|
+
return {
|
|
144
|
+
persistId: ref.persistIdRef,
|
|
145
|
+
bytes: container.bytes
|
|
146
|
+
};
|
|
147
|
+
});
|
|
50
148
|
const notesPersists = [];
|
|
51
149
|
const notesContainers = [];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
150
|
+
slides.forEach((slide, index) => {
|
|
151
|
+
const notesId = notesIdRefs[index];
|
|
152
|
+
if (notesId === void 0 || notesId === NO_NOTES_ID_REF) return;
|
|
153
|
+
const persistIdRef = FIRST_SLIDE_PERSIST_ID + slides.length + notesPersists.length;
|
|
55
154
|
notesPersists.push({
|
|
56
|
-
persistIdRef
|
|
155
|
+
persistIdRef,
|
|
57
156
|
notesId
|
|
58
157
|
});
|
|
59
|
-
|
|
60
|
-
|
|
158
|
+
const container = writeNotesContainer(FIRST_SLIDE_ID + index, slide.notes, size, contextFor(`slide ${index + 1}'s speaker notes`));
|
|
159
|
+
account(container);
|
|
160
|
+
notesContainers.push({
|
|
161
|
+
persistId: persistIdRef,
|
|
162
|
+
bytes: container.bytes
|
|
163
|
+
});
|
|
61
164
|
});
|
|
62
165
|
const environment = writeEnvironment(fontNames);
|
|
63
166
|
const documentChildren = [writeDocumentAtom(size)];
|
|
167
|
+
const exObjList = writeExObjListContainer(oleEmbeds.embeds);
|
|
168
|
+
if (exObjList !== void 0) documentChildren.push(exObjList);
|
|
64
169
|
if (environment !== void 0) documentChildren.push(environment);
|
|
170
|
+
documentChildren.push(writeDrawingGroupContainer(store.blips, {
|
|
171
|
+
spidMax: maxSpid,
|
|
172
|
+
shapeCount,
|
|
173
|
+
drawingCount
|
|
174
|
+
}));
|
|
65
175
|
documentChildren.push(writeMasterListWithText(MASTER_PERSIST_ID));
|
|
66
176
|
documentChildren.push(writeSlideListWithText(slidePersistRefs));
|
|
67
177
|
if (notesPersists.length > 0) documentChildren.push(writeNotesListWithText(notesPersists));
|
|
68
178
|
const documentContainer = writeContainer(RT_Document, documentChildren);
|
|
69
|
-
const persistObjects = [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
persistObjects
|
|
81
|
-
|
|
82
|
-
bytes: writeSlideContainer(slide.shapes, notesIdRef, fontIndexOf)
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
notesPersists.forEach((persist, index) => {
|
|
86
|
-
const bytes = notesContainers[index];
|
|
87
|
-
if (bytes === void 0) throw new PptUnsupportedContentError("internal error: notes container missing for a notes persist reference");
|
|
88
|
-
persistObjects.push({
|
|
89
|
-
persistId: persist.persistIdRef,
|
|
90
|
-
bytes
|
|
91
|
-
});
|
|
92
|
-
});
|
|
179
|
+
const persistObjects = [
|
|
180
|
+
{
|
|
181
|
+
persistId: DOCUMENT_PERSIST_ID,
|
|
182
|
+
bytes: documentContainer
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
persistId: MASTER_PERSIST_ID,
|
|
186
|
+
bytes: mainMaster.bytes
|
|
187
|
+
},
|
|
188
|
+
...slideContainers,
|
|
189
|
+
...notesContainers,
|
|
190
|
+
...oleEmbeds.persistObjects
|
|
191
|
+
];
|
|
93
192
|
const persistEntries = [];
|
|
94
193
|
let offset = 0;
|
|
95
194
|
for (const object of persistObjects) {
|
|
@@ -115,8 +214,8 @@ function writePptStreams(document) {
|
|
|
115
214
|
powerPointDocumentStream: concatBytes(...persistObjects.map((object) => object.bytes), persistDirectory, userEdit)
|
|
116
215
|
};
|
|
117
216
|
}
|
|
118
|
-
function writePptContent(document) {
|
|
119
|
-
const { currentUserStream, powerPointDocumentStream } = writePptStreams(document);
|
|
217
|
+
function writePptContent(document, options = {}) {
|
|
218
|
+
const { currentUserStream, powerPointDocumentStream } = writePptStreams(document, options);
|
|
120
219
|
const streams = [{
|
|
121
220
|
path: CURRENT_USER_STREAM,
|
|
122
221
|
bytes: currentUserStream
|
|
@@ -130,13 +229,13 @@ function writePptContent(document) {
|
|
|
130
229
|
});
|
|
131
230
|
return writeCompoundFile(streams);
|
|
132
231
|
}
|
|
133
|
-
function writePpt(tree) {
|
|
232
|
+
function writePpt(tree, options = {}) {
|
|
134
233
|
const content = flattenTree(tree);
|
|
135
234
|
if (content.kind !== "presentation") throw new PptUnsupportedContentError(`ppt-codec's writer only writes presentation documents; got a '${content.kind}' document`);
|
|
136
235
|
return writePptContent({
|
|
137
236
|
metadata: content.metadata,
|
|
138
237
|
slides: content.slides
|
|
139
|
-
});
|
|
238
|
+
}, options);
|
|
140
239
|
}
|
|
141
240
|
//#endregion
|
|
142
241
|
export { writePpt, writePptContent, writePptStreams };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ppt-codec",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Hand-written PowerPoint 97-2003 binary (.ppt, [MS-PPT]) reader and writer against the shared document-schema.js content pivot.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"packageManager": "pnpm@11.6.0",
|
|
80
80
|
"dependencies": {
|
|
81
81
|
"archive-codec": "1.11.0",
|
|
82
|
+
"byte-codec": "1.5.0",
|
|
82
83
|
"document-schema.js": "7.11.0"
|
|
83
84
|
},
|
|
84
85
|
"devDependencies": {
|