pptxtojson 2.0.1 → 2.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptxtojson",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
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
+ }
@@ -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,8 @@ 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 './align'
6
+ import { getVerticalAlign, getTextAutoFit } from './paragraph'
7
+ import { getTextInsets } from './textInsets'
7
8
  import { getPosition, getSize } from './position'
8
9
  import { genTextBody, getTextNodeValue } from './text'
9
10
  import { getCustomShapePath, identifyShape } from './shape'
@@ -33,6 +34,7 @@ export async function parse(file, options = {}) {
33
34
  const filesInfo = await getContentTypes(zip)
34
35
  const { width, height, defaultTextStyle } = await getSlideInfo(zip)
35
36
  const { themeContent, themeColors } = await getTheme(zip)
37
+ const usedFonts = await getUsedFonts(zip)
36
38
 
37
39
  for (const filename of filesInfo.slides) {
38
40
  const singleSlide = await processSingleSlide(zip, filename, themeContent, defaultTextStyle, loadedImages, loadedVideos, loadedAudios, parseOptions)
@@ -41,6 +43,7 @@ export async function parse(file, options = {}) {
41
43
 
42
44
  return {
43
45
  slides,
46
+ usedFonts,
44
47
  themeColors,
45
48
  size: {
46
49
  width,
@@ -81,6 +84,22 @@ async function getContentTypes(zip) {
81
84
  }
82
85
  }
83
86
 
87
+ async function getUsedFonts(zip) {
88
+ const content = await readXmlFile(zip, 'ppt/presentation.xml')
89
+ const embeddedFontList = getTextByPathList(content, ['p:presentation', 'p:embeddedFontLst', 'p:embeddedFont'])
90
+ const usedFonts = []
91
+
92
+ if (!embeddedFontList) return usedFonts
93
+
94
+ const embeddedFonts = embeddedFontList.constructor === Array ? embeddedFontList : [embeddedFontList]
95
+ for (const embeddedFont of embeddedFonts) {
96
+ const typeface = getTextByPathList(embeddedFont, ['p:font', 'attrs', 'typeface'])
97
+ if (typeface && !usedFonts.includes(typeface)) usedFonts.push(typeface)
98
+ }
99
+
100
+ return usedFonts
101
+ }
102
+
84
103
  async function getSlideInfo(zip) {
85
104
  const content = await readXmlFile(zip, 'ppt/presentation.xml')
86
105
  const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']
@@ -624,6 +643,8 @@ async function processGroupSpNode(node, warpObj, source, parentGroupHierarchy =
624
643
  return elements.map(element => {
625
644
  const processed = {
626
645
  ...element,
646
+ left: numberToFixed(element.left * ws),
647
+ top: numberToFixed(element.top * hs),
627
648
  width: numberToFixed(element.width * ws),
628
649
  height: numberToFixed(element.height * hs),
629
650
  }
@@ -680,6 +701,7 @@ async function processSpNode(node, warpObj, source, groupHierarchy = []) {
680
701
  }
681
702
  if (!type) type = getTextByPathList(slideLayoutSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
682
703
  if (!type) type = getTextByPathList(slideMasterSpNode, ['p:nvSpPr', 'p:nvPr', 'p:ph', 'attrs', 'type'])
704
+ if (!slideMasterSpNode && type === 'ctrTitle') slideMasterSpNode = warpObj['slideMasterTables']['typeTable']['title']
683
705
 
684
706
  if (!type) {
685
707
  if (source === 'diagramBg') type = 'diagram'
@@ -754,6 +776,7 @@ async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type,
754
776
  const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
755
777
  const isVertical = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) === 'eaVert'
756
778
  const autoFit = getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode)
779
+ const textInset = getTextInsets(node, slideLayoutSpNode, slideMasterSpNode)
757
780
 
758
781
  const data = {
759
782
  left,
@@ -777,6 +800,7 @@ async function genShape(node, slideLayoutSpNode, slideMasterSpNode, name, type,
777
800
  if (shadow) data.shadow = shadow
778
801
  if (autoFit) data.autoFit = autoFit
779
802
  if (link) data.link = link
803
+ if (textInset) data.textInset = textInset
780
804
 
781
805
  const isHasValidText = data.content && hasValidText(data.content)
782
806
 
@@ -1168,6 +1192,7 @@ async function genTable(node, warpObj) {
1168
1192
  if (cell.colSpan) td.colSpan = cell.colSpan
1169
1193
  if (cell.vMerge) td.vMerge = cell.vMerge
1170
1194
  if (cell.hMerge) td.hMerge = cell.hMerge
1195
+ if (cell.vAlign) td.vAlign = cell.vAlign
1171
1196
  if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1172
1197
  if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1173
1198
  if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
@@ -1200,6 +1225,7 @@ async function genTable(node, warpObj) {
1200
1225
  if (cell.colSpan) td.colSpan = cell.colSpan
1201
1226
  if (cell.vMerge) td.vMerge = cell.vMerge
1202
1227
  if (cell.hMerge) td.hMerge = cell.hMerge
1228
+ if (cell.vAlign) td.vAlign = cell.vAlign
1203
1229
  if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
1204
1230
  if (cell.fontColor || fontColor) td.fontColor = cell.fontColor || fontColor
1205
1231
  if (cell.fillColor || fillColor || tbl_bgcolor) td.fillColor = cell.fillColor || fillColor || tbl_bgcolor
@@ -1298,4 +1324,4 @@ async function genDiagram(node, warpObj) {
1298
1324
  textList,
1299
1325
  order,
1300
1326
  }
1301
- }
1327
+ }
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
- let fillColor
58
- let fontColor
59
- let fontBold
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
- rowSpan: rowSpan ? +rowSpan : undefined,
118
- colSpan: colSpan ? +colSpan : undefined,
119
- vMerge: vMerge ? +vMerge : undefined,
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 './align'
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
+ }
@@ -0,0 +1,64 @@
1
+ import { getTextByPathList, numberToFixed } from './utils'
2
+ import { RATIO_EMUs_Points } from './constants'
3
+
4
+ const DEFAULT_INSET_EMU = {
5
+ lIns: 91440, // 0.1 in
6
+ rIns: 91440, // 0.1 in
7
+ tIns: 45720, // 0.05 in
8
+ bIns: 45720, // 0.05 in
9
+ }
10
+
11
+ function getInsetAttr(slideNode, layoutNode, masterNode, attrName) {
12
+ let v = getTextByPathList(slideNode, ['p:txBody', 'a:bodyPr', 'attrs', attrName])
13
+ if (v !== undefined && v !== null && v !== '') return v
14
+
15
+ v = getTextByPathList(layoutNode, ['p:txBody', 'a:bodyPr', 'attrs', attrName])
16
+ if (v !== undefined && v !== null && v !== '') return v
17
+
18
+ return getTextByPathList(masterNode, ['p:txBody', 'a:bodyPr', 'attrs', attrName])
19
+ }
20
+
21
+ function emuToPt(emuStr) {
22
+ if (emuStr === undefined || emuStr === null || emuStr === '') return null
23
+ const v = parseInt(emuStr, 10)
24
+ if (!Number.isFinite(v)) return null
25
+ return numberToFixed(v * RATIO_EMUs_Points)
26
+ }
27
+
28
+ export function getTextInsets(node, slideLayoutSpNode, slideMasterSpNode) {
29
+ const nodeBodyPr = getTextByPathList(node, ['p:txBody', 'a:bodyPr'])
30
+ const layoutBodyPr = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr'])
31
+ const masterBodyPr = getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr'])
32
+
33
+ if (!nodeBodyPr) {
34
+ if (!layoutBodyPr) {
35
+ if (!masterBodyPr) return null
36
+ }
37
+ }
38
+
39
+ let li = getInsetAttr(node, slideLayoutSpNode, slideMasterSpNode, 'lIns')
40
+ if (li === undefined || li === null || li === '') li = DEFAULT_INSET_EMU.lIns
41
+
42
+ let ti = getInsetAttr(node, slideLayoutSpNode, slideMasterSpNode, 'tIns')
43
+ if (ti === undefined || ti === null || ti === '') ti = DEFAULT_INSET_EMU.tIns
44
+
45
+ let ri = getInsetAttr(node, slideLayoutSpNode, slideMasterSpNode, 'rIns')
46
+ if (ri === undefined || ri === null || ri === '') ri = DEFAULT_INSET_EMU.rIns
47
+
48
+ let bi = getInsetAttr(node, slideLayoutSpNode, slideMasterSpNode, 'bIns')
49
+ if (bi === undefined || bi === null || bi === '') bi = DEFAULT_INSET_EMU.bIns
50
+
51
+ let l = emuToPt(li)
52
+ if (l === null) l = 0
53
+
54
+ let t = emuToPt(ti)
55
+ if (t === null) t = 0
56
+
57
+ let r = emuToPt(ri)
58
+ if (r === null) r = 0
59
+
60
+ let b = emuToPt(bi)
61
+ if (b === null) b = 0
62
+
63
+ return { l, t, r, b }
64
+ }