Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
refactor MML loading, support absolute paths in MML stylesheet file r…
Browse files Browse the repository at this point in the history
…eferences
  • Loading branch information
nebulon42 committed Nov 18, 2016
1 parent 516289b commit 849929f
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 195 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,22 +211,26 @@ The `Renderer` interface is the main API for developers, and it takes an MML fil

// defined variables:
// - input (the name or identifier of the file being parsed)
// - data (a string containing the MML or an object of MML)
var carto = require('carto');

try {
var output = new carto.Renderer({
filename: input,
local_data_dir: path.dirname(input),
}).render(data);
var data = fs.readFileSync(input, 'utf-8');
var mml = new carto.MML();
mml.load(path.dirname(input), data, function (err, data) {
if (err) throw err;
var output = new carto.Renderer({
filename: input,
local_data_dir: path.dirname(input),
}).render(data);
console.log(output);
});
} catch(err) {
if (Array.isArray(err)) {
err.forEach(function(e) {
carto.writeError(e, options);
});
} else { throw err; }
}
console.log(output);

### Vim

Expand Down
113 changes: 25 additions & 88 deletions bin/carto
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ var path = require('path'),
carto = require('../lib/carto'),
semver = require('semver'),
url = require('url'),
_ = require('lodash'),
yaml = require('js-yaml');
_ = require('lodash');

var existsSync = require('fs').existsSync || require('path').existsSync

Expand Down Expand Up @@ -65,12 +64,24 @@ if (!existsSync(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() {});
}
try {
var data = fs.readFileSync(input, 'utf-8');
} catch(err) {
console.error("carto: " + err.message.replace(/^[A-Z]+, /, ''));
process.exit(1);
}

if (ext === '.mml') {
var mml = new carto.MML(options);
mml.load(path.dirname(input), data, compile);
} else if (ext === '.mss') {
compile(null, data);
} else {
console.error("carto: please pass either a .mml file or .mss file");
}


function compile(err, data) {
if (err) {
console.error(err);
process.exit(1);
Expand All @@ -84,7 +95,12 @@ function compileMML(err, data) {
mapnik_version: options.api
});
try {
var output = renderer.render(data);
var output;
if (ext === '.mml') {
output = renderer.render(data);
} else if (ext === '.mss') {
output = renderer.renderMSS(data);
}
} catch (e) {
if (e.stack) {
console.error(e.stack);
Expand All @@ -103,82 +119,3 @@ function compileMML(err, data) {
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
},
{
mapnik_version: options.api
});
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 = yaml.safeLoad(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 {
if (_.has(data, 'Stylesheet') && !_.isNil(data.Stylesheet)) {
data.Stylesheet = _.castArray(data.Stylesheet);
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.error("carto: please pass either a .mml file or .mss file");
}
1 change: 1 addition & 0 deletions lib/carto/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var carto = {
version: getVersion(),
Parser: require('./parser').Parser,
Renderer: require('./renderer').Renderer,
MML: require('./mml').MML,
tree: require('./tree'),

// @TODO
Expand Down
76 changes: 76 additions & 0 deletions lib/carto/mml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var path = require('path'),
fs = require('fs'),
_ = require('lodash'),
yaml = require('js-yaml');

var carto = require('./index');

carto.MML = function MML(options) {
this.options = options || {};
};

/**
* Load a MML document.
*
* @param {String} basedir base directory of MML document.
* @param {String} data the MML document.
* @param {Callback} callback function to be called when finished loading.
*/
carto.MML.prototype.load = function load(basedir, data, callback) {
var mml = '',
that = this;

try {
mml = yaml.safeLoad(data);
} catch (err) {
return callback("carto: " + err.message.replace(/^[A-Z]+, /, ''), null);
}

if (this.options.localize) {
var millstone;
try {
require.resolve('millstone');
millstone = require('millstone');
} catch (err) {
return callback('carto: Millstone not found, required if localizing stylesheet resources. ' + err.message.replace(/^[A-Z]+, /, ''), null);
}
millstone.resolve({
mml: mml,
base: basedir,
cache: path.join(basedir, 'cache'),
nosymlink: this.options.nosymlink
}, function (err, data) {
// force drain the millstone download pool now
// to ensure we can exit without waiting
if (that.options.localize && millstone.drainPool) {
millstone.drainPool(function() {});
}
return callback(err, data);
});
} else {
if (_.has(mml, 'Stylesheet') && !_.isNil(mml.Stylesheet)) {
mml.Stylesheet = _.castArray(mml.Stylesheet);
for (var i = 0; i < mml.Stylesheet.length; i++) {
var stylesheet = mml.Stylesheet[i];
if (typeof stylesheet !== 'string') {
mml.Stylesheet[i] = stylesheet;
continue;
}
var mss,
file = path.resolve(basedir, stylesheet);
try {
mss = fs.readFileSync(file, 'utf-8');
} catch (err) {
return callback('Failed to load file ' + file + ".\n", null);
}
mml.Stylesheet[i] = { id: stylesheet, data: mss };
}
return callback(null, mml);
}
else {
return callback("Expecting a Stylesheet property containing an (array of) stylesheet object(s) of the form { id: 'x', 'data': 'y' }.\n", null);
}
}
};

module.exports = carto;
44 changes: 23 additions & 21 deletions test/errorhandling.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,29 @@ describe('Error handling mml+mss', function() {
helper.files('errorhandling', 'mml', function(file) {
var basename = path.basename(file);
it('should handle errors in ' + basename, function(done) {
var mml = helper.mml(file);
try {
new carto.Renderer({
paths: [ path.dirname(file) ],
data_dir: path.join(__dirname, '../data'),
local_data_dir: path.join(__dirname, 'rendering'),
filename: file
}).render(mml);
// should not get here
assert.ok(false);
done();
} catch (err) {
if (err.message.indexOf('***') > -1) throw err;
var output = err.message;
// @TODO for some reason, fs.readFile includes an additional \n
// at the end of read files. Determine why.
// fs.writeFileSync(helper.resultFile(file), output);
var data = fs.readFileSync(helper.resultFile(file), 'utf8');
assert.deepEqual(output, data);
done();
}
helper.mml(file, function (err, mml) {
try {
if (err) throw new Error(err);
new carto.Renderer({
paths: [ path.dirname(file) ],
data_dir: path.join(__dirname, '../data'),
local_data_dir: path.join(__dirname, 'rendering'),
filename: file
}).render(mml);
// should not get here
assert.ok(false);
done();
} catch (err) {
if (err.message.indexOf('***') > -1) throw err;
var output = err.message;
// @TODO for some reason, fs.readFile includes an additional \n
// at the end of read files. Determine why.
// fs.writeFileSync(helper.resultFile(file), output);
var data = fs.readFileSync(helper.resultFile(file), 'utf8');
assert.deepEqual(output, data);
done();
}
});
});
});
});
Expand Down
5 changes: 5 additions & 0 deletions test/errorhandling/stylesheet_absolute_file.mml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Stylesheet": [
"/home/test/test.mss"
]
}
1 change: 1 addition & 0 deletions test/errorhandling/stylesheet_absolute_file.result
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Failed to load file /home/test/test.mss.
1 change: 1 addition & 0 deletions test/errorhandling/stylesheet_absolute_file_syswin.result
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Failed to load file C:\home\test\test.mss.
Loading

0 comments on commit 849929f

Please sign in to comment.