pptxtojson 0.1.1 → 0.1.3
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/LICENSE +21 -661
- package/README.md +169 -3
- package/dist/index.d.ts +5 -6
- 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/package.json +2 -2
- package/src/align.js +43 -14
- package/src/fill.js +10 -1
- package/src/fontStyle.js +7 -9
- package/src/position.js +4 -4
- package/src/pptxtojson.js +174 -95
- package/src/readXmlFile.js +4 -2
- package/src/shadow.js +5 -4
- package/src/shape.js +12 -3
- package/src/text.js +13 -11
package/src/pptxtojson.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import JSZip from 'jszip'
|
|
2
2
|
import { readXmlFile } from './readXmlFile'
|
|
3
3
|
import { getBorder } from './border'
|
|
4
|
-
import { getSlideBackgroundFill, getShapeFill } from './fill'
|
|
4
|
+
import { getSlideBackgroundFill, getShapeFill, getSolidFill } from './fill'
|
|
5
5
|
import { getChartInfo } from './chart'
|
|
6
6
|
import { getVerticalAlign } from './align'
|
|
7
7
|
import { getPosition, getSize } from './position'
|
|
@@ -10,30 +10,24 @@ import { getCustomShapePath } from './shape'
|
|
|
10
10
|
import { extractFileExtension, base64ArrayBuffer, getTextByPathList, angleToDegrees, getMimeType, isVideoLink, escapeHtml } from './utils'
|
|
11
11
|
import { getShadow } from './shadow'
|
|
12
12
|
|
|
13
|
-
let SLIDE_FACTOR = 96 / 914400
|
|
14
|
-
let FONTSIZE_FACTOR = 100 / 75
|
|
15
|
-
|
|
16
|
-
const defaultOptions = {
|
|
17
|
-
slideFactor: SLIDE_FACTOR,
|
|
18
|
-
fontsizeFactor: FONTSIZE_FACTOR,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
13
|
export async function parse(file, options = {}) {
|
|
22
|
-
|
|
14
|
+
const defaultOptions = {
|
|
15
|
+
slideFactor: 96 / 914400,
|
|
16
|
+
fontsizeFactor: 100 / 75,
|
|
17
|
+
}
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
if (options.fontsizeFactor) FONTSIZE_FACTOR = options.fontsizeFactor
|
|
19
|
+
options = { ...defaultOptions, ...options }
|
|
26
20
|
|
|
27
21
|
const slides = []
|
|
28
22
|
|
|
29
23
|
const zip = await JSZip.loadAsync(file)
|
|
30
24
|
|
|
31
25
|
const filesInfo = await getContentTypes(zip)
|
|
32
|
-
const { width, height, defaultTextStyle } = await getSlideInfo(zip)
|
|
26
|
+
const { width, height, defaultTextStyle } = await getSlideInfo(zip, options)
|
|
33
27
|
const themeContent = await loadTheme(zip)
|
|
34
28
|
|
|
35
29
|
for (const filename of filesInfo.slides) {
|
|
36
|
-
const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle)
|
|
30
|
+
const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle, options)
|
|
37
31
|
slides.push(singleSlide)
|
|
38
32
|
}
|
|
39
33
|
|
|
@@ -78,13 +72,13 @@ async function getContentTypes(zip) {
|
|
|
78
72
|
}
|
|
79
73
|
}
|
|
80
74
|
|
|
81
|
-
async function getSlideInfo(zip) {
|
|
75
|
+
async function getSlideInfo(zip, options) {
|
|
82
76
|
const content = await readXmlFile(zip, 'ppt/presentation.xml')
|
|
83
77
|
const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']
|
|
84
78
|
const defaultTextStyle = content['p:presentation']['p:defaultTextStyle']
|
|
85
79
|
return {
|
|
86
|
-
width: parseInt(sldSzAttrs['cx']) *
|
|
87
|
-
height: parseInt(sldSzAttrs['cy']) *
|
|
80
|
+
width: parseInt(sldSzAttrs['cx']) * options.slideFactor,
|
|
81
|
+
height: parseInt(sldSzAttrs['cy']) * options.slideFactor,
|
|
88
82
|
defaultTextStyle,
|
|
89
83
|
}
|
|
90
84
|
}
|
|
@@ -110,7 +104,7 @@ async function loadTheme(zip) {
|
|
|
110
104
|
return await readXmlFile(zip, 'ppt/' + themeURI)
|
|
111
105
|
}
|
|
112
106
|
|
|
113
|
-
async function processSingleSlide(zip, sldFileName, themeContent, defaultTextStyle) {
|
|
107
|
+
async function processSingleSlide(zip, sldFileName, themeContent, defaultTextStyle, options) {
|
|
114
108
|
const resName = sldFileName.replace('slides/slide', 'slides/_rels/slide') + '.rels'
|
|
115
109
|
const resContent = await readXmlFile(zip, resName)
|
|
116
110
|
let relationshipArray = resContent['Relationships']['Relationship']
|
|
@@ -252,37 +246,42 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
252
246
|
}
|
|
253
247
|
}
|
|
254
248
|
|
|
249
|
+
const tableStyles = await readXmlFile(zip, 'ppt/tableStyles.xml')
|
|
250
|
+
|
|
255
251
|
const slideContent = await readXmlFile(zip, sldFileName)
|
|
256
252
|
const nodes = slideContent['p:sld']['p:cSld']['p:spTree']
|
|
257
253
|
const warpObj = {
|
|
258
254
|
zip,
|
|
259
|
-
slideLayoutContent
|
|
260
|
-
slideLayoutTables
|
|
261
|
-
slideMasterContent
|
|
262
|
-
slideMasterTables
|
|
263
|
-
slideContent
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
255
|
+
slideLayoutContent,
|
|
256
|
+
slideLayoutTables,
|
|
257
|
+
slideMasterContent,
|
|
258
|
+
slideMasterTables,
|
|
259
|
+
slideContent,
|
|
260
|
+
tableStyles,
|
|
261
|
+
slideResObj,
|
|
262
|
+
slideMasterTextStyles,
|
|
263
|
+
layoutResObj,
|
|
264
|
+
masterResObj,
|
|
265
|
+
themeContent,
|
|
266
|
+
themeResObj,
|
|
267
|
+
digramFileContent,
|
|
268
|
+
diagramResObj,
|
|
269
|
+
defaultTextStyle,
|
|
270
|
+
options,
|
|
273
271
|
}
|
|
272
|
+
// const bgElements = await getBackground(warpObj)
|
|
274
273
|
const bgColor = await getSlideBackgroundFill(warpObj)
|
|
275
274
|
|
|
276
275
|
const elements = []
|
|
277
276
|
for (const nodeKey in nodes) {
|
|
278
277
|
if (nodes[nodeKey].constructor === Array) {
|
|
279
278
|
for (const node of nodes[nodeKey]) {
|
|
280
|
-
const ret = await processNodesInSlide(nodeKey, node, warpObj)
|
|
279
|
+
const ret = await processNodesInSlide(nodeKey, node, warpObj, 'slide')
|
|
281
280
|
if (ret) elements.push(ret)
|
|
282
281
|
}
|
|
283
282
|
}
|
|
284
283
|
else {
|
|
285
|
-
const ret = await processNodesInSlide(nodeKey, nodes[nodeKey], warpObj)
|
|
284
|
+
const ret = await processNodesInSlide(nodeKey, nodes[nodeKey], warpObj, 'slide')
|
|
286
285
|
if (ret) elements.push(ret)
|
|
287
286
|
}
|
|
288
287
|
}
|
|
@@ -293,6 +292,51 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
293
292
|
}
|
|
294
293
|
}
|
|
295
294
|
|
|
295
|
+
// async function getBackground(warpObj) {
|
|
296
|
+
// const elements = []
|
|
297
|
+
// const slideLayoutContent = warpObj['slideLayoutContent']
|
|
298
|
+
// const slideMasterContent = warpObj['slideMasterContent']
|
|
299
|
+
// const nodesSldLayout = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:spTree'])
|
|
300
|
+
// const nodesSldMaster = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:spTree'])
|
|
301
|
+
|
|
302
|
+
// const showMasterSp = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'attrs', 'showMasterSp'])
|
|
303
|
+
// if (nodesSldLayout) {
|
|
304
|
+
// for (const nodeKey in nodesSldLayout) {
|
|
305
|
+
// if (nodesSldLayout[nodeKey].constructor === Array) {
|
|
306
|
+
// for (let i = 0; i < nodesSldLayout[nodeKey].length; i++) {
|
|
307
|
+
// const ph_type = getTextByPathList(nodesSldLayout[nodeKey][i], ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
308
|
+
// if (ph_type !== 'pic') {
|
|
309
|
+
// const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey][i], warpObj, 'slideLayoutBg')
|
|
310
|
+
// if (ret) elements.push(ret)
|
|
311
|
+
// }
|
|
312
|
+
// }
|
|
313
|
+
// }
|
|
314
|
+
// else {
|
|
315
|
+
// const ph_type = getTextByPathList(nodesSldLayout[nodeKey], ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
316
|
+
// if (ph_type !== 'pic') {
|
|
317
|
+
// const ret = await processNodesInSlide(nodeKey, nodesSldLayout[nodeKey], warpObj, 'slideLayoutBg')
|
|
318
|
+
// if (ret) elements.push(ret)
|
|
319
|
+
// }
|
|
320
|
+
// }
|
|
321
|
+
// }
|
|
322
|
+
// }
|
|
323
|
+
// if (nodesSldMaster && (showMasterSp === '1' || showMasterSp)) {
|
|
324
|
+
// for (const nodeKey in nodesSldMaster) {
|
|
325
|
+
// if (nodesSldMaster[nodeKey].constructor === Array) {
|
|
326
|
+
// for (let i = 0; i < nodesSldMaster[nodeKey].length; i++) {
|
|
327
|
+
// const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey][i], warpObj, 'slideMasterBg')
|
|
328
|
+
// if (ret) elements.push(ret)
|
|
329
|
+
// }
|
|
330
|
+
// }
|
|
331
|
+
// else {
|
|
332
|
+
// const ret = await processNodesInSlide(nodeKey, nodesSldMaster[nodeKey], warpObj, 'slideMasterBg')
|
|
333
|
+
// if (ret) elements.push(ret)
|
|
334
|
+
// }
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
337
|
+
// return elements
|
|
338
|
+
// }
|
|
339
|
+
|
|
296
340
|
function indexNodes(content) {
|
|
297
341
|
const keys = Object.keys(content)
|
|
298
342
|
const spTreeNode = content[keys[0]]['p:cSld']['p:spTree']
|
|
@@ -332,27 +376,27 @@ function indexNodes(content) {
|
|
|
332
376
|
return { idTable, idxTable, typeTable }
|
|
333
377
|
}
|
|
334
378
|
|
|
335
|
-
async function processNodesInSlide(nodeKey, nodeValue, warpObj) {
|
|
379
|
+
async function processNodesInSlide(nodeKey, nodeValue, warpObj, source) {
|
|
336
380
|
let json
|
|
337
381
|
|
|
338
382
|
switch (nodeKey) {
|
|
339
383
|
case 'p:sp': // Shape, Text
|
|
340
|
-
json = processSpNode(nodeValue, warpObj)
|
|
384
|
+
json = processSpNode(nodeValue, warpObj, source)
|
|
341
385
|
break
|
|
342
386
|
case 'p:cxnSp': // Shape, Text
|
|
343
|
-
json = processCxnSpNode(nodeValue, warpObj)
|
|
387
|
+
json = processCxnSpNode(nodeValue, warpObj, source)
|
|
344
388
|
break
|
|
345
389
|
case 'p:pic': // Image, Video, Audio
|
|
346
|
-
json = processPicNode(nodeValue, warpObj)
|
|
390
|
+
json = processPicNode(nodeValue, warpObj, source)
|
|
347
391
|
break
|
|
348
392
|
case 'p:graphicFrame': // Chart, Diagram, Table
|
|
349
|
-
json = await processGraphicFrameNode(nodeValue, warpObj)
|
|
393
|
+
json = await processGraphicFrameNode(nodeValue, warpObj, source)
|
|
350
394
|
break
|
|
351
395
|
case 'p:grpSp':
|
|
352
|
-
json = await processGroupSpNode(nodeValue, warpObj)
|
|
396
|
+
json = await processGroupSpNode(nodeValue, warpObj, source)
|
|
353
397
|
break
|
|
354
398
|
case 'mc:AlternateContent':
|
|
355
|
-
json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj)
|
|
399
|
+
json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj, source)
|
|
356
400
|
break
|
|
357
401
|
default:
|
|
358
402
|
}
|
|
@@ -360,45 +404,55 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj) {
|
|
|
360
404
|
return json
|
|
361
405
|
}
|
|
362
406
|
|
|
363
|
-
async function processGroupSpNode(node, warpObj) {
|
|
407
|
+
async function processGroupSpNode(node, warpObj, source) {
|
|
364
408
|
const xfrmNode = getTextByPathList(node, ['p:grpSpPr', 'a:xfrm'])
|
|
365
409
|
if (!xfrmNode) return null
|
|
366
410
|
|
|
367
|
-
const x = parseInt(xfrmNode['a:off']['attrs']['x']) *
|
|
368
|
-
const y = parseInt(xfrmNode['a:off']['attrs']['y']) *
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
const
|
|
372
|
-
const
|
|
373
|
-
const
|
|
374
|
-
|
|
411
|
+
const x = parseInt(xfrmNode['a:off']['attrs']['x']) * warpObj.options.slideFactor
|
|
412
|
+
const y = parseInt(xfrmNode['a:off']['attrs']['y']) * warpObj.options.slideFactor
|
|
413
|
+
// https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.drawing.childoffset?view=openxml-2.8.1
|
|
414
|
+
const chx = parseInt(xfrmNode['a:chOff']['attrs']['x']) * warpObj.options.slideFactor
|
|
415
|
+
const chy = parseInt(xfrmNode['a:chOff']['attrs']['y']) * warpObj.options.slideFactor
|
|
416
|
+
const cx = parseInt(xfrmNode['a:ext']['attrs']['cx']) * warpObj.options.slideFactor
|
|
417
|
+
const cy = parseInt(xfrmNode['a:ext']['attrs']['cy']) * warpObj.options.slideFactor
|
|
418
|
+
// https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.drawing.childextents?view=openxml-2.8.1
|
|
419
|
+
const chcx = parseInt(xfrmNode['a:chExt']['attrs']['cx']) * warpObj.options.slideFactor
|
|
420
|
+
const chcy = parseInt(xfrmNode['a:chExt']['attrs']['cy']) * warpObj.options.slideFactor
|
|
421
|
+
// children coordinate
|
|
422
|
+
const ws = cx / chcx
|
|
423
|
+
const hs = cy / chcy
|
|
375
424
|
|
|
376
425
|
const elements = []
|
|
377
426
|
for (const nodeKey in node) {
|
|
378
427
|
if (node[nodeKey].constructor === Array) {
|
|
379
428
|
for (const item of node[nodeKey]) {
|
|
380
|
-
const ret = await processNodesInSlide(nodeKey, item, warpObj)
|
|
429
|
+
const ret = await processNodesInSlide(nodeKey, item, warpObj, source)
|
|
381
430
|
if (ret) elements.push(ret)
|
|
382
431
|
}
|
|
383
432
|
}
|
|
384
433
|
else {
|
|
385
|
-
const ret = await processNodesInSlide(nodeKey, node[nodeKey], warpObj)
|
|
434
|
+
const ret = await processNodesInSlide(nodeKey, node[nodeKey], warpObj, source)
|
|
386
435
|
if (ret) elements.push(ret)
|
|
387
436
|
}
|
|
388
437
|
}
|
|
389
438
|
|
|
390
439
|
return {
|
|
391
440
|
type: 'group',
|
|
392
|
-
top: y
|
|
393
|
-
left: x
|
|
394
|
-
width: cx
|
|
395
|
-
height: cy
|
|
396
|
-
elements
|
|
441
|
+
top: parseFloat(y.toFixed(2)),
|
|
442
|
+
left: parseFloat(x.toFixed(2)),
|
|
443
|
+
width: parseFloat(cx.toFixed(2)),
|
|
444
|
+
height: parseFloat(cy.toFixed(2)),
|
|
445
|
+
elements: elements.map(element => ({
|
|
446
|
+
...element,
|
|
447
|
+
left: parseFloat(((element.left - chx) * ws).toFixed(2)),
|
|
448
|
+
top: parseFloat(((element.top - chy) * hs).toFixed(2)),
|
|
449
|
+
width: parseFloat((element.width * ws).toFixed(2)),
|
|
450
|
+
height: parseFloat((element.height * hs).toFixed(2)),
|
|
451
|
+
}))
|
|
397
452
|
}
|
|
398
453
|
}
|
|
399
454
|
|
|
400
455
|
function processSpNode(node, warpObj, source) {
|
|
401
|
-
const id = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'id'])
|
|
402
456
|
const name = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'name'])
|
|
403
457
|
const idx = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'idx'])
|
|
404
458
|
let type = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
@@ -432,19 +486,17 @@ function processSpNode(node, warpObj, source) {
|
|
|
432
486
|
else type = 'obj'
|
|
433
487
|
}
|
|
434
488
|
|
|
435
|
-
return genShape(node, slideLayoutSpNode, slideMasterSpNode,
|
|
489
|
+
return genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj)
|
|
436
490
|
}
|
|
437
491
|
|
|
438
492
|
function processCxnSpNode(node, warpObj) {
|
|
439
|
-
const id = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['id']
|
|
440
493
|
const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
|
|
441
|
-
const idx = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['idx']
|
|
442
494
|
const type = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
|
|
443
495
|
|
|
444
|
-
return genShape(node, undefined, undefined,
|
|
496
|
+
return genShape(node, undefined, undefined, name, type, warpObj)
|
|
445
497
|
}
|
|
446
498
|
|
|
447
|
-
function genShape(node, slideLayoutSpNode, slideMasterSpNode,
|
|
499
|
+
function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj) {
|
|
448
500
|
const xfrmList = ['p:spPr', 'a:xfrm']
|
|
449
501
|
const slideXfrmNode = getTextByPathList(node, xfrmList)
|
|
450
502
|
const slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList)
|
|
@@ -453,8 +505,8 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
|
|
|
453
505
|
const shapType = getTextByPathList(node, ['p:spPr', 'a:prstGeom', 'attrs', 'prst'])
|
|
454
506
|
const custShapType = getTextByPathList(node, ['p:spPr', 'a:custGeom'])
|
|
455
507
|
|
|
456
|
-
const { top, left } = getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode,
|
|
457
|
-
const { width, height } = getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode,
|
|
508
|
+
const { top, left } = getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, warpObj.options.slideFactor)
|
|
509
|
+
const { width, height } = getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, warpObj.options.slideFactor)
|
|
458
510
|
|
|
459
511
|
const isFlipV = getTextByPathList(slideXfrmNode, ['attrs', 'flipV']) === '1'
|
|
460
512
|
const isFlipH = getTextByPathList(slideXfrmNode, ['attrs', 'flipH']) === '1'
|
|
@@ -470,14 +522,14 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
|
|
|
470
522
|
else txtRotate = rotate
|
|
471
523
|
|
|
472
524
|
let content = ''
|
|
473
|
-
if (node['p:txBody']) content = genTextBody(node['p:txBody'],
|
|
525
|
+
if (node['p:txBody']) content = genTextBody(node['p:txBody'], node, slideLayoutSpNode, type, warpObj)
|
|
474
526
|
|
|
475
527
|
const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(node, type, warpObj)
|
|
476
528
|
const fillColor = getShapeFill(node, undefined, warpObj) || ''
|
|
477
529
|
|
|
478
530
|
let shadow
|
|
479
531
|
const outerShdwNode = getTextByPathList(node, ['p:spPr', 'a:effectLst', 'a:outerShdw'])
|
|
480
|
-
if (outerShdwNode) shadow = getShadow(outerShdwNode, warpObj
|
|
532
|
+
if (outerShdwNode) shadow = getShadow(outerShdwNode, warpObj)
|
|
481
533
|
|
|
482
534
|
const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
|
|
483
535
|
const isVertical = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) === 'eaVert'
|
|
@@ -497,40 +549,28 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
|
|
|
497
549
|
isFlipH,
|
|
498
550
|
rotate,
|
|
499
551
|
vAlign,
|
|
500
|
-
id,
|
|
501
552
|
name,
|
|
502
|
-
idx,
|
|
503
553
|
}
|
|
504
554
|
|
|
505
555
|
if (shadow) data.shadow = shadow
|
|
506
556
|
|
|
507
557
|
if (custShapType && type !== 'diagram') {
|
|
508
558
|
const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
|
|
509
|
-
const
|
|
510
|
-
const
|
|
511
|
-
const w = parseInt(ext['cx']) * SLIDE_FACTOR
|
|
512
|
-
const h = parseInt(ext['cy']) * SLIDE_FACTOR
|
|
559
|
+
const w = parseInt(ext['cx']) * warpObj.options.slideFactor
|
|
560
|
+
const h = parseInt(ext['cy']) * warpObj.options.slideFactor
|
|
513
561
|
const d = getCustomShapePath(custShapType, w, h)
|
|
514
562
|
|
|
515
563
|
return {
|
|
516
564
|
...data,
|
|
517
565
|
type: 'shape',
|
|
518
|
-
cx,
|
|
519
|
-
cy,
|
|
520
566
|
shapType: 'custom',
|
|
521
567
|
path: d,
|
|
522
568
|
}
|
|
523
569
|
}
|
|
524
570
|
if (shapType && type !== 'text') {
|
|
525
|
-
const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
|
|
526
|
-
const cx = parseInt(ext['cx']) * SLIDE_FACTOR
|
|
527
|
-
const cy = parseInt(ext['cy']) * SLIDE_FACTOR
|
|
528
|
-
|
|
529
571
|
return {
|
|
530
572
|
...data,
|
|
531
573
|
type: 'shape',
|
|
532
|
-
cx,
|
|
533
|
-
cy,
|
|
534
574
|
shapType,
|
|
535
575
|
}
|
|
536
576
|
}
|
|
@@ -556,10 +596,13 @@ async function processPicNode(node, warpObj, source) {
|
|
|
556
596
|
const xfrmNode = node['p:spPr']['a:xfrm']
|
|
557
597
|
|
|
558
598
|
const mimeType = getMimeType(imgFileExt)
|
|
559
|
-
const { top, left } = getPosition(xfrmNode, undefined, undefined,
|
|
560
|
-
const { width, height } = getSize(xfrmNode, undefined, undefined,
|
|
599
|
+
const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
600
|
+
const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
561
601
|
const src = `data:${mimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
|
|
562
602
|
|
|
603
|
+
const isFlipV = getTextByPathList(xfrmNode, ['attrs', 'flipV']) === '1'
|
|
604
|
+
const isFlipH = getTextByPathList(xfrmNode, ['attrs', 'flipH']) === '1'
|
|
605
|
+
|
|
563
606
|
let rotate = 0
|
|
564
607
|
const rotateNode = getTextByPathList(node, ['p:spPr', 'a:xfrm', 'attrs', 'rot'])
|
|
565
608
|
if (rotateNode) rotate = angleToDegrees(rotateNode)
|
|
@@ -640,10 +683,12 @@ async function processPicNode(node, warpObj, source) {
|
|
|
640
683
|
height,
|
|
641
684
|
rotate,
|
|
642
685
|
src,
|
|
686
|
+
isFlipV,
|
|
687
|
+
isFlipH
|
|
643
688
|
}
|
|
644
689
|
}
|
|
645
690
|
|
|
646
|
-
async function processGraphicFrameNode(node, warpObj) {
|
|
691
|
+
async function processGraphicFrameNode(node, warpObj, source) {
|
|
647
692
|
const graphicTypeUri = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'attrs', 'uri'])
|
|
648
693
|
|
|
649
694
|
let result
|
|
@@ -660,7 +705,7 @@ async function processGraphicFrameNode(node, warpObj) {
|
|
|
660
705
|
case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
|
|
661
706
|
let oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'mc:AlternateContent', 'mc:Fallback', 'p:oleObj'])
|
|
662
707
|
if (!oleObjNode) oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'p:oleObj'])
|
|
663
|
-
else processGroupSpNode(oleObjNode, warpObj)
|
|
708
|
+
else processGroupSpNode(oleObjNode, warpObj, source)
|
|
664
709
|
break
|
|
665
710
|
default:
|
|
666
711
|
}
|
|
@@ -670,8 +715,41 @@ async function processGraphicFrameNode(node, warpObj) {
|
|
|
670
715
|
function genTable(node, warpObj) {
|
|
671
716
|
const tableNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl'])
|
|
672
717
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
673
|
-
const { top, left } = getPosition(xfrmNode, undefined, undefined,
|
|
674
|
-
const { width, height } = getSize(xfrmNode, undefined, undefined,
|
|
718
|
+
const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
719
|
+
const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
720
|
+
|
|
721
|
+
const getTblPr = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl', 'a:tblPr'])
|
|
722
|
+
|
|
723
|
+
let thisTblStyle
|
|
724
|
+
const tbleStyleId = getTblPr['a:tableStyleId']
|
|
725
|
+
if (tbleStyleId) {
|
|
726
|
+
const tbleStylList = warpObj['tableStyles']['a:tblStyleLst']['a:tblStyle']
|
|
727
|
+
if (tbleStylList) {
|
|
728
|
+
if (tbleStylList.constructor === Array) {
|
|
729
|
+
for (let k = 0; k < tbleStylList.length; k++) {
|
|
730
|
+
if (tbleStylList[k]['attrs']['styleId'] === tbleStyleId) {
|
|
731
|
+
thisTblStyle = tbleStylList[k]
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
if (tbleStylList['attrs']['styleId'] === tbleStyleId) {
|
|
737
|
+
thisTblStyle = tbleStylList
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
let themeColor = ''
|
|
744
|
+
let tbl_bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:tblBg', 'a:fillRef'])
|
|
745
|
+
if (tbl_bgFillschemeClr) {
|
|
746
|
+
themeColor = getSolidFill(tbl_bgFillschemeClr, undefined, undefined, warpObj)
|
|
747
|
+
}
|
|
748
|
+
if (tbl_bgFillschemeClr === undefined) {
|
|
749
|
+
tbl_bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:fill', 'a:solidFill'])
|
|
750
|
+
themeColor = getSolidFill(tbl_bgFillschemeClr, undefined, undefined, warpObj)
|
|
751
|
+
}
|
|
752
|
+
if (themeColor !== '') themeColor = '#' + themeColor
|
|
675
753
|
|
|
676
754
|
const trNodes = tableNode['a:tr']
|
|
677
755
|
|
|
@@ -683,7 +761,7 @@ function genTable(node, warpObj) {
|
|
|
683
761
|
|
|
684
762
|
if (tcNodes.constructor === Array) {
|
|
685
763
|
for (const tcNode of tcNodes) {
|
|
686
|
-
const text = genTextBody(tcNode['a:txBody'],
|
|
764
|
+
const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
|
|
687
765
|
const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
|
|
688
766
|
const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
|
|
689
767
|
const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
|
|
@@ -693,7 +771,7 @@ function genTable(node, warpObj) {
|
|
|
693
771
|
}
|
|
694
772
|
}
|
|
695
773
|
else {
|
|
696
|
-
const text = genTextBody(tcNodes['a:txBody'],
|
|
774
|
+
const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
|
|
697
775
|
tr.push({ text })
|
|
698
776
|
}
|
|
699
777
|
data.push(tr)
|
|
@@ -705,12 +783,12 @@ function genTable(node, warpObj) {
|
|
|
705
783
|
|
|
706
784
|
if (tcNodes.constructor === Array) {
|
|
707
785
|
for (const tcNode of tcNodes) {
|
|
708
|
-
const text = genTextBody(tcNode['a:txBody'],
|
|
786
|
+
const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
|
|
709
787
|
tr.push({ text })
|
|
710
788
|
}
|
|
711
789
|
}
|
|
712
790
|
else {
|
|
713
|
-
const text = genTextBody(tcNodes['a:txBody'],
|
|
791
|
+
const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
|
|
714
792
|
tr.push({ text })
|
|
715
793
|
}
|
|
716
794
|
data.push(tr)
|
|
@@ -723,13 +801,14 @@ function genTable(node, warpObj) {
|
|
|
723
801
|
width,
|
|
724
802
|
height,
|
|
725
803
|
data,
|
|
804
|
+
themeColor,
|
|
726
805
|
}
|
|
727
806
|
}
|
|
728
807
|
|
|
729
808
|
async function genChart(node, warpObj) {
|
|
730
809
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
731
|
-
const { top, left } = getPosition(xfrmNode, undefined, undefined,
|
|
732
|
-
const { width, height } = getSize(xfrmNode, undefined, undefined,
|
|
810
|
+
const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
811
|
+
const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
733
812
|
|
|
734
813
|
const rid = node['a:graphic']['a:graphicData']['c:chart']['attrs']['r:id']
|
|
735
814
|
const refName = warpObj['slideResObj'][rid]['target']
|
|
@@ -760,8 +839,8 @@ async function genChart(node, warpObj) {
|
|
|
760
839
|
|
|
761
840
|
function genDiagram(node, warpObj) {
|
|
762
841
|
const xfrmNode = getTextByPathList(node, ['p:xfrm'])
|
|
763
|
-
const { left, top } = getPosition(xfrmNode, undefined, undefined,
|
|
764
|
-
const { width, height } = getSize(xfrmNode, undefined, undefined,
|
|
842
|
+
const { left, top } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
843
|
+
const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
|
|
765
844
|
|
|
766
845
|
const dgmDrwSpArray = getTextByPathList(warpObj['digramFileContent'], ['p:drawing', 'p:spTree', 'p:sp'])
|
|
767
846
|
const elements = []
|
package/src/readXmlFile.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as txml from 'txml/dist/txml.mjs'
|
|
2
2
|
|
|
3
|
+
let cust_attr_order = 0
|
|
4
|
+
|
|
3
5
|
export function simplifyLostLess(children, parentAttributes = {}) {
|
|
4
6
|
const out = {}
|
|
5
7
|
if (!children.length) return out
|
|
6
8
|
|
|
7
9
|
if (children.length === 1 && typeof children[0] === 'string') {
|
|
8
10
|
return Object.keys(parentAttributes).length ? {
|
|
9
|
-
attrs: parentAttributes,
|
|
11
|
+
attrs: { order: cust_attr_order++, ...parentAttributes },
|
|
10
12
|
value: children[0],
|
|
11
13
|
} : children[0]
|
|
12
14
|
}
|
|
@@ -20,7 +22,7 @@ export function simplifyLostLess(children, parentAttributes = {}) {
|
|
|
20
22
|
out[child.tagName].push(kids)
|
|
21
23
|
|
|
22
24
|
if (Object.keys(child.attributes).length) {
|
|
23
|
-
kids.attrs = child.attributes
|
|
25
|
+
kids.attrs = { order: cust_attr_order++, ...child.attributes }
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
for (const child in out) {
|
package/src/shadow.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { getSolidFill } from './fill'
|
|
2
2
|
|
|
3
|
-
export function getShadow(node, warpObj
|
|
3
|
+
export function getShadow(node, warpObj) {
|
|
4
|
+
const slideFactor = warpObj.options.slideFactor
|
|
4
5
|
const chdwClrNode = getSolidFill(node, undefined, undefined, warpObj)
|
|
5
6
|
const outerShdwAttrs = node['attrs']
|
|
6
7
|
const dir = (outerShdwAttrs['dir']) ? (parseInt(outerShdwAttrs['dir']) / 60000) : 0
|
|
7
8
|
const dist = parseInt(outerShdwAttrs['dist']) * slideFactor
|
|
8
|
-
const blurRad = outerShdwAttrs['blurRad'] ? (parseInt(outerShdwAttrs['blurRad']) * slideFactor) : ''
|
|
9
|
+
const blurRad = outerShdwAttrs['blurRad'] ? parseFloat((parseInt(outerShdwAttrs['blurRad']) * slideFactor).toFixed(2)) : ''
|
|
9
10
|
const vx = dist * Math.sin(dir * Math.PI / 180)
|
|
10
11
|
const hx = dist * Math.cos(dir * Math.PI / 180)
|
|
11
12
|
|
|
12
13
|
return {
|
|
13
|
-
h: hx,
|
|
14
|
-
v: vx,
|
|
14
|
+
h: parseFloat(hx.toFixed(2)),
|
|
15
|
+
v: parseFloat(vx.toFixed(2)),
|
|
15
16
|
blur: blurRad,
|
|
16
17
|
color: '#' + chdwClrNode,
|
|
17
18
|
}
|
package/src/shape.js
CHANGED
|
@@ -57,11 +57,12 @@ export function getCustomShapePath(custShapType, w, h) {
|
|
|
57
57
|
const moveToNoPt = moveToPtNode[key]
|
|
58
58
|
const spX = moveToNoPt['attrs', 'x']
|
|
59
59
|
const spY = moveToNoPt['attrs', 'y']
|
|
60
|
-
|
|
60
|
+
const order = moveToNoPt['attrs', 'order']
|
|
61
61
|
multiSapeAry.push({
|
|
62
62
|
type: 'movto',
|
|
63
63
|
x: spX,
|
|
64
64
|
y: spY,
|
|
65
|
+
order,
|
|
65
66
|
})
|
|
66
67
|
})
|
|
67
68
|
}
|
|
@@ -74,10 +75,12 @@ export function getCustomShapePath(custShapType, w, h) {
|
|
|
74
75
|
const lnToNoPt = lnToPtNode[key]
|
|
75
76
|
const ptX = lnToNoPt['attrs', 'x']
|
|
76
77
|
const ptY = lnToNoPt['attrs', 'y']
|
|
78
|
+
const order = lnToNoPt['attrs', 'order']
|
|
77
79
|
multiSapeAry.push({
|
|
78
80
|
type: 'lnto',
|
|
79
81
|
x: ptX,
|
|
80
82
|
y: ptY,
|
|
83
|
+
order,
|
|
81
84
|
})
|
|
82
85
|
})
|
|
83
86
|
}
|
|
@@ -101,14 +104,17 @@ export function getCustomShapePath(custShapType, w, h) {
|
|
|
101
104
|
}
|
|
102
105
|
pts_ary.push(pt_obj)
|
|
103
106
|
})
|
|
107
|
+
const order = key[0]['attrs']['order']
|
|
104
108
|
multiSapeAry.push({
|
|
105
109
|
type: 'cubicBezTo',
|
|
106
|
-
cubBzPt: pts_ary
|
|
110
|
+
cubBzPt: pts_ary,
|
|
111
|
+
order,
|
|
107
112
|
})
|
|
108
113
|
})
|
|
109
114
|
}
|
|
110
115
|
if (arcToNodes) {
|
|
111
116
|
const arcToNodesAttrs = arcToNodes['attrs']
|
|
117
|
+
const order = arcToNodesAttrs['order']
|
|
112
118
|
const hR = arcToNodesAttrs['hR']
|
|
113
119
|
const wR = arcToNodesAttrs['wR']
|
|
114
120
|
const stAng = arcToNodesAttrs['stAng']
|
|
@@ -128,6 +134,7 @@ export function getCustomShapePath(custShapType, w, h) {
|
|
|
128
134
|
swAng: swAng,
|
|
129
135
|
shftX: shftX,
|
|
130
136
|
shftY: shftY,
|
|
137
|
+
order,
|
|
131
138
|
})
|
|
132
139
|
}
|
|
133
140
|
if (closeNode) {
|
|
@@ -135,13 +142,15 @@ export function getCustomShapePath(custShapType, w, h) {
|
|
|
135
142
|
Object.keys(closeNode).forEach(() => {
|
|
136
143
|
multiSapeAry.push({
|
|
137
144
|
type: 'close',
|
|
145
|
+
order: Infinity,
|
|
138
146
|
})
|
|
139
147
|
})
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
multiSapeAry.sort((a, b) => a.order - b.order)
|
|
151
|
+
|
|
142
152
|
let k = 0
|
|
143
153
|
while (k < multiSapeAry.length) {
|
|
144
|
-
|
|
145
154
|
if (multiSapeAry[k].type === 'movto') {
|
|
146
155
|
const spX = parseInt(multiSapeAry[k].x) * cX
|
|
147
156
|
const spY = parseInt(multiSapeAry[k].y) * cY
|