pptxtojson 0.1.2 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptxtojson",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
@@ -12,7 +12,7 @@
12
12
  "lint": "eslint src --ext .js,.jsx,.ts,.tsx"
13
13
  },
14
14
  "author": "",
15
- "license": "AGPL-3.0",
15
+ "license": "MIT",
16
16
  "publishConfig": {
17
17
  "registry": "https://registry.npmjs.com/"
18
18
  },
package/src/align.js CHANGED
@@ -1,26 +1,55 @@
1
1
  import { getTextByPathList } from './utils'
2
2
 
3
- export function getHorizontalAlign(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) {
3
+ export function getHorizontalAlign(node, pNode, type, warpObj) {
4
4
  let algn = getTextByPathList(node, ['a:pPr', 'attrs', 'algn'])
5
+ if (!algn) algn = getTextByPathList(pNode, ['a:pPr', 'attrs', 'algn'])
5
6
 
6
- if (!algn) algn = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:p', 'a:pPr', 'attrs', 'algn'])
7
- if (!algn) algn = getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:p', 'a:pPr', 'attrs', 'algn'])
8
7
  if (!algn) {
9
- switch (type) {
10
- case 'title':
11
- case 'subTitle':
12
- case 'ctrTitle':
13
- algn = getTextByPathList(slideMasterTextStyles, ['p:titleStyle', 'a:lvl1pPr', 'attrs', 'algn'])
8
+ if (type === 'title' || type === 'ctrTitle' || type === 'subTitle') {
9
+ let lvlIdx = 1
10
+ const lvlNode = getTextByPathList(pNode, ['a:pPr', 'attrs', 'lvl'])
11
+ if (lvlNode) {
12
+ lvlIdx = parseInt(lvlNode) + 1
13
+ }
14
+ const lvlStr = 'a:lvl' + lvlIdx + 'pPr'
15
+ algn = getTextByPathList(warpObj, ['slideLayoutTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
16
+ if (!algn) algn = getTextByPathList(warpObj, ['slideMasterTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
17
+ if (!algn) algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:titleStyle', lvlStr, 'attrs', 'algn'])
18
+ if (!algn && type === 'subTitle') {
19
+ algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', lvlStr, 'attrs', 'algn'])
20
+ }
21
+ }
22
+ else if (type === 'body') {
23
+ algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', 'a:lvl1pPr', 'attrs', 'algn'])
24
+ }
25
+ else {
26
+ algn = getTextByPathList(warpObj, ['slideMasterTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', 'a:lvl1pPr', 'attrs', 'algn'])
27
+ }
28
+ }
29
+
30
+ let align = 'left'
31
+ if (algn) {
32
+ switch (algn) {
33
+ case 'l':
34
+ align = 'left'
35
+ break
36
+ case 'r':
37
+ align = 'right'
38
+ break
39
+ case 'ctr':
40
+ align = 'center'
41
+ break
42
+ case 'just':
43
+ align = 'justify'
44
+ break
45
+ case 'dist':
46
+ align = 'justify'
14
47
  break
15
48
  default:
16
- algn = getTextByPathList(slideMasterTextStyles, ['p:otherStyle', 'a:lvl1pPr', 'attrs', 'algn'])
49
+ align = 'inherit'
17
50
  }
18
51
  }
19
- if (!algn) {
20
- if (type === 'title' || type === 'subTitle' || type === 'ctrTitle') return 'center'
21
- else if (type === 'sldNum') return 'right'
22
- }
23
- return algn === 'ctr' ? 'center' : algn === 'r' ? 'right' : 'left'
52
+ return align
24
53
  }
25
54
 
26
55
  export function getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode) {
package/src/fill.js CHANGED
@@ -244,7 +244,7 @@ export function getShapeFill(node, isSvgMode, warpObj) {
244
244
  if (isNaN(lumOff)) lumOff = 0
245
245
 
246
246
  const color = tinycolor(fillColor).toHsl()
247
- const lum = color.l * (1 + lumOff)
247
+ const lum = color.l * lumMod + lumOff
248
248
  return tinycolor({ h: color.h, s: color.s, l: lum, a: color.a }).toHexString()
249
249
  }
250
250
 
@@ -264,6 +264,15 @@ export function getSolidFill(solidFill, clrMap, phClr, warpObj) {
264
264
  else if (solidFill['a:schemeClr']) {
265
265
  const schemeClr = 'a:' + getTextByPathList(solidFill['a:schemeClr'], ['attrs', 'val'])
266
266
  color = getSchemeColorFromTheme(schemeClr, warpObj)
267
+
268
+ let lumMod = parseInt(getTextByPathList(solidFill, ['a:schemeClr', 'a:lumMod', 'attrs', 'val'])) / 100000
269
+ let lumOff = parseInt(getTextByPathList(solidFill, ['a:schemeClr', 'a:lumOff', 'attrs', 'val'])) / 100000
270
+ if (isNaN(lumMod)) lumMod = 1.0
271
+ if (isNaN(lumOff)) lumOff = 0
272
+
273
+ color = tinycolor(color).toHsl()
274
+ const lum = color.l * lumMod + lumOff
275
+ return tinycolor({ h: color.h, s: color.s, l: lum, a: color.a }).toHex()
267
276
  }
268
277
  else if (solidFill['a:scrgbClr']) {
269
278
  clrNode = solidFill['a:scrgbClr']
package/src/fontStyle.js CHANGED
@@ -58,7 +58,7 @@ export function getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles
58
58
 
59
59
  fontSize = (isNaN(fontSize) || !fontSize) ? 18 : fontSize
60
60
 
61
- return fontSize * fontsizeFactor + 'px'
61
+ return parseFloat((fontSize * fontsizeFactor).toFixed(2)) + (fontsizeFactor === 1 ? 'pt' : 'px')
62
62
  }
63
63
 
64
64
  export function getFontBold(node) {
@@ -88,10 +88,10 @@ export function getFontSubscript(node) {
88
88
  return parseInt(baseline) > 0 ? 'super' : 'sub'
89
89
  }
90
90
 
91
- export function getFontShadow(node, warpObj, slideFactor) {
91
+ export function getFontShadow(node, warpObj) {
92
92
  const txtShadow = getTextByPathList(node, ['a:rPr', 'a:effectLst', 'a:outerShdw'])
93
93
  if (txtShadow) {
94
- const shadow = getShadow(txtShadow, warpObj, slideFactor)
94
+ const shadow = getShadow(txtShadow, warpObj)
95
95
  if (shadow) {
96
96
  const { h, v, blur, color } = shadow
97
97
  if (!isNaN(v) && !isNaN(h)) {
package/src/position.js CHANGED
@@ -8,8 +8,8 @@ export function getPosition(slideSpNode, slideLayoutSpNode, slideMasterSpNode, f
8
8
  if (!off) return { top: 0, left: 0 }
9
9
 
10
10
  return {
11
- top: parseInt(off['y']) * factor,
12
- left: parseInt(off['x']) * factor,
11
+ top: parseFloat((parseInt(off['y']) * factor).toFixed(2)),
12
+ left: parseFloat((parseInt(off['x']) * factor).toFixed(2)),
13
13
  }
14
14
  }
15
15
 
@@ -23,7 +23,7 @@ export function getSize(slideSpNode, slideLayoutSpNode, slideMasterSpNode, facto
23
23
  if (!ext) return { width: 0, height: 0 }
24
24
 
25
25
  return {
26
- width: parseInt(ext['cx']) * factor,
27
- height: parseInt(ext['cy']) * factor,
26
+ width: parseFloat((parseInt(ext['cx']) * factor).toFixed(2)),
27
+ height: parseFloat((parseInt(ext['cy']) * factor).toFixed(2)),
28
28
  }
29
29
  }
package/src/pptxtojson.js CHANGED
@@ -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
- options = { ...defaultOptions, ...options }
14
+ const defaultOptions = {
15
+ slideFactor: 96 / 914400,
16
+ fontsizeFactor: 100 / 75,
17
+ }
23
18
 
24
- if (options.slideFactor) SLIDE_FACTOR = options.slideFactor
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']) * SLIDE_FACTOR,
87
- height: parseInt(sldSzAttrs['cy']) * SLIDE_FACTOR,
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']
@@ -258,34 +252,36 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
258
252
  const nodes = slideContent['p:sld']['p:cSld']['p:spTree']
259
253
  const warpObj = {
260
254
  zip,
261
- slideLayoutContent: slideLayoutContent,
262
- slideLayoutTables: slideLayoutTables,
263
- slideMasterContent: slideMasterContent,
264
- slideMasterTables: slideMasterTables,
265
- slideContent: slideContent,
266
- tableStyles: tableStyles,
267
- slideResObj: slideResObj,
268
- slideMasterTextStyles: slideMasterTextStyles,
269
- layoutResObj: layoutResObj,
270
- masterResObj: masterResObj,
271
- themeContent: themeContent,
272
- themeResObj: themeResObj,
273
- digramFileContent: digramFileContent,
274
- diagramResObj: diagramResObj,
275
- defaultTextStyle: defaultTextStyle,
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,
276
271
  }
272
+ // const bgElements = await getBackground(warpObj)
277
273
  const bgColor = await getSlideBackgroundFill(warpObj)
278
274
 
279
275
  const elements = []
280
276
  for (const nodeKey in nodes) {
281
277
  if (nodes[nodeKey].constructor === Array) {
282
278
  for (const node of nodes[nodeKey]) {
283
- const ret = await processNodesInSlide(nodeKey, node, warpObj)
279
+ const ret = await processNodesInSlide(nodeKey, node, warpObj, 'slide')
284
280
  if (ret) elements.push(ret)
285
281
  }
286
282
  }
287
283
  else {
288
- const ret = await processNodesInSlide(nodeKey, nodes[nodeKey], warpObj)
284
+ const ret = await processNodesInSlide(nodeKey, nodes[nodeKey], warpObj, 'slide')
289
285
  if (ret) elements.push(ret)
290
286
  }
291
287
  }
@@ -296,6 +292,51 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
296
292
  }
297
293
  }
298
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
+
299
340
  function indexNodes(content) {
300
341
  const keys = Object.keys(content)
301
342
  const spTreeNode = content[keys[0]]['p:cSld']['p:spTree']
@@ -335,27 +376,27 @@ function indexNodes(content) {
335
376
  return { idTable, idxTable, typeTable }
336
377
  }
337
378
 
338
- async function processNodesInSlide(nodeKey, nodeValue, warpObj) {
379
+ async function processNodesInSlide(nodeKey, nodeValue, warpObj, source) {
339
380
  let json
340
381
 
341
382
  switch (nodeKey) {
342
383
  case 'p:sp': // Shape, Text
343
- json = processSpNode(nodeValue, warpObj)
384
+ json = processSpNode(nodeValue, warpObj, source)
344
385
  break
345
386
  case 'p:cxnSp': // Shape, Text
346
- json = processCxnSpNode(nodeValue, warpObj)
387
+ json = processCxnSpNode(nodeValue, warpObj, source)
347
388
  break
348
389
  case 'p:pic': // Image, Video, Audio
349
- json = processPicNode(nodeValue, warpObj)
390
+ json = processPicNode(nodeValue, warpObj, source)
350
391
  break
351
392
  case 'p:graphicFrame': // Chart, Diagram, Table
352
- json = await processGraphicFrameNode(nodeValue, warpObj)
393
+ json = await processGraphicFrameNode(nodeValue, warpObj, source)
353
394
  break
354
395
  case 'p:grpSp':
355
- json = await processGroupSpNode(nodeValue, warpObj)
396
+ json = await processGroupSpNode(nodeValue, warpObj, source)
356
397
  break
357
398
  case 'mc:AlternateContent':
358
- json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj)
399
+ json = await processGroupSpNode(getTextByPathList(nodeValue, ['mc:Fallback']), warpObj, source)
359
400
  break
360
401
  default:
361
402
  }
@@ -363,45 +404,55 @@ async function processNodesInSlide(nodeKey, nodeValue, warpObj) {
363
404
  return json
364
405
  }
365
406
 
366
- async function processGroupSpNode(node, warpObj) {
407
+ async function processGroupSpNode(node, warpObj, source) {
367
408
  const xfrmNode = getTextByPathList(node, ['p:grpSpPr', 'a:xfrm'])
368
409
  if (!xfrmNode) return null
369
410
 
370
- const x = parseInt(xfrmNode['a:off']['attrs']['x']) * SLIDE_FACTOR
371
- const y = parseInt(xfrmNode['a:off']['attrs']['y']) * SLIDE_FACTOR
372
- const chx = parseInt(xfrmNode['a:chOff']['attrs']['x']) * SLIDE_FACTOR
373
- const chy = parseInt(xfrmNode['a:chOff']['attrs']['y']) * SLIDE_FACTOR
374
- const cx = parseInt(xfrmNode['a:ext']['attrs']['cx']) * SLIDE_FACTOR
375
- const cy = parseInt(xfrmNode['a:ext']['attrs']['cy']) * SLIDE_FACTOR
376
- const chcx = parseInt(xfrmNode['a:chExt']['attrs']['cx']) * SLIDE_FACTOR
377
- const chcy = parseInt(xfrmNode['a:chExt']['attrs']['cy']) * SLIDE_FACTOR
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
378
424
 
379
425
  const elements = []
380
426
  for (const nodeKey in node) {
381
427
  if (node[nodeKey].constructor === Array) {
382
428
  for (const item of node[nodeKey]) {
383
- const ret = await processNodesInSlide(nodeKey, item, warpObj)
429
+ const ret = await processNodesInSlide(nodeKey, item, warpObj, source)
384
430
  if (ret) elements.push(ret)
385
431
  }
386
432
  }
387
433
  else {
388
- const ret = await processNodesInSlide(nodeKey, node[nodeKey], warpObj)
434
+ const ret = await processNodesInSlide(nodeKey, node[nodeKey], warpObj, source)
389
435
  if (ret) elements.push(ret)
390
436
  }
391
437
  }
392
438
 
393
439
  return {
394
440
  type: 'group',
395
- top: y - chy,
396
- left: x - chx,
397
- width: cx - chcx,
398
- height: cy - chcy,
399
- 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
+ }))
400
452
  }
401
453
  }
402
454
 
403
455
  function processSpNode(node, warpObj, source) {
404
- const id = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'id'])
405
456
  const name = getTextByPathList(node, ['p:nvSpPr', 'p:cNvPr', 'attrs', 'name'])
406
457
  const idx = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'idx'])
407
458
  let type = getTextByPathList(node, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
@@ -435,19 +486,17 @@ function processSpNode(node, warpObj, source) {
435
486
  else type = 'obj'
436
487
  }
437
488
 
438
- return genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, warpObj)
489
+ return genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj)
439
490
  }
440
491
 
441
492
  function processCxnSpNode(node, warpObj) {
442
- const id = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['id']
443
493
  const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
444
- const idx = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['idx']
445
494
  const type = (node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined) ? undefined : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
446
495
 
447
- return genShape(node, undefined, undefined, id, name, idx, type, warpObj)
496
+ return genShape(node, undefined, undefined, name, type, warpObj)
448
497
  }
449
498
 
450
- function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, warpObj) {
499
+ function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type, warpObj) {
451
500
  const xfrmList = ['p:spPr', 'a:xfrm']
452
501
  const slideXfrmNode = getTextByPathList(node, xfrmList)
453
502
  const slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList)
@@ -456,8 +505,8 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
456
505
  const shapType = getTextByPathList(node, ['p:spPr', 'a:prstGeom', 'attrs', 'prst'])
457
506
  const custShapType = getTextByPathList(node, ['p:spPr', 'a:custGeom'])
458
507
 
459
- const { top, left } = getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, SLIDE_FACTOR)
460
- const { width, height } = getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, SLIDE_FACTOR)
508
+ const { top, left } = getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, warpObj.options.slideFactor)
509
+ const { width, height } = getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode, warpObj.options.slideFactor)
461
510
 
462
511
  const isFlipV = getTextByPathList(slideXfrmNode, ['attrs', 'flipV']) === '1'
463
512
  const isFlipH = getTextByPathList(slideXfrmNode, ['attrs', 'flipH']) === '1'
@@ -473,14 +522,14 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
473
522
  else txtRotate = rotate
474
523
 
475
524
  let content = ''
476
- if (node['p:txBody']) content = genTextBody(node['p:txBody'], slideLayoutSpNode, slideMasterSpNode, type, warpObj, FONTSIZE_FACTOR, SLIDE_FACTOR)
525
+ if (node['p:txBody']) content = genTextBody(node['p:txBody'], node, slideLayoutSpNode, type, warpObj)
477
526
 
478
527
  const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(node, type, warpObj)
479
528
  const fillColor = getShapeFill(node, undefined, warpObj) || ''
480
529
 
481
530
  let shadow
482
531
  const outerShdwNode = getTextByPathList(node, ['p:spPr', 'a:effectLst', 'a:outerShdw'])
483
- if (outerShdwNode) shadow = getShadow(outerShdwNode, warpObj, SLIDE_FACTOR)
532
+ if (outerShdwNode) shadow = getShadow(outerShdwNode, warpObj)
484
533
 
485
534
  const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
486
535
  const isVertical = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) === 'eaVert'
@@ -500,40 +549,28 @@ function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, typ
500
549
  isFlipH,
501
550
  rotate,
502
551
  vAlign,
503
- id,
504
552
  name,
505
- idx,
506
553
  }
507
554
 
508
555
  if (shadow) data.shadow = shadow
509
556
 
510
557
  if (custShapType && type !== 'diagram') {
511
558
  const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
512
- const cx = parseInt(ext['cx']) * SLIDE_FACTOR
513
- const cy = parseInt(ext['cy']) * SLIDE_FACTOR
514
- const w = parseInt(ext['cx']) * SLIDE_FACTOR
515
- 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
516
561
  const d = getCustomShapePath(custShapType, w, h)
517
562
 
518
563
  return {
519
564
  ...data,
520
565
  type: 'shape',
521
- cx,
522
- cy,
523
566
  shapType: 'custom',
524
567
  path: d,
525
568
  }
526
569
  }
527
570
  if (shapType && type !== 'text') {
528
- const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
529
- const cx = parseInt(ext['cx']) * SLIDE_FACTOR
530
- const cy = parseInt(ext['cy']) * SLIDE_FACTOR
531
-
532
571
  return {
533
572
  ...data,
534
573
  type: 'shape',
535
- cx,
536
- cy,
537
574
  shapType,
538
575
  }
539
576
  }
@@ -559,10 +596,13 @@ async function processPicNode(node, warpObj, source) {
559
596
  const xfrmNode = node['p:spPr']['a:xfrm']
560
597
 
561
598
  const mimeType = getMimeType(imgFileExt)
562
- const { top, left } = getPosition(xfrmNode, undefined, undefined, SLIDE_FACTOR)
563
- const { width, height } = getSize(xfrmNode, undefined, undefined, SLIDE_FACTOR)
599
+ const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
600
+ const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
564
601
  const src = `data:${mimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
565
602
 
603
+ const isFlipV = getTextByPathList(xfrmNode, ['attrs', 'flipV']) === '1'
604
+ const isFlipH = getTextByPathList(xfrmNode, ['attrs', 'flipH']) === '1'
605
+
566
606
  let rotate = 0
567
607
  const rotateNode = getTextByPathList(node, ['p:spPr', 'a:xfrm', 'attrs', 'rot'])
568
608
  if (rotateNode) rotate = angleToDegrees(rotateNode)
@@ -643,10 +683,12 @@ async function processPicNode(node, warpObj, source) {
643
683
  height,
644
684
  rotate,
645
685
  src,
686
+ isFlipV,
687
+ isFlipH
646
688
  }
647
689
  }
648
690
 
649
- async function processGraphicFrameNode(node, warpObj) {
691
+ async function processGraphicFrameNode(node, warpObj, source) {
650
692
  const graphicTypeUri = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'attrs', 'uri'])
651
693
 
652
694
  let result
@@ -663,7 +705,7 @@ async function processGraphicFrameNode(node, warpObj) {
663
705
  case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
664
706
  let oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'mc:AlternateContent', 'mc:Fallback', 'p:oleObj'])
665
707
  if (!oleObjNode) oleObjNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'p:oleObj'])
666
- else processGroupSpNode(oleObjNode, warpObj)
708
+ else processGroupSpNode(oleObjNode, warpObj, source)
667
709
  break
668
710
  default:
669
711
  }
@@ -673,8 +715,8 @@ async function processGraphicFrameNode(node, warpObj) {
673
715
  function genTable(node, warpObj) {
674
716
  const tableNode = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl'])
675
717
  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
676
- const { top, left } = getPosition(xfrmNode, undefined, undefined, SLIDE_FACTOR)
677
- const { width, height } = getSize(xfrmNode, undefined, undefined, SLIDE_FACTOR)
718
+ const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
719
+ const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
678
720
 
679
721
  const getTblPr = getTextByPathList(node, ['a:graphic', 'a:graphicData', 'a:tbl', 'a:tblPr'])
680
722
 
@@ -719,7 +761,7 @@ function genTable(node, warpObj) {
719
761
 
720
762
  if (tcNodes.constructor === Array) {
721
763
  for (const tcNode of tcNodes) {
722
- const text = genTextBody(tcNode['a:txBody'], undefined, undefined, undefined, warpObj, FONTSIZE_FACTOR, SLIDE_FACTOR)
764
+ const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
723
765
  const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
724
766
  const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
725
767
  const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
@@ -729,7 +771,7 @@ function genTable(node, warpObj) {
729
771
  }
730
772
  }
731
773
  else {
732
- const text = genTextBody(tcNodes['a:txBody'], undefined, undefined, undefined, warpObj, FONTSIZE_FACTOR, SLIDE_FACTOR)
774
+ const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
733
775
  tr.push({ text })
734
776
  }
735
777
  data.push(tr)
@@ -741,12 +783,12 @@ function genTable(node, warpObj) {
741
783
 
742
784
  if (tcNodes.constructor === Array) {
743
785
  for (const tcNode of tcNodes) {
744
- const text = genTextBody(tcNode['a:txBody'], undefined, undefined, undefined, warpObj, FONTSIZE_FACTOR, SLIDE_FACTOR)
786
+ const text = genTextBody(tcNode['a:txBody'], tcNode, undefined, undefined, warpObj)
745
787
  tr.push({ text })
746
788
  }
747
789
  }
748
790
  else {
749
- const text = genTextBody(tcNodes['a:txBody'], undefined, undefined, undefined, warpObj, FONTSIZE_FACTOR, SLIDE_FACTOR)
791
+ const text = genTextBody(tcNodes['a:txBody'], tcNodes, undefined, undefined, warpObj)
750
792
  tr.push({ text })
751
793
  }
752
794
  data.push(tr)
@@ -765,8 +807,8 @@ function genTable(node, warpObj) {
765
807
 
766
808
  async function genChart(node, warpObj) {
767
809
  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
768
- const { top, left } = getPosition(xfrmNode, undefined, undefined, SLIDE_FACTOR)
769
- const { width, height } = getSize(xfrmNode, undefined, undefined, SLIDE_FACTOR)
810
+ const { top, left } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
811
+ const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
770
812
 
771
813
  const rid = node['a:graphic']['a:graphicData']['c:chart']['attrs']['r:id']
772
814
  const refName = warpObj['slideResObj'][rid]['target']
@@ -797,8 +839,8 @@ async function genChart(node, warpObj) {
797
839
 
798
840
  function genDiagram(node, warpObj) {
799
841
  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
800
- const { left, top } = getPosition(xfrmNode, undefined, undefined, SLIDE_FACTOR)
801
- const { width, height } = getSize(xfrmNode, undefined, undefined, SLIDE_FACTOR)
842
+ const { left, top } = getPosition(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
843
+ const { width, height } = getSize(xfrmNode, undefined, undefined, warpObj.options.slideFactor)
802
844
 
803
845
  const dgmDrwSpArray = getTextByPathList(warpObj['digramFileContent'], ['p:drawing', 'p:spTree', 'p:sp'])
804
846
  const elements = []
package/src/shadow.js CHANGED
@@ -1,17 +1,18 @@
1
1
  import { getSolidFill } from './fill'
2
2
 
3
- export function getShadow(node, warpObj, slideFactor) {
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
  }