pptxtojson 1.1.0 → 1.2.0
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/README.md +55 -37
- package/dist/index.d.ts +45 -30
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/wx.png +0 -0
- package/index.html +1 -1
- package/package.json +2 -2
- package/src/chart.js +41 -1
- package/src/fill.js +72 -37
- package/src/pptxtojson.js +187 -172
- package/src/readXmlFile.js +8 -4
- package/src/table.js +6 -2
- package/src/utils.js +9 -2
package/src/pptxtojson.js
CHANGED
|
@@ -7,7 +7,7 @@ import { getVerticalAlign } from './align'
|
|
|
7
7
|
import { getPosition, getSize } from './position'
|
|
8
8
|
import { genTextBody } from './text'
|
|
9
9
|
import { getCustomShapePath } from './shape'
|
|
10
|
-
import { extractFileExtension, base64ArrayBuffer, getTextByPathList, angleToDegrees, getMimeType, isVideoLink, escapeHtml } from './utils'
|
|
10
|
+
import { extractFileExtension, base64ArrayBuffer, getTextByPathList, angleToDegrees, getMimeType, isVideoLink, escapeHtml, hasValidText } from './utils'
|
|
11
11
|
import { getShadow } from './shadow'
|
|
12
12
|
import { getTableBorders, getTableCellParams, getTableRowParams } from './table'
|
|
13
13
|
import { RATIO_EMUs_Points } from './constants'
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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,
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
|
227
|
-
|
|
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
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
274
|
-
const
|
|
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
|
|
279
|
-
|
|
280
|
-
|
|
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
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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 =
|
|
417
|
+
json = processMathNode(getTextByPathList(nodeValue, ['mc:Choice']))
|
|
425
418
|
}
|
|
426
419
|
break
|
|
427
420
|
default:
|
|
@@ -431,6 +424,7 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj, source) {
|
|
|
431
424
|
}
|
|
432
425
|
|
|
433
426
|
function processMathNode(node) {
|
|
427
|
+
const order = node['attrs']['order']
|
|
434
428
|
const xfrmNode = getTextByPathList(node, ['p:sp', 'p:spPr', 'a:xfrm'])
|
|
435
429
|
const { top, left } = getPosition(xfrmNode, undefined, undefined)
|
|
436
430
|
const { width, height } = getSize(xfrmNode, undefined, undefined)
|
|
@@ -445,10 +439,12 @@ function processMathNode(node) {
|
|
|
445
439
|
width,
|
|
446
440
|
height,
|
|
447
441
|
latex,
|
|
442
|
+
order,
|
|
448
443
|
}
|
|
449
444
|
}
|
|
450
445
|
|
|
451
446
|
async function processGroupSpNode(node, warpObj, source) {
|
|
447
|
+
const order = node['attrs']['order']
|
|
452
448
|
const xfrmNode = getTextByPathList(node, ['p:grpSpPr', 'a:xfrm'])
|
|
453
449
|
if (!xfrmNode) return null
|
|
454
450
|
|
|
@@ -488,6 +484,7 @@ async function processGroupSpNode(node, warpObj, source) {
|
|
|
488
484
|
width: cx,
|
|
489
485
|
height: cy,
|
|
490
486
|
rotate,
|
|
487
|
+
order,
|
|
491
488
|
elements: elements.map(element => ({
|
|
492
489
|
...element,
|
|
493
490
|
left: (element.left - chx) * ws,
|
|
@@ -498,10 +495,11 @@ async function processGroupSpNode(node, warpObj, source) {
|
|
|
498
495
|
}
|
|
499
496
|
}
|
|
500
497
|
|
|
501
|
-
function processSpNode(node, warpObj, source) {
|
|
498
|
+
async function processSpNode(node, warpObj, source) {
|
|
502
499
|
const name = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'name'])
|
|
503
500
|
const idx = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'idx'])
|
|
504
501
|
let type = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
502
|
+
const order = getTextByPathList(node, ['attrs', 'order'])
|
|
505
503
|
|
|
506
504
|
let slideLayoutSpNode, slideMasterSpNode
|
|
507
505
|
|
|
@@ -532,17 +530,18 @@ function processSpNode(node, warpObj, source) {
|
|
|
532
530
|
else type = 'obj'
|
|
533
531
|
}
|
|
534
532
|
|
|
535
|
-
return genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj)
|
|
533
|
+
return await genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj, source)
|
|
536
534
|
}
|
|
537
535
|
|
|
538
|
-
function processCxnSpNode(node, warpObj) {
|
|
536
|
+
async function processCxnSpNode(node, warpObj, source) {
|
|
539
537
|
const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
|
|
540
538
|
const type = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
|
|
539
|
+
const order = node['attrs']['order']
|
|
541
540
|
|
|
542
|
-
return genShape(node, undefined, undefined, name, type, warpObj)
|
|
541
|
+
return await genShape(node, undefined, undefined, name, type, order, warpObj, source)
|
|
543
542
|
}
|
|
544
543
|
|
|
545
|
-
function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj) {
|
|
544
|
+
async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, order, warpObj, source) {
|
|
546
545
|
const xfrmList = ['p:spPr', 'a:xfrm']
|
|
547
546
|
const slideXfrmNode = getTextByPathList(node, xfrmList)
|
|
548
547
|
const slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList)
|
|
@@ -571,7 +570,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpOb
|
|
|
571
570
|
if (node['p:txBody']) content = genTextBody(node['p:txBody'], node, slideLayoutSpNode, type, warpObj)
|
|
572
571
|
|
|
573
572
|
const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(node, type, warpObj)
|
|
574
|
-
const
|
|
573
|
+
const fill = await getShapeFill(node, undefined, warpObj, source) || ''
|
|
575
574
|
|
|
576
575
|
let shadow
|
|
577
576
|
const outerShdwNode = getTextByPathList(node, ['p:spPr', 'a:effectLst', 'a:outerShdw'])
|
|
@@ -589,13 +588,14 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpOb
|
|
|
589
588
|
borderWidth,
|
|
590
589
|
borderType,
|
|
591
590
|
borderStrokeDasharray: strokeDasharray,
|
|
592
|
-
|
|
591
|
+
fill,
|
|
593
592
|
content,
|
|
594
593
|
isFlipV,
|
|
595
594
|
isFlipH,
|
|
596
595
|
rotate,
|
|
597
596
|
vAlign,
|
|
598
597
|
name,
|
|
598
|
+
order,
|
|
599
599
|
}
|
|
600
600
|
|
|
601
601
|
if (shadow) data.shadow = shadow
|
|
@@ -605,6 +605,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpOb
|
|
|
605
605
|
const w = parseInt(ext['cx']) * RATIO_EMUs_Points
|
|
606
606
|
const h = parseInt(ext['cy']) * RATIO_EMUs_Points
|
|
607
607
|
const d = getCustomShapePath(custShapType, w, h)
|
|
608
|
+
if (data.content && !hasValidText(data.content)) data.content = ''
|
|
608
609
|
|
|
609
610
|
return {
|
|
610
611
|
...data,
|
|
@@ -614,6 +615,7 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpOb
|
|
|
614
615
|
}
|
|
615
616
|
}
|
|
616
617
|
if (shapType && (type === 'obj' || !type)) {
|
|
618
|
+
if (data.content && !hasValidText(data.content)) data.content = ''
|
|
617
619
|
return {
|
|
618
620
|
...data,
|
|
619
621
|
type: 'shape',
|
|
@@ -633,6 +635,8 @@ async function processPicNode(node, warpObj, source) {
|
|
|
633
635
|
if (source === 'slideMasterBg') resObj = warpObj['masterResObj']
|
|
634
636
|
else if (source === 'slideLayoutBg') resObj = warpObj['layoutResObj']
|
|
635
637
|
else resObj = warpObj['slideResObj']
|
|
638
|
+
|
|
639
|
+
const order = node['attrs']['order']
|
|
636
640
|
|
|
637
641
|
const rid = node['p:blipFill']['a:blip']['attrs']['r:embed']
|
|
638
642
|
const imgName = resObj[rid]['target']
|
|
@@ -697,6 +701,7 @@ async function processPicNode(node, warpObj, source) {
|
|
|
697
701
|
height,
|
|
698
702
|
rotate,
|
|
699
703
|
blob: videoBlob,
|
|
704
|
+
order,
|
|
700
705
|
}
|
|
701
706
|
}
|
|
702
707
|
if (videoNode && isVdeoLink) {
|
|
@@ -708,6 +713,7 @@ async function processPicNode(node, warpObj, source) {
|
|
|
708
713
|
height,
|
|
709
714
|
rotate,
|
|
710
715
|
src: videoFile,
|
|
716
|
+
order,
|
|
711
717
|
}
|
|
712
718
|
}
|
|
713
719
|
if (audioNode) {
|
|
@@ -719,6 +725,7 @@ async function processPicNode(node, warpObj, source) {
|
|
|
719
725
|
height,
|
|
720
726
|
rotate,
|
|
721
727
|
blob: audioBlob,
|
|
728
|
+
order,
|
|
722
729
|
}
|
|
723
730
|
}
|
|
724
731
|
return {
|
|
@@ -730,7 +737,8 @@ async function processPicNode(node, warpObj, source) {
|
|
|
730
737
|
rotate,
|
|
731
738
|
src,
|
|
732
739
|
isFlipV,
|
|
733
|
-
isFlipH
|
|
740
|
+
isFlipH,
|
|
741
|
+
order,
|
|
734
742
|
}
|
|
735
743
|
}
|
|
736
744
|
|
|
@@ -740,25 +748,26 @@ async function processGraphicFrameNode(node, warpObj, source) {
|
|
|
740
748
|
let result
|
|
741
749
|
switch (graphicTypeUri) {
|
|
742
750
|
case 'http://schemas.openxmlformats.org/drawingml/2006/table':
|
|
743
|
-
result = genTable(node, warpObj)
|
|
751
|
+
result = await genTable(node, warpObj)
|
|
744
752
|
break
|
|
745
753
|
case 'http://schemas.openxmlformats.org/drawingml/2006/chart':
|
|
746
754
|
result = await genChart(node, warpObj)
|
|
747
755
|
break
|
|
748
756
|
case 'http://schemas.openxmlformats.org/drawingml/2006/diagram':
|
|
749
|
-
result = genDiagram(node, warpObj)
|
|
757
|
+
result = await genDiagram(node, warpObj)
|
|
750
758
|
break
|
|
751
759
|
case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
|
|
752
760
|
let oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'mc:AlternateContent', 'mc:Fallback', 'p:oleObj'])
|
|
753
761
|
if (!oleObjNode) oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'p:oleObj'])
|
|
754
|
-
|
|
762
|
+
if (oleObjNode) result = await processGroupSpNode(oleObjNode, warpObj, source)
|
|
755
763
|
break
|
|
756
764
|
default:
|
|
757
765
|
}
|
|
758
766
|
return result
|
|
759
767
|
}
|
|
760
768
|
|
|
761
|
-
function genTable(node, warpObj) {
|
|
769
|
+
async function genTable(node, warpObj) {
|
|
770
|
+
const order = node['attrs']['order']
|
|
762
771
|
const tableNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl'])
|
|
763
772
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
764
773
|
const { top, left } = getPosition(xfrmNode, undefined, undefined)
|
|
@@ -875,7 +884,7 @@ function genTable(node, warpObj) {
|
|
|
875
884
|
}
|
|
876
885
|
}
|
|
877
886
|
const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
|
|
878
|
-
const cell = getTableCellParams(tcNode, thisTblStyle, a_sorce, warpObj)
|
|
887
|
+
const cell = await getTableCellParams(tcNode, thisTblStyle, a_sorce, warpObj)
|
|
879
888
|
const td = { text }
|
|
880
889
|
if (cell.rowSpan) td.rowSpan = cell.rowSpan
|
|
881
890
|
if (cell.colSpan) td.colSpan = cell.colSpan
|
|
@@ -906,7 +915,7 @@ function genTable(node, warpObj) {
|
|
|
906
915
|
}
|
|
907
916
|
|
|
908
917
|
const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
|
|
909
|
-
const cell = getTableCellParams(tcNodes, thisTblStyle, a_sorce, warpObj)
|
|
918
|
+
const cell = await getTableCellParams(tcNodes, thisTblStyle, a_sorce, warpObj)
|
|
910
919
|
const td = { text }
|
|
911
920
|
if (cell.rowSpan) td.rowSpan = cell.rowSpan
|
|
912
921
|
if (cell.colSpan) td.colSpan = cell.colSpan
|
|
@@ -928,11 +937,13 @@ function genTable(node, warpObj) {
|
|
|
928
937
|
width,
|
|
929
938
|
height,
|
|
930
939
|
data,
|
|
940
|
+
order,
|
|
931
941
|
...(tbl_border || {}),
|
|
932
942
|
}
|
|
933
943
|
}
|
|
934
944
|
|
|
935
945
|
async function genChart(node, warpObj) {
|
|
946
|
+
const order = node['attrs']['order']
|
|
936
947
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
937
948
|
const { top, left } = getPosition(xfrmNode, undefined, undefined)
|
|
938
949
|
const { width, height } = getSize(xfrmNode, undefined, undefined)
|
|
@@ -942,7 +953,7 @@ async function genChart(node, warpObj) {
|
|
|
942
953
|
const content = await readXmlFile(warpObj['zip'], refName)
|
|
943
954
|
const plotArea = getTextByPathList(content, ['c:chartSpace', 'c:chart', 'c:plotArea'])
|
|
944
955
|
|
|
945
|
-
const chart = getChartInfo(plotArea)
|
|
956
|
+
const chart = getChartInfo(plotArea, warpObj)
|
|
946
957
|
|
|
947
958
|
if (!chart) return {}
|
|
948
959
|
|
|
@@ -953,7 +964,9 @@ async function genChart(node, warpObj) {
|
|
|
953
964
|
width,
|
|
954
965
|
height,
|
|
955
966
|
data: chart.data,
|
|
967
|
+
colors: chart.colors,
|
|
956
968
|
chartType: chart.type,
|
|
969
|
+
order,
|
|
957
970
|
}
|
|
958
971
|
if (chart.marker !== undefined) data.marker = chart.marker
|
|
959
972
|
if (chart.barDir !== undefined) data.barDir = chart.barDir
|
|
@@ -964,7 +977,8 @@ async function genChart(node, warpObj) {
|
|
|
964
977
|
return data
|
|
965
978
|
}
|
|
966
979
|
|
|
967
|
-
function genDiagram(node, warpObj) {
|
|
980
|
+
async function genDiagram(node, warpObj) {
|
|
981
|
+
const order = node['attrs']['order']
|
|
968
982
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
969
983
|
const { left, top } = getPosition(xfrmNode, undefined, undefined)
|
|
970
984
|
const { width, height } = getSize(xfrmNode, undefined, undefined)
|
|
@@ -973,7 +987,7 @@ function genDiagram(node, warpObj) {
|
|
|
973
987
|
const elements = []
|
|
974
988
|
if (dgmDrwSpArray) {
|
|
975
989
|
for (const item of dgmDrwSpArray) {
|
|
976
|
-
const el = processSpNode(item, warpObj, 'diagramBg')
|
|
990
|
+
const el = await processSpNode(item, warpObj, 'diagramBg')
|
|
977
991
|
if (el) elements.push(el)
|
|
978
992
|
}
|
|
979
993
|
}
|
|
@@ -985,5 +999,6 @@ function genDiagram(node, warpObj) {
|
|
|
985
999
|
width,
|
|
986
1000
|
height,
|
|
987
1001
|
elements,
|
|
1002
|
+
order,
|
|
988
1003
|
}
|
|
989
1004
|
}
|