1 | const { html2json } = require('html2json')
|
2 | const flatten = require('flatten')
|
3 | const SvgOptimiser = require('svgo')
|
4 | const toCamelCase = require('to-camel-case')
|
5 | const toPascalCase = require('to-pascal-case')
|
6 |
|
7 | const getAttrs = attr =>
|
8 | Object.keys(attr)
|
9 | .filter(a => a !== 'xmlns')
|
10 | .map(prop => {
|
11 | let value = attr[prop]
|
12 | if (Array.isArray(value)) {
|
13 | value = value.join(' ')
|
14 | }
|
15 | return `${toCamelCase(prop)} ${value}`
|
16 | })
|
17 |
|
18 | const getBlock = raw => {
|
19 | switch (raw) {
|
20 | case 'svg':
|
21 | return 'Svg'
|
22 |
|
23 | case 'g':
|
24 | return 'SvgGroup'
|
25 |
|
26 | default:
|
27 | return `Svg${toPascalCase(raw)}`
|
28 | }
|
29 | }
|
30 |
|
31 | const IGNORE = ['title', 'desc']
|
32 |
|
33 | const parseSvg = ({ attr, child, tag }) => {
|
34 | const s = []
|
35 |
|
36 | if (!tag || IGNORE.includes(tag.toLowerCase())) return false
|
37 |
|
38 | s.push(getBlock(tag))
|
39 | if (attr) {
|
40 | const attrs = getAttrs(attr)
|
41 | s.push(attrs)
|
42 | }
|
43 | if (child) {
|
44 | s.push(
|
45 | child.map(c => {
|
46 | const parsed = parseSvg(c)
|
47 | return parsed && [parsed, '']
|
48 | })
|
49 | )
|
50 | }
|
51 |
|
52 | return s
|
53 | }
|
54 |
|
55 | module.exports = async raw => {
|
56 | const svgo = new SvgOptimiser()
|
57 |
|
58 |
|
59 | svgo.config.plugins = svgo.config.plugins.map(list =>
|
60 | list.filter(
|
61 | plugin =>
|
62 | !(plugin.name === 'removeDimensions' || plugin.name === 'removeViewBox')
|
63 | )
|
64 | )
|
65 | const res = await svgo.optimize(raw)
|
66 | return flatten(parseSvg(html2json(res.data).child[0]))
|
67 | .filter(Boolean)
|
68 | .join('\n')
|
69 | }
|