pptxtojson 2.0.1 → 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/fontStyle.js +11 -2
- package/src/paragraph.js +223 -0
- package/src/pptxtojson.js +42 -19
- package/src/table.js +15 -13
- package/src/text.js +12 -11
- package/src/align.js +0 -164
package/package.json
CHANGED
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,7 +3,7 @@ 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
8
|
import { genTextBody, getTextNodeValue } from './text'
|
|
9
9
|
import { getCustomShapePath, identifyShape } from './shape'
|
|
@@ -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']
|
|
@@ -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/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 {
|
|
@@ -25,8 +25,9 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMaster
|
|
|
25
25
|
|
|
26
26
|
let text = ''
|
|
27
27
|
|
|
28
|
-
const pFontStyle = getTextByPathList(spNode, ['p:style', 'a:fontRef'])
|
|
29
|
-
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
|
|
30
31
|
|
|
31
32
|
const pNode = textBodyNode['a:p']
|
|
32
33
|
const pNodes = pNode.constructor === Array ? pNode : [pNode]
|
|
@@ -58,7 +59,7 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMaster
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
const align = getHorizontalAlign(pNode, spNode, type, slideLayoutSpNode, slideMasterSpNode, warpObj)
|
|
61
|
-
const spacing = getParagraphSpacing(pNode)
|
|
62
|
+
const spacing = getParagraphSpacing(pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
62
63
|
|
|
63
64
|
let styleText = `text-align: ${align};`
|
|
64
65
|
if (spacing) {
|
|
@@ -96,14 +97,14 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, slideMaster
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
if (!rNode) {
|
|
99
|
-
text += genSpanElement(pNode, spNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj)
|
|
100
|
+
text += genSpanElement(pNode, spNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, defaultTextStyle, warpObj)
|
|
100
101
|
}
|
|
101
102
|
else {
|
|
102
103
|
let prevStyleInfo = null
|
|
103
104
|
let accumulatedText = ''
|
|
104
105
|
|
|
105
106
|
for (const rNodeItem of rNode) {
|
|
106
|
-
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)
|
|
107
108
|
|
|
108
109
|
if (!prevStyleInfo || prevStyleInfo.styleText !== styleInfo.styleText || prevStyleInfo.hasLink !== styleInfo.hasLink || styleInfo.hasLink) {
|
|
109
110
|
if (accumulatedText) {
|
|
@@ -160,8 +161,8 @@ export function getListLevel(node) {
|
|
|
160
161
|
return 0
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, warpObj) {
|
|
164
|
-
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)
|
|
165
166
|
const processedText = text.replace(/\t/g, ' ').replace(/\s/g, ' ')
|
|
166
167
|
|
|
167
168
|
if (hasLink) {
|
|
@@ -170,7 +171,7 @@ export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayou
|
|
|
170
171
|
return `<span style="${styleText}">${processedText}</span>`
|
|
171
172
|
}
|
|
172
173
|
|
|
173
|
-
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) {
|
|
174
175
|
let lvl = 1
|
|
175
176
|
const pPrNode = pNode['a:pPr']
|
|
176
177
|
const lvlNode = getTextByPathList(pPrNode, ['attrs', 'lvl'])
|
|
@@ -182,7 +183,7 @@ export function getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLay
|
|
|
182
183
|
|
|
183
184
|
let styleText = ''
|
|
184
185
|
const fontColor = getFontColor(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, pFontStyle, warpObj)
|
|
185
|
-
const fontSize = getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
186
|
+
const fontSize = getFontSize(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, defaultTextStyle)
|
|
186
187
|
const fontType = getFontType(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl, warpObj)
|
|
187
188
|
const fontBold = getFontBold(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
188
189
|
const fontItalic = getFontItalic(node, pNode, textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles, lvl)
|
|
@@ -220,4 +221,4 @@ export function getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLay
|
|
|
220
221
|
hasLink,
|
|
221
222
|
linkURL: hasLink ? warpObj['slideResObj'][linkID]['target'] : null
|
|
222
223
|
}
|
|
223
|
-
}
|
|
224
|
+
}
|
package/src/align.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
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
|
-
export function getParagraphSpacing(pNode) {
|
|
117
|
-
if (!pNode) return null
|
|
118
|
-
|
|
119
|
-
const pPrNode = pNode['a:pPr']
|
|
120
|
-
if (!pPrNode) return null
|
|
121
|
-
|
|
122
|
-
const spacing = {}
|
|
123
|
-
|
|
124
|
-
const lnSpcNode = pPrNode['a:lnSpc']
|
|
125
|
-
if (lnSpcNode) {
|
|
126
|
-
const spcPct = getTextByPathList(lnSpcNode, ['a:spcPct', 'attrs', 'val'])
|
|
127
|
-
const spcPts = getTextByPathList(lnSpcNode, ['a:spcPts', 'attrs', 'val'])
|
|
128
|
-
|
|
129
|
-
if (spcPct) {
|
|
130
|
-
spacing.lineSpacing = parseInt(spcPct) / 1000 / 100
|
|
131
|
-
}
|
|
132
|
-
else if (spcPts) {
|
|
133
|
-
spacing.lineSpacing = parseInt(spcPts) / 100 + 'pt'
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const spcBefNode = pPrNode['a:spcBef']
|
|
138
|
-
if (spcBefNode) {
|
|
139
|
-
const spcPct = getTextByPathList(spcBefNode, ['a:spcPct', 'attrs', 'val'])
|
|
140
|
-
const spcPts = getTextByPathList(spcBefNode, ['a:spcPts', 'attrs', 'val'])
|
|
141
|
-
|
|
142
|
-
if (spcPct) {
|
|
143
|
-
spacing.spaceBefore = parseInt(spcPct) / 1000 + 'em'
|
|
144
|
-
}
|
|
145
|
-
else if (spcPts) {
|
|
146
|
-
spacing.spaceBefore = parseInt(spcPts) / 100 + 'pt'
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const spcAftNode = pPrNode['a:spcAft']
|
|
151
|
-
if (spcAftNode) {
|
|
152
|
-
const spcPct = getTextByPathList(spcAftNode, ['a:spcPct', 'attrs', 'val'])
|
|
153
|
-
const spcPts = getTextByPathList(spcAftNode, ['a:spcPts', 'attrs', 'val'])
|
|
154
|
-
|
|
155
|
-
if (spcPct) {
|
|
156
|
-
spacing.spaceAfter = parseInt(spcPct) / 1000 + 'em'
|
|
157
|
-
}
|
|
158
|
-
else if (spcPts) {
|
|
159
|
-
spacing.spaceAfter = parseInt(spcPts) / 100 + 'pt'
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return Object.keys(spacing).length > 0 ? spacing : null
|
|
164
|
-
}
|