#!/usr/bin/env node 'use strict'; var argv = require('minimist')(process.argv.slice(2)); if (argv.help || argv.h || !argv.svg) { return help(); } var fs = require('fs'); var json = (argv.json ? JSON.parse(fs.readFileSync(argv.json)) : {}); var _ = require('lodash'); var xml2js = require('xml2js'); xmlToJs(argv.svg, function (err, obj) { if (err) throw (err); jsToXml(obj, function (err) { if (err) console.log(err); }); }); function xmlToJs(filename, cb) { fs.readFile(filename, 'utf8', function (err, xmlStr) { if (err) throw (err); var opts = { explicitArray: true, explicitCharkey: true, explicitChildren: true, preserveChildrenOrder: true, normalize: true, attrkey: '#attr', childkey: '#child', charkey: '#char' }, parser = new xml2js.Parser(opts); parser.parseString(xmlStr, function (err, obj) { cb(err, obj); }); }); } function jsToXml(obj, cb) { var src = transform(obj.svg); var builder = require('xmlbuilder'); var doc = builder.create('svg', { version: '1.0', encoding: 'UTF-8' }, { pubID: '-//W3C//DTD SVG 1.1//EN', sysID: 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'} ); doc = build(doc, src); process.stdout.write(doc.end({ pretty: true }), 'utf8', cb); } function transform(source) { var target = {}; target['#name'] = source['#name']; if (source['#char'] !== undefined) { target['#char'] = source['#char']; } if (source['#attr'] !== undefined) { var id = source['#attr'].id, replace = (id && json[id] !== undefined) ? json[id] : {}; target['#attr'] = _.merge(source['#attr'], replace); if (replace.viewBox !== undefined) { target['#name'] = 'symbol'; } } if (source['#child'] !== undefined && source['#child'].constructor === Array) { target['#child'] = []; for (var i = 0; i < source['#child'].length; i++) { target['#child'].push(transform(source['#child'][i])); } } return target; } function build(doc, source) { if (source['#name']) { var isRoot = (source['#name'] === 'svg'); if (!isRoot) { doc = doc.ele(source['#name']); } if (source['#attr']) { doc = doc.att(source['#attr']); } if (source['#char']) { doc = doc.txt(source['#char']); } if (source['#child'] && source['#child'].constructor === Array) { for (var i = 0; i < source['#child'].length; i++) { doc = build(doc, source['#child'][i]); } } if (isRoot) { doc = doc.att({ 'version': "1.1", 'xmlns': "http://www.w3.org/2000/svg", 'xmlns:xlink': "http://www.w3.org/1999/xlink" }); } else { doc = doc.up(); } } return doc; } function help() { console.log('usage:'); console.log(' spriteify --svg source.svg --json source.json > destination.svg'); console.log(''); }