UNPKG

1.55 kBJavaScriptView Raw
1const { html2json } = require('html2json')
2const flatten = require('flatten')
3const SvgOptimiser = require('svgo')
4const toCamelCase = require('to-camel-case')
5const toPascalCase = require('to-pascal-case')
6
7const 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
18const 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
31const IGNORE = ['title', 'desc']
32
33const 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
55module.exports = async raw => {
56 const svgo = new SvgOptimiser()
57 // TODO revisit this hack to SVGO's plugin config :/, it's too complex
58 // and undocumented to spend time going through it
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}