Skip to content

Commit e9c6d91

Browse files
committed
chore(xml): add ModifyXmlCallback; add sortCollection
1 parent 9927424 commit e9c6d91

File tree

6 files changed

+86
-41
lines changed

6 files changed

+86
-41
lines changed

src/automizer.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { IPresentationProps } from './interfaces/ipresentation-props';
1010
import { PresTemplate } from './interfaces/pres-template';
1111
import { RootPresTemplate } from './interfaces/root-pres-template';
1212
import { Template } from './classes/template';
13-
import { ModifyPresentationCallback, TemplateInfo } from './types/xml-types';
13+
import { ModifyXmlCallback, TemplateInfo } from './types/xml-types';
1414
import { vd } from './helper/general-helper';
1515
import { Master } from './classes/master';
1616
import path from 'path';
@@ -41,7 +41,7 @@ export default class Automizer implements IPresentationProps {
4141
params: AutomizerParams;
4242
status: StatusTracker;
4343

44-
modifyPresentation: ModifyPresentationCallback[];
44+
modifyPresentation: ModifyXmlCallback[];
4545

4646
/**
4747
* Creates an instance of `pptx-automizer`.
@@ -177,7 +177,7 @@ export default class Automizer implements IPresentationProps {
177177
return templateCreationId;
178178
}
179179

180-
public async modify(cb: ModifyPresentationCallback): Promise<this> {
180+
public modify(cb: ModifyXmlCallback): this {
181181
this.modifyPresentation.push(cb);
182182
return this;
183183
}
@@ -284,23 +284,6 @@ export default class Automizer implements IPresentationProps {
284284
);
285285
}
286286

287-
async applyModifyPresentationCallbacks() {
288-
const presentationXml = await XmlHelper.getXmlFromArchive(
289-
await this.rootTemplate.archive,
290-
`ppt/presentation.xml`,
291-
);
292-
293-
for (const cb of this.modifyPresentation) {
294-
cb(presentationXml);
295-
}
296-
297-
await XmlHelper.writeXmlToArchive(
298-
await this.rootTemplate.archive,
299-
`ppt/presentation.xml`,
300-
presentationXml,
301-
);
302-
}
303-
304287
/**
305288
* Write all slides into archive.
306289
*/
@@ -317,6 +300,18 @@ export default class Automizer implements IPresentationProps {
317300
}
318301
}
319302

303+
/**
304+
* Applies all callbacks in this.modifyPresentation-array.
305+
* The callback array can be pushed by this.modify()
306+
*/
307+
async applyModifyPresentationCallbacks(): Promise<void> {
308+
await XmlHelper.modifyXmlInArchive(
309+
this.rootTemplate.archive,
310+
`ppt/presentation.xml`,
311+
this.modifyPresentation,
312+
);
313+
}
314+
320315
/**
321316
* Applies path prefix to given location string.
322317
* @param location path and/or filename

src/dev.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Automizer, {
66
XmlHelper,
77
} from './index';
88
import { vd } from './helper/general-helper';
9+
import ModifyPresentationHelper from './helper/modify-presentation-helper';
910

1011
const automizer = new Automizer({
1112
templateDir: `${__dirname}/../__tests__/pptx-templates`,
@@ -20,29 +21,11 @@ const run = async () => {
2021
.load(`SlideWithImages.pptx`, 'images');
2122

2223
ppt.addSlide('charts', 1);
24+
ppt.addSlide('charts', 2);
2325
ppt.addSlide('images', 1);
2426
ppt.addSlide('images', 2);
2527

26-
ppt.modify((xml: XMLDocument) => {
27-
// Dump before to console
28-
XmlHelper.dump(xml);
29-
30-
const sldIdLst = xml.getElementsByTagName('p:sldIdLst')[0];
31-
const existingSlides = sldIdLst.getElementsByTagName('p:sldId');
32-
33-
// reordering logic here
34-
const order = [3, 2, 1];
35-
let id = 256;
36-
order.forEach((sourceSlideNumber) => {
37-
const slide = existingSlides[sourceSlideNumber - 1];
38-
slide.setAttribute('id', String(id));
39-
sldIdLst.appendChild(slide);
40-
id++;
41-
});
42-
43-
// Dump after to console
44-
XmlHelper.dump(sldIdLst);
45-
});
28+
ppt.modify(ModifyPresentationHelper.sortSlides([3, 1, 2, 4]));
4629

4730
const summary = await ppt.write('reorder.pptx');
4831
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { XmlHelper } from './xml-helper';
2+
import { vd } from './general-helper';
3+
4+
export default class ModifyPresentationHelper {
5+
/**
6+
* Pass an array of slide numbers to define a target sort order.
7+
* First slide starts by 1.
8+
* @order Array of slide numbers, starting by 1
9+
*/
10+
static sortSlides = (order: number[]) => (xml: XMLDocument) => {
11+
order.map((index, i) => order[i]--);
12+
const slides = xml.getElementsByTagName('p:sldId');
13+
const firstId = 256;
14+
XmlHelper.sortCollection(slides, order, (slide: Element, i) => {
15+
slide.setAttribute('id', String(firstId + i));
16+
});
17+
18+
// XmlHelper.dump(
19+
// xml.getElementsByTagName('p:sldId')[0].parentNode as Element,
20+
// );
21+
};
22+
}

src/helper/xml-helper.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
OverrideAttribute,
88
RelationshipAttribute,
99
HelperElement,
10+
ModifyXmlCallback,
1011
} from '../types/xml-types';
1112
import { TargetByRelIdMap } from '../constants/constants';
1213
import { XmlPrettyPrint } from './xml-pretty-print';
@@ -19,6 +20,20 @@ import { XmlTemplateHelper } from './xml-template-helper';
1920
import { vd } from './general-helper';
2021

2122
export class XmlHelper {
23+
static async modifyXmlInArchive(
24+
archive: Promise<JSZip>,
25+
file: string,
26+
callbacks: ModifyXmlCallback[],
27+
): Promise<JSZip> {
28+
const xml = await XmlHelper.getXmlFromArchive(await archive, file);
29+
30+
for (const callback of callbacks) {
31+
callback(xml);
32+
}
33+
34+
return await XmlHelper.writeXmlToArchive(await archive, file, xml);
35+
}
36+
2237
static async getXmlFromArchive(
2338
archive: JSZip,
2439
file: string,
@@ -403,6 +418,29 @@ export class XmlHelper {
403418
}
404419
}
405420

421+
static sortCollection(
422+
collection: HTMLCollectionOf<Element>,
423+
order: number[],
424+
callback?: ModifyXmlCallback,
425+
): void {
426+
if (collection.length === 0) {
427+
return;
428+
}
429+
const parent = collection[0].parentNode;
430+
order.forEach((index, i) => {
431+
if (!collection[index]) {
432+
vd('sortCollection index not found' + index);
433+
return;
434+
}
435+
436+
const item = collection[index];
437+
if (callback) {
438+
callback(item, i);
439+
}
440+
parent.appendChild(item);
441+
});
442+
}
443+
406444
static dump(element: XMLDocument | Element): void {
407445
const s = new XMLSerializer();
408446
const xmlBuffer = s.serializeToString(element);

src/types/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export type AutomizerParams = {
2929
* You can set a path here.
3030
*/
3131
outputDir?: string;
32+
/**
33+
* Buffer unzipped pptx on disk
34+
*/
35+
cacheDir?: string;
3236
rootTemplate?: string;
3337
presTemplates?: string[];
3438
useCreationIds?: boolean;

src/types/xml-types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,7 @@ export type ElementInfo = {
6363
};
6464
};
6565

66-
export type ModifyPresentationCallback = (xml: XMLDocument) => void;
66+
export type ModifyXmlCallback = (
67+
xml: XMLDocument | Element,
68+
index?: number,
69+
) => void;

0 commit comments

Comments
 (0)