pptxtojson 2.0.3 → 2.0.5
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 +352 -335
- package/README_zh.md +352 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -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/fill.js +56 -12
- package/src/paragraph.js +156 -126
- package/src/pptxtojson.js +63 -30
- package/src/shape.js +9 -0
- 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/fill.js
CHANGED
|
@@ -702,25 +702,47 @@ export async function getSlideBackgroundFill(warpObj) {
|
|
|
702
702
|
}
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
|
|
706
|
-
const
|
|
705
|
+
function getShapeFillCandidates(node, source, slideLayoutSpNode, slideMasterSpNode) {
|
|
706
|
+
const candidates = [{ node, source }]
|
|
707
|
+
|
|
708
|
+
if (slideLayoutSpNode) {
|
|
709
|
+
candidates.push({
|
|
710
|
+
node: slideLayoutSpNode,
|
|
711
|
+
source: 'slideLayoutBg',
|
|
712
|
+
})
|
|
713
|
+
}
|
|
714
|
+
if (slideMasterSpNode) {
|
|
715
|
+
candidates.push({
|
|
716
|
+
node: slideMasterSpNode,
|
|
717
|
+
source: 'slideMasterBg',
|
|
718
|
+
})
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
return candidates
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
async function resolveShapeFillFromNode(node, warpObj, source, groupHierarchy) {
|
|
725
|
+
if (!node) return { state: 'missing' }
|
|
726
|
+
|
|
727
|
+
const spPr = getTextByPathList(node, ['p:spPr'])
|
|
728
|
+
const fillType = spPr ? getFillType(spPr) : ''
|
|
707
729
|
let type = 'color'
|
|
708
730
|
let fillValue = ''
|
|
709
731
|
if (fillType === 'NO_FILL') {
|
|
710
|
-
return
|
|
732
|
+
return { state: 'none' }
|
|
711
733
|
}
|
|
712
734
|
else if (fillType === 'SOLID_FILL') {
|
|
713
|
-
const shpFill =
|
|
735
|
+
const shpFill = spPr['a:solidFill']
|
|
714
736
|
fillValue = getSolidFill(shpFill, undefined, undefined, warpObj)
|
|
715
737
|
type = 'color'
|
|
716
738
|
}
|
|
717
739
|
else if (fillType === 'GRADIENT_FILL') {
|
|
718
|
-
const shpFill =
|
|
740
|
+
const shpFill = spPr['a:gradFill']
|
|
719
741
|
fillValue = getGradientFill(shpFill, warpObj)
|
|
720
742
|
type = 'gradient'
|
|
721
743
|
}
|
|
722
744
|
else if (fillType === 'PIC_FILL') {
|
|
723
|
-
const shpFill =
|
|
745
|
+
const shpFill = spPr['a:blipFill']
|
|
724
746
|
const picFill = await getPicFill(source, shpFill, warpObj)
|
|
725
747
|
const opacity = getPicFillOpacity(shpFill)
|
|
726
748
|
fillValue = {
|
|
@@ -732,12 +754,13 @@ export async function getShapeFill(node, warpObj, source, groupHierarchy = []) {
|
|
|
732
754
|
type = 'image'
|
|
733
755
|
}
|
|
734
756
|
else if (fillType === 'PATTERN_FILL') {
|
|
735
|
-
const shpFill =
|
|
757
|
+
const shpFill = spPr['a:pattFill']
|
|
736
758
|
fillValue = getPatternFill({ 'a:pattFill': shpFill }, warpObj)
|
|
737
759
|
type = 'pattern'
|
|
738
760
|
}
|
|
739
761
|
else if (fillType === 'GROUP_FILL') {
|
|
740
|
-
|
|
762
|
+
const groupFill = await findFillInGroupHierarchy(groupHierarchy, warpObj, source)
|
|
763
|
+
return groupFill ? { state: 'found', fill: groupFill } : { state: 'none' }
|
|
741
764
|
}
|
|
742
765
|
if (!fillValue) {
|
|
743
766
|
const clrName = getTextByPathList(node, ['p:style', 'a:fillRef'])
|
|
@@ -745,15 +768,36 @@ export async function getShapeFill(node, warpObj, source, groupHierarchy = []) {
|
|
|
745
768
|
type = 'color'
|
|
746
769
|
}
|
|
747
770
|
if (!fillValue) {
|
|
748
|
-
return
|
|
771
|
+
return { state: 'missing' }
|
|
749
772
|
}
|
|
750
773
|
|
|
751
774
|
return {
|
|
752
|
-
|
|
753
|
-
|
|
775
|
+
state: 'found',
|
|
776
|
+
fill: {
|
|
777
|
+
type,
|
|
778
|
+
value: fillValue,
|
|
779
|
+
}
|
|
754
780
|
}
|
|
755
781
|
}
|
|
756
782
|
|
|
783
|
+
export async function getShapeFill(node, warpObj, source, options = {}) {
|
|
784
|
+
const {
|
|
785
|
+
groupHierarchy = [],
|
|
786
|
+
slideLayoutSpNode,
|
|
787
|
+
slideMasterSpNode,
|
|
788
|
+
} = options
|
|
789
|
+
|
|
790
|
+
const candidates = getShapeFillCandidates(node, source, slideLayoutSpNode, slideMasterSpNode)
|
|
791
|
+
for (const candidate of candidates) {
|
|
792
|
+
const result = await resolveShapeFillFromNode(candidate.node, warpObj, candidate.source, groupHierarchy)
|
|
793
|
+
|
|
794
|
+
if (result.state === 'none') return null
|
|
795
|
+
if (result.state === 'found') return result.fill
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return null
|
|
799
|
+
}
|
|
800
|
+
|
|
757
801
|
async function findFillInGroupHierarchy(groupHierarchy, warpObj, source) {
|
|
758
802
|
for (const groupNode of groupHierarchy) {
|
|
759
803
|
if (!groupNode || !groupNode['p:grpSpPr']) continue
|
|
@@ -892,4 +936,4 @@ export function getSolidFill(solidFill, clrMap, phClr, warpObj) {
|
|
|
892
936
|
if (color && color.indexOf('#') === -1) color = '#' + color
|
|
893
937
|
|
|
894
938
|
return color
|
|
895
|
-
}
|
|
939
|
+
}
|
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
|
+
}
|