forked from gisquick/gisquick-settings-web
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsvg-sprite.js
110 lines (103 loc) · 2.97 KB
/
svg-sprite.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
const fs = require('fs')
const path = require('path')
const { optimize } = require('svgo')
const { parseSvg } = require('svgo/lib/parser')
const { stringifySvg } = require('svgo/lib/stringifier')
const JsAPI = require('svgo/lib/svgo/jsAPI')
const opts = {
plugins: [
'preset-default',
{ name: 'removeDoctype', active: true },
{ name: 'removeDesc', active: true },
{ name: 'mergePaths', active: true },
{ name: 'removeDimensions', active: true } // important
]
}
function allFiles (dirPath) {
const entries = fs.readdirSync(dirPath, { withFileTypes: true })
return entries.reduce((list, dirent) => {
if (dirent.isFile()) {
list.push(path.join(dirPath, dirent.name))
} else {
list.push(...allFiles(path.join(dirPath, dirent.name)))
}
return list
}, [])
}
function directFiles (dirPath) {
return fs.readdirSync(dirPath, { withFileTypes: true })
.filter(dirent => dirent.isFile())
.map(dirent => path.join(dirPath, dirent.name))
}
async function buildSprite (dirPaths) {
// const svgs = recursive ? allFiles(dirPath) : directFiles(dirPath)
const svgs = dirPaths.reduce((list, dirPath) => list.concat(directFiles(dirPath)), [])
const symbols = []
const ids = new Set()
for (const filename of svgs) {
const id = path.basename(filename, '.svg')
if (!filename.includes('.svg')) continue
if (!ids.has(id)) {
const data = fs.readFileSync(filename, 'utf8')
const result = await optimize(data, opts)
const el = parseSvg(result.data)
const svg = el.children[0]
svg.name = 'symbol'
svg.attributes = {
id,
viewBox: svg.attributes.viewBox
}
symbols.push(svg)
ids.add(id)
} else {
console.log('Skipping duplicate icon:', id)
}
}
const svg = new JsAPI({
type: 'root',
children: [new JsAPI({
type: 'element',
name: 'svg',
attributes: {
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'width': 0,
'height': 0,
'style': 'position: absolute'
},
children: [new JsAPI({
type: 'element',
name: 'defs',
children: symbols
})]
})]
})
return stringifySvg(svg).data
}
// export default (config) => {
module.exports = (config) => { // allows to run this script as node command
return {
name: 'html-transform',
async transformIndexHtml (html, ctx) {
const page = path.basename(path.dirname(ctx.filename))
if (config[page]) {
const sprite = await buildSprite(config[page])
// const sprite = await buildSprite(directory)
return html.replace('<!-- svg-sprite -->', sprite)
}
}
}
}
async function main () {
const paths = process.argv.slice(2)
const dest = paths.pop()
if (paths.length < 1) {
console.error('Not enough argmunets')
} else {
const sprite = await buildSprite(paths)
fs.writeFileSync(dest, sprite)
}
}
if (require.main === module) {
main()
}