Files
iD/svg/spriteify.js
2016-07-19 12:04:16 -04:00

125 lines
3.2 KiB
JavaScript
Executable File

#!/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('');
}