UNPKG

svgtoavg-cli

Version:

A simple command-line tool to convert SVG file to AVG (Alexa Presentation Language)

137 lines (129 loc) 4.44 kB
const fs = require('fs'); const SVGO = require('svgo'); const svgson = require('svgson'); const svgo = new SVGO({ plugins: [{ cleanupAttrs: false, }, { removeDoctype: true, }, { removeXMLProcInst: true, }, { removeComments: true, }, { removeMetadata: true, }, { removeTitle: true, }, { removeDesc: true, }, { removeUselessDefs: true, }, { removeEditorsNSData: true, }, { removeEmptyAttrs: false, }, { removeHiddenElems: true, }, { removeEmptyText: true, }, { removeEmptyContainers: true, }, { removeViewBox: true, }, { cleanupEnableBackground: true, }, { convertStyleToAttrs: true, }, { convertColors: true, }, { convertPathData: true, }, { convertTransform: true, }, { removeUnknownsAndDefaults: true, }, { removeNonInheritableGroupAttrs: true, }, { removeUselessStrokeAndFill: false, }, { removeUnusedNS: true, }, { cleanupIDs: true, }, { cleanupNumericValues: true, }, { moveElemsAttrsToGroup: false, }, { moveGroupAttrsToElems: true, }, { collapseGroups: true, }, { removeRasterImages: false, }, { mergePaths: false, }, { convertShapeToPath: true, }, { sortAttrs: true, }, { removeDimensions: false, }] }); function buildItems(children) { let items = children.map(child => { if (child.name != 'g' && child.name != 'path') return null; let transform = parseTransform(child.attributes && child.attributes.transform); return { type: child.name === 'g' ? 'group' : 'path', fillOpacity: child.attributes && child.attributes['fill-opacity'] && parseFloat(child.attributes['fill-opacity']), fill: child.attributes && child.attributes['fill'], pathData: child.attributes && child.attributes['d'], strokeOpacity: child.attributes && child.attributes['stroke-opacity'] && parseFloat(child.attributes['stroke-opacity']), stroke: child.attributes && child.attributes['stroke'], strokeWidth: child.attributes && child.attributes['stroke-width'] && parseInt(child.attributes['stroke-width'], 10) || undefined, opacity: child.attributes && child.attributes['opacity'] && parseFloat(child.attributes['opacity']), rotation: transform && transform.rotate && transform.rotate[0] && parseInt(transform.rotate[0], 10), pivotX: transform && transform.rotate && transform.rotate[1] && parseInt(transform.rotate[1], 10), pivotY: transform && transform.rotate && transform.rotate[2] && parseInt(transform.rotate[2], 10), scaleX: transform && transform.scale && transform.scale[0] && parseInt(transform.scale[0], 10), scaleY: transform && transform.scale && transform.scale[1] && parseInt(transform.scale[1], 10), translateX: transform && transform.translate && transform.translate[0] && parseInt(transform.translate[0], 10), translateY: transform && transform.translate && transform.translate[1] && parseInt(transform.translate[1], 10), items: child.children && buildItems(child.children) } }).filter(child => !!child); return items.length > 0 ? items : undefined; } /** https://stackoverflow.com/questions/17824145/parse-svg-transform-attribute-with-javascript **/ function parseTransform(transform) { if (!transform) return undefined; let result = {}; for (let i in transform = transform.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*[, ]?)+\))+/g)) { let res = transform[i].match(/[\w\.\-]+/g); result[res.shift()] = res; } return result; } async function convertFile(sourcePath, destPath) { const content = fs.readFileSync(sourcePath); const json = await convertContent(content); fs.writeFileSync(destPath, JSON.stringify(json, null, 2)); } async function convertContent(content) { let optimizedFile = await svgo.optimize(content, {}); let parsedJSON = await svgson.parse(optimizedFile.data) let respJSON = { type: 'AVG', version: '1.0' }; respJSON.width = parseInt(parsedJSON.attributes && parsedJSON.attributes.width || '100', 10); respJSON.height = parseInt(parsedJSON.attributes && parsedJSON.attributes.height || '100', 10); respJSON.items = buildItems(parsedJSON.children); return respJSON; } module.exports = { convertFile, convertContent }