pptxtojson 1.6.1 → 1.7.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.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "A javascript tool for parsing .pptx file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
package/src/fill.js CHANGED
@@ -85,6 +85,79 @@ export function getPicFillOpacity(node) {
85
85
  return opacity
86
86
  }
87
87
 
88
+ export function getPicFilters(node) {
89
+ if (!node) return null
90
+
91
+ const aBlipNode = node['a:blip']
92
+ if (!aBlipNode) return null
93
+
94
+ const filters = {}
95
+
96
+ // 从a:extLst中获取滤镜效果(Microsoft Office 2010+扩展)
97
+ const extLstNode = aBlipNode['a:extLst']
98
+ if (extLstNode && extLstNode['a:ext']) {
99
+ const extNodes = Array.isArray(extLstNode['a:ext']) ? extLstNode['a:ext'] : [extLstNode['a:ext']]
100
+
101
+ for (const extNode of extNodes) {
102
+ if (!extNode['a14:imgProps'] || !extNode['a14:imgProps']['a14:imgLayer']) continue
103
+
104
+ const imgLayerNode = extNode['a14:imgProps']['a14:imgLayer']
105
+ const imgEffects = imgLayerNode['a14:imgEffect']
106
+
107
+ if (!imgEffects) continue
108
+
109
+ const effectArray = Array.isArray(imgEffects) ? imgEffects : [imgEffects]
110
+
111
+ for (const effect of effectArray) {
112
+ // 饱和度
113
+ if (effect['a14:saturation']) {
114
+ const satAttr = getTextByPathList(effect, ['a14:saturation', 'attrs', 'sat'])
115
+ if (satAttr) {
116
+ filters.saturation = parseInt(satAttr) / 100000
117
+ }
118
+ }
119
+
120
+ // 亮度、对比度
121
+ if (effect['a14:brightnessContrast']) {
122
+ const brightAttr = getTextByPathList(effect, ['a14:brightnessContrast', 'attrs', 'bright'])
123
+ const contrastAttr = getTextByPathList(effect, ['a14:brightnessContrast', 'attrs', 'contrast'])
124
+
125
+ if (brightAttr) {
126
+ filters.brightness = parseInt(brightAttr) / 100000
127
+ }
128
+ if (contrastAttr) {
129
+ filters.contrast = parseInt(contrastAttr) / 100000
130
+ }
131
+ }
132
+
133
+ // 锐化/柔化
134
+ if (effect['a14:sharpenSoften']) {
135
+ const amountAttr = getTextByPathList(effect, ['a14:sharpenSoften', 'attrs', 'amount'])
136
+ if (amountAttr) {
137
+ const amount = parseInt(amountAttr) / 100000
138
+ if (amount > 0) {
139
+ filters.sharpen = amount
140
+ }
141
+ else {
142
+ filters.soften = Math.abs(amount)
143
+ }
144
+ }
145
+ }
146
+
147
+ // 色温
148
+ if (effect['a14:colorTemperature']) {
149
+ const tempAttr = getTextByPathList(effect, ['a14:colorTemperature', 'attrs', 'colorTemp'])
150
+ if (tempAttr) {
151
+ filters.colorTemperature = parseInt(tempAttr)
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ return Object.keys(filters).length > 0 ? filters : null
159
+ }
160
+
88
161
  export async function getBgPicFill(bgPr, sorce, warpObj) {
89
162
  const picBase64 = await getPicFill(sorce, bgPr['a:blipFill'], warpObj)
90
163
  const aBlipNode = bgPr['a:blipFill']['a:blip']
package/src/fontStyle.js CHANGED
@@ -48,14 +48,49 @@ export function getFontColor(node, pNode, lstStyle, pFontStyle, lvl, warpObj) {
48
48
  return color || ''
49
49
  }
50
50
 
51
- export function getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles) {
51
+ export function getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles, textBodyNode, pNode) {
52
52
  let fontSize
53
53
 
54
54
  if (getTextByPathList(node, ['a:rPr', 'attrs', 'sz'])) fontSize = getTextByPathList(node, ['a:rPr', 'attrs', 'sz']) / 100
55
55
 
56
+ if ((isNaN(fontSize) || !fontSize) && pNode) {
57
+ if (getTextByPathList(pNode, ['a:endParaRPr', 'attrs', 'sz'])) {
58
+ fontSize = getTextByPathList(pNode, ['a:endParaRPr', 'attrs', 'sz']) / 100
59
+ }
60
+ }
61
+
62
+ if ((isNaN(fontSize) || !fontSize) && textBodyNode) {
63
+ const lstStyle = getTextByPathList(textBodyNode, ['a:lstStyle'])
64
+ if (lstStyle) {
65
+ let lvl = 1
66
+ if (pNode) {
67
+ const lvlNode = getTextByPathList(pNode, ['a:pPr', 'attrs', 'lvl'])
68
+ if (lvlNode !== undefined) lvl = parseInt(lvlNode) + 1
69
+ }
70
+
71
+ const sz = getTextByPathList(lstStyle, [`a:lvl${lvl}pPr`, 'a:defRPr', 'attrs', 'sz'])
72
+ if (sz) fontSize = parseInt(sz) / 100
73
+ }
74
+ }
75
+
56
76
  if ((isNaN(fontSize) || !fontSize)) {
57
77
  const sz = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:lstStyle', 'a:lvl1pPr', 'a:defRPr', 'attrs', 'sz'])
58
- fontSize = parseInt(sz) / 100
78
+ if (sz) fontSize = parseInt(sz) / 100
79
+ }
80
+
81
+ if ((isNaN(fontSize) || !fontSize) && slideLayoutSpNode) {
82
+ let lvl = 1
83
+ if (pNode) {
84
+ const lvlNode = getTextByPathList(pNode, ['a:pPr', 'attrs', 'lvl'])
85
+ if (lvlNode !== undefined) lvl = parseInt(lvlNode) + 1
86
+ }
87
+ const layoutSz = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:lstStyle', `a:lvl${lvl}pPr`, 'a:defRPr', 'attrs', 'sz'])
88
+ if (layoutSz) fontSize = parseInt(layoutSz) / 100
89
+ }
90
+
91
+ if ((isNaN(fontSize) || !fontSize) && pNode) {
92
+ const paraSz = getTextByPathList(pNode, ['a:pPr', 'a:defRPr', 'attrs', 'sz'])
93
+ if (paraSz) fontSize = parseInt(paraSz) / 100
59
94
  }
60
95
 
61
96
  if (isNaN(fontSize) || !fontSize) {
package/src/pptxtojson.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import JSZip from 'jszip'
2
2
  import { readXmlFile } from './readXmlFile'
3
3
  import { getBorder } from './border'
4
- import { getSlideBackgroundFill, getShapeFill, getSolidFill, getPicFill } from './fill'
4
+ import { getSlideBackgroundFill, getShapeFill, getSolidFill, getPicFill, getPicFilters } from './fill'
5
5
  import { getChartInfo } from './chart'
6
6
  import { getVerticalAlign } from './align'
7
7
  import { getPosition, getSize } from './position'
@@ -135,9 +135,17 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
135
135
  switch (relationshipArrayItem['attrs']['Type']) {
136
136
  case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout':
137
137
  layoutFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
138
+ slideResObj[relationshipArrayItem['attrs']['Id']] = {
139
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
140
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
141
+ }
138
142
  break
139
143
  case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide':
140
144
  noteFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
145
+ slideResObj[relationshipArrayItem['attrs']['Id']] = {
146
+ type: relationshipArrayItem['attrs']['Type'].replace('http://schemas.openxmlformats.org/officeDocument/2006/relationships/', ''),
147
+ target: relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
148
+ }
141
149
  break
142
150
  case 'http://schemas.microsoft.com/office/2007/relationships/diagramDrawing':
143
151
  diagramFilename = relationshipArrayItem['attrs']['Target'].replace('../', 'ppt/')
@@ -794,11 +802,13 @@ async function processPicNode(node, warpObj, source) {
794
802
 
795
803
  const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(node, undefined, warpObj)
796
804
 
797
- return {
805
+ const filters = getPicFilters(node['p:blipFill'])
806
+
807
+ const imageData = {
798
808
  type: 'image',
799
809
  top,
800
810
  left,
801
- width,
811
+ width,
802
812
  height,
803
813
  rotate,
804
814
  src,
@@ -812,6 +822,10 @@ async function processPicNode(node, warpObj, source) {
812
822
  borderType,
813
823
  borderStrokeDasharray: strokeDasharray,
814
824
  }
825
+
826
+ if (filters) imageData.filters = filters
827
+
828
+ return imageData
815
829
  }
816
830
 
817
831
  async function processGraphicFrameNode(node, warpObj, source) {
package/src/text.js CHANGED
@@ -111,7 +111,7 @@ export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayou
111
111
 
112
112
  let styleText = ''
113
113
  const fontColor = getFontColor(node, pNode, lstStyle, pFontStyle, lvl, warpObj)
114
- const fontSize = getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles)
114
+ const fontSize = getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles, textBodyNode, pNode)
115
115
  const fontType = getFontType(node, type, warpObj)
116
116
  const fontBold = getFontBold(node)
117
117
  const fontItalic = getFontItalic(node)
@@ -133,7 +133,7 @@ export function genSpanElement(node, pNode, textBodyNode, pFontStyle, slideLayou
133
133
  if (shadow) styleText += `text-shadow: ${shadow};`
134
134
 
135
135
  const linkID = getTextByPathList(node, ['a:rPr', 'a:hlinkClick', 'attrs', 'r:id'])
136
- if (linkID) {
136
+ if (linkID && warpObj['slideResObj'][linkID]) {
137
137
  const linkURL = warpObj['slideResObj'][linkID]['target']
138
138
  return `<span style="${styleText}"><a href="${linkURL}" target="_blank">${text.replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;').replace(/\s/g, '&nbsp;')}</a></span>`
139
139
  }