pptxtojson 2.0.3 → 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/README.md +3 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- 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/index.html +10 -2
- package/package.json +1 -1
- package/src/chart.js +58 -48
- package/src/paragraph.js +156 -126
- package/src/pptxtojson.js +22 -10
- package/src/text.js +21 -17
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
|
|
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
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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:
|
|
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:
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
@@ -22,6 +22,7 @@ export async function parse(file, options = {}) {
|
|
|
22
22
|
const loadedImages = {}
|
|
23
23
|
const loadedVideos = {}
|
|
24
24
|
const loadedAudios = {}
|
|
25
|
+
const xmlCache = {}
|
|
25
26
|
const parseOptions = {
|
|
26
27
|
...options,
|
|
27
28
|
imageMode: options.imageMode || 'base64',
|
|
@@ -37,7 +38,7 @@ export async function parse(file, options = {}) {
|
|
|
37
38
|
const usedFonts = await getUsedFonts(zip)
|
|
38
39
|
|
|
39
40
|
for (const filename of filesInfo.slides) {
|
|
40
|
-
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)
|
|
41
42
|
slides.push(singleSlide)
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -143,7 +144,16 @@ async function getTheme(zip) {
|
|
|
143
144
|
return { themeContent, themeColors }
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
async function
|
|
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) {
|
|
147
157
|
const resName = sldFileName.replace('slides/slide', 'slides/_rels/slide') + '.rels'
|
|
148
158
|
const resContent = await readXmlFile(zip, resName)
|
|
149
159
|
let relationshipArray = resContent['Relationships']['Relationship']
|
|
@@ -206,10 +216,10 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
206
216
|
const slideNotesContent = await readXmlFile(zip, noteFilename)
|
|
207
217
|
const note = getNote(slideNotesContent)
|
|
208
218
|
|
|
209
|
-
const slideLayoutContent = await
|
|
210
|
-
const slideLayoutTables =
|
|
219
|
+
const slideLayoutContent = await readXmlFileCached(zip, layoutFilename, xmlCache)
|
|
220
|
+
const slideLayoutTables = indexNodes(slideLayoutContent)
|
|
211
221
|
const slideLayoutResFilename = layoutFilename.replace('slideLayouts/slideLayout', 'slideLayouts/_rels/slideLayout') + '.rels'
|
|
212
|
-
const slideLayoutResContent = await
|
|
222
|
+
const slideLayoutResContent = await readXmlFileCached(zip, slideLayoutResFilename, xmlCache)
|
|
213
223
|
relationshipArray = slideLayoutResContent['Relationships']['Relationship']
|
|
214
224
|
if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
|
|
215
225
|
|
|
@@ -231,11 +241,11 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
231
241
|
}
|
|
232
242
|
}
|
|
233
243
|
|
|
234
|
-
const slideMasterContent = await
|
|
244
|
+
const slideMasterContent = await readXmlFileCached(zip, masterFilename, xmlCache)
|
|
235
245
|
const slideMasterTextStyles = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:txStyles'])
|
|
236
246
|
const slideMasterTables = indexNodes(slideMasterContent)
|
|
237
247
|
const slideMasterResFilename = masterFilename.replace('slideMasters/slideMaster', 'slideMasters/_rels/slideMaster') + '.rels'
|
|
238
|
-
const slideMasterResContent = await
|
|
248
|
+
const slideMasterResContent = await readXmlFileCached(zip, slideMasterResFilename, xmlCache)
|
|
239
249
|
relationshipArray = slideMasterResContent['Relationships']['Relationship']
|
|
240
250
|
if (relationshipArray.constructor !== Array) relationshipArray = [relationshipArray]
|
|
241
251
|
|
|
@@ -275,7 +285,7 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
275
285
|
}
|
|
276
286
|
}
|
|
277
287
|
|
|
278
|
-
const tableStyles = await
|
|
288
|
+
const tableStyles = await readXmlFileCached(zip, 'ppt/tableStyles.xml', xmlCache)
|
|
279
289
|
|
|
280
290
|
const slideContent = await readXmlFile(zip, sldFileName)
|
|
281
291
|
const nodes = slideContent['p:sld']['p:cSld']['p:spTree']
|
|
@@ -398,7 +408,7 @@ function getNote(noteContent) {
|
|
|
398
408
|
text += `<${listType}>`
|
|
399
409
|
listTypes[listLevel] = listType
|
|
400
410
|
}
|
|
401
|
-
text += `<li style="text-align:${align};">`
|
|
411
|
+
text += `<li><p style="text-align:${align};">`
|
|
402
412
|
}
|
|
403
413
|
else {
|
|
404
414
|
while (listTypes.length > 0) {
|
|
@@ -416,7 +426,7 @@ function getNote(noteContent) {
|
|
|
416
426
|
}
|
|
417
427
|
}
|
|
418
428
|
|
|
419
|
-
if (listType) text += '</li>'
|
|
429
|
+
if (listType) text += '</p></li>'
|
|
420
430
|
else text += '</p>'
|
|
421
431
|
}
|
|
422
432
|
while (listTypes.length > 0) {
|
|
@@ -559,6 +569,8 @@ async function processMathNode(node, warpObj, source) {
|
|
|
559
569
|
const { width, height } = getSize(xfrmNode, undefined, undefined)
|
|
560
570
|
|
|
561
571
|
const oMath = findOMath(choice)[0]
|
|
572
|
+
if (!oMath) return null
|
|
573
|
+
|
|
562
574
|
const latex = latexFormart(parseOMath(oMath))
|
|
563
575
|
|
|
564
576
|
const blipFill = getTextByPathList(fallback, ['p:sp', 'p:spPr', 'a:blipFill'])
|