Skip to content

Commit 30c91d7

Browse files
committed
feat: Allow using layout controls in PowerPoint slides using the ph option of addText.
1 parent 9ad27f3 commit 30c91d7

File tree

4 files changed

+126
-93
lines changed

4 files changed

+126
-93
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
- Version 0.5.1:
2+
- Allow using layout controls in PowerPoint slides using the ph option of addText.
13
- Version 0.5.0:
24
- Microsoft Word Document new features:
35
- addText now have 2 new options: superscript and subscript (fixed issue #299).

lib/pptx/genpptx.js

Lines changed: 108 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,123 +1333,148 @@ function makePptx(genobj, new_type, options, gen_private, type_info) {
13331333
// } // Endif.
13341334
// } // Endif.
13351335

1336+
var pNvPr = '<p:nvPr/>'
1337+
if (objs_list[i].options.ph) {
1338+
pNvPr = objs_list[i].options.phIdx
1339+
? '<p:nvPr><p:ph type="' +
1340+
objs_list[i].options.ph +
1341+
'" idx="' +
1342+
objs_list[i].options.phIdx +
1343+
'"/></p:nvPr>'
1344+
: '<p:nvPr><p:ph type="' +
1345+
objs_list[i].options.ph +
1346+
'"/></p:nvPr>'
1347+
} // Endif.
1348+
13361349
if (objs_list[i].type === 'cxn') {
13371350
outString += '<p:cxnSp><p:nvCxnSpPr>'
13381351
outString +=
13391352
'<p:cNvPr id="' +
13401353
(i + 2) +
13411354
'" name="Object ' +
13421355
(i + 1) +
1343-
'"/><p:nvPr/></p:nvCxnSpPr>'
1356+
'"/>' +
1357+
pNvPr +
1358+
'</p:nvCxnSpPr>'
13441359
} else {
13451360
outString += '<p:sp><p:nvSpPr>'
13461361
outString +=
13471362
'<p:cNvPr id="' +
13481363
(i + 2) +
13491364
'" name="Object ' +
13501365
(i + 1) +
1351-
'"/><p:cNvSpPr txBox="1"/><p:nvPr/></p:nvSpPr>'
1366+
'"/><p:cNvSpPr txBox="1"/>' +
1367+
pNvPr +
1368+
'</p:nvSpPr>'
13521369
} // Endif.
13531370

1354-
outString += '<p:spPr>'
1371+
if (objs_list[i].options.ph) {
1372+
outString += '<p:spPr/>'
1373+
} else {
1374+
outString += '<p:spPr>'
13551375

1356-
outString += '<a:xfrm' + locationAttr + '>'
1376+
outString += '<a:xfrm' + locationAttr + '>'
13571377

1358-
outString +=
1359-
'<a:off x="' +
1360-
x +
1361-
'" y="' +
1362-
y +
1363-
'"/><a:ext cx="' +
1364-
cx +
1365-
'" cy="' +
1366-
cy +
1367-
'"/></a:xfrm><a:prstGeom prst="' +
1368-
shapeType.name +
1369-
'">'
1370-
1371-
// string changed to take into account change of shape that you do by moving the little yellow dot
1372-
1373-
if (shapeType.avLst !== {}) {
1374-
outString += '<a:avLst>'
1375-
for (var adj in shapeType.avLst) {
1376-
outString +=
1377-
'<a:gd name="' +
1378-
adj +
1379-
'" fmla="val ' +
1380-
shapeType.avLst[adj] +
1381-
'"/>'
1382-
}
1383-
}
1378+
outString +=
1379+
'<a:off x="' +
1380+
x +
1381+
'" y="' +
1382+
y +
1383+
'"/><a:ext cx="' +
1384+
cx +
1385+
'" cy="' +
1386+
cy +
1387+
'"/></a:xfrm><a:prstGeom prst="' +
1388+
shapeType.name +
1389+
'">'
13841390

1385-
outString += '</a:avLst></a:prstGeom>'
1391+
// string changed to take into account change of shape that you do by moving the little yellow dot
13861392

1387-
if (objs_list[i].options) {
1388-
if (objs_list[i].options.fill) {
1389-
outString += shapes.createColorElements(objs_list[i].options.fill)
1390-
} else {
1391-
outString += '<a:noFill/>'
1392-
} // Endif.
1393+
if (shapeType.avLst !== {}) {
1394+
outString += '<a:avLst>'
1395+
for (var adj in shapeType.avLst) {
1396+
outString +=
1397+
'<a:gd name="' +
1398+
adj +
1399+
'" fmla="val ' +
1400+
shapeType.avLst[adj] +
1401+
'"/>'
1402+
}
1403+
}
13931404

1394-
if (objs_list[i].options.line) {
1395-
var lineAttr = ''
1405+
outString += '</a:avLst></a:prstGeom>'
13961406

1397-
if (objs_list[i].options.line_size) {
1398-
lineAttr +=
1399-
' w="' + objs_list[i].options.line_size * 12700 + '"'
1407+
if (objs_list[i].options) {
1408+
if (objs_list[i].options.fill) {
1409+
outString += shapes.createColorElements(
1410+
objs_list[i].options.fill
1411+
)
1412+
} else {
1413+
outString += '<a:noFill/>'
14001414
} // Endif.
14011415

1402-
// cmpd="dbl"
1416+
if (objs_list[i].options.line) {
1417+
var lineAttr = ''
14031418

1404-
outString += '<a:ln' + lineAttr + '>'
1405-
outString += shapes.createColorElements(objs_list[i].options.line)
1419+
if (objs_list[i].options.line_size) {
1420+
lineAttr +=
1421+
' w="' + objs_list[i].options.line_size * 12700 + '"'
1422+
} // Endif.
14061423

1407-
if (objs_list[i].options.line_head) {
1408-
outString +=
1409-
'<a:headEnd type="' + objs_list[i].options.line_head + '"/>'
1410-
} // Endif.
1424+
// cmpd="dbl"
14111425

1412-
if (objs_list[i].options.line_tail) {
1413-
outString +=
1414-
'<a:tailEnd type="' + objs_list[i].options.line_tail + '"/>'
1415-
} // Endif.
1426+
outString += '<a:ln' + lineAttr + '>'
1427+
outString += shapes.createColorElements(
1428+
objs_list[i].options.line
1429+
)
14161430

1417-
outString += '</a:ln>'
1431+
if (objs_list[i].options.line_head) {
1432+
outString +=
1433+
'<a:headEnd type="' + objs_list[i].options.line_head + '"/>'
1434+
} // Endif.
1435+
1436+
if (objs_list[i].options.line_tail) {
1437+
outString +=
1438+
'<a:tailEnd type="' + objs_list[i].options.line_tail + '"/>'
1439+
} // Endif.
1440+
1441+
outString += '</a:ln>'
1442+
} // Endif.
1443+
} else {
1444+
outString += '<a:noFill/>'
14181445
} // Endif.
1419-
} else {
1420-
outString += '<a:noFill/>'
1421-
} // Endif.
14221446

1423-
if (objs_list[i].options.effects) {
1424-
for (
1425-
var ii = 0, total_size_ii = objs_list[i].options.effects.length;
1426-
ii < total_size_ii;
1427-
ii++
1428-
) {
1429-
switch (objs_list[i].options.effects[ii].type) {
1430-
case 'outerShadow':
1431-
effectsList += generateEffects(
1432-
objs_list[i].options.effects[ii],
1433-
'outerShdw'
1434-
)
1435-
break
1447+
if (objs_list[i].options.effects) {
1448+
for (
1449+
var ii = 0, total_size_ii = objs_list[i].options.effects.length;
1450+
ii < total_size_ii;
1451+
ii++
1452+
) {
1453+
switch (objs_list[i].options.effects[ii].type) {
1454+
case 'outerShadow':
1455+
effectsList += generateEffects(
1456+
objs_list[i].options.effects[ii],
1457+
'outerShdw'
1458+
)
1459+
break
1460+
1461+
case 'innerShadow':
1462+
effectsList += generateEffects(
1463+
objs_list[i].options.effects[ii],
1464+
'innerShdw'
1465+
)
1466+
break
1467+
} // End of switch.
1468+
} // End of for loop.
1469+
} // Endif.
14361470

1437-
case 'innerShadow':
1438-
effectsList += generateEffects(
1439-
objs_list[i].options.effects[ii],
1440-
'innerShdw'
1441-
)
1442-
break
1443-
} // End of switch.
1444-
} // End of for loop.
1445-
} // Endif.
1471+
if (effectsList !== '') {
1472+
outString += '<a:effectLst>' + effectsList + '</a:effectLst>'
1473+
} // Endif.
14461474

1447-
if (effectsList !== '') {
1448-
outString += '<a:effectLst>' + effectsList + '</a:effectLst>'
1475+
outString += '</p:spPr>'
14491476
} // Endif.
14501477

1451-
outString += '</p:spPr>'
1452-
14531478
if (objs_list[i].options) {
14541479
if (objs_list[i].options.align) {
14551480
switch (objs_list[i].options.align) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "officegen",
33
"description": "Office Open XML Generator using Node.js streams. Supporting Microsoft Office 2007 and later Word (docx), PowerPoint (pptx,ppsx) and Excel (xlsx). This module is for all frameworks and environments. No need for any commandline tool - this module is doing everything inside it.",
4-
"version": "0.5.0",
4+
"version": "0.5.1",
55
"author": {
66
"name": "Ziv Barber",
77
"url": "https://github.com/Ziv-Barber"

tests/pptx-layouts.test.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ describe('PPTX Layouts plugin', function() {
165165
// Create a custom layout:
166166
//
167167

168-
pptx.makeNewLayout('1_Title Slide-2lines', {
169-
display: '1_Title Slide-2lines',
168+
pptx.makeNewLayout('my custom layout', {
169+
display: 'my custom layout',
170170
back: {
171171
type: 'solid',
172172
color: 'tx2',
@@ -176,16 +176,22 @@ describe('PPTX Layouts plugin', function() {
176176
'<p:sp><p:nvSpPr><p:cNvPr id="4" name="מלבן 3"><a:extLst><a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}"><a16:creationId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" id="{FCF6DB08-1F1C-44AA-B6F7-C031B856AC29}"/></a:ext></a:extLst></p:cNvPr><p:cNvSpPr/><p:nvPr userDrawn="1"/></p:nvSpPr><p:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="9144000" cy="5143500"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:solidFill><a:schemeClr val="accent4"/></a:solidFill><a:ln><a:noFill/></a:ln></p:spPr><p:style><a:lnRef idx="2"><a:schemeClr val="accent1"><a:shade val="50000"/></a:schemeClr></a:lnRef><a:fillRef idx="1"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="0"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></p:style><p:txBody><a:bodyPr rtlCol="0" anchor="ctr"/><a:lstStyle/><a:p><a:pPr algn="ctr"/><a:endParaRPr lang="en-IL"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="9" name="מלבן 8"><a:extLst><a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}"><a16:creationId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" id="{D005C2FB-DC1A-4D47-B65E-94719652F9D1}"/></a:ext></a:extLst></p:cNvPr><p:cNvSpPr/><p:nvPr userDrawn="1"/></p:nvSpPr><p:spPr><a:xfrm><a:off x="0" y="3425482"/><a:ext cx="9144000" cy="1718017"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:solidFill><a:schemeClr val="accent3"/></a:solidFill><a:ln><a:noFill/></a:ln></p:spPr><p:style><a:lnRef idx="2"><a:schemeClr val="accent1"><a:shade val="50000"/></a:schemeClr></a:lnRef><a:fillRef idx="1"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="0"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></p:style><p:txBody><a:bodyPr rtlCol="0" anchor="ctr"/><a:lstStyle/><a:p><a:pPr algn="ctr"/><a:endParaRPr lang="en-IL"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="2" name="Title 1"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ctrTitle" hasCustomPrompt="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="888901" y="864893"/><a:ext cx="7375868" cy="1441518"/></a:xfrm><a:noFill/></p:spPr><p:txBody><a:bodyPr anchor="t" anchorCtr="0"><a:noAutofit/></a:bodyPr><a:lstStyle><a:lvl1pPr algn="l"><a:defRPr sz="4800" b="1"><a:solidFill><a:schemeClr val="bg1"/></a:solidFill><a:latin typeface="+mj-lt"/><a:ea typeface="Open Sans Semibold" panose="020B0706030804020204" pitchFamily="34" charset="0"/><a:cs typeface="Open Sans Semibold" panose="020B0706030804020204" pitchFamily="34" charset="0"/></a:defRPr></a:lvl1pPr></a:lstStyle><a:p><a:r><a:rPr lang="en-US" sz="4800" dirty="0"/><a:t>Add Title Here</a:t></a:r><a:endParaRPr lang="en-US" dirty="0"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="13" name="Text Placeholder 2"><a:extLst><a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}"><a16:creationId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" id="{6A3C93B3-F38C-45C3-82A7-C60718709D9A}"/></a:ext></a:extLst></p:cNvPr><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="body" idx="32" hasCustomPrompt="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="888901" y="3961326"/><a:ext cx="7375868" cy="646329"/></a:xfrm><a:noFill/></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="0" tIns="45719" rIns="0" bIns="45719" rtlCol="0" anchor="t" anchorCtr="0"><a:spAutoFit/></a:bodyPr><a:lstStyle><a:lvl1pPr marL="0" indent="0"><a:buNone/><a:defRPr lang="en-US" sz="3600" b="1" dirty="0"><a:solidFill><a:schemeClr val="bg1"/></a:solidFill><a:latin typeface="+mj-lt"/><a:ea typeface="Open Sans Semibold" panose="020B0706030804020204" pitchFamily="34" charset="0"/><a:cs typeface="Open Sans Semibold" panose="020B0706030804020204" pitchFamily="34" charset="0"/></a:defRPr></a:lvl1pPr></a:lstStyle><a:p><a:pPr marL="179384" lvl="0" indent="-179384"><a:spcBef><a:spcPct val="0"/></a:spcBef></a:pPr><a:r><a:rPr lang="en-US" dirty="0"/><a:t>Full Name</a:t></a:r></a:p></p:txBody></p:sp>'
177177
})
178178

179+
//
180+
// Create a slide using the custom layout:
181+
//
182+
179183
slide = pptx.makeNewSlide({
180-
useLayout: '1_Title Slide-2lines'
184+
useLayout: 'my custom layout'
181185
})
182186

183-
var layoutCode =
184-
'<p:sp><p:nvSpPr><p:cNvPr id="5" name="Title 4"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ctrTitle"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr lang="en-US" dirty="0"/><a:t>%%text1%%</a:t></a:r><a:br><a:rPr lang="en-US" dirty="0"/></a:br><a:r><a:rPr lang="en-US" dirty="0"/><a:t>%%text2%%</a:t></a:r></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="6" name="Subtitle 5"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="subTitle" idx="32"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:endParaRPr lang="en-US" dirty="0"/></a:p></p:txBody></p:sp>'
185-
layoutCode = layoutCode
186-
.replace(/%%text1%%/, 'Title number 1')
187-
.replace(/%%text2%%/, 'Title number 2')
188-
slide.addDirectXmlCode(layoutCode)
187+
slide.addText('Title text', {
188+
ph: 'ctrTitle'
189+
})
190+
191+
slide.addText('Other text', {
192+
ph: 'subTitle',
193+
phIdx: 32
194+
})
189195

190196
//
191197
// Generate the pptx file:

0 commit comments

Comments
 (0)