pptxtojson 0.0.12 → 0.1.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/README.md +9 -6
- package/dist/index.d.ts +67 -8
- 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/index.html +4 -1
- package/package.json +2 -2
- package/src/align.js +36 -0
- package/src/border.js +95 -0
- package/src/chart.js +173 -0
- package/src/color.js +168 -0
- package/src/fill.js +330 -0
- package/src/fontStyle.js +105 -0
- package/src/position.js +29 -0
- package/src/pptxtojson.js +218 -1076
- package/src/readXmlFile.js +41 -0
- package/src/schemeColor.js +24 -0
- package/src/shadow.js +18 -0
- package/src/shape.js +178 -0
- package/src/text.js +131 -0
- package/src/utils.js +16 -3
- package/test.pptx +0 -0
- package/test2.pptx +0 -0
- package/test3.pptx +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as txml from 'txml/dist/txml.mjs'
|
|
2
|
+
|
|
3
|
+
export function simplifyLostLess(children, parentAttributes = {}) {
|
|
4
|
+
const out = {}
|
|
5
|
+
if (!children.length) return out
|
|
6
|
+
|
|
7
|
+
if (children.length === 1 && typeof children[0] === 'string') {
|
|
8
|
+
return Object.keys(parentAttributes).length ? {
|
|
9
|
+
attrs: parentAttributes,
|
|
10
|
+
value: children[0],
|
|
11
|
+
} : children[0]
|
|
12
|
+
}
|
|
13
|
+
for (const child of children) {
|
|
14
|
+
if (typeof child !== 'object') return
|
|
15
|
+
if (child.tagName === '?xml') continue
|
|
16
|
+
|
|
17
|
+
if (!out[child.tagName]) out[child.tagName] = []
|
|
18
|
+
|
|
19
|
+
const kids = simplifyLostLess(child.children || [], child.attributes)
|
|
20
|
+
out[child.tagName].push(kids)
|
|
21
|
+
|
|
22
|
+
if (Object.keys(child.attributes).length) {
|
|
23
|
+
kids.attrs = child.attributes
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const child in out) {
|
|
27
|
+
if (out[child].length === 1) out[child] = out[child][0]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return out
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function readXmlFile(zip, filename) {
|
|
34
|
+
try {
|
|
35
|
+
const data = await zip.file(filename).async('string')
|
|
36
|
+
return simplifyLostLess(txml.parse(data))
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getTextByPathList } from './utils'
|
|
2
|
+
|
|
3
|
+
export function getSchemeColorFromTheme(schemeClr, warpObj) {
|
|
4
|
+
switch (schemeClr) {
|
|
5
|
+
case 'tx1':
|
|
6
|
+
schemeClr = 'a:dk1'
|
|
7
|
+
break
|
|
8
|
+
case 'tx2':
|
|
9
|
+
schemeClr = 'a:dk2'
|
|
10
|
+
break
|
|
11
|
+
case 'bg1':
|
|
12
|
+
schemeClr = 'a:lt1'
|
|
13
|
+
break
|
|
14
|
+
case 'bg2':
|
|
15
|
+
schemeClr = 'a:lt2'
|
|
16
|
+
break
|
|
17
|
+
default:
|
|
18
|
+
break
|
|
19
|
+
}
|
|
20
|
+
const refNode = getTextByPathList(warpObj['themeContent'], ['a:theme', 'a:themeElements', 'a:clrScheme', schemeClr])
|
|
21
|
+
let color = getTextByPathList(refNode, ['a:srgbClr', 'attrs', 'val'])
|
|
22
|
+
if (!color && refNode) color = getTextByPathList(refNode, ['a:sysClr', 'attrs', 'lastClr'])
|
|
23
|
+
return color
|
|
24
|
+
}
|
package/src/shadow.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getSolidFill } from './fill'
|
|
2
|
+
|
|
3
|
+
export function getShadow(node, warpObj, slideFactor) {
|
|
4
|
+
const chdwClrNode = getSolidFill(node, undefined, undefined, warpObj)
|
|
5
|
+
const outerShdwAttrs = node['attrs']
|
|
6
|
+
const dir = (outerShdwAttrs['dir']) ? (parseInt(outerShdwAttrs['dir']) / 60000) : 0
|
|
7
|
+
const dist = parseInt(outerShdwAttrs['dist']) * slideFactor
|
|
8
|
+
const blurRad = outerShdwAttrs['blurRad'] ? (parseInt(outerShdwAttrs['blurRad']) * slideFactor) : ''
|
|
9
|
+
const vx = dist * Math.sin(dir * Math.PI / 180)
|
|
10
|
+
const hx = dist * Math.cos(dir * Math.PI / 180)
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
h: hx,
|
|
14
|
+
v: vx,
|
|
15
|
+
blur: blurRad,
|
|
16
|
+
color: '#' + chdwClrNode,
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/shape.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { getTextByPathList } from './utils'
|
|
2
|
+
|
|
3
|
+
export function shapeArc(cX, cY, rX, rY, stAng, endAng, isClose) {
|
|
4
|
+
let dData
|
|
5
|
+
let angle = stAng
|
|
6
|
+
if (endAng >= stAng) {
|
|
7
|
+
while (angle <= endAng) {
|
|
8
|
+
const radians = angle * (Math.PI / 180)
|
|
9
|
+
const x = cX + Math.cos(radians) * rX
|
|
10
|
+
const y = cY + Math.sin(radians) * rY
|
|
11
|
+
if (angle === stAng) {
|
|
12
|
+
dData = ' M' + x + ' ' + y
|
|
13
|
+
}
|
|
14
|
+
dData += ' L' + x + ' ' + y
|
|
15
|
+
angle++
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
while (angle > endAng) {
|
|
20
|
+
const radians = angle * (Math.PI / 180)
|
|
21
|
+
const x = cX + Math.cos(radians) * rX
|
|
22
|
+
const y = cY + Math.sin(radians) * rY
|
|
23
|
+
if (angle === stAng) {
|
|
24
|
+
dData = ' M ' + x + ' ' + y
|
|
25
|
+
}
|
|
26
|
+
dData += ' L ' + x + ' ' + y
|
|
27
|
+
angle--
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
dData += (isClose ? ' z' : '')
|
|
31
|
+
return dData
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getCustomShapePath(custShapType, w, h) {
|
|
35
|
+
const pathLstNode = getTextByPathList(custShapType, ['a:pathLst'])
|
|
36
|
+
const pathNodes = getTextByPathList(pathLstNode, ['a:path'])
|
|
37
|
+
const maxX = parseInt(pathNodes['attrs']['w'])
|
|
38
|
+
const maxY = parseInt(pathNodes['attrs']['h'])
|
|
39
|
+
const cX = (1 / maxX) * w
|
|
40
|
+
const cY = (1 / maxY) * h
|
|
41
|
+
let d = ''
|
|
42
|
+
|
|
43
|
+
let moveToNode = getTextByPathList(pathNodes, ['a:moveTo'])
|
|
44
|
+
|
|
45
|
+
const lnToNodes = pathNodes['a:lnTo']
|
|
46
|
+
let cubicBezToNodes = pathNodes['a:cubicBezTo']
|
|
47
|
+
const arcToNodes = pathNodes['a:arcTo']
|
|
48
|
+
let closeNode = getTextByPathList(pathNodes, ['a:close'])
|
|
49
|
+
if (!Array.isArray(moveToNode)) moveToNode = [moveToNode]
|
|
50
|
+
|
|
51
|
+
const multiSapeAry = []
|
|
52
|
+
if (moveToNode.length > 0) {
|
|
53
|
+
Object.keys(moveToNode).forEach(key => {
|
|
54
|
+
const moveToPtNode = moveToNode[key]['a:pt']
|
|
55
|
+
if (moveToPtNode) {
|
|
56
|
+
Object.keys(moveToPtNode).forEach(key => {
|
|
57
|
+
const moveToNoPt = moveToPtNode[key]
|
|
58
|
+
const spX = moveToNoPt['attrs', 'x']
|
|
59
|
+
const spY = moveToNoPt['attrs', 'y']
|
|
60
|
+
|
|
61
|
+
multiSapeAry.push({
|
|
62
|
+
type: 'movto',
|
|
63
|
+
x: spX,
|
|
64
|
+
y: spY,
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
if (lnToNodes) {
|
|
70
|
+
Object.keys(lnToNodes).forEach(key => {
|
|
71
|
+
const lnToPtNode = lnToNodes[key]['a:pt']
|
|
72
|
+
if (lnToPtNode) {
|
|
73
|
+
Object.keys(lnToPtNode).forEach(key => {
|
|
74
|
+
const lnToNoPt = lnToPtNode[key]
|
|
75
|
+
const ptX = lnToNoPt['attrs', 'x']
|
|
76
|
+
const ptY = lnToNoPt['attrs', 'y']
|
|
77
|
+
multiSapeAry.push({
|
|
78
|
+
type: 'lnto',
|
|
79
|
+
x: ptX,
|
|
80
|
+
y: ptY,
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
if (cubicBezToNodes) {
|
|
87
|
+
const cubicBezToPtNodesAry = []
|
|
88
|
+
if (!Array.isArray(cubicBezToNodes)) {
|
|
89
|
+
cubicBezToNodes = [cubicBezToNodes]
|
|
90
|
+
}
|
|
91
|
+
Object.keys(cubicBezToNodes).forEach(key => {
|
|
92
|
+
cubicBezToPtNodesAry.push(cubicBezToNodes[key]['a:pt'])
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
cubicBezToPtNodesAry.forEach(key => {
|
|
96
|
+
const pts_ary = []
|
|
97
|
+
key.forEach(pt => {
|
|
98
|
+
const pt_obj = {
|
|
99
|
+
x: pt['attrs']['x'],
|
|
100
|
+
y: pt['attrs']['y'],
|
|
101
|
+
}
|
|
102
|
+
pts_ary.push(pt_obj)
|
|
103
|
+
})
|
|
104
|
+
multiSapeAry.push({
|
|
105
|
+
type: 'cubicBezTo',
|
|
106
|
+
cubBzPt: pts_ary
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
if (arcToNodes) {
|
|
111
|
+
const arcToNodesAttrs = arcToNodes['attrs']
|
|
112
|
+
const hR = arcToNodesAttrs['hR']
|
|
113
|
+
const wR = arcToNodesAttrs['wR']
|
|
114
|
+
const stAng = arcToNodesAttrs['stAng']
|
|
115
|
+
const swAng = arcToNodesAttrs['swAng']
|
|
116
|
+
let shftX = 0
|
|
117
|
+
let shftY = 0
|
|
118
|
+
const arcToPtNode = getTextByPathList(arcToNodes, ['a:pt', 'attrs'])
|
|
119
|
+
if (arcToPtNode) {
|
|
120
|
+
shftX = arcToPtNode['x']
|
|
121
|
+
shftY = arcToPtNode['y']
|
|
122
|
+
}
|
|
123
|
+
multiSapeAry.push({
|
|
124
|
+
type: 'arcTo',
|
|
125
|
+
hR: hR,
|
|
126
|
+
wR: wR,
|
|
127
|
+
stAng: stAng,
|
|
128
|
+
swAng: swAng,
|
|
129
|
+
shftX: shftX,
|
|
130
|
+
shftY: shftY,
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
if (closeNode) {
|
|
134
|
+
if (!Array.isArray(closeNode)) closeNode = [closeNode]
|
|
135
|
+
Object.keys(closeNode).forEach(() => {
|
|
136
|
+
multiSapeAry.push({
|
|
137
|
+
type: 'close',
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let k = 0
|
|
143
|
+
while (k < multiSapeAry.length) {
|
|
144
|
+
|
|
145
|
+
if (multiSapeAry[k].type === 'movto') {
|
|
146
|
+
const spX = parseInt(multiSapeAry[k].x) * cX
|
|
147
|
+
const spY = parseInt(multiSapeAry[k].y) * cY
|
|
148
|
+
d += ' M' + spX + ',' + spY
|
|
149
|
+
}
|
|
150
|
+
else if (multiSapeAry[k].type === 'lnto') {
|
|
151
|
+
const Lx = parseInt(multiSapeAry[k].x) * cX
|
|
152
|
+
const Ly = parseInt(multiSapeAry[k].y) * cY
|
|
153
|
+
d += ' L' + Lx + ',' + Ly
|
|
154
|
+
}
|
|
155
|
+
else if (multiSapeAry[k].type === 'cubicBezTo') {
|
|
156
|
+
const Cx1 = parseInt(multiSapeAry[k].cubBzPt[0].x) * cX
|
|
157
|
+
const Cy1 = parseInt(multiSapeAry[k].cubBzPt[0].y) * cY
|
|
158
|
+
const Cx2 = parseInt(multiSapeAry[k].cubBzPt[1].x) * cX
|
|
159
|
+
const Cy2 = parseInt(multiSapeAry[k].cubBzPt[1].y) * cY
|
|
160
|
+
const Cx3 = parseInt(multiSapeAry[k].cubBzPt[2].x) * cX
|
|
161
|
+
const Cy3 = parseInt(multiSapeAry[k].cubBzPt[2].y) * cY
|
|
162
|
+
d += ' C' + Cx1 + ',' + Cy1 + ' ' + Cx2 + ',' + Cy2 + ' ' + Cx3 + ',' + Cy3
|
|
163
|
+
}
|
|
164
|
+
else if (multiSapeAry[k].type === 'arcTo') {
|
|
165
|
+
const hR = parseInt(multiSapeAry[k].hR) * cX
|
|
166
|
+
const wR = parseInt(multiSapeAry[k].wR) * cY
|
|
167
|
+
const stAng = parseInt(multiSapeAry[k].stAng) / 60000
|
|
168
|
+
const swAng = parseInt(multiSapeAry[k].swAng) / 60000
|
|
169
|
+
const endAng = stAng + swAng
|
|
170
|
+
d += shapeArc(wR, hR, wR, hR, stAng, endAng, false)
|
|
171
|
+
}
|
|
172
|
+
else if (multiSapeAry[k].type === 'close') d += 'z'
|
|
173
|
+
k++
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return d
|
|
178
|
+
}
|
package/src/text.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { getHorizontalAlign } from './align'
|
|
2
|
+
import { getTextByPathList } from './utils'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
getFontType,
|
|
6
|
+
getFontColor,
|
|
7
|
+
getFontSize,
|
|
8
|
+
getFontBold,
|
|
9
|
+
getFontItalic,
|
|
10
|
+
getFontDecoration,
|
|
11
|
+
getFontSpace,
|
|
12
|
+
getFontSubscript,
|
|
13
|
+
getFontShadow,
|
|
14
|
+
} from './fontStyle'
|
|
15
|
+
|
|
16
|
+
export function genTextBody(textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj, fontsizeFactor, slideFactor) {
|
|
17
|
+
if (!textBodyNode) return ''
|
|
18
|
+
|
|
19
|
+
let text = ''
|
|
20
|
+
const slideMasterTextStyles = warpObj['slideMasterTextStyles']
|
|
21
|
+
|
|
22
|
+
const pNode = textBodyNode['a:p']
|
|
23
|
+
const pNodes = pNode.constructor === Array ? pNode : [pNode]
|
|
24
|
+
|
|
25
|
+
let isList = ''
|
|
26
|
+
|
|
27
|
+
for (const pNode of pNodes) {
|
|
28
|
+
let rNode = pNode['a:r']
|
|
29
|
+
let fldNode = pNode['a:fld']
|
|
30
|
+
let brNode = pNode['a:br']
|
|
31
|
+
if (rNode) {
|
|
32
|
+
rNode = (rNode.constructor === Array) ? rNode : [rNode]
|
|
33
|
+
|
|
34
|
+
if (fldNode) {
|
|
35
|
+
fldNode = (fldNode.constructor === Array) ? fldNode : [fldNode]
|
|
36
|
+
rNode = rNode.concat(fldNode)
|
|
37
|
+
}
|
|
38
|
+
if (brNode) {
|
|
39
|
+
brNode = (brNode.constructor === Array) ? brNode : [brNode]
|
|
40
|
+
brNode.forEach(item => item.type = 'br')
|
|
41
|
+
|
|
42
|
+
if (brNode.length > 1) brNode.shift()
|
|
43
|
+
rNode = rNode.concat(brNode)
|
|
44
|
+
rNode.sort((a, b) => {
|
|
45
|
+
if (!a.attrs || !b.attrs) return true
|
|
46
|
+
return a.attrs.order - b.attrs.order
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const align = getHorizontalAlign(pNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles)
|
|
52
|
+
|
|
53
|
+
const listType = getListType(pNode)
|
|
54
|
+
if (listType) {
|
|
55
|
+
if (!isList) {
|
|
56
|
+
text += `<${listType}>`
|
|
57
|
+
isList = listType
|
|
58
|
+
}
|
|
59
|
+
else if (isList && isList !== listType) {
|
|
60
|
+
text += `</${isList}>`
|
|
61
|
+
text += `<${listType}>`
|
|
62
|
+
isList = listType
|
|
63
|
+
}
|
|
64
|
+
text += `<li style="text-align: ${align};">`
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
if (isList) {
|
|
68
|
+
text += `</${isList}>`
|
|
69
|
+
isList = ''
|
|
70
|
+
}
|
|
71
|
+
text += `<p style="text-align: ${align};">`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!rNode) text += genSpanElement(pNode, slideLayoutSpNode, type, warpObj, fontsizeFactor, slideFactor)
|
|
75
|
+
else {
|
|
76
|
+
for (const rNodeItem of rNode) {
|
|
77
|
+
text += genSpanElement(rNodeItem, slideLayoutSpNode, type, warpObj, fontsizeFactor, slideFactor)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (listType) text += '</li>'
|
|
82
|
+
else text += '</p>'
|
|
83
|
+
}
|
|
84
|
+
return text
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function getListType(node) {
|
|
88
|
+
const pPrNode = node['a:pPr']
|
|
89
|
+
if (!pPrNode) return ''
|
|
90
|
+
|
|
91
|
+
if (pPrNode['a:buChar']) return 'ul'
|
|
92
|
+
if (pPrNode['a:buAutoNum']) return 'ol'
|
|
93
|
+
|
|
94
|
+
return ''
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function genSpanElement(node, slideLayoutSpNode, type, warpObj, fontsizeFactor, slideFactor) {
|
|
98
|
+
const slideMasterTextStyles = warpObj['slideMasterTextStyles']
|
|
99
|
+
|
|
100
|
+
let text = node['a:t']
|
|
101
|
+
if (typeof text !== 'string') text = getTextByPathList(node, ['a:fld', 'a:t'])
|
|
102
|
+
if (typeof text !== 'string') text = ' '
|
|
103
|
+
|
|
104
|
+
let styleText = ''
|
|
105
|
+
const fontColor = getFontColor(node)
|
|
106
|
+
const fontSize = getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles, fontsizeFactor)
|
|
107
|
+
const fontType = getFontType(node, type, warpObj)
|
|
108
|
+
const fontBold = getFontBold(node)
|
|
109
|
+
const fontItalic = getFontItalic(node)
|
|
110
|
+
const fontDecoration = getFontDecoration(node)
|
|
111
|
+
const fontSpace = getFontSpace(node, fontsizeFactor)
|
|
112
|
+
const shadow = getFontShadow(node, warpObj, slideFactor)
|
|
113
|
+
const subscript = getFontSubscript(node)
|
|
114
|
+
|
|
115
|
+
if (fontColor) styleText += `color: ${fontColor};`
|
|
116
|
+
if (fontSize) styleText += `font-size: ${fontSize};`
|
|
117
|
+
if (fontType) styleText += `font-family: ${fontType};`
|
|
118
|
+
if (fontBold) styleText += `font-weight: ${fontBold};`
|
|
119
|
+
if (fontItalic) styleText += `font-style: ${fontItalic};`
|
|
120
|
+
if (fontDecoration) styleText += `text-decoration: ${fontDecoration};`
|
|
121
|
+
if (fontSpace) styleText += `letter-spacing: ${fontSpace};`
|
|
122
|
+
if (subscript) styleText += `vertical-align: ${subscript}; font-size: smaller;`
|
|
123
|
+
if (shadow) styleText += `text-shadow: ${shadow};`
|
|
124
|
+
|
|
125
|
+
const linkID = getTextByPathList(node, ['a:rPr', 'a:hlinkClick', 'attrs', 'r:id'])
|
|
126
|
+
if (linkID) {
|
|
127
|
+
const linkURL = warpObj['slideResObj'][linkID]['target']
|
|
128
|
+
return `<span style="${styleText}"><a href="${linkURL}" target="_blank">${text.replace(/\s/i, ' ')}</a></span>`
|
|
129
|
+
}
|
|
130
|
+
return `<span style="${styleText}">${text.replace(/\s/i, ' ')}</span>`
|
|
131
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -39,16 +39,16 @@ export function extractFileExtension(filename) {
|
|
|
39
39
|
return filename.substr((~-filename.lastIndexOf('.') >>> 0) + 2)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export function eachElement(node,
|
|
42
|
+
export function eachElement(node, func) {
|
|
43
43
|
if (!node) return node
|
|
44
44
|
|
|
45
45
|
let result = ''
|
|
46
46
|
if (node.constructor === Array) {
|
|
47
47
|
for (let i = 0; i < node.length; i++) {
|
|
48
|
-
result +=
|
|
48
|
+
result += func(node[i], i)
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
else result +=
|
|
51
|
+
else result += func(node, 0)
|
|
52
52
|
|
|
53
53
|
return result
|
|
54
54
|
}
|
|
@@ -135,4 +135,17 @@ export function getMimeType(imgFileExt) {
|
|
|
135
135
|
default:
|
|
136
136
|
}
|
|
137
137
|
return mimeType
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function isVideoLink(vdoFile) {
|
|
141
|
+
const urlRegex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
|
142
|
+
return urlRegex.test(vdoFile)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function toHex(n) {
|
|
146
|
+
let hex = n.toString(16)
|
|
147
|
+
while (hex.length < 2) {
|
|
148
|
+
hex = '0' + hex
|
|
149
|
+
}
|
|
150
|
+
return hex
|
|
138
151
|
}
|
package/test.pptx
CHANGED
|
Binary file
|
package/test2.pptx
ADDED
|
Binary file
|
package/test3.pptx
ADDED
|
Binary file
|