pptxtojson 1.8.0 → 1.10.0

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": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
package/src/align.js CHANGED
@@ -62,4 +62,88 @@ export function getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode) {
62
62
  }
63
63
  }
64
64
  return (anchor === 'ctr') ? 'mid' : ((anchor === 'b') ? 'down' : 'up')
65
+ }
66
+
67
+ export function getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode) {
68
+ function checkBodyPr(bodyPr) {
69
+ if (!bodyPr) return null
70
+
71
+ if (bodyPr['a:noAutofit']) return { result: null }
72
+ else if (bodyPr['a:spAutoFit']) return { result: { type: 'shape' } }
73
+ else if (bodyPr['a:normAutofit']) {
74
+ const fontScale = getTextByPathList(bodyPr['a:normAutofit'], ['attrs', 'fontScale'])
75
+ if (fontScale) {
76
+ const scalePercent = parseInt(fontScale) / 1000
77
+ return {
78
+ result: {
79
+ type: 'text',
80
+ fontScale: scalePercent,
81
+ }
82
+ }
83
+ }
84
+ return { result: { type: 'text' } }
85
+ }
86
+ return null
87
+ }
88
+
89
+ const nodeCheck = checkBodyPr(getTextByPathList(node, ['p:txBody', 'a:bodyPr']))
90
+ if (nodeCheck) return nodeCheck.result
91
+
92
+ const layoutCheck = checkBodyPr(getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr']))
93
+ if (layoutCheck) return layoutCheck.result
94
+
95
+ const masterCheck = checkBodyPr(getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr']))
96
+ if (masterCheck) return masterCheck.result
97
+
98
+ return null
99
+ }
100
+
101
+ export function getParagraphSpacing(pNode) {
102
+ if (!pNode) return null
103
+
104
+ const pPrNode = pNode['a:pPr']
105
+ if (!pPrNode) return null
106
+
107
+ const spacing = {}
108
+
109
+ const lnSpcNode = pPrNode['a:lnSpc']
110
+ if (lnSpcNode) {
111
+ const spcPct = getTextByPathList(lnSpcNode, ['a:spcPct', 'attrs', 'val'])
112
+ const spcPts = getTextByPathList(lnSpcNode, ['a:spcPts', 'attrs', 'val'])
113
+
114
+ if (spcPct) {
115
+ spacing.lineSpacing = parseInt(spcPct) / 1000 / 100
116
+ }
117
+ else if (spcPts) {
118
+ spacing.lineSpacing = parseInt(spcPts) / 100 + 'pt'
119
+ }
120
+ }
121
+
122
+ const spcBefNode = pPrNode['a:spcBef']
123
+ if (spcBefNode) {
124
+ const spcPct = getTextByPathList(spcBefNode, ['a:spcPct', 'attrs', 'val'])
125
+ const spcPts = getTextByPathList(spcBefNode, ['a:spcPts', 'attrs', 'val'])
126
+
127
+ if (spcPct) {
128
+ spacing.spaceBefore = parseInt(spcPct) / 1000 + 'em'
129
+ }
130
+ else if (spcPts) {
131
+ spacing.spaceBefore = parseInt(spcPts) / 100 + 'pt'
132
+ }
133
+ }
134
+
135
+ const spcAftNode = pPrNode['a:spcAft']
136
+ if (spcAftNode) {
137
+ const spcPct = getTextByPathList(spcAftNode, ['a:spcPct', 'attrs', 'val'])
138
+ const spcPts = getTextByPathList(spcAftNode, ['a:spcPts', 'attrs', 'val'])
139
+
140
+ if (spcPct) {
141
+ spacing.spaceAfter = parseInt(spcPct) / 1000 + 'em'
142
+ }
143
+ else if (spcPts) {
144
+ spacing.spaceAfter = parseInt(spcPts) / 100 + 'pt'
145
+ }
146
+ }
147
+
148
+ return Object.keys(spacing).length > 0 ? spacing : null
65
149
  }
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 } from './fill'
5
5
  import { getChartInfo } from './chart'
6
- import { getVerticalAlign } from './align'
6
+ import { getVerticalAlign, getTextAutoFit } from './align'
7
7
  import { getPosition, getSize } from './position'
8
8
  import { genTextBody } from './text'
9
9
  import { getCustomShapePath } from './shape'
@@ -617,6 +617,7 @@ async function genShape(node, pNode, slideLayoutSpNode, slideMasterSpNode, name,
617
617
 
618
618
  const vAlign = getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type)
619
619
  const isVertical = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) === 'eaVert'
620
+ const autoFit = getTextAutoFit(node, slideLayoutSpNode, slideMasterSpNode)
620
621
 
621
622
  const data = {
622
623
  left,
@@ -638,6 +639,7 @@ async function genShape(node, pNode, slideLayoutSpNode, slideMasterSpNode, name,
638
639
  }
639
640
 
640
641
  if (shadow) data.shadow = shadow
642
+ if (autoFit) data.autoFit = autoFit
641
643
 
642
644
  const isHasValidText = data.content && hasValidText(data.content)
643
645
 
package/src/text.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getHorizontalAlign } from './align'
1
+ import { getHorizontalAlign, getParagraphSpacing } from './align'
2
2
  import { getTextByPathList } from './utils'
3
3
 
4
4
  import {
@@ -24,7 +24,7 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, type, warpO
24
24
  const pNode = textBodyNode['a:p']
25
25
  const pNodes = pNode.constructor === Array ? pNode : [pNode]
26
26
 
27
- let isList = ''
27
+ const listTypes = []
28
28
 
29
29
  for (const pNode of pNodes) {
30
30
  let rNode = pNode['a:r']
@@ -51,26 +51,41 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, type, warpO
51
51
  }
52
52
 
53
53
  const align = getHorizontalAlign(pNode, spNode, type, warpObj)
54
+ const spacing = getParagraphSpacing(pNode)
55
+
56
+ let styleText = `text-align: ${align};`
57
+ if (spacing) {
58
+ if (spacing.lineSpacing) styleText += `line-height: ${spacing.lineSpacing};`
59
+ if (spacing.spaceBefore) styleText += `margin-top: ${spacing.spaceBefore};`
60
+ if (spacing.spaceAfter) styleText += `margin-bottom: ${spacing.spaceAfter};`
61
+ }
54
62
 
55
63
  const listType = getListType(pNode)
64
+ const listLevel = getListLevel(pNode)
65
+
56
66
  if (listType) {
57
- if (!isList) {
67
+ while (listTypes.length > listLevel + 1) {
68
+ const closedListType = listTypes.pop()
69
+ text += `</${closedListType}>`
70
+ }
71
+
72
+ if (listTypes[listLevel] === undefined) {
58
73
  text += `<${listType}>`
59
- isList = listType
74
+ listTypes[listLevel] = listType
60
75
  }
61
- else if (isList && isList !== listType) {
62
- text += `</${isList}>`
76
+ else if (listTypes[listLevel] !== listType) {
77
+ text += `</${listTypes[listLevel]}>`
63
78
  text += `<${listType}>`
64
- isList = listType
79
+ listTypes[listLevel] = listType
65
80
  }
66
- text += `<li style="text-align: ${align};">`
81
+ text += `<li style="${styleText}">`
67
82
  }
68
83
  else {
69
- if (isList) {
70
- text += `</${isList}>`
71
- isList = ''
84
+ while (listTypes.length > 0) {
85
+ const closedListType = listTypes.pop()
86
+ text += `</${closedListType}>`
72
87
  }
73
- text += `<p style="text-align: ${align};">`
88
+ text += `<p style="${styleText}">`
74
89
  }
75
90
 
76
91
  if (!rNode) {
@@ -112,6 +127,10 @@ export function genTextBody(textBodyNode, spNode, slideLayoutSpNode, type, warpO
112
127
  if (listType) text += '</li>'
113
128
  else text += '</p>'
114
129
  }
130
+ while (listTypes.length > 0) {
131
+ const closedListType = listTypes.pop()
132
+ text += `</${closedListType}>`
133
+ }
115
134
  return text
116
135
  }
117
136
 
@@ -124,6 +143,15 @@ export function getListType(node) {
124
143
 
125
144
  return ''
126
145
  }
146
+ export function getListLevel(node) {
147
+ const pPrNode = node['a:pPr']
148
+ if (!pPrNode) return -1
149
+
150
+ const lvlNode = getTextByPathList(pPrNode, ['attrs', 'lvl'])
151
+ if (lvlNode !== undefined) return parseInt(lvlNode)
152
+
153
+ return 0
154
+ }
127
155
 
128
156
  export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, type, warpObj) {
129
157
  const { styleText, text, hasLink, linkURL } = getSpanStyleInfo(node, pNode, textBodyNode, pFontStyle, slideLayoutSpNode, type, warpObj)