carto/bin/carto
2014-05-20 16:01:43 -04:00

163 lines
4.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
carto = require('../lib/carto'),
url = require('url'),
_ = require('underscore');
var existsSync = require('fs').existsSync || require('path').existsSync
var optimist = require('optimist')
.usage("Usage: $0 <source MML file>")
.options('h', {alias:'help', describe:'Display this help message'})
.options('v', {alias:'version', boolean:true, describe:'Display version information'})
.options('b', {alias:'benchmark', boolean:true, describe:'Outputs total compile time'})
.options('l', {alias:'localize', boolean:true, default:false, describe:'Use millstone to localize resources when loading an MML'})
.options('n', {alias:'nosymlink', boolean:true, describe:'Use absolute paths instead of symlinking files'})
.options('ppi', {describe:'Pixels per inch used to convert m, mm, cm, in, pt, pc to pixels', default:90.714});
var options = optimist.argv;
if (options.help) {
optimist.showHelp();
process.exit(0);
}
if (options.version) {
console.log("carto " + carto.version.join('.') + " (Carto map stylesheet compiler)");
process.exit(0);
}
var input = options._[0];
if (input && input[0] != '/') {
input = path.join(process.cwd(), input);
}
if (!input) {
console.log("carto: no input files ('carto -h or --help' for help)");
process.exit(1);
}
if (options.benchmark) {
var start = +new Date;
}
var ext = path.extname(input);
if (!ext) {
console.log("carto: please pass either a .mml file or .mss file");
process.exit(1);
}
if (!existsSync(input)) {
console.log("carto: file does not exist: '" + input + "'");
process.exit(1);
}
function compileMML(err, data) {
// force drain the millstone download pool now
// to ensure we can exit without waiting
if (options.localize && millstone.drainPool) {
millstone.drainPool(function() {});
}
if (err) {
console.error(err);
process.exit(1);
}
var renderer = new carto.Renderer({
filename: input,
benchmark: options.benchmark,
ppi: options.ppi
});
try {
var output = renderer.render(data);
} catch (e) {
if (e.stack) {
console.error(e.stack);
} else {
console.error(e);
}
process.exit(1);
}
if (!options.benchmark) {
console.log(output);
} else {
var duration = (+new Date) - start;
console.log('TOTAL: ' + (duration) + 'ms');
}
};
function compileMSS(err, data) {
if (err) {
console.error(err);
process.exit(1);
}
var renderer = new carto.Renderer({
filename: path.basename(input),
benchmark: options.benchmark,
ppi: options.ppi
});
try {
var output = renderer.renderMSS(data);
} catch (e) {
if (e.stack) {
console.error(e.stack);
} else {
console.error(e);
}
process.exit(1);
}
if (!options.benchmark) {
console.log(output);
} else {
var duration = (+new Date) - start;
console.log('TOTAL: ' + (duration) + 'ms');
}
};
try {
var data = fs.readFileSync(input, 'utf-8');
} catch(err) {
console.error("carto: " + err.message.replace(/^[A-Z]+, /, ''));
process.exit(1);
}
if (ext == '.mml') {
try {
data = JSON.parse(data);
} catch(err) {
console.error("carto: " + err.message.replace(/^[A-Z]+, /, ''));
process.exit(1);
}
if (options.localize) {
var millstone = undefined;
try {
require.resolve('millstone');
millstone = require('millstone');
} catch (err) {
console.error('carto: Millstone not found, required if localizing stylesheet resources. ' + err.message.replace(/^[A-Z]+, /, ''));
process.exit(1);
}
millstone.resolve({
mml: data,
base: path.dirname(input),
cache: path.join(path.dirname(input), 'cache'),
nosymlink: options.nosymlink
}, compileMML);
} else {
data.Stylesheet = data.Stylesheet.map(function(x) {
if (typeof x !== 'string') {
return { id: x, data: x.data }
}
return { id: x, data: fs.readFileSync(path.join(path.dirname(input), x), 'utf8') }
});
compileMML(null,data);
}
} else if (ext == '.mss') {
compileMSS(null,data);
} else {
console.log("carto: please pass either a .mml file or .mss file");
}