pptxtojson 2.0.0 → 2.0.2
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 +11 -11
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/diagram.js +2 -1
- package/src/fontStyle.js +11 -2
- package/src/paragraph.js +223 -0
- package/src/pptxtojson.js +44 -21
- package/src/readXmlFile.js +6 -1
- package/src/shapePath.js +27 -21
- package/src/table.js +15 -13
- package/src/text.js +20 -13
- package/src/align.js +0 -164
package/package.json
CHANGED
package/src/diagram.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readXmlFile } from './readXmlFile'
|
|
2
|
+
import { getTextNodeValue } from './text'
|
|
2
3
|
import { getTextByPathList } from './utils'
|
|
3
4
|
|
|
4
5
|
export async function loadDiagramFile(warpObj, filename, transformDrawing = false) {
|
|
@@ -112,7 +113,7 @@ export function getSmartArtTextData(dataContent) {
|
|
|
112
113
|
if (!Array.isArray(runs)) runs = [runs]
|
|
113
114
|
|
|
114
115
|
runs.forEach(r => {
|
|
115
|
-
const t = getTextByPathList(r, ['a:t'])
|
|
116
|
+
const t = getTextNodeValue(getTextByPathList(r, ['a:t']))
|
|
116
117
|
if (t && typeof t === 'string') nodeText += t
|
|
117
118
|
})
|
|
118
119
|
}
|
package/src/fontStyle.js
CHANGED
|
@@ -44,6 +44,14 @@ function appendMasterTextStyleNodes(styleNodes, type, lvl, slideMasterTextStyles
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function appendDefaultTextStyleNodes(styleNodes, lvl, defaultTextStyle) {
|
|
48
|
+
if (!defaultTextStyle) return
|
|
49
|
+
|
|
50
|
+
const lvlPath = getLevelPath(lvl)
|
|
51
|
+
pushStyleNode(styleNodes, getTextByPathList(defaultTextStyle, [lvlPath, 'a:defRPr']))
|
|
52
|
+
pushStyleNode(styleNodes, getTextByPathList(defaultTextStyle, ['a:defPPr', 'a:defRPr']))
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
function getBaseFontStyleNodes(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, lvl) {
|
|
48
56
|
const styleNodes = []
|
|
49
57
|
const runStyleNode = getTextByPathList(node, ['a:rPr'])
|
|
@@ -180,8 +188,9 @@ export function getFontColor(node, pNode, textBodyNode, slideLayoutSpNode, slide
|
|
|
180
188
|
return color || ''
|
|
181
189
|
}
|
|
182
190
|
|
|
183
|
-
export function getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl) {
|
|
191
|
+
export function getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, defaultTextStyle) {
|
|
184
192
|
const styleNodes = getFontStyleNodes(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
193
|
+
appendDefaultTextStyleNodes(styleNodes, lvl, defaultTextStyle)
|
|
185
194
|
const sz = getFontAttr(styleNodes, 'sz')
|
|
186
195
|
let fontSize = sz ? parseInt(sz) / 100 : undefined
|
|
187
196
|
|
|
@@ -235,4 +244,4 @@ export function getFontShadow(node, pNode, textBodyNode, slideLayoutSpNode, slid
|
|
|
235
244
|
}
|
|
236
245
|
}
|
|
237
246
|
return ''
|
|
238
|
-
}
|
|
247
|
+
}
|
package/src/paragraph.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
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'])
|
|
15
|
+
|
|
16
|
+
return algn || ''
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getHorizontalAlign(node, pNode, type, slideLayoutSpNode, slideMasterSpNode, warpObj) {
|
|
20
|
+
let algn = getTextByPathList(node, ['a:pPr', 'attrs', 'algn'])
|
|
21
|
+
|
|
22
|
+
if (!algn) algn = getTextByPathList(pNode, ['p:txBody', 'a:p', 'a:pPr', 'attrs', 'algn'])
|
|
23
|
+
|
|
24
|
+
if (!algn) {
|
|
25
|
+
const lvlIdx = getParagraphLevel(node)
|
|
26
|
+
const lvlStr = 'a:lvl' + lvlIdx + 'pPr'
|
|
27
|
+
|
|
28
|
+
algn = getAlignFromTextNode(slideLayoutSpNode, lvlStr)
|
|
29
|
+
if (!algn) algn = getAlignFromTextNode(slideMasterSpNode, lvlStr)
|
|
30
|
+
|
|
31
|
+
if (!algn && (type === 'title' || type === 'ctrTitle' || type === 'subTitle')) {
|
|
32
|
+
algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:titleStyle', lvlStr, 'attrs', 'algn'])
|
|
33
|
+
if (!algn && type === 'subTitle') {
|
|
34
|
+
algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', lvlStr, 'attrs', 'algn'])
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (!algn && type === 'body') {
|
|
38
|
+
algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', lvlStr, 'attrs', 'algn'])
|
|
39
|
+
}
|
|
40
|
+
else if (!algn) {
|
|
41
|
+
algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:otherStyle', lvlStr, 'attrs', 'algn'])
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let align = 'left'
|
|
46
|
+
if (algn) {
|
|
47
|
+
switch (algn) {
|
|
48
|
+
case 'l':
|
|
49
|
+
align = 'left'
|
|
50
|
+
break
|
|
51
|
+
case 'r':
|
|
52
|
+
align = 'right'
|
|
53
|
+
break
|
|
54
|
+
case 'ctr':
|
|
55
|
+
align = 'center'
|
|
56
|
+
break
|
|
57
|
+
case 'just':
|
|
58
|
+
align = 'justify'
|
|
59
|
+
break
|
|
60
|
+
case 'dist':
|
|
61
|
+
align = 'justify'
|
|
62
|
+
break
|
|
63
|
+
default:
|
|
64
|
+
align = 'inherit'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return align
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode) {
|
|
71
|
+
let anchor = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
|
|
72
|
+
if (!anchor) {
|
|
73
|
+
anchor = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
|
|
74
|
+
if (!anchor) {
|
|
75
|
+
anchor = getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
|
|
76
|
+
if (!anchor) anchor = 't'
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return (anchor === 'ctr') ? 'mid' : ((anchor === 'b') ? 'down' : 'up')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode) {
|
|
83
|
+
function checkBodyPr(bodyPr) {
|
|
84
|
+
if (!bodyPr) return null
|
|
85
|
+
|
|
86
|
+
if (bodyPr['a:noAutofit']) return { result: null }
|
|
87
|
+
else if (bodyPr['a:spAutoFit']) return { result: { type: 'shape' } }
|
|
88
|
+
else if (bodyPr['a:normAutofit']) {
|
|
89
|
+
const fontScale = getTextByPathList(bodyPr['a:normAutofit'], ['attrs', 'fontScale'])
|
|
90
|
+
if (fontScale) {
|
|
91
|
+
const scalePercent = parseInt(fontScale) / 1000
|
|
92
|
+
return {
|
|
93
|
+
result: {
|
|
94
|
+
type: 'text',
|
|
95
|
+
fontScale: scalePercent,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { result: { type: 'text' } }
|
|
100
|
+
}
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const nodeCheck = checkBodyPr(getTextByPathList(node, ['p:txBody', 'a:bodyPr']))
|
|
105
|
+
if (nodeCheck) return nodeCheck.result
|
|
106
|
+
|
|
107
|
+
const layoutCheck = checkBodyPr(getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr']))
|
|
108
|
+
if (layoutCheck) return layoutCheck.result
|
|
109
|
+
|
|
110
|
+
const masterCheck = checkBodyPr(getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr']))
|
|
111
|
+
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
|
+
}
|
package/src/pptxtojson.js
CHANGED
|
@@ -3,9 +3,9 @@ import { readXmlFile } from './readXmlFile'
|
|
|
3
3
|
import { getBorder } from './border'
|
|
4
4
|
import { getSlideBackgroundFill, getShapeFill, getSolidFill, getPicFill, getPicFilters, getImageData, getVideoData, getAudioData } from './fill'
|
|
5
5
|
import { getChartInfo } from './chart'
|
|
6
|
-
import { getVerticalAlign, getTextAutoFit } from './
|
|
6
|
+
import { getVerticalAlign, getTextAutoFit } from './paragraph'
|
|
7
7
|
import { getPosition, getSize } from './position'
|
|
8
|
-
import { genTextBody } from './text'
|
|
8
|
+
import { genTextBody, getTextNodeValue } from './text'
|
|
9
9
|
import { getCustomShapePath, identifyShape } from './shape'
|
|
10
10
|
import { extractFileExtension, getTextByPathList, angleToDegrees, isVideoLink, escapeHtml, hasValidText, numberToFixed } from './utils'
|
|
11
11
|
import { getShadow } from './shadow'
|
|
@@ -33,6 +33,7 @@ export async function parse(file, options = {}) {
|
|
|
33
33
|
const filesInfo = await getContentTypes(zip)
|
|
34
34
|
const { width, height, defaultTextStyle } = await getSlideInfo(zip)
|
|
35
35
|
const { themeContent, themeColors } = await getTheme(zip)
|
|
36
|
+
const usedFonts = await getUsedFonts(zip)
|
|
36
37
|
|
|
37
38
|
for (const filename of filesInfo.slides) {
|
|
38
39
|
const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, parseOptions)
|
|
@@ -41,6 +42,7 @@ export async function parse(file, options = {}) {
|
|
|
41
42
|
|
|
42
43
|
return {
|
|
43
44
|
slides,
|
|
45
|
+
usedFonts,
|
|
44
46
|
themeColors,
|
|
45
47
|
size: {
|
|
46
48
|
width,
|
|
@@ -81,6 +83,22 @@ async function getContentTypes(zip) {
|
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
async function getUsedFonts(zip) {
|
|
87
|
+
const content = await readXmlFile(zip, 'ppt/presentation.xml')
|
|
88
|
+
const embeddedFontList = getTextByPathList(content, ['p:presentation', 'p:embeddedFontLst', 'p:embeddedFont'])
|
|
89
|
+
const usedFonts = []
|
|
90
|
+
|
|
91
|
+
if (!embeddedFontList) return usedFonts
|
|
92
|
+
|
|
93
|
+
const embeddedFonts = embeddedFontList.constructor === Array ? embeddedFontList : [embeddedFontList]
|
|
94
|
+
for (const embeddedFont of embeddedFonts) {
|
|
95
|
+
const typeface = getTextByPathList(embeddedFont, ['p:font', 'attrs', 'typeface'])
|
|
96
|
+
if (typeface && !usedFonts.includes(typeface)) usedFonts.push(typeface)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return usedFonts
|
|
100
|
+
}
|
|
101
|
+
|
|
84
102
|
async function getSlideInfo(zip) {
|
|
85
103
|
const content = await readXmlFile(zip, 'ppt/presentation.xml')
|
|
86
104
|
const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']
|
|
@@ -392,7 +410,7 @@ function getNote(noteContent) {
|
|
|
392
410
|
if (rNodes) {
|
|
393
411
|
if (rNodes.constructor !== Array) rNodes = [rNodes]
|
|
394
412
|
for (const r of rNodes) {
|
|
395
|
-
const t = getTextByPathList(r, ['a:t'])
|
|
413
|
+
const t = getTextNodeValue(getTextByPathList(r, ['a:t']))
|
|
396
414
|
if (t && typeof t === 'string') text += t
|
|
397
415
|
}
|
|
398
416
|
}
|
|
@@ -622,11 +640,13 @@ async function processGroupSpNode(node, warpObj, source, parentGroupHierarchy =
|
|
|
622
640
|
if (depth > 10) return elements
|
|
623
641
|
|
|
624
642
|
return elements.map(element => {
|
|
625
|
-
const processed = {
|
|
626
|
-
...element,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
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
|
+
}
|
|
630
650
|
if (element.type === 'group' && element.elements) {
|
|
631
651
|
processed.elements = processNestedGroupElements(element.elements, ws, hs, depth + 1)
|
|
632
652
|
}
|
|
@@ -678,10 +698,11 @@ async function processSpNode(node, warpObj, source, groupHierarchy = []) {
|
|
|
678
698
|
const txBoxVal = getTextByPathList(node, ['p:nvSpPr', 'p:cNvSpPr', 'attrs', 'txBox'])
|
|
679
699
|
if (txBoxVal === '1') type = 'text'
|
|
680
700
|
}
|
|
681
|
-
if (!type) type = getTextByPathList(slideLayoutSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
682
|
-
if (!type) type = getTextByPathList(slideMasterSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
|
|
683
|
-
|
|
684
|
-
|
|
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) {
|
|
685
706
|
if (source === 'diagramBg') type = 'diagram'
|
|
686
707
|
else type = 'obj'
|
|
687
708
|
}
|
|
@@ -1167,10 +1188,11 @@ async function genTable(node, warpObj) {
|
|
|
1167
1188
|
if (cell.rowSpan) td.rowSpan = cell.rowSpan
|
|
1168
1189
|
if (cell.colSpan) td.colSpan = cell.colSpan
|
|
1169
1190
|
if (cell.vMerge) td.vMerge = cell.vMerge
|
|
1170
|
-
if (cell.hMerge) td.hMerge = cell.hMerge
|
|
1171
|
-
if (cell.
|
|
1172
|
-
if (cell.
|
|
1173
|
-
if (cell.
|
|
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
|
|
1174
1196
|
if (cell.borders) td.borders = cell.borders
|
|
1175
1197
|
|
|
1176
1198
|
tr.push(td)
|
|
@@ -1199,10 +1221,11 @@ async function genTable(node, warpObj) {
|
|
|
1199
1221
|
if (cell.rowSpan) td.rowSpan = cell.rowSpan
|
|
1200
1222
|
if (cell.colSpan) td.colSpan = cell.colSpan
|
|
1201
1223
|
if (cell.vMerge) td.vMerge = cell.vMerge
|
|
1202
|
-
if (cell.hMerge) td.hMerge = cell.hMerge
|
|
1203
|
-
if (cell.
|
|
1204
|
-
if (cell.
|
|
1205
|
-
if (cell.
|
|
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
|
|
1206
1229
|
if (cell.borders) td.borders = cell.borders
|
|
1207
1230
|
|
|
1208
1231
|
tr.push(td)
|
|
@@ -1298,4 +1321,4 @@ async function genDiagram(node, warpObj) {
|
|
|
1298
1321
|
textList,
|
|
1299
1322
|
order,
|
|
1300
1323
|
}
|
|
1301
|
-
}
|
|
1324
|
+
}
|
package/src/readXmlFile.js
CHANGED
|
@@ -2,6 +2,10 @@ import * as txml from 'txml/dist/txml.mjs'
|
|
|
2
2
|
|
|
3
3
|
let cust_attr_order = 0
|
|
4
4
|
|
|
5
|
+
function isWhitespaceTextNode(node) {
|
|
6
|
+
return typeof node === 'string' && node.trim() === ''
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
export function simplifyLostLess(children, parentAttributes = {}) {
|
|
6
10
|
const out = {}
|
|
7
11
|
if (!children.length) return out
|
|
@@ -13,6 +17,7 @@ export function simplifyLostLess(children, parentAttributes = {}) {
|
|
|
13
17
|
} : children[0]
|
|
14
18
|
}
|
|
15
19
|
for (const child of children) {
|
|
20
|
+
if (isWhitespaceTextNode(child)) continue
|
|
16
21
|
if (typeof child !== 'object') return
|
|
17
22
|
if (child.tagName === '?xml') continue
|
|
18
23
|
|
|
@@ -39,7 +44,7 @@ export function simplifyLostLess(children, parentAttributes = {}) {
|
|
|
39
44
|
export async function readXmlFile(zip, filename) {
|
|
40
45
|
try {
|
|
41
46
|
const data = await zip.file(filename).async('string')
|
|
42
|
-
return simplifyLostLess(txml.parse(data))
|
|
47
|
+
return simplifyLostLess(txml.parse(data, { keepWhitespace: true }))
|
|
43
48
|
}
|
|
44
49
|
catch {
|
|
45
50
|
return null
|
package/src/shapePath.js
CHANGED
|
@@ -4,28 +4,33 @@ import { RATIO_EMUs_Points } from './constants'
|
|
|
4
4
|
import { getTextByPathList } from './utils'
|
|
5
5
|
|
|
6
6
|
function shapePie(H, w, adj1, adj2, isClose) {
|
|
7
|
-
const pieVal =
|
|
8
|
-
const piAngle =
|
|
7
|
+
const pieVal = parseFloat(adj2)
|
|
8
|
+
const piAngle = parseFloat(adj1)
|
|
9
9
|
const size = parseInt(H)
|
|
10
|
-
const
|
|
10
|
+
const radiusY = size / 2
|
|
11
|
+
const radiusX = w / 2
|
|
12
|
+
const centerX = radiusX
|
|
13
|
+
const centerY = radiusY
|
|
11
14
|
|
|
12
15
|
let value = pieVal - piAngle
|
|
13
16
|
if (value < 0) value = 360 + value
|
|
14
17
|
value = Math.min(Math.max(value, 0), 360)
|
|
15
18
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
19
|
+
const startRadians = piAngle * Math.PI / 180
|
|
20
|
+
const endRadians = (piAngle + value) * Math.PI / 180
|
|
21
|
+
const startX = centerX + Math.cos(startRadians) * radiusX
|
|
22
|
+
const startY = centerY + Math.sin(startRadians) * radiusY
|
|
23
|
+
const endX = centerX + Math.cos(endRadians) * radiusX
|
|
24
|
+
const endY = centerY + Math.sin(endRadians) * radiusY
|
|
18
25
|
|
|
19
26
|
let longArc, d
|
|
20
27
|
if (isClose) {
|
|
21
28
|
longArc = (value <= 180) ? 0 : 1
|
|
22
|
-
d = `M${
|
|
29
|
+
d = `M${centerX},${centerY} L${startX},${startY} A${radiusX},${radiusY} 0 ${longArc},1 ${endX},${endY} z`
|
|
23
30
|
}
|
|
24
31
|
else {
|
|
25
32
|
longArc = (value <= 180) ? 0 : 1
|
|
26
|
-
|
|
27
|
-
const radius2 = w / 2
|
|
28
|
-
d = `M${radius1},0 A${radius2},${radius1} 0 ${longArc},1 ${radius2 + y * radius2},${radius1 - x * radius1}`
|
|
33
|
+
d = `M${startX},${startY} A${radiusX},${radiusY} 0 ${longArc},1 ${endX},${endY}`
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
return d
|
|
@@ -1434,17 +1439,18 @@ export function getShapePath(shapType, w, h, node) {
|
|
|
1434
1439
|
}
|
|
1435
1440
|
|
|
1436
1441
|
if (shapAdjst) {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1442
|
+
const shapAdjstAry = Array.isArray(shapAdjst) ? shapAdjst : [shapAdjst]
|
|
1443
|
+
for (const adj of shapAdjstAry) {
|
|
1444
|
+
const name = getTextByPathList(adj, ['attrs', 'name'])
|
|
1445
|
+
const fmla = getTextByPathList(adj, ['attrs', 'fmla'])
|
|
1446
|
+
if (!name || !fmla) continue
|
|
1447
|
+
|
|
1448
|
+
if (name === 'adj1') {
|
|
1449
|
+
adj1 = parseInt(fmla.substring(4)) / 60000
|
|
1450
|
+
}
|
|
1451
|
+
else if (name === 'adj2') {
|
|
1452
|
+
adj2 = parseInt(fmla.substring(4)) / 60000
|
|
1453
|
+
}
|
|
1448
1454
|
}
|
|
1449
1455
|
}
|
|
1450
1456
|
|
|
@@ -4628,4 +4634,4 @@ export function getShapePath(shapType, w, h, node) {
|
|
|
4628
4634
|
}
|
|
4629
4635
|
|
|
4630
4636
|
return pathData
|
|
4631
|
-
}
|
|
4637
|
+
}
|
package/src/table.js
CHANGED
|
@@ -49,14 +49,15 @@ export function getTableBorders(node, warpObj) {
|
|
|
49
49
|
return borders
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export async function getTableCellParams(tcNode, thisTblStyle, cellSource, warpObj) {
|
|
53
|
-
const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
|
|
54
|
-
const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
|
|
55
|
-
const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
|
|
56
|
-
const hMerge = getTextByPathList(tcNode, ['attrs', 'hMerge'])
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
let
|
|
52
|
+
export async function getTableCellParams(tcNode, thisTblStyle, cellSource, warpObj) {
|
|
53
|
+
const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
|
|
54
|
+
const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
|
|
55
|
+
const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
|
|
56
|
+
const hMerge = getTextByPathList(tcNode, ['attrs', 'hMerge'])
|
|
57
|
+
const anchor = getTextByPathList(tcNode, ['a:tcPr', 'attrs', 'anchor'])
|
|
58
|
+
let fillColor
|
|
59
|
+
let fontColor
|
|
60
|
+
let fontBold
|
|
60
61
|
|
|
61
62
|
const getCelFill = getTextByPathList(tcNode, ['a:tcPr'])
|
|
62
63
|
if (getCelFill) {
|
|
@@ -113,10 +114,11 @@ export async function getTableCellParams(tcNode, thisTblStyle, cellSource, warpO
|
|
|
113
114
|
fillColor,
|
|
114
115
|
fontColor,
|
|
115
116
|
fontBold,
|
|
116
|
-
borders,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
borders,
|
|
118
|
+
vAlign: (anchor === 'ctr') ? 'mid' : ((anchor === 'b') ? 'down' : 'up'),
|
|
119
|
+
rowSpan: rowSpan ? +rowSpan : undefined,
|
|
120
|
+
colSpan: colSpan ? +colSpan : undefined,
|
|
121
|
+
vMerge: vMerge ? +vMerge : undefined,
|
|
120
122
|
hMerge: hMerge ? +hMerge : undefined,
|
|
121
123
|
}
|
|
122
124
|
}
|
|
@@ -202,4 +204,4 @@ export function getTableRowParams(trNodes, i, tblStylAttrObj, thisTblStyle, warp
|
|
|
202
204
|
fontColor,
|
|
203
205
|
fontBold,
|
|
204
206
|
}
|
|
205
|
-
}
|
|
207
|
+
}
|
package/src/text.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHorizontalAlign, getParagraphSpacing } from './
|
|
1
|
+
import { getHorizontalAlign, getParagraphSpacing } from './paragraph'
|
|
2
2
|
import { getTextByPathList } from './utils'
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -14,13 +14,20 @@ import {
|
|
|
14
14
|
getFontShadow,
|
|
15
15
|
} from './fontStyle'
|
|
16
16
|
|
|
17
|
+
export function getTextNodeValue(node) {
|
|
18
|
+
if (typeof node === 'string') return node
|
|
19
|
+
if (node && typeof node.value === 'string') return node.value
|
|
20
|
+
return undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj) {
|
|
18
24
|
if (!textBodyNode) return ''
|
|
19
25
|
|
|
20
26
|
let text = ''
|
|
21
27
|
|
|
22
|
-
const pFontStyle = getTextByPathList(spNode, ['p:style', 'a:fontRef'])
|
|
23
|
-
const slideMasterTextStyles = spNode && spNode['a:tcPr'] ? undefined : warpObj['slideMasterTextStyles']
|
|
28
|
+
const pFontStyle = getTextByPathList(spNode, ['p:style', 'a:fontRef'])
|
|
29
|
+
const slideMasterTextStyles = spNode && spNode['a:tcPr'] ? undefined : warpObj['slideMasterTextStyles']
|
|
30
|
+
const defaultTextStyle = spNode && spNode['a:tcPr'] ? warpObj['defaultTextStyle'] : undefined
|
|
24
31
|
|
|
25
32
|
const pNode = textBodyNode['a:p']
|
|
26
33
|
const pNodes = pNode.constructor === Array ? pNode : [pNode]
|
|
@@ -52,7 +59,7 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMaster
|
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
const align = getHorizontalAlign(pNode, spNode, type, slideLayoutSpNode, slideMasterSpNode, warpObj)
|
|
55
|
-
const spacing = getParagraphSpacing(pNode)
|
|
62
|
+
const spacing = getParagraphSpacing(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
56
63
|
|
|
57
64
|
let styleText = `text-align: ${align};`
|
|
58
65
|
if (spacing) {
|
|
@@ -90,14 +97,14 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMaster
|
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
if (!rNode) {
|
|
93
|
-
text += genSpanElement(pNode, spNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
100
|
+
text += genSpanElement(pNode, spNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj)
|
|
94
101
|
}
|
|
95
102
|
else {
|
|
96
103
|
let prevStyleInfo = null
|
|
97
104
|
let accumulatedText = ''
|
|
98
105
|
|
|
99
106
|
for (const rNodeItem of rNode) {
|
|
100
|
-
const styleInfo = getSpanStyleInfo(rNodeItem, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
107
|
+
const styleInfo = getSpanStyleInfo(rNodeItem, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj)
|
|
101
108
|
|
|
102
109
|
if (!prevStyleInfo || prevStyleInfo.styleText !== styleInfo.styleText || prevStyleInfo.hasLink !== styleInfo.hasLink || styleInfo.hasLink) {
|
|
103
110
|
if (accumulatedText) {
|
|
@@ -154,8 +161,8 @@ export function getListLevel(node) {
|
|
|
154
161
|
return 0
|
|
155
162
|
}
|
|
156
163
|
|
|
157
|
-
export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
|
|
158
|
-
const { styleText, text, hasLink, linkURL } = getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
164
|
+
export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj) {
|
|
165
|
+
const { styleText, text, hasLink, linkURL } = getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj)
|
|
159
166
|
const processedText = text.replace(/\t/g, ' ').replace(/\s/g, ' ')
|
|
160
167
|
|
|
161
168
|
if (hasLink) {
|
|
@@ -164,19 +171,19 @@ export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayou
|
|
|
164
171
|
return `<span style="${styleText}">${processedText}</span>`
|
|
165
172
|
}
|
|
166
173
|
|
|
167
|
-
export function getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
|
|
174
|
+
export function getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj) {
|
|
168
175
|
let lvl = 1
|
|
169
176
|
const pPrNode = pNode['a:pPr']
|
|
170
177
|
const lvlNode = getTextByPathList(pPrNode, ['attrs', 'lvl'])
|
|
171
178
|
if (lvlNode !== undefined) lvl = parseInt(lvlNode) + 1
|
|
172
179
|
|
|
173
|
-
let text = node['a:t']
|
|
174
|
-
if (typeof text !== 'string') text = getTextByPathList(node, ['a:fld', 'a:t'])
|
|
180
|
+
let text = getTextNodeValue(node['a:t'])
|
|
181
|
+
if (typeof text !== 'string') text = getTextNodeValue(getTextByPathList(node, ['a:fld', 'a:t']))
|
|
175
182
|
if (typeof text !== 'string') text = ' '
|
|
176
183
|
|
|
177
184
|
let styleText = ''
|
|
178
185
|
const fontColor = getFontColor(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, pFontStyle, warpObj)
|
|
179
|
-
const fontSize = getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
186
|
+
const fontSize = getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, defaultTextStyle)
|
|
180
187
|
const fontType = getFontType(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, warpObj)
|
|
181
188
|
const fontBold = getFontBold(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
182
189
|
const fontItalic = getFontItalic(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
@@ -214,4 +221,4 @@ export function getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLay
|
|
|
214
221
|
hasLink,
|
|
215
222
|
linkURL: hasLink ? warpObj['slideResObj'][linkID]['target'] : null
|
|
216
223
|
}
|
|
217
|
-
}
|
|
224
|
+
}
|