pptxtojson 2.0.2 → 2.0.4

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/index.html CHANGED
@@ -432,11 +432,13 @@
432
432
  loadingOverlay.classList.add('show')
433
433
 
434
434
  try {
435
+ const parseStart = performance.now()
435
436
  const json = await pptxtojson.parse(e.target.result, {
436
437
  imageMode: 'both',
437
438
  videoMode: 'blob',
438
439
  audioMode: 'blob',
439
440
  })
441
+ console.log('parse time:', ((performance.now() - parseStart) / 1000).toFixed(3) + 's')
440
442
  editor.set(json)
441
443
  console.log(json)
442
444
  jsonString = JSON.stringify(json, null, 2)
@@ -459,7 +461,13 @@
459
461
  loadingOverlay.classList.add('show')
460
462
 
461
463
  try {
462
- const json = await pptxtojson.parse(file)
464
+ const parseStart = performance.now()
465
+ const json = await pptxtojson.parse(file, {
466
+ imageMode: 'both',
467
+ videoMode: 'blob',
468
+ audioMode: 'blob',
469
+ })
470
+ console.log('parse time:', ((performance.now() - parseStart) / 1000).toFixed(3) + 's')
463
471
  editor.set(json)
464
472
  console.log(json)
465
473
  jsonString = JSON.stringify(json, null, 2)
@@ -542,4 +550,4 @@
542
550
  })
543
551
  </script>
544
552
  </body>
545
- </html>
553
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptxtojson",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
package/src/chart.js CHANGED
@@ -31,56 +31,66 @@ function extractChartData(serNode) {
31
31
  const dataMat = []
32
32
  if (!serNode) return dataMat
33
33
 
34
- if (serNode['c:xVal']) {
35
- let dataRow = []
36
- eachElement(serNode['c:xVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
37
- dataRow.push(parseFloat(innerNode['c:v']))
38
- return ''
39
- })
40
- dataMat.push(dataRow)
41
- dataRow = []
42
- eachElement(serNode['c:yVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
43
- dataRow.push(parseFloat(innerNode['c:v']))
44
- return ''
45
- })
46
- dataMat.push(dataRow)
47
- }
48
- else {
49
- eachElement(serNode, (innerNode, index) => {
50
- const dataRow = []
51
- const colName = getTextByPathList(innerNode, ['c:tx', 'c:strRef', 'c:strCache', 'c:pt', 'c:v']) || index
52
-
53
- const rowNames = {}
54
- if (getTextByPathList(innerNode, ['c:cat', 'c:strRef', 'c:strCache', 'c:pt'])) {
55
- eachElement(innerNode['c:cat']['c:strRef']['c:strCache']['c:pt'], innerNode => {
56
- rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
57
- return ''
58
- })
59
- }
60
- else if (getTextByPathList(innerNode, ['c:cat', 'c:numRef', 'c:numCache', 'c:pt'])) {
61
- eachElement(innerNode['c:cat']['c:numRef']['c:numCache']['c:pt'], innerNode => {
62
- rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
63
- return ''
64
- })
65
- }
34
+ eachElement(serNode, (innerNode, index) => {
35
+ const dataRow = []
36
+ const colName = getTextByPathList(innerNode, ['c:tx', 'c:strRef', 'c:strCache', 'c:pt', 'c:v']) || index
66
37
 
67
- if (getTextByPathList(innerNode, ['c:val', 'c:numRef', 'c:numCache', 'c:pt'])) {
68
- eachElement(innerNode['c:val']['c:numRef']['c:numCache']['c:pt'], innerNode => {
69
- dataRow.push({
70
- x: innerNode['attrs']['idx'],
71
- y: parseFloat(innerNode['c:v']),
72
- })
73
- return ''
74
- })
75
- }
38
+ const rowNames = {}
39
+ if (getTextByPathList(innerNode, ['c:cat', 'c:strRef', 'c:strCache', 'c:pt'])) {
40
+ eachElement(innerNode['c:cat']['c:strRef']['c:strCache']['c:pt'], innerNode => {
41
+ rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
42
+ return ''
43
+ })
44
+ }
45
+ else if (getTextByPathList(innerNode, ['c:cat', 'c:numRef', 'c:numCache', 'c:pt'])) {
46
+ eachElement(innerNode['c:cat']['c:numRef']['c:numCache']['c:pt'], innerNode => {
47
+ rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
48
+ return ''
49
+ })
50
+ }
76
51
 
77
- dataMat.push({
78
- key: colName,
79
- values: dataRow,
80
- xlabels: rowNames,
52
+ if (getTextByPathList(innerNode, ['c:val', 'c:numRef', 'c:numCache', 'c:pt'])) {
53
+ eachElement(innerNode['c:val']['c:numRef']['c:numCache']['c:pt'], innerNode => {
54
+ dataRow.push({
55
+ x: innerNode['attrs']['idx'],
56
+ y: parseFloat(innerNode['c:v']),
57
+ })
58
+ return ''
81
59
  })
60
+ }
61
+
62
+ dataMat.push({
63
+ key: colName,
64
+ values: dataRow,
65
+ xlabels: rowNames,
66
+ })
67
+ return ''
68
+ })
69
+
70
+ return dataMat
71
+ }
72
+
73
+ function extractScatterChartData(serNode) {
74
+ const dataMat = []
75
+ if (!serNode) return dataMat
76
+
77
+ const serNodes = serNode.constructor === Array ? serNode : [serNode]
78
+ const firstSerNode = serNodes[0]
79
+ const xData = []
80
+
81
+ eachElement(firstSerNode['c:xVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
82
+ xData.push(parseFloat(innerNode['c:v']))
83
+ return ''
84
+ })
85
+ dataMat.push(xData)
86
+
87
+ for (const node of serNodes) {
88
+ const yData = []
89
+ eachElement(node['c:yVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
90
+ yData.push(parseFloat(innerNode['c:v']))
82
91
  return ''
83
92
  })
93
+ dataMat.push(yData)
84
94
  }
85
95
 
86
96
  return dataMat
@@ -168,7 +178,7 @@ export function getChartInfo(plotArea, warpObj) {
168
178
  case 'c:scatterChart':
169
179
  chart = {
170
180
  type: 'scatterChart',
171
- data: extractChartData(plotArea[key]['c:ser']),
181
+ data: extractScatterChartData(plotArea[key]['c:ser']),
172
182
  colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
173
183
  style: getTextByPathList(plotArea[key], ['c:scatterStyle', 'attrs', 'val']),
174
184
  }
@@ -176,7 +186,7 @@ export function getChartInfo(plotArea, warpObj) {
176
186
  case 'c:bubbleChart':
177
187
  chart = {
178
188
  type: 'bubbleChart',
179
- data: extractChartData(plotArea[key]['c:ser']),
189
+ data: extractScatterChartData(plotArea[key]['c:ser']),
180
190
  colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
181
191
  }
182
192
  break
@@ -214,4 +224,4 @@ export function getChartInfo(plotArea, warpObj) {
214
224
  }
215
225
 
216
226
  return chart
217
- }
227
+ }
package/src/paragraph.js CHANGED
@@ -1,17 +1,18 @@
1
- import { getTextByPathList } from './utils'
2
-
3
- function getParagraphLevel(node) {
4
- let lvlIdx = 1
5
- const lvlNode = getTextByPathList(node, ['a:pPr', 'attrs', 'lvl'])
6
- if (lvlNode !== undefined) lvlIdx = parseInt(lvlNode) + 1
7
- return lvlIdx
8
- }
9
-
10
- function getAlignFromTextNode(node, lvlStr) {
11
- if (!node) return ''
12
-
13
- let algn = getTextByPathList(node, ['p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
14
- if (!algn) algn = getTextByPathList(node, ['p:txBody', 'a:p', 'a:pPr', 'attrs', 'algn'])
1
+ import { RATIO_EMUs_Points } from './constants'
2
+ import { getTextByPathList, numberToFixed } from './utils'
3
+
4
+ function getParagraphLevel(node) {
5
+ let lvlIdx = 1
6
+ const lvlNode = getTextByPathList(node, ['a:pPr', 'attrs', 'lvl'])
7
+ if (lvlNode !== undefined) lvlIdx = parseInt(lvlNode) + 1
8
+ return lvlIdx
9
+ }
10
+
11
+ function getAlignFromTextNode(node, lvlStr) {
12
+ if (!node) return ''
13
+
14
+ let algn = getTextByPathList(node, ['p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
15
+ if (!algn) algn = getTextByPathList(node, ['p:txBody', 'a:p', 'a:pPr', 'attrs', 'algn'])
15
16
 
16
17
  return algn || ''
17
18
  }
@@ -109,115 +110,144 @@ export function getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode) {
109
110
 
110
111
  const masterCheck = checkBodyPr(getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr']))
111
112
  if (masterCheck) return masterCheck.result
112
-
113
- return null
114
- }
115
-
116
- function pushParagraphStyleNode(styleNodes, styleNode) {
117
- if (styleNode) styleNodes.push(styleNode)
118
- }
119
-
120
- function appendTextBodyParagraphStyleNodes(styleNodes, textBodyNode, lvl) {
121
- if (!textBodyNode) return
122
-
123
- const lvlPath = `a:lvl${lvl}pPr`
124
- pushParagraphStyleNode(styleNodes, getTextByPathList(textBodyNode, ['a:lstStyle', lvlPath]))
125
- }
126
-
127
- function appendShapeParagraphStyleNodes(styleNodes, shapeNode, lvl) {
128
- if (!shapeNode) return
129
-
130
- const lvlPath = `a:lvl${lvl}pPr`
131
- pushParagraphStyleNode(styleNodes, getTextByPathList(shapeNode, ['p:txBody', 'a:lstStyle', lvlPath]))
132
- pushParagraphStyleNode(styleNodes, getTextByPathList(shapeNode, ['p:txBody', 'a:p', 'a:pPr']))
133
- }
134
-
135
- function appendMasterTextParagraphStyleNodes(styleNodes, type, lvl, slideMasterTextStyles) {
136
- if (!slideMasterTextStyles) return
137
-
138
- const lvlPath = `a:lvl${lvl}pPr`
139
-
140
- if (type === 'title' || type === 'ctrTitle' || type === 'subTitle') {
141
- pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:titleStyle', lvlPath]))
142
- if (type === 'subTitle') {
143
- pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:bodyStyle', lvlPath]))
144
- }
145
- }
146
- else if (type === 'body') {
147
- pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:bodyStyle', lvlPath]))
148
- }
149
- else {
150
- pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:otherStyle', lvlPath]))
151
- }
152
- }
153
-
154
- function appendDefaultTextParagraphStyleNodes(styleNodes, defaultTextStyle, lvl) {
155
- if (!defaultTextStyle) return
156
-
157
- const lvlPath = `a:lvl${lvl}pPr`
158
- pushParagraphStyleNode(styleNodes, getTextByPathList(defaultTextStyle, [lvlPath]))
159
- pushParagraphStyleNode(styleNodes, getTextByPathList(defaultTextStyle, ['a:defPPr']))
160
- }
161
-
162
- function getParagraphStyleNodes(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
163
- if (!pNode) return null
164
-
165
- const pPrNode = pNode['a:pPr']
166
- const lvl = getParagraphLevel(pNode)
167
- const styleNodes = []
168
-
169
- pushParagraphStyleNode(styleNodes, pPrNode)
170
- appendTextBodyParagraphStyleNodes(styleNodes, textBodyNode, lvl)
171
- appendShapeParagraphStyleNodes(styleNodes, slideLayoutSpNode, lvl)
172
- appendShapeParagraphStyleNodes(styleNodes, slideMasterSpNode, lvl)
173
- appendMasterTextParagraphStyleNodes(styleNodes, type, lvl, slideMasterTextStyles)
174
- appendDefaultTextParagraphStyleNodes(styleNodes, getTextByPathList(warpObj, ['defaultTextStyle']), lvl)
175
-
176
- return styleNodes
177
- }
178
-
179
- function getLineSpacingValue(spacingNode) {
180
- const spcPct = getTextByPathList(spacingNode, ['a:spcPct', 'attrs', 'val'])
181
- const spcPts = getTextByPathList(spacingNode, ['a:spcPts', 'attrs', 'val'])
182
-
183
- if (spcPct) return parseInt(spcPct) / 1000 / 100
184
- if (spcPts) return parseInt(spcPts) / 100 + 'pt'
185
-
186
- return undefined
187
- }
188
-
189
- function getParagraphSpacingValue(spacingNode) {
190
- const spcPct = getTextByPathList(spacingNode, ['a:spcPct', 'attrs', 'val'])
191
- const spcPts = getTextByPathList(spacingNode, ['a:spcPts', 'attrs', 'val'])
192
-
193
- if (spcPct) return parseInt(spcPct) / 1000 + 'em'
194
- if (spcPts) return parseInt(spcPts) / 100 + 'pt'
195
-
196
- return undefined
197
- }
198
-
199
- export function getParagraphSpacing(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
200
- const styleNodes = getParagraphStyleNodes(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
201
- if (!styleNodes) return null
202
-
203
- const spacing = {}
204
-
205
- for (const styleNode of styleNodes) {
206
- if (spacing.lineSpacing === undefined) {
207
- const lineSpacing = getLineSpacingValue(styleNode['a:lnSpc'])
208
- if (lineSpacing !== undefined) spacing.lineSpacing = lineSpacing
209
- }
210
-
211
- if (spacing.spaceBefore === undefined) {
212
- const spaceBefore = getParagraphSpacingValue(styleNode['a:spcBef'])
213
- if (spaceBefore !== undefined) spacing.spaceBefore = spaceBefore
214
- }
215
-
216
- if (spacing.spaceAfter === undefined) {
217
- const spaceAfter = getParagraphSpacingValue(styleNode['a:spcAft'])
218
- if (spaceAfter !== undefined) spacing.spaceAfter = spaceAfter
219
- }
220
- }
221
-
222
- return Object.keys(spacing).length > 0 ? spacing : null
223
- }
113
+
114
+ return null
115
+ }
116
+
117
+ function pushParagraphStyleNode(styleNodes, styleNode) {
118
+ if (styleNode) styleNodes.push(styleNode)
119
+ }
120
+
121
+ function appendTextBodyParagraphStyleNodes(styleNodes, textBodyNode, lvl) {
122
+ if (!textBodyNode) return
123
+
124
+ const lvlPath = `a:lvl${lvl}pPr`
125
+ pushParagraphStyleNode(styleNodes, getTextByPathList(textBodyNode, ['a:lstStyle', lvlPath]))
126
+ }
127
+
128
+ function appendShapeParagraphStyleNodes(styleNodes, shapeNode, lvl) {
129
+ if (!shapeNode) return
130
+
131
+ const lvlPath = `a:lvl${lvl}pPr`
132
+ pushParagraphStyleNode(styleNodes, getTextByPathList(shapeNode, ['p:txBody', 'a:lstStyle', lvlPath]))
133
+ pushParagraphStyleNode(styleNodes, getTextByPathList(shapeNode, ['p:txBody', 'a:p', 'a:pPr']))
134
+ }
135
+
136
+ function appendMasterTextParagraphStyleNodes(styleNodes, type, lvl, slideMasterTextStyles) {
137
+ if (!slideMasterTextStyles) return
138
+
139
+ const lvlPath = `a:lvl${lvl}pPr`
140
+
141
+ if (type === 'title' || type === 'ctrTitle' || type === 'subTitle') {
142
+ pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:titleStyle', lvlPath]))
143
+ if (type === 'subTitle') {
144
+ pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:bodyStyle', lvlPath]))
145
+ }
146
+ }
147
+ else if (type === 'body') {
148
+ pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:bodyStyle', lvlPath]))
149
+ }
150
+ else {
151
+ pushParagraphStyleNode(styleNodes, getTextByPathList(slideMasterTextStyles, ['p:otherStyle', lvlPath]))
152
+ }
153
+ }
154
+
155
+ function appendDefaultTextParagraphStyleNodes(styleNodes, defaultTextStyle, lvl) {
156
+ if (!defaultTextStyle) return
157
+
158
+ const lvlPath = `a:lvl${lvl}pPr`
159
+ pushParagraphStyleNode(styleNodes, getTextByPathList(defaultTextStyle, [lvlPath]))
160
+ pushParagraphStyleNode(styleNodes, getTextByPathList(defaultTextStyle, ['a:defPPr']))
161
+ }
162
+
163
+ function getParagraphStyleNodes(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
164
+ if (!pNode) return null
165
+
166
+ const pPrNode = pNode['a:pPr']
167
+ const lvl = getParagraphLevel(pNode)
168
+ const styleNodes = []
169
+
170
+ pushParagraphStyleNode(styleNodes, pPrNode)
171
+ appendTextBodyParagraphStyleNodes(styleNodes, textBodyNode, lvl)
172
+ appendShapeParagraphStyleNodes(styleNodes, slideLayoutSpNode, lvl)
173
+ appendShapeParagraphStyleNodes(styleNodes, slideMasterSpNode, lvl)
174
+ appendMasterTextParagraphStyleNodes(styleNodes, type, lvl, slideMasterTextStyles)
175
+ appendDefaultTextParagraphStyleNodes(styleNodes, getTextByPathList(warpObj, ['defaultTextStyle']), lvl)
176
+
177
+ return styleNodes
178
+ }
179
+
180
+ function getLineSpacingValue(spacingNode) {
181
+ const spcPct = getTextByPathList(spacingNode, ['a:spcPct', 'attrs', 'val'])
182
+ const spcPts = getTextByPathList(spacingNode, ['a:spcPts', 'attrs', 'val'])
183
+
184
+ if (spcPct) return parseInt(spcPct) / 1000 / 100
185
+ if (spcPts) return parseInt(spcPts) / 100 + 'pt'
186
+
187
+ return undefined
188
+ }
189
+
190
+ function getParagraphSpacingValue(spacingNode) {
191
+ const spcPct = getTextByPathList(spacingNode, ['a:spcPct', 'attrs', 'val'])
192
+ const spcPts = getTextByPathList(spacingNode, ['a:spcPts', 'attrs', 'val'])
193
+
194
+ if (spcPct) return parseInt(spcPct) / 1000 + 'em'
195
+ if (spcPts) return parseInt(spcPts) / 100 + 'pt'
196
+
197
+ return undefined
198
+ }
199
+
200
+ function getParagraphIndentValue(styleNode, attrName) {
201
+ const val = getTextByPathList(styleNode, ['attrs', attrName])
202
+
203
+ if (val !== undefined && val !== '') return numberToFixed(parseInt(val) * RATIO_EMUs_Points) + 'pt'
204
+
205
+ return undefined
206
+ }
207
+
208
+ export function getParagraphSpacing(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
209
+ const styleNodes = getParagraphStyleNodes(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
210
+ if (!styleNodes) return null
211
+
212
+ const spacing = {}
213
+
214
+ for (const styleNode of styleNodes) {
215
+ if (spacing.lineSpacing === undefined) {
216
+ const lineSpacing = getLineSpacingValue(styleNode['a:lnSpc'])
217
+ if (lineSpacing !== undefined) spacing.lineSpacing = lineSpacing
218
+ }
219
+
220
+ if (spacing.spaceBefore === undefined) {
221
+ const spaceBefore = getParagraphSpacingValue(styleNode['a:spcBef'])
222
+ if (spaceBefore !== undefined) spacing.spaceBefore = spaceBefore
223
+ }
224
+
225
+ if (spacing.spaceAfter === undefined) {
226
+ const spaceAfter = getParagraphSpacingValue(styleNode['a:spcAft'])
227
+ if (spaceAfter !== undefined) spacing.spaceAfter = spaceAfter
228
+ }
229
+ }
230
+
231
+ return Object.keys(spacing).length > 0 ? spacing : null
232
+ }
233
+
234
+ export function getParagraphIndent(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
235
+ const styleNodes = getParagraphStyleNodes(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
236
+ if (!styleNodes) return null
237
+
238
+ const indent = {}
239
+
240
+ for (const styleNode of styleNodes) {
241
+ if (indent.marginLeft === undefined) {
242
+ const marginLeft = getParagraphIndentValue(styleNode, 'marL')
243
+ if (marginLeft !== undefined) indent.marginLeft = marginLeft
244
+ }
245
+
246
+ if (indent.textIndent === undefined) {
247
+ const textIndent = getParagraphIndentValue(styleNode, 'indent')
248
+ if (textIndent !== undefined) indent.textIndent = textIndent
249
+ }
250
+ }
251
+
252
+ return Object.keys(indent).length > 0 ? indent : null
253
+ }
package/src/pptxtojson.js CHANGED
@@ -4,6 +4,7 @@ import { getBorder } from './border'
4
4
  import { getSlideBackgroundFill, getShapeFill, getSolidFill, getPicFill, getPicFilters, getImageData, getVideoData, getAudioData } from './fill'
5
5
  import { getChartInfo } from './chart'
6
6
  import { getVerticalAlign, getTextAutoFit } from './paragraph'
7
+ import { getTextInsets } from './textInsets'
7
8
  import { getPosition, getSize } from './position'
8
9
  import { genTextBody, getTextNodeValue } from './text'
9
10
  import { getCustomShapePath, identifyShape } from './shape'
@@ -21,6 +22,7 @@ export async function parse(file, options = {}) {
21
22
  const loadedImages = {}
22
23
  const loadedVideos = {}
23
24
  const loadedAudios = {}
25
+ const xmlCache = {}
24
26
  const parseOptions = {
25
27
  ...options,
26
28
  imageMode: options.imageMode || 'base64',
@@ -36,7 +38,7 @@ export async function parse(file, options = {}) {
36
38
  const usedFonts = await getUsedFonts(zip)
37
39
 
38
40
  for (const filename of filesInfo.slides) {
39
- const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, parseOptions)
41
+ const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, parseOptions, xmlCache)
40
42
  slides.push(singleSlide)
41
43
  }
42
44
 
@@ -142,7 +144,16 @@ async function getTheme(zip) {
142
144
  return { themeContent, themeColors }
143
145
  }
144
146
 
145
- async function processSingleSlide(zip, sldFileName, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, options) {
147
+ async function readXmlFileCached(zip, filename, xmlCache) {
148
+ if (!filename) return null
149
+ if (Object.prototype.hasOwnProperty.call(xmlCache, filename)) return xmlCache[filename]
150
+
151
+ const content = await readXmlFile(zip, filename)
152
+ xmlCache[filename] = content
153
+ return content
154
+ }
155
+
156
+ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, options, xmlCache) {
146
157
  const resName = sldFileName.replace('slides/slide', 'slides/_rels/slide') + '.rels'
147
158
  const resContent = await readXmlFile(zip, resName)
148
159
  let relationshipArray = resContent['Relationships']['Relationship']
@@ -205,10 +216,10 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
205
216
  const slideNotesContent = await readXmlFile(zip, noteFilename)
206
217
  const note = getNote(slideNotesContent)
207
218
 
208
- const slideLayoutContent = await readXmlFile(zip, layoutFilename)
209
- const slideLayoutTables = await indexNodes(slideLayoutContent)
219
+ const slideLayoutContent = await readXmlFileCached(zip, layoutFilename, xmlCache)
220
+ const slideLayoutTables = indexNodes(slideLayoutContent)
210
221
  const slideLayoutResFilename = layoutFilename.replace('slideLayouts/slideLayout', 'slideLayouts/_rels/slideLayout') + '.rels'
211
- const slideLayoutResContent = await readXmlFile(zip, slideLayoutResFilename)
222
+ const slideLayoutResContent = await readXmlFileCached(zip, slideLayoutResFilename, xmlCache)
212
223
  relationshipArray = slideLayoutResContent['Relationships']['Relationship']
213
224
  if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
214
225
 
@@ -230,11 +241,11 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
230
241
  }
231
242
  }
232
243
 
233
- const slideMasterContent = await readXmlFile(zip, masterFilename)
244
+ const slideMasterContent = await readXmlFileCached(zip, masterFilename, xmlCache)
234
245
  const slideMasterTextStyles = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:txStyles'])
235
246
  const slideMasterTables = indexNodes(slideMasterContent)
236
247
  const slideMasterResFilename = masterFilename.replace('slideMasters/slideMaster', 'slideMasters/_rels/slideMaster') + '.rels'
237
- const slideMasterResContent = await readXmlFile(zip, slideMasterResFilename)
248
+ const slideMasterResContent = await readXmlFileCached(zip, slideMasterResFilename, xmlCache)
238
249
  relationshipArray = slideMasterResContent['Relationships']['Relationship']
239
250
  if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
240
251
 
@@ -274,7 +285,7 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
274
285
  }
275
286
  }
276
287
 
277
- const tableStyles = await readXmlFile(zip, 'ppt/tableStyles.xml')
288
+ const tableStyles = await readXmlFileCached(zip, 'ppt/tableStyles.xml', xmlCache)
278
289
 
279
290
  const slideContent = await readXmlFile(zip, sldFileName)
280
291
  const nodes = slideContent['p:sld']['p:cSld']['p:spTree']
@@ -397,7 +408,7 @@ function getNote(noteContent) {
397
408
  text += `<${listType}>`
398
409
  listTypes[listLevel] = listType
399
410
  }
400
- text += `<li style="text-align:${align};">`
411
+ text += `<li><p style="text-align:${align};">`
401
412
  }
402
413
  else {
403
414
  while (listTypes.length > 0) {
@@ -415,7 +426,7 @@ function getNote(noteContent) {
415
426
  }
416
427
  }
417
428
 
418
- if (listType) text += '</li>'
429
+ if (listType) text += '</p></li>'
419
430
  else text += '</p>'
420
431
  }
421
432
  while (listTypes.length > 0) {
@@ -558,6 +569,8 @@ async function processMathNode(node, warpObj, source) {
558
569
  const { width, height } = getSize(xfrmNode, undefined, undefined)
559
570
 
560
571
  const oMath = findOMath(choice)[0]
572
+ if (!oMath) return null
573
+
561
574
  const latex = latexFormart(parseOMath(oMath))
562
575
 
563
576
  const blipFill = getTextByPathList(fallback, ['p:sp', 'p:spPr', 'a:blipFill'])
@@ -640,13 +653,13 @@ async function processGroupSpNode(node, warpObj, source, parentGroupHierarchy =
640
653
  if (depth > 10) return elements
641
654
 
642
655
  return elements.map(element => {
643
- const processed = {
644
- ...element,
645
- left: numberToFixed(element.left * ws),
646
- top: numberToFixed(element.top * hs),
647
- width: numberToFixed(element.width * ws),
648
- height: numberToFixed(element.height * hs),
649
- }
656
+ const processed = {
657
+ ...element,
658
+ left: numberToFixed(element.left * ws),
659
+ top: numberToFixed(element.top * hs),
660
+ width: numberToFixed(element.width * ws),
661
+ height: numberToFixed(element.height * hs),
662
+ }
650
663
  if (element.type === 'group' && element.elements) {
651
664
  processed.elements = processNestedGroupElements(element.elements, ws, hs, depth + 1)
652
665
  }
@@ -698,11 +711,11 @@ async function processSpNode(node, warpObj, source, groupHierarchy = []) {
698
711
  const txBoxVal = getTextByPathList(node, ['p:nvSpPr', 'p:cNvSpPr', 'attrs', 'txBox'])
699
712
  if (txBoxVal === '1') type = 'text'
700
713
  }
701
- if (!type) type = getTextByPathList(slideLayoutSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
702
- if (!type) type = getTextByPathList(slideMasterSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
703
- if (!slideMasterSpNode && type === 'ctrTitle') slideMasterSpNode = warpObj['slideMasterTables']['typeTable']['title']
704
-
705
- if (!type) {
714
+ if (!type) type = getTextByPathList(slideLayoutSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
715
+ if (!type) type = getTextByPathList(slideMasterSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
716
+ if (!slideMasterSpNode && type === 'ctrTitle') slideMasterSpNode = warpObj['slideMasterTables']['typeTable']['title']
717
+
718
+ if (!type) {
706
719
  if (source === 'diagramBg') type = 'diagram'
707
720
  else type = 'obj'
708
721
  }
@@ -775,6 +788,7 @@ async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type,
775
788
  const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
776
789
  const isVertical = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) === 'eaVert'
777
790
  const autoFit = getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode)
791
+ const textInset = getTextInsets(node, slideLayoutSpNode, slideMasterSpNode)
778
792
 
779
793
  const data = {
780
794
  left,
@@ -798,6 +812,7 @@ async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type,
798
812
  if (shadow) data.shadow = shadow
799
813
  if (autoFit) data.autoFit = autoFit
800
814
  if (link) data.link = link
815
+ if (textInset) data.textInset = textInset
801
816
 
802
817
  const isHasValidText = data.content && hasValidText(data.content)
803
818
 
@@ -1188,11 +1203,11 @@ async function genTable(node, warpObj) {
1188
1203
  if (cell.rowSpan) td.rowSpan = cell.rowSpan
1189
1204
  if (cell.colSpan) td.colSpan = cell.colSpan
1190
1205
  if (cell.vMerge) td.vMerge = cell.vMerge
1191
- if (cell.hMerge) td.hMerge = cell.hMerge
1192
- if (cell.vAlign) td.vAlign = cell.vAlign
1193
- if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1194
- if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1195
- if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
1206
+ if (cell.hMerge) td.hMerge = cell.hMerge
1207
+ if (cell.vAlign) td.vAlign = cell.vAlign
1208
+ if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1209
+ if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1210
+ if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
1196
1211
  if (cell.borders) td.borders = cell.borders
1197
1212
 
1198
1213
  tr.push(td)
@@ -1221,11 +1236,11 @@ async function genTable(node, warpObj) {
1221
1236
  if (cell.rowSpan) td.rowSpan = cell.rowSpan
1222
1237
  if (cell.colSpan) td.colSpan = cell.colSpan
1223
1238
  if (cell.vMerge) td.vMerge = cell.vMerge
1224
- if (cell.hMerge) td.hMerge = cell.hMerge
1225
- if (cell.vAlign) td.vAlign = cell.vAlign
1226
- if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1227
- if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1228
- if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
1239
+ if (cell.hMerge) td.hMerge = cell.hMerge
1240
+ if (cell.vAlign) td.vAlign = cell.vAlign
1241
+ if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1242
+ if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1243
+ if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
1229
1244
  if (cell.borders) td.borders = cell.borders
1230
1245
 
1231
1246
  tr.push(td)