Did you mean for properties, with proper levenstein distance for

better matching. Fixes #199
This commit is contained in:
Tom MacWright 2012-10-09 21:30:42 -04:00
parent e7658c618e
commit 00e797dc2d
4 changed files with 41 additions and 6 deletions

View File

@ -22,7 +22,7 @@ tree.Call.prototype = {
// we try to pass a variable to a function, like: `saturate(@color)`.
// The function should receive the value, not the variable.
//
eval: function(env) {
'eval': function(env) {
var args = this.args.map(function(a) { return a.eval(env); });
for (var i = 0; i < args.length; i++) {
@ -55,11 +55,11 @@ tree.Call.prototype = {
if (!fn) {
var functions = tree.Reference.mapnikFunctions();
// cheap closest, needs improvement.
var name_array = this.name.split('');
var name = this.name;
var mean = functions.map(function(f) {
return [f[0], _.intersection(name_array, f[0].split('')).length, f[1]];
return [f[0], tree.Reference.editDistance(name, f[0]), f[1]];
}).sort(function(a, b) {
return b[1] - a[1];
return a[1] - b[1];
});
env.error({
message: 'unknown function ' + this.name + '(), did you mean ' +

View File

@ -138,6 +138,31 @@ tree.Reference.isFont = function(selector) {
return tree.Reference.selector(selector).validate == 'font';
};
// https://gist.github.com/982927
tree.Reference.editDistance = function(a, b){
if (a.length === 0) return b.length;
if (b.length === 0) return a.length;
var matrix = [];
for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i-1) == a.charAt(j-1)) {
matrix[i][j] = matrix[i-1][j-1];
} else {
matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
Math.min(matrix[i][j-1] + 1, // insertion
matrix[i-1][j] + 1)); // deletion
}
}
}
return matrix[b.length][a.length];
};
tree.Reference.validValue = function(env, selector, value) {
var i, j;
// TODO: handle in reusable way

View File

@ -39,8 +39,18 @@ tree.Rule.prototype.toString = function() {
// properties in reference.json which specify serialization=content
tree.Rule.prototype.toXML = function(env, content, sep, format) {
if (!tree.Reference.validSelector(this.name)) {
var name = this.name;
var mean = tree.Reference.selectors.map(function(f) {
return [f, tree.Reference.editDistance(name, f)];
}).sort(function(a, b) {
return a[1] - b[1];
});
var mean_message = '';
if (mean[0][1] < 3) {
mean_message = '. Did you mean ' + mean[0][0] + '?';
}
return env.error({
message: "Unrecognized rule: " + this.name,
message: "Unrecognized rule: " + this.name + mean_message,
index: this.index,
type: 'syntax',
filename: this.filename

View File

@ -1 +1 @@
invalid_property.mss:3:2 Unrecognized rule: polygonopacity
invalid_property.mss:3:2 Unrecognized rule: polygonopacity. Did you mean polygon-opacity?