pptxtojson 0.0.10 → 0.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptxtojson",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
package/src/pptxtojson.js CHANGED
@@ -76,8 +76,8 @@ async function readXmlFile(zip, filename) {
76
76
  async function getContentTypes(zip) {
77
77
  const ContentTypesJson = await readXmlFile(zip, '[Content_Types].xml')
78
78
  const subObj = ContentTypesJson['Types']['Override']
79
- const slidesLocArray = []
80
- const slideLayoutsLocArray = []
79
+ let slidesLocArray = []
80
+ let slideLayoutsLocArray = []
81
81
 
82
82
  for (const item of subObj) {
83
83
  switch (item['attrs']['ContentType']) {
@@ -90,6 +90,15 @@ async function getContentTypes(zip) {
90
90
  default:
91
91
  }
92
92
  }
93
+
94
+ const sortSlideXml = (p1, p2) => {
95
+ const n1 = +/(\d+)\.xml/.exec(p1)[1]
96
+ const n2 = +/(\d+)\.xml/.exec(p2)[1]
97
+ return n1 - n2
98
+ }
99
+ slidesLocArray = slidesLocArray.sort(sortSlideXml)
100
+ slideLayoutsLocArray = slideLayoutsLocArray.sort(sortSlideXml)
101
+
93
102
  return {
94
103
  slides: slidesLocArray,
95
104
  slideLayouts: slideLayoutsLocArray,
@@ -196,6 +205,8 @@ async function processSingleSlide(zip, sldFileName) {
196
205
  const slideMasterResFilename = masterFilename.replace('slideMasters/slideMaster', 'slideMasters/_rels/slideMaster') + '.rels'
197
206
  const slideMasterResContent = await readXmlFile(zip, slideMasterResFilename)
198
207
  relationshipArray = slideMasterResContent['Relationships']['Relationship']
208
+
209
+ let themeFilename = ''
199
210
  const masterResObj = {}
200
211
  if (relationshipArray.constructor === Array) {
201
212
  for (const relationshipArrayItem of relationshipArray) {
@@ -210,6 +221,35 @@ async function processSingleSlide(zip, sldFileName) {
210
221
  }
211
222
  }
212
223
  }
224
+ else {
225
+ themeFilename = relationshipArray['attrs']['Target'].replace('../', 'ppt/')
226
+ }
227
+
228
+ const themeResObj = {}
229
+ if (themeFilename) {
230
+ const themeName = themeFilename.split('/').pop()
231
+ const themeResFileName = themeFilename.replace(themeName, '_rels/' + themeName) + '.rels'
232
+ const themeResContent = await readXmlFile(zip, themeResFileName)
233
+ if (themeResContent) {
234
+ relationshipArray = themeResContent['Relationships']['Relationship']
235
+ if (relationshipArray) {
236
+ if (relationshipArray.constructor === Array) {
237
+ for (const relationshipArrayItem of relationshipArray) {
238
+ themeResObj[relationshipArrayItem['attrs']['Id']] = {
239
+ 'type': relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
240
+ 'target': relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
241
+ }
242
+ }
243
+ }
244
+ else {
245
+ themeResObj[relationshipArray['attrs']['Id']] = {
246
+ 'type': relationshipArray['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
247
+ 'target': relationshipArray['attrs']['Target'].replace('../', 'ppt/')
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
213
253
 
214
254
  const diagramResObj = {}
215
255
  let digramFileContent = {}
@@ -257,6 +297,7 @@ async function processSingleSlide(zip, sldFileName) {
257
297
  layoutResObj: layoutResObj,
258
298
  masterResObj: masterResObj,
259
299
  themeContent: themeContent,
300
+ themeResObj: themeResObj,
260
301
  digramFileContent: digramFileContent,
261
302
  diagramResObj: diagramResObj,
262
303
  defaultTextStyle: defaultTextStyle,
@@ -343,6 +384,9 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj) {
343
384
  case 'p:grpSp':
344
385
  json = await processGroupSpNode(nodeValue, warpObj)
345
386
  break
387
+ case 'mc:AlternateContent':
388
+ json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj)
389
+ break
346
390
  default:
347
391
  }
348
392
 
@@ -420,8 +464,55 @@ function processSpNode(node, warpObj) {
420
464
  function processCxnSpNode(node, warpObj) {
421
465
  const id = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['id']
422
466
  const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
467
+ const idx = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['idx']
468
+ const type = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
469
+
470
+ return genShape(node, undefined, undefined, id, name, idx, type, warpObj)
471
+ }
472
+
473
+ function shapeArc(cX, cY, rX, rY, stAng, endAng, isClose) {
474
+ let dData
475
+ let angle = stAng
476
+ if (endAng >= stAng) {
477
+ while (angle <= endAng) {
478
+ const radians = angle * (Math.PI / 180)
479
+ const x = cX + Math.cos(radians) * rX
480
+ const y = cY + Math.sin(radians) * rY
481
+ if (angle === stAng) {
482
+ dData = ' M' + x + ' ' + y
483
+ }
484
+ dData += ' L' + x + ' ' + y
485
+ angle++
486
+ }
487
+ }
488
+ else {
489
+ while (angle > endAng) {
490
+ const radians = angle * (Math.PI / 180)
491
+ const x = cX + Math.cos(radians) * rX
492
+ const y = cY + Math.sin(radians) * rY
493
+ if (angle === stAng) {
494
+ dData = ' M ' + x + ' ' + y
495
+ }
496
+ dData += ' L ' + x + ' ' + y
497
+ angle--
498
+ }
499
+ }
500
+ dData += (isClose ? ' z' : '')
501
+ return dData
502
+ }
423
503
 
424
- return genShape(node, undefined, undefined, id, name, undefined, undefined, warpObj)
504
+ function getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode) {
505
+ let anchor = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
506
+ if (anchor) {
507
+ anchor = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
508
+ if (anchor) {
509
+ anchor = getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
510
+ if (anchor) {
511
+ anchor = 't'
512
+ }
513
+ }
514
+ }
515
+ return (anchor === 'ctr') ? 'mid' : ((anchor === 'b') ? 'down' : 'up')
425
516
  }
426
517
 
427
518
  function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, warpObj) {
@@ -431,6 +522,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
431
522
  const slideMasterXfrmNode = getTextByPathList(slideMasterSpNode, xfrmList)
432
523
 
433
524
  const shapType = getTextByPathList(node, ['p:spPr', 'a:prstGeom', 'attrs', 'prst'])
525
+ const custShapType = getTextByPathList(node, ['p:spPr', 'a:custGeom'])
434
526
 
435
527
  const { top, left } = getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode)
436
528
  const { width, height } = getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode)
@@ -460,6 +552,193 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
460
552
  const { borderColor, borderWidth, borderType } = getBorder(node, type)
461
553
  const fillColor = getShapeFill(node) || ''
462
554
 
555
+ const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
556
+
557
+ if (custShapType) {
558
+ const pathLstNode = getTextByPathList(custShapType, ['a:pathLst'])
559
+ const pathNodes = getTextByPathList(pathLstNode, ['a:path'])
560
+ const maxX = parseInt(pathNodes['attrs']['w'])
561
+ const maxY = parseInt(pathNodes['attrs']['h'])
562
+ const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
563
+ const cx = parseInt(ext['cx']) * FACTOR
564
+ const cy = parseInt(ext['cy']) * FACTOR
565
+ const w = parseInt(ext['cx']) * FACTOR
566
+ const h = parseInt(ext['cy']) * FACTOR
567
+ const cX = (1 / maxX) * w
568
+ const cY = (1 / maxY) * h
569
+ let d = ''
570
+
571
+ let moveToNode = getTextByPathList(pathNodes, ['a:moveTo'])
572
+
573
+ const lnToNodes = pathNodes['a:lnTo']
574
+ let cubicBezToNodes = pathNodes['a:cubicBezTo']
575
+ const arcToNodes = pathNodes['a:arcTo']
576
+ let closeNode = getTextByPathList(pathNodes, ['a:close'])
577
+ if (!Array.isArray(moveToNode)) {
578
+ moveToNode = [moveToNode]
579
+ }
580
+
581
+ const multiSapeAry = []
582
+ if (moveToNode.length > 0) {
583
+ // a:moveTo
584
+ Object.keys(moveToNode).forEach(key => {
585
+ const moveToPtNode = moveToNode[key]['a:pt']
586
+ if (moveToPtNode) {
587
+ Object.keys(moveToPtNode).forEach(key2 => {
588
+ const moveToNoPt = moveToPtNode[key2]
589
+ const spX = moveToNoPt['attrs', 'x']
590
+ const spY = moveToNoPt['attrs', 'y']
591
+
592
+ multiSapeAry.push({
593
+ type: 'movto',
594
+ x: spX,
595
+ y: spY,
596
+ })
597
+ })
598
+ }
599
+ })
600
+ // a:lnTo
601
+ if (lnToNodes) {
602
+ Object.keys(lnToNodes).forEach(key => {
603
+ const lnToPtNode = lnToNodes[key]['a:pt']
604
+ if (lnToPtNode) {
605
+ Object.keys(lnToPtNode).forEach(key2 => {
606
+ const lnToNoPt = lnToPtNode[key2]
607
+ const ptX = lnToNoPt['attrs', 'x']
608
+ const ptY = lnToNoPt['attrs', 'y']
609
+ multiSapeAry.push({
610
+ type: 'lnto',
611
+ x: ptX,
612
+ y: ptY,
613
+ })
614
+ })
615
+ }
616
+ })
617
+ }
618
+ // a:cubicBezTo
619
+ if (cubicBezToNodes) {
620
+
621
+ const cubicBezToPtNodesAry = []
622
+ if (!Array.isArray(cubicBezToNodes)) {
623
+ cubicBezToNodes = [cubicBezToNodes]
624
+ }
625
+ Object.keys(cubicBezToNodes).forEach(key => {
626
+ cubicBezToPtNodesAry.push(cubicBezToNodes[key]['a:pt'])
627
+ })
628
+
629
+ cubicBezToPtNodesAry.forEach(key2 => {
630
+ const pts_ary = []
631
+ key2.forEach(pt => {
632
+ const pt_obj = {
633
+ x: pt['attrs']['x'],
634
+ y: pt['attrs']['y'],
635
+ }
636
+ pts_ary.push(pt_obj)
637
+ })
638
+ multiSapeAry.push({
639
+ type: 'cubicBezTo',
640
+ cubBzPt: pts_ary
641
+ })
642
+ })
643
+ }
644
+ // a:arcTo
645
+ if (arcToNodes) {
646
+ const arcToNodesAttrs = arcToNodes['attrs']
647
+ const hR = arcToNodesAttrs['hR']
648
+ const wR = arcToNodesAttrs['wR']
649
+ const stAng = arcToNodesAttrs['stAng']
650
+ const swAng = arcToNodesAttrs['swAng']
651
+ let shftX = 0
652
+ let shftY = 0
653
+ const arcToPtNode = getTextByPathList(arcToNodes, ['a:pt', 'attrs'])
654
+ if (arcToPtNode) {
655
+ shftX = arcToPtNode['x']
656
+ shftY = arcToPtNode['y']
657
+ }
658
+
659
+ multiSapeAry.push({
660
+ type: 'arcTo',
661
+ hR: hR,
662
+ wR: wR,
663
+ stAng: stAng,
664
+ swAng: swAng,
665
+ shftX: shftX,
666
+ shftY: shftY,
667
+ })
668
+
669
+ }
670
+ // a:close
671
+ if (closeNode) {
672
+ if (!Array.isArray(closeNode)) closeNode = [closeNode]
673
+ Object.keys(closeNode).forEach(() => {
674
+ multiSapeAry.push({
675
+ type: 'close',
676
+ })
677
+ })
678
+ }
679
+
680
+ let k = 0
681
+ while (k < multiSapeAry.length) {
682
+
683
+ if (multiSapeAry[k].type === 'movto') {
684
+ const spX = parseInt(multiSapeAry[k].x) * cX
685
+ const spY = parseInt(multiSapeAry[k].y) * cY
686
+ d += ' M' + spX + ',' + spY
687
+ }
688
+ else if (multiSapeAry[k].type === 'lnto') {
689
+ const Lx = parseInt(multiSapeAry[k].x) * cX
690
+ const Ly = parseInt(multiSapeAry[k].y) * cY
691
+ d += ' L' + Lx + ',' + Ly
692
+ }
693
+ else if (multiSapeAry[k].type === 'cubicBezTo') {
694
+ const Cx1 = parseInt(multiSapeAry[k].cubBzPt[0].x) * cX
695
+ const Cy1 = parseInt(multiSapeAry[k].cubBzPt[0].y) * cY
696
+ const Cx2 = parseInt(multiSapeAry[k].cubBzPt[1].x) * cX
697
+ const Cy2 = parseInt(multiSapeAry[k].cubBzPt[1].y) * cY
698
+ const Cx3 = parseInt(multiSapeAry[k].cubBzPt[2].x) * cX
699
+ const Cy3 = parseInt(multiSapeAry[k].cubBzPt[2].y) * cY
700
+ d += ' C' + Cx1 + ',' + Cy1 + ' ' + Cx2 + ',' + Cy2 + ' ' + Cx3 + ',' + Cy3
701
+ }
702
+ else if (multiSapeAry[k].type === 'arcTo') {
703
+ const hR = parseInt(multiSapeAry[k].hR) * cX
704
+ const wR = parseInt(multiSapeAry[k].wR) * cY
705
+ const stAng = parseInt(multiSapeAry[k].stAng) / 60000
706
+ const swAng = parseInt(multiSapeAry[k].swAng) / 60000
707
+ const endAng = stAng + swAng
708
+ d += shapeArc(wR, hR, wR, hR, stAng, endAng, false)
709
+ }
710
+ else if (multiSapeAry[k].type === 'close') {
711
+ d += 'z'
712
+ }
713
+ k++
714
+ }
715
+ }
716
+
717
+ return {
718
+ type: 'shape',
719
+ left,
720
+ top,
721
+ width,
722
+ height,
723
+ cx,
724
+ cy,
725
+ borderColor,
726
+ borderWidth,
727
+ borderType,
728
+ fillColor,
729
+ content,
730
+ isFlipV,
731
+ isFlipH,
732
+ rotate,
733
+ shapType: 'custom',
734
+ vAlign,
735
+ path: d,
736
+ id,
737
+ name,
738
+ idx,
739
+ }
740
+ }
741
+
463
742
  if (shapType) {
464
743
  const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
465
744
  const cx = parseInt(ext['cx']) * FACTOR
@@ -482,6 +761,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
482
761
  isFlipH,
483
762
  rotate,
484
763
  shapType,
764
+ vAlign,
485
765
  id,
486
766
  name,
487
767
  idx,
@@ -502,6 +782,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
502
782
  isFlipH,
503
783
  rotate: txtRotate,
504
784
  content,
785
+ vAlign,
505
786
  id,
506
787
  name,
507
788
  idx,
@@ -515,28 +796,8 @@ async function processPicNode(node, warpObj) {
515
796
  const zip = warpObj['zip']
516
797
  const imgArrayBuffer = await zip.file(imgName).async('arraybuffer')
517
798
  const xfrmNode = node['p:spPr']['a:xfrm']
518
- let mimeType = ''
519
799
 
520
- switch (imgFileExt) {
521
- case 'jpg':
522
- case 'jpeg':
523
- mimeType = 'image/jpeg'
524
- break
525
- case 'png':
526
- mimeType = 'image/png'
527
- break
528
- case 'gif':
529
- mimeType = 'image/gif'
530
- break
531
- case 'emf':
532
- mimeType = 'image/x-emf'
533
- break
534
- case 'wmf':
535
- mimeType = 'image/x-wmf'
536
- break
537
- default:
538
- mimeType = 'image/*'
539
- }
800
+ const mimeType = getMimeType(imgFileExt)
540
801
  const { top, left } = getPosition(xfrmNode, undefined, undefined)
541
802
  const { width, height } = getSize(xfrmNode, undefined, undefined)
542
803
  const src = `data:${mimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
@@ -570,6 +831,11 @@ async function processGraphicFrameNode(node, warpObj) {
570
831
  case 'http://schemas.openxmlformats.org/drawingml/2006/diagram':
571
832
  result = genDiagram(node, warpObj)
572
833
  break
834
+ case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
835
+ let oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'mc:AlternateContent', 'mc:Fallback', 'p:oleObj'])
836
+ if (!oleObjNode) oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'p:oleObj'])
837
+ else processGroupSpNode(oleObjNode, warpObj)
838
+ break
573
839
  default:
574
840
  }
575
841
  return result
@@ -587,7 +853,26 @@ function genTextBody(textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, w
587
853
  let isList = ''
588
854
 
589
855
  for (const pNode of pNodes) {
590
- const rNode = pNode['a:r']
856
+ let rNode = pNode['a:r']
857
+ let fldNode = pNode['a:fld']
858
+ let brNode = pNode['a:br']
859
+ if (rNode) {
860
+ rNode = (rNode.constructor === Array) ? rNode : [rNode]
861
+
862
+ if (fldNode) {
863
+ fldNode = (fldNode.constructor === Array) ? fldNode : [fldNode]
864
+ rNode = rNode.concat(fldNode)
865
+ }
866
+ if (brNode) {
867
+ brNode = (brNode.constructor === Array) ? brNode : [brNode]
868
+ brNode.forEach(item => item.type = 'br')
869
+
870
+ if (brNode.length > 1) brNode.shift()
871
+ rNode = rNode.concat(brNode)
872
+ rNode.sort((a, b) => a.attrs.order - b.attrs.order)
873
+ }
874
+ }
875
+
591
876
  const align = getHorizontalAlign(pNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles)
592
877
 
593
878
  const listType = getListType(pNode)
@@ -601,21 +886,22 @@ function genTextBody(textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, w
601
886
  text += `<${listType}>`
602
887
  isList = listType
603
888
  }
604
- text += `<li style="text-align: ${align}; color: ${type === 'text' ? '#000000' : '#ffffff'}">`
889
+ text += `<li style="text-align: ${align};">`
605
890
  }
606
891
  else {
607
892
  if (isList) {
608
893
  text += `</${isList}>`
609
894
  isList = ''
610
895
  }
611
- text += `<p style="text-align: ${align}; color: ${type === 'text' ? '#000000' : '#ffffff'}">`
896
+ text += `<p style="text-align: ${align};">`
612
897
  }
613
898
 
614
899
  if (!rNode) text += genSpanElement(pNode, slideLayoutSpNode, type, warpObj)
615
- else if (rNode.constructor === Array) {
616
- for (const rNodeItem of rNode) text += genSpanElement(rNodeItem, slideLayoutSpNode, type, warpObj)
617
- }
618
- else text += genSpanElement(rNode, slideLayoutSpNode, type, warpObj)
900
+ else {
901
+ for (const rNodeItem of rNode) {
902
+ text += genSpanElement(rNodeItem, slideLayoutSpNode, type, warpObj)
903
+ }
904
+ }
619
905
 
620
906
  if (listType) text += '</li>'
621
907
  else text += '</p>'
@@ -1083,6 +1369,37 @@ async function getBgPicFill(bgPr, sorce, warpObj) {
1083
1369
  }
1084
1370
  }
1085
1371
 
1372
+ function getBgGradientFill(bgPr, phClr, slideMasterContent, warpObj) {
1373
+ if (bgPr) {
1374
+ const grdFill = bgPr['a:gradFill']
1375
+ const gsLst = grdFill['a:gsLst']['a:gs']
1376
+ const color_ary = []
1377
+ const pos_ary = []
1378
+
1379
+ for (let i = 0; i < gsLst.length; i++) {
1380
+ const lo_color = getSolidFill(gsLst[i], slideMasterContent['p:sldMaster']['p:clrMap']['attrs'], phClr, warpObj)
1381
+ const pos = getTextByPathList(gsLst[i], ['attrs', 'pos'])
1382
+
1383
+ if (pos) pos_ary[i] = pos / 1000 + '%'
1384
+ else pos_ary[i] = ''
1385
+ color_ary[i] = `#${lo_color}`
1386
+ }
1387
+ const lin = grdFill['a:lin']
1388
+ let rot = 90
1389
+ if (lin) {
1390
+ rot = angleToDegrees(lin['attrs']['ang'])
1391
+ rot = rot + 90
1392
+ }
1393
+ return {
1394
+ rot,
1395
+ colors: color_ary,
1396
+ pos: pos_ary,
1397
+ }
1398
+ }
1399
+ else if (phClr) return `#${phClr}`
1400
+ return null
1401
+ }
1402
+
1086
1403
  async function getSlideBackgroundFill(warpObj) {
1087
1404
  const slideContent = warpObj['slideContent']
1088
1405
  const slideLayoutContent = warpObj['slideLayoutContent']
@@ -1109,6 +1426,16 @@ async function getSlideBackgroundFill(warpObj) {
1109
1426
  const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
1110
1427
  background = `#${sldBgClr}`
1111
1428
  }
1429
+ else if (bgFillTyp === 'GRADIENT_FILL') {
1430
+ const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
1431
+ if (typeof gradientFill === 'string') {
1432
+ background = gradientFill
1433
+ }
1434
+ else if (gradientFill) {
1435
+ background = gradientFill
1436
+ backgroundType = 'gradient'
1437
+ }
1438
+ }
1112
1439
  else if (bgFillTyp === 'PIC_FILL') {
1113
1440
  background = await getBgPicFill(bgPr, 'slideBg', warpObj)
1114
1441
  backgroundType = 'image'
@@ -1129,6 +1456,16 @@ async function getSlideBackgroundFill(warpObj) {
1129
1456
  const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
1130
1457
  background = `#${sldBgClr}`
1131
1458
  }
1459
+ else if (bgFillTyp === 'GRADIENT_FILL') {
1460
+ const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
1461
+ if (typeof gradientFill === 'string') {
1462
+ background = gradientFill
1463
+ }
1464
+ else if (gradientFill) {
1465
+ background = gradientFill
1466
+ backgroundType = 'gradient'
1467
+ }
1468
+ }
1132
1469
  else if (bgFillTyp === 'PIC_FILL') {
1133
1470
  background = await getBgPicFill(bgPr, 'slideLayoutBg', warpObj)
1134
1471
  backgroundType = 'image'
@@ -1145,6 +1482,16 @@ async function getSlideBackgroundFill(warpObj) {
1145
1482
  const sldBgClr = getSolidFill(sldFill, clrMap, undefined, warpObj)
1146
1483
  background = `#${sldBgClr}`
1147
1484
  }
1485
+ else if (bgFillTyp === 'GRADIENT_FILL') {
1486
+ const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
1487
+ if (typeof gradientFill === 'string') {
1488
+ background = gradientFill
1489
+ }
1490
+ else if (gradientFill) {
1491
+ background = gradientFill
1492
+ backgroundType = 'gradient'
1493
+ }
1494
+ }
1148
1495
  else if (bgFillTyp === 'PIC_FILL') {
1149
1496
  background = await getBgPicFill(bgPr, 'slideMasterBg', warpObj)
1150
1497
  backgroundType = 'image'
@@ -1291,4 +1638,4 @@ function extractChartData(serNode) {
1291
1638
  }
1292
1639
 
1293
1640
  return dataMat
1294
- }
1641
+ }