Skip to content

Commit a6e3903

Browse files
committed
add ability to create indented lists
1 parent 58b5f0d commit a6e3903

File tree

5 files changed

+133
-3
lines changed

5 files changed

+133
-3
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,30 @@ pres
632632
});
633633
```
634634

635-
# Tipps and Tricks
635+
## Add Bulleted List
636+
637+
You can add a bulleted list to a shape.
638+
639+
```ts
640+
// Remove existing charts, images or shapes from added slide.
641+
const bulletPoints = ['first line', 'second line', 'third line'];
642+
const indentedBulletPoints = ['first line', [ 'indent 1-1', 'indent 1-2', [ 'indent 2-1', 'indent 2-2', ] ], 'second line', 'third line'];
643+
644+
pres.addSlide('general', 2, (slide) => {
645+
slide.modifyElement(
646+
'replaceText', //shape selector
647+
modify.setBulletList(bulletPoints),
648+
);
649+
})
650+
.addSlide('general', 2, (slide) => {
651+
slide.modifyElement(
652+
'replaceText', //shape selector
653+
modify.setBulletList(indentedBulletPoints),
654+
);
655+
});
656+
```
657+
658+
# Tips and Tricks
636659

637660
## Loop through the slides of a presentation
638661

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import Automizer, { modify } from '../src/index';
2+
3+
const bulletPoints = ['first line', 'second line', 'third line'];
4+
const multiLevelBullet = [
5+
'top line 1',
6+
[
7+
'indent 1-1',
8+
'indent 1-2',
9+
[
10+
'indent 2-1',
11+
'indent 2-2',
12+
],
13+
],
14+
'top line 2',
15+
];
16+
17+
test('create presentation, replace bullet list text.', async () => {
18+
const automizer = new Automizer({
19+
templateDir: `${__dirname}/pptx-templates`,
20+
outputDir: `${__dirname}/pptx-output`,
21+
});
22+
23+
const pres = automizer.loadRoot(`RootTemplate.pptx`).load(`TextReplace.pptx`);
24+
25+
const result = await pres
26+
27+
.addSlide('TextReplace.pptx', 2, (slide) => {
28+
slide.modifyElement(
29+
'replaceTextBullet1',
30+
modify.setBulletList(bulletPoints),
31+
);
32+
}).addSlide('TextReplace.pptx', 2, (slide) => {
33+
slide.modifyElement(
34+
'replaceTextBullet1',
35+
modify.setBulletList(multiLevelBullet),
36+
);
37+
})
38+
.write(`replace-bullet-text.test.pptx`);
39+
40+
expect(result.slides).toBe(3);
41+
});

src/helper/modify-shape-helper.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ export default class ModifyShapeHelper {
4040
ModifyTextHelper.setText(text)(element as XmlElement);
4141
};
4242

43+
/**
44+
* Set content to bulleted list of modified shape
45+
*/
46+
static setBulletList =
47+
(list) =>
48+
(element: XmlElement): void => {
49+
ModifyTextHelper.setBulletList(list)(element as XmlElement);
50+
};
51+
4352
/**
4453
* Replace tagged text content within modified shape
4554
*/

src/helper/modify-text-helper.ts

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,61 @@ export default class ModifyTextHelper {
3232
}
3333
};
3434

35+
static setBulletList =
36+
(list) => (element: XmlElement): void => {
37+
const namespaceURIs = {
38+
'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
39+
'p': 'http://schemas.openxmlformats.org/presentationml/2006/main'
40+
};
41+
const doc = element.ownerDocument;
42+
43+
let txBody = element.getElementsByTagName('p:txBody')[0];
44+
if (!txBody) {
45+
txBody = doc.createElementNS(namespaceURIs['p'], 'p:txBody');
46+
element.appendChild(txBody);
47+
} else {
48+
while (txBody.firstChild) {
49+
txBody.removeChild(txBody.firstChild);
50+
}
51+
}
52+
53+
const bodyPr = doc.createElementNS(namespaceURIs['a'], 'a:bodyPr');
54+
txBody.appendChild(bodyPr);
55+
const lstStyle = doc.createElementNS(namespaceURIs['a'], 'a:lstStyle');
56+
txBody.appendChild(lstStyle);
57+
58+
const processList = (items, level) => {
59+
items.forEach((item) => {
60+
if (Array.isArray(item)) {
61+
processList(item, level + 1);
62+
} else {
63+
const p = doc.createElementNS(namespaceURIs['a'], 'a:p');
64+
65+
const pPr = doc.createElementNS(namespaceURIs['a'], 'a:pPr');
66+
if (level > 0) {
67+
pPr.setAttribute('lvl', String(level));
68+
}
69+
p.appendChild(pPr);
70+
71+
const r = doc.createElementNS(namespaceURIs['a'], 'a:r');
72+
73+
const rPr = doc.createElementNS(namespaceURIs['a'], 'a:rPr');
74+
r.appendChild(rPr);
75+
76+
const t = doc.createElementNS(namespaceURIs['a'], 'a:t');
77+
const textNode = doc.createTextNode(String(item));
78+
t.appendChild(textNode);
79+
80+
r.appendChild(t);
81+
p.appendChild(r);
82+
txBody.appendChild(p);
83+
}
84+
});
85+
};
86+
87+
processList(list, 0);
88+
};
89+
3590
static content =
3691
(label: number | string) =>
3792
(element: XmlElement): void => {
@@ -41,7 +96,7 @@ export default class ModifyTextHelper {
4196
};
4297

4398
/**
44-
* Set text style insinde an <a:rPr> element
99+
* Set text style inside an <a:rPr> element
45100
*/
46101
static style =
47102
(style: TextStyle) =>
@@ -71,7 +126,7 @@ export default class ModifyTextHelper {
71126
};
72127

73128
/**
74-
* Set size of text insinde an <a:rPr> element
129+
* Set size of text inside an <a:rPr> element
75130
*/
76131
static setSize =
77132
(size: number) =>

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const setAttribute = ModifyHelper.setAttribute;
4949

5050
const setSolidFill = ModifyShapeHelper.setSolidFill;
5151
const setText = ModifyShapeHelper.setText;
52+
const setBulletList = ModifyShapeHelper.setBulletList;
5253
const replaceText = ModifyShapeHelper.replaceText;
5354
const setPosition = ModifyShapeHelper.setPosition;
5455
const updatePosition = ModifyShapeHelper.updatePosition;
@@ -118,6 +119,7 @@ export const modify = {
118119
setAttribute,
119120
setSolidFill,
120121
setText,
122+
setBulletList,
121123
replaceText,
122124
setPosition,
123125
updatePosition,

0 commit comments

Comments
 (0)