Skip to content

Instantly share code, notes, and snippets.

@emilis
Created May 31, 2012 11:38
Show Gist options
  • Save emilis/2842834 to your computer and use it in GitHub Desktop.
Save emilis/2842834 to your computer and use it in GitHub Desktop.
Shows only specified Inkscape layers in a file and then runs Inkscape on it
/// Requirements: -------------------------------------------------------------
/// npm install node-expat temp
var child_process = require("child_process");
var expat = require("node-expat");
var fs = require("fs");
var path = require("path");
var temp = require("temp");
/// Main: ---------------------------------------------------------------------
/// Usage: node with-inkscape-layers.js "LayerName1,LayerName2*" file.svg [inkscape_args]
main(process.argv);
/// Functions: ----------------------------------------------------------------
/**
*
*/
function main(argv) {
var file_name = argv[2];
var layers = argv[3].split(",");
var ink_args = argv.slice(4);
if (!path.existsSync(file_name)) {
throw Error("The specified file " + file_name + " does not exist.");
}
/// Create temp file:
var tmp_path = temp.path({suffix: ".svg"});
/// Transform XML: --------------------------------------------------------
fs.writeFileSync(
tmp_path,
showOnlyLayers(
fs.readFileSync(file_name),
layers));
/// --- -------------------------------------------------------------------
// Run Inkscape on tmp_file:
var inkscape = child_process.spawn(
"inkscape",
ink_args.concat(tmp_path));
inkscape.stdout.on("data", function(data){ console.log(data.toString()); });
inkscape.stderr.on("data", function(data){ console.error(data.toString()); });
inkscape.on("exit", function(code){ fs.unlink(tmp_path); });
};
/**
*
*/
function showOnlyLayers(str, layers) {
layers = layers || [];
layers = layers.map(function(l){
return new RegExp("^" + l.replace(/\*/g, ".*") + "$");
});
var l_path = [];
var el_is_layer = [];
return transformXml(
str,
{
"startElement": function(name, attrs) {
if (name === "g" && attrs["inkscape:groupmode"] === "layer") {
el_is_layer.push(true);
l_path.push(attrs["inkscape:label"]);
var l_name = l_path.join("/");
if (layers.some(function(l){ return l.test(l_name) })) {
attrs["style"] = "display:inline";
} else {
attrs["style"] = "display:none";
}
} else {
el_is_layer.push(false);
}
return startElementToString(name, attrs);
},
"endElement": function(name) {
if (el_is_layer.pop()) {
l_path.pop();
}
return endElementToString(name);
},
});
};
/**
*
*/
function transformXml(str, listeners) {
listeners = listeners || {};
var default_listeners = {
startElement: startElementToString,
endElement: endElementToString,
text: textToString,
processingInstruction: processingInstructionToString,
comment: commentToString,
xmlDecl: xmlDeclToString,
startCdata: startCdataToString,
endCdata: endCdataToString,
entityDecl: entityDeclToString,
};
for (var ln in default_listeners) {
listeners[ln] = listeners[ln] || default_listeners[ln];
};
var p = new expat.Parser("UTF-8");
var result = [];
Object.getOwnPropertyNames(listeners).map(function(ln){
p.addListener(ln, function(){
result.push( listeners[ln].apply({}, arguments) );
});
});
p.parse(str);
return result.join("");
};
function startElementToString(name, attrs) {
var out = [];
out.push('<', name);
for (var n in attrs) {
out.push(' ', n, '="', attrs[n], '"');
}
out.push('>');
return out.join("");
};
function endElementToString(name) {
return ['</', name, '>'].join("");
};
function textToString(s) {
return s;
};
function processingInstructionToString(target, data) {
return ['<?', target, ' ', data, '?>'].join("");
};
function commentToString(s) {
return ['<!-- ', s, ' -->'].join("");
};
function xmlDeclToString(version, encoding, standalone) {
/// todo
var out = [];
out.push('<?xml ');
version && out.push(' version="', version, '"');
encoding && out.push(' encoding="', encoding, '"');
out.push('?>');
return out.join("");
};
function startCdataToString() {
return '<![CDATA[';
};
function endCdataToString() {
return ']]>';
};
function entityDeclToString(entityName, isParameterEntity, value, base, systemId, publicId, notationName) {
/// todo: expand this properly
if (isParameterEntity && value) {
return ['<!ENTITY ', entityName, ' "', value, '">'].join("");
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment