pptxtojson 1.1.1 → 1.2.1

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/src/pptxtojson.js CHANGED
@@ -20,7 +20,7 @@ export async function parse(file) {
20
20
 
21
21
  const filesInfo = await getContentTypes(zip)
22
22
  const { width, height, defaultTextStyle } = await getSlideInfo(zip)
23
- const themeContent = await loadTheme(zip)
23
+ const { themeContent, themeColors } = await getTheme(zip)
24
24
 
25
25
  for (const filename of filesInfo.slides) {
26
26
  const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle)
@@ -29,6 +29,7 @@ export async function parse(file) {
29
29
 
30
30
  return {
31
31
  slides,
32
+ themeColors,
32
33
  size: {
33
34
  width,
34
35
  height,
@@ -79,7 +80,7 @@ async function getSlideInfo(zip) {
79
80
  }
80
81
  }
81
82
 
82
- async function loadTheme(zip) {
83
+ async function getTheme(zip) {
83
84
  const preResContent = await readXmlFile(zip, 'ppt/_rels/presentation.xml.rels')
84
85
  const relationshipArray = preResContent['Relationships']['Relationship']
85
86
  let themeURI
@@ -95,103 +96,109 @@ async function loadTheme(zip) {
95
96
  else if (relationshipArray['attrs']['Type'] === 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {
96
97
  themeURI = relationshipArray['attrs']['Target']
97
98
  }
98
- if (!themeURI) throw Error(`Can't open theme file.`)
99
99
 
100
- return await readXmlFile(zip, 'ppt/' + themeURI)
100
+ const themeContent = await readXmlFile(zip, 'ppt/' + themeURI)
101
+
102
+ const themeColors = []
103
+ const clrScheme = getTextByPathList(themeContent, ['a:theme', 'a:themeElements', 'a:clrScheme'])
104
+ if (clrScheme) {
105
+ for (let i = 1; i <= 6; i++) {
106
+ if (clrScheme[`a:accent${i}`] === undefined) break
107
+ const color = getTextByPathList(clrScheme, [`a:accent${i}`, 'a:srgbClr', 'attrs', 'val'])
108
+ if (color) themeColors.push('#' + color)
109
+ }
110
+ }
111
+
112
+ return { themeContent, themeColors }
101
113
  }
102
114
 
103
115
  async function processSingleSlide(zip, sldFileName, themeContent, defaultTextStyle) {
104
116
  const resName = sldFileName.replace('slides/slide', 'slides/_rels/slide') + '.rels'
105
117
  const resContent = await readXmlFile(zip, resName)
106
118
  let relationshipArray = resContent['Relationships']['Relationship']
119
+ if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
120
+
121
+ let noteFilename = ''
107
122
  let layoutFilename = ''
123
+ let masterFilename = ''
124
+ let themeFilename = ''
108
125
  let diagramFilename = ''
109
- let notesFilename = ''
110
126
  const slideResObj = {}
127
+ const layoutResObj = {}
128
+ const masterResObj = {}
129
+ const themeResObj = {}
130
+ const diagramResObj = {}
111
131
 
112
- if (relationshipArray.constructor === Array) {
113
- for (const relationshipArrayItem of relationshipArray) {
114
- switch (relationshipArrayItem['attrs']['Type']) {
115
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout':
116
- layoutFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
117
- break
118
- case 'http://schemas.microsoft.com/office/2007/relationships/diagramDrawing':
119
- diagramFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
120
- slideResObj[relationshipArrayItem['attrs']['Id']] = {
121
- type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
122
- target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
123
- }
124
- break
125
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide':
126
- notesFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
127
- break
128
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image':
129
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart':
130
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink':
131
- default:
132
- slideResObj[relationshipArrayItem['attrs']['Id']] = {
133
- type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
134
- target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
135
- }
136
- }
132
+ for (const relationshipArrayItem of relationshipArray) {
133
+ switch (relationshipArrayItem['attrs']['Type']) {
134
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout':
135
+ layoutFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
136
+ break
137
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide':
138
+ noteFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
139
+ break
140
+ case 'http://schemas.microsoft.com/office/2007/relationships/diagramDrawing':
141
+ diagramFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
142
+ slideResObj[relationshipArrayItem['attrs']['Id']] = {
143
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
144
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
145
+ }
146
+ break
147
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image':
148
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart':
149
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink':
150
+ default:
151
+ slideResObj[relationshipArrayItem['attrs']['Id']] = {
152
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
153
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
154
+ }
137
155
  }
138
- }
139
- else layoutFilename = relationshipArray['attrs']['Target'].replace('../', 'ppt/')
156
+ }
140
157
 
141
- const slideNotesContent = await readXmlFile(zip, notesFilename)
158
+ const slideNotesContent = await readXmlFile(zip, noteFilename)
142
159
  const note = getNote(slideNotesContent)
143
160
 
144
161
  const slideLayoutContent = await readXmlFile(zip, layoutFilename)
145
162
  const slideLayoutTables = await indexNodes(slideLayoutContent)
146
-
147
163
  const slideLayoutResFilename = layoutFilename.replace('slideLayouts/slideLayout', 'slideLayouts/_rels/slideLayout') + '.rels'
148
164
  const slideLayoutResContent = await readXmlFile(zip, slideLayoutResFilename)
149
165
  relationshipArray = slideLayoutResContent['Relationships']['Relationship']
166
+ if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
150
167
 
151
- let masterFilename = ''
152
- const layoutResObj = {}
153
- if (relationshipArray.constructor === Array) {
154
- for (const relationshipArrayItem of relationshipArray) {
155
- switch (relationshipArrayItem['attrs']['Type']) {
156
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster':
157
- masterFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
158
- break
159
- default:
160
- layoutResObj[relationshipArrayItem['attrs']['Id']] = {
161
- type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
162
- target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
163
- }
164
- }
168
+ for (const relationshipArrayItem of relationshipArray) {
169
+ switch (relationshipArrayItem['attrs']['Type']) {
170
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster':
171
+ masterFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
172
+ break
173
+ default:
174
+ layoutResObj[relationshipArrayItem['attrs']['Id']] = {
175
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
176
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
177
+ }
165
178
  }
166
- }
167
- else masterFilename = relationshipArray['attrs']['Target'].replace('../', 'ppt/')
179
+ }
168
180
 
169
181
  const slideMasterContent = await readXmlFile(zip, masterFilename)
170
182
  const slideMasterTextStyles = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:txStyles'])
171
183
  const slideMasterTables = indexNodes(slideMasterContent)
172
-
173
184
  const slideMasterResFilename = masterFilename.replace('slideMasters/slideMaster', 'slideMasters/_rels/slideMaster') + '.rels'
174
185
  const slideMasterResContent = await readXmlFile(zip, slideMasterResFilename)
175
186
  relationshipArray = slideMasterResContent['Relationships']['Relationship']
187
+ if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
176
188
 
177
- let themeFilename = ''
178
- const masterResObj = {}
179
- if (relationshipArray.constructor === Array) {
180
- for (const relationshipArrayItem of relationshipArray) {
181
- switch (relationshipArrayItem['attrs']['Type']) {
182
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme':
183
- break
184
- default:
185
- masterResObj[relationshipArrayItem['attrs']['Id']] = {
186
- type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
187
- target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
188
- }
189
- }
189
+ for (const relationshipArrayItem of relationshipArray) {
190
+ switch (relationshipArrayItem['attrs']['Type']) {
191
+ case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme':
192
+ themeFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
193
+ break
194
+ default:
195
+ masterResObj[relationshipArrayItem['attrs']['Id']] = {
196
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
197
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/'),
198
+ }
190
199
  }
191
200
  }
192
- else themeFilename = relationshipArray['attrs']['Target'].replace('../', 'ppt/')
193
201
 
194
- const themeResObj = {}
195
202
  if (themeFilename) {
196
203
  const themeName = themeFilename.split('/').pop()
197
204
  const themeResFileName = themeFilename.replace(themeName, '_rels/' + themeName) + '.rels'
@@ -199,50 +206,34 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
199
206
  if (themeResContent) {
200
207
  relationshipArray = themeResContent['Relationships']['Relationship']
201
208
  if (relationshipArray) {
202
- if (relationshipArray.constructor === Array) {
203
- for (const relationshipArrayItem of relationshipArray) {
204
- themeResObj[relationshipArrayItem['attrs']['Id']] = {
205
- 'type': relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
206
- 'target': relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
207
- }
208
- }
209
- }
210
- else {
211
- themeResObj[relationshipArray['attrs']['Id']] = {
212
- 'type': relationshipArray['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
213
- 'target': relationshipArray['attrs']['Target'].replace('../', 'ppt/')
209
+ if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
210
+ for (const relationshipArrayItem of relationshipArray) {
211
+ themeResObj[relationshipArrayItem['attrs']['Id']] = {
212
+ 'type': relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
213
+ 'target': relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
214
214
  }
215
215
  }
216
216
  }
217
217
  }
218
218
  }
219
219
 
220
- const diagramResObj = {}
221
220
  let digramFileContent = {}
222
221
  if (diagramFilename) {
223
222
  const diagName = diagramFilename.split('/').pop()
224
223
  const diagramResFileName = diagramFilename.replace(diagName, '_rels/' + diagName) + '.rels'
225
224
  digramFileContent = await readXmlFile(zip, diagramFilename)
226
- if (digramFileContent && digramFileContent && digramFileContent) {
227
- let digramFileContentObjToStr = JSON.stringify(digramFileContent)
228
- digramFileContentObjToStr = digramFileContentObjToStr.replace(/dsp:/g, 'p:')
225
+ if (digramFileContent) {
226
+ const digramFileContentObjToStr = JSON.stringify(digramFileContent).replace(/dsp:/g, 'p:')
229
227
  digramFileContent = JSON.parse(digramFileContentObjToStr)
230
228
  }
231
229
  const digramResContent = await readXmlFile(zip, diagramResFileName)
232
230
  if (digramResContent) {
233
231
  relationshipArray = digramResContent['Relationships']['Relationship']
234
- if (relationshipArray.constructor === Array) {
235
- for (const relationshipArrayItem of relationshipArray) {
236
- diagramResObj[relationshipArrayItem['attrs']['Id']] = {
237
- 'type': relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
238
- 'target': relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
239
- }
240
- }
241
- }
242
- else {
243
- diagramResObj[relationshipArray['attrs']['Id']] = {
244
- 'type': relationshipArray['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
245
- 'target': relationshipArray['attrs']['Target'].replace('../', 'ppt/')
232
+ if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
233
+ for (const relationshipArrayItem of relationshipArray) {
234
+ diagramResObj[relationshipArrayItem['attrs']['Id']] = {
235
+ 'type': relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
236
+ 'target': relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
246
237
  }
247
238
  }
248
239
  }
@@ -270,26 +261,22 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
270
261
  diagramResObj,
271
262
  defaultTextStyle,
272
263
  }
273
- // const bgElements = await getBackground(warpObj)
274
- const bgColor = await getSlideBackgroundFill(warpObj)
264
+ const layoutElements = await getLayoutElements(warpObj)
265
+ const fill = await getSlideBackgroundFill(warpObj)
275
266
 
276
267
  const elements = []
277
268
  for (const nodeKey in nodes) {
278
- if (nodes[nodeKey].constructor === Array) {
279
- for (const node of nodes[nodeKey]) {
280
- const ret = await processNodesInSlide(nodeKey, node, warpObj, 'slide')
281
- if (ret) elements.push(ret)
282
- }
283
- }
284
- else {
285
- const ret = await processNodesInSlide(nodeKey, nodes[nodeKey], warpObj, 'slide')
269
+ if (nodes[nodeKey].constructor !== Array) nodes[nodeKey] = [nodes[nodeKey]]
270
+ for (const node of nodes[nodeKey]) {
271
+ const ret = await processNodesInSlide(nodeKey, node, warpObj, 'slide')
286
272
  if (ret) elements.push(ret)
287
273
  }
288
274
  }
289
275
 
290
276
  return {
291
- fill: bgColor,
277
+ fill,
292
278
  elements,
279
+ layoutElements,
293
280
  note,
294
281
  }
295
282
  }
@@ -307,56 +294,62 @@ function getNote(noteContent) {
307
294
  if (rNodes.constructor !== Array) rNodes = [rNodes]
308
295
  for (const rNode of rNodes) {
309
296
  const t = getTextByPathList(rNode, ['a:t'])
310
- if (t) text += t
297
+ if (t && typeof t === 'string') text += t
311
298
  }
312
299
  }
313
300
  return text
314
301
  }
315
302
 
316
- // async function getBackground(warpObj) {
317
- // const elements = []
318
- // const slideLayoutContent = warpObj['slideLayoutContent']
319
- // const slideMasterContent = warpObj['slideMasterContent']
320
- // const nodesSldLayout = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:spTree'])
321
- // const nodesSldMaster = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:spTree'])
322
-
323
- // const showMasterSp = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'attrs', 'showMasterSp'])
324
- // if (nodesSldLayout) {
325
- // for (const nodeKey in nodesSldLayout) {
326
- // if (nodesSldLayout[nodeKey].constructor === Array) {
327
- // for (let i = 0; i < nodesSldLayout[nodeKey].length; i++) {
328
- // const ph_type = getTextByPathList(nodesSldLayout[nodeKey][i], ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
329
- // if (ph_type !== 'pic') {
330
- // const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey][i], warpObj, 'slideLayoutBg')
331
- // if (ret) elements.push(ret)
332
- // }
333
- // }
334
- // }
335
- // else {
336
- // const ph_type = getTextByPathList(nodesSldLayout[nodeKey], ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
337
- // if (ph_type !== 'pic') {
338
- // const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey], warpObj, 'slideLayoutBg')
339
- // if (ret) elements.push(ret)
340
- // }
341
- // }
342
- // }
343
- // }
344
- // if (nodesSldMaster && (showMasterSp === '1' || showMasterSp)) {
345
- // for (const nodeKey in nodesSldMaster) {
346
- // if (nodesSldMaster[nodeKey].constructor === Array) {
347
- // for (let i = 0; i < nodesSldMaster[nodeKey].length; i++) {
348
- // const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey][i], warpObj, 'slideMasterBg')
349
- // if (ret) elements.push(ret)
350
- // }
351
- // }
352
- // else {
353
- // const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey], warpObj, 'slideMasterBg')
354
- // if (ret) elements.push(ret)
355
- // }
356
- // }
357
- // }
358
- // return elements
359
- // }
303
+ async function getLayoutElements(warpObj) {
304
+ const elements = []
305
+ const slideLayoutContent = warpObj['slideLayoutContent']
306
+ const slideMasterContent = warpObj['slideMasterContent']
307
+ const nodesSldLayout = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:spTree'])
308
+ const nodesSldMaster = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:spTree'])
309
+
310
+ const showMasterSp = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'attrs', 'showMasterSp'])
311
+ if (nodesSldLayout) {
312
+ for (const nodeKey in nodesSldLayout) {
313
+ if (nodesSldLayout[nodeKey].constructor === Array) {
314
+ for (let i = 0; i < nodesSldLayout[nodeKey].length; i++) {
315
+ const ph = getTextByPathList(nodesSldLayout[nodeKey][i], ['p:nvSpPr', 'p:nvPr', 'p:ph'])
316
+ if (!ph) {
317
+ const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey][i], warpObj, 'slideLayoutBg')
318
+ if (ret) elements.push(ret)
319
+ }
320
+ }
321
+ }
322
+ else {
323
+ const ph = getTextByPathList(nodesSldLayout[nodeKey], ['p:nvSpPr', 'p:nvPr', 'p:ph'])
324
+ if (!ph) {
325
+ const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey], warpObj, 'slideLayoutBg')
326
+ if (ret) elements.push(ret)
327
+ }
328
+ }
329
+ }
330
+ }
331
+ if (nodesSldMaster && showMasterSp !== '0') {
332
+ for (const nodeKey in nodesSldMaster) {
333
+ if (nodesSldMaster[nodeKey].constructor === Array) {
334
+ for (let i = 0; i < nodesSldMaster[nodeKey].length; i++) {
335
+ const ph = getTextByPathList(nodesSldMaster[nodeKey][i], ['p:nvSpPr', 'p:nvPr', 'p:ph'])
336
+ if (!ph) {
337
+ const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey][i], warpObj, 'slideMasterBg')
338
+ if (ret) elements.push(ret)
339
+ }
340
+ }
341
+ }
342
+ else {
343
+ const ph = getTextByPathList(nodesSldMaster[nodeKey], ['p:nvSpPr', 'p:nvPr', 'p:ph'])
344
+ if (!ph) {
345
+ const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey], warpObj, 'slideMasterBg')
346
+ if (ret) elements.push(ret)
347
+ }
348
+ }
349
+ }
350
+ }
351
+ return elements
352
+ }
360
353
 
361
354
  function indexNodes(content) {
362
355
  const keys = Object.keys(content)
@@ -402,13 +395,13 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj, source) {
402
395
 
403
396
  switch (nodeKey) {
404
397
  case 'p:sp': // Shape, Text
405
- json = processSpNode(nodeValue, warpObj, source)
398
+ json = await processSpNode(nodeValue, warpObj, source)
406
399
  break
407
400
  case 'p:cxnSp': // Shape, Text
408
- json = processCxnSpNode(nodeValue, warpObj, source)
401
+ json = await processCxnSpNode(nodeValue, warpObj, source)
409
402
  break
410
403
  case 'p:pic': // Image, Video, Audio
411
- json = processPicNode(nodeValue, warpObj, source)
404
+ json = await processPicNode(nodeValue, warpObj, source)
412
405
  break
413
406
  case 'p:graphicFrame': // Chart, Diagram, Table
414
407
  json = await processGraphicFrameNode(nodeValue, warpObj, source)
@@ -421,7 +414,7 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj, source) {
421
414
  json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj, source)
422
415
  }
423
416
  else if (getTextByPathList(nodeValue, ['mc:Choice'])) {
424
- json = await processMathNode(getTextByPathList(nodeValue, ['mc:Choice']))
417
+ json = processMathNode(getTextByPathList(nodeValue, ['mc:Choice']))
425
418
  }
426
419
  break
427
420
  default:
@@ -502,7 +495,7 @@ async function processGroupSpNode(node, warpObj, source) {
502
495
  }
503
496
  }
504
497
 
505
- function processSpNode(node, warpObj, source) {
498
+ async function processSpNode(node, warpObj, source) {
506
499
  const name = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'name'])
507
500
  const idx = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'idx'])
508
501
  let type = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
@@ -537,18 +530,18 @@ function processSpNode(node, warpObj, source) {
537
530
  else type = 'obj'
538
531
  }
539
532
 
540
- return genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj)
533
+ return await genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj, source)
541
534
  }
542
535
 
543
- function processCxnSpNode(node, warpObj) {
536
+ async function processCxnSpNode(node, warpObj, source) {
544
537
  const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
545
538
  const type = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
546
539
  const order = node['attrs']['order']
547
540
 
548
- return genShape(node, undefined, undefined, name, type, order, warpObj)
541
+ return await genShape(node, undefined, undefined, name, type, order, warpObj, source)
549
542
  }
550
543
 
551
- function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj) {
544
+ async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj, source) {
552
545
  const xfrmList = ['p:spPr', 'a:xfrm']
553
546
  const slideXfrmNode = getTextByPathList(node, xfrmList)
554
547
  const slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList)
@@ -574,13 +567,10 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order,
574
567
  else txtRotate = rotate
575
568
 
576
569
  let content = ''
577
- if (node['p:txBody']) {
578
- content = genTextBody(node['p:txBody'], node, slideLayoutSpNode, type, warpObj)
579
- if (!hasValidText(content)) content = ''
580
- }
570
+ if (node['p:txBody']) content = genTextBody(node['p:txBody'], node, slideLayoutSpNode, type, warpObj)
581
571
 
582
572
  const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(node, type, warpObj)
583
- const fillColor = getShapeFill(node, undefined, warpObj) || ''
573
+ const fill = await getShapeFill(node, undefined, warpObj, source) || ''
584
574
 
585
575
  let shadow
586
576
  const outerShdwNode = getTextByPathList(node, ['p:spPr', 'a:effectLst', 'a:outerShdw'])
@@ -598,7 +588,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order,
598
588
  borderWidth,
599
589
  borderType,
600
590
  borderStrokeDasharray: strokeDasharray,
601
- fillColor,
591
+ fill,
602
592
  content,
603
593
  isFlipV,
604
594
  isFlipH,
@@ -615,6 +605,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order,
615
605
  const w = parseInt(ext['cx']) * RATIO_EMUs_Points
616
606
  const h = parseInt(ext['cy']) * RATIO_EMUs_Points
617
607
  const d = getCustomShapePath(custShapType, w, h)
608
+ if (data.content && !hasValidText(data.content)) data.content = ''
618
609
 
619
610
  return {
620
611
  ...data,
@@ -624,6 +615,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order,
624
615
  }
625
616
  }
626
617
  if (shapType && (type === 'obj' || !type)) {
618
+ if (data.content && !hasValidText(data.content)) data.content = ''
627
619
  return {
628
620
  ...data,
629
621
  type: 'shape',
@@ -756,25 +748,25 @@ async function processGraphicFrameNode(node, warpObj, source) {
756
748
  let result
757
749
  switch (graphicTypeUri) {
758
750
  case 'http://schemas.openxmlformats.org/drawingml/2006/table':
759
- result = genTable(node, warpObj)
751
+ result = await genTable(node, warpObj)
760
752
  break
761
753
  case 'http://schemas.openxmlformats.org/drawingml/2006/chart':
762
754
  result = await genChart(node, warpObj)
763
755
  break
764
756
  case 'http://schemas.openxmlformats.org/drawingml/2006/diagram':
765
- result = genDiagram(node, warpObj)
757
+ result = await genDiagram(node, warpObj)
766
758
  break
767
759
  case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
768
760
  let oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'mc:AlternateContent', 'mc:Fallback', 'p:oleObj'])
769
761
  if (!oleObjNode) oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'p:oleObj'])
770
- else processGroupSpNode(oleObjNode, warpObj, source)
762
+ if (oleObjNode) result = await processGroupSpNode(oleObjNode, warpObj, source)
771
763
  break
772
764
  default:
773
765
  }
774
766
  return result
775
767
  }
776
768
 
777
- function genTable(node, warpObj) {
769
+ async function genTable(node, warpObj) {
778
770
  const order = node['attrs']['order']
779
771
  const tableNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl'])
780
772
  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
@@ -892,7 +884,7 @@ function genTable(node, warpObj) {
892
884
  }
893
885
  }
894
886
  const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
895
- const cell = getTableCellParams(tcNode, thisTblStyle, a_sorce, warpObj)
887
+ const cell = await getTableCellParams(tcNode, thisTblStyle, a_sorce, warpObj)
896
888
  const td = { text }
897
889
  if (cell.rowSpan) td.rowSpan = cell.rowSpan
898
890
  if (cell.colSpan) td.colSpan = cell.colSpan
@@ -923,7 +915,7 @@ function genTable(node, warpObj) {
923
915
  }
924
916
 
925
917
  const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
926
- const cell = getTableCellParams(tcNodes, thisTblStyle, a_sorce, warpObj)
918
+ const cell = await getTableCellParams(tcNodes, thisTblStyle, a_sorce, warpObj)
927
919
  const td = { text }
928
920
  if (cell.rowSpan) td.rowSpan = cell.rowSpan
929
921
  if (cell.colSpan) td.colSpan = cell.colSpan
@@ -957,11 +949,15 @@ async function genChart(node, warpObj) {
957
949
  const { width, height } = getSize(xfrmNode, undefined, undefined)
958
950
 
959
951
  const rid = node['a:graphic']['a:graphicData']['c:chart']['attrs']['r:id']
960
- const refName = warpObj['slideResObj'][rid]['target']
952
+ let refName = getTextByPathList(warpObj['slideResObj'], [rid, 'target'])
953
+ if (!refName) refName = getTextByPathList(warpObj['layoutResObj'], [rid, 'target'])
954
+ if (!refName) refName = getTextByPathList(warpObj['masterResObj'], [rid, 'target'])
955
+ if (!refName) return {}
956
+
961
957
  const content = await readXmlFile(warpObj['zip'], refName)
962
958
  const plotArea = getTextByPathList(content, ['c:chartSpace', 'c:chart', 'c:plotArea'])
963
959
 
964
- const chart = getChartInfo(plotArea)
960
+ const chart = getChartInfo(plotArea, warpObj)
965
961
 
966
962
  if (!chart) return {}
967
963
 
@@ -972,6 +968,7 @@ async function genChart(node, warpObj) {
972
968
  width,
973
969
  height,
974
970
  data: chart.data,
971
+ colors: chart.colors,
975
972
  chartType: chart.type,
976
973
  order,
977
974
  }
@@ -984,7 +981,7 @@ async function genChart(node, warpObj) {
984
981
  return data
985
982
  }
986
983
 
987
- function genDiagram(node, warpObj) {
984
+ async function genDiagram(node, warpObj) {
988
985
  const order = node['attrs']['order']
989
986
  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
990
987
  const { left, top } = getPosition(xfrmNode, undefined, undefined)
@@ -994,7 +991,7 @@ function genDiagram(node, warpObj) {
994
991
  const elements = []
995
992
  if (dgmDrwSpArray) {
996
993
  for (const item of dgmDrwSpArray) {
997
- const el = processSpNode(item, warpObj, 'diagramBg')
994
+ const el = await processSpNode(item, warpObj, 'diagramBg')
998
995
  if (el) elements.push(el)
999
996
  }
1000
997
  }
package/src/table.js CHANGED
@@ -43,7 +43,7 @@ export function getTableBorders(node, warpObj) {
43
43
  return borderStyles
44
44
  }
45
45
 
46
- export function getTableCellParams(tcNode, thisTblStyle, cellSource, warpObj) {
46
+ export async function getTableCellParams(tcNode, thisTblStyle, cellSource, warpObj) {
47
47
  const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
48
48
  const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
49
49
  const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
@@ -55,7 +55,11 @@ export function getTableCellParams(tcNode, thisTblStyle, cellSource, warpObj) {
55
55
  const getCelFill = getTextByPathList(tcNode, ['a:tcPr'])
56
56
  if (getCelFill) {
57
57
  const cellObj = { 'p:spPr': getCelFill }
58
- fillColor = getShapeFill(cellObj, undefined, warpObj)
58
+ const fill = await getShapeFill(cellObj, undefined, warpObj)
59
+
60
+ if (fill && fill.type === 'color' && fill.value) {
61
+ fillColor = fill.value
62
+ }
59
63
  }
60
64
  if (!fillColor) {
61
65
  let bgFillschemeClr
package/src/utils.js CHANGED
@@ -54,8 +54,6 @@ export function eachElement(node, func) {
54
54
  }
55
55
 
56
56
  export function getTextByPathList(node, path) {
57
- if (path.constructor !== Array) throw Error('Error of path type! path is not array.')
58
-
59
57
  if (!node) return node
60
58
 
61
59
  for (const key of path) {