Simplify quoted implementation, move field logic up to

operate level, add Literal, add tests for transforms with fields.
This commit is contained in:
Tom MacWright 2012-06-26 17:54:01 -04:00
parent a66fa6c462
commit 651a650f2e
14 changed files with 86 additions and 43 deletions

View File

@ -133,7 +133,7 @@ tree.functions = {
.replace(/%[da]/, args[i].toString());
}
str = str.replace(/%%/g, '%');
return new tree.Quoted('"' + str + '"', str);
return new tree.Quoted(str);
}
};

View File

@ -52,7 +52,7 @@ var carto = {
[ 'call', 'color', 'comment', 'definition', 'dimension',
'directive', 'element', 'expression', 'filterset', 'filter', 'field',
'keyword', 'layer', 'operation', 'quoted', 'imagefilter',
'keyword', 'layer', 'literal', 'operation', 'quoted', 'imagefilter',
'reference', 'rule', 'ruleset', 'selector', 'style', 'url', 'value',
'variable', 'zoom', 'invalid', 'fontset'
].forEach(function(n) {

View File

@ -419,7 +419,7 @@ carto.Parser = function Parser(env) {
if (input.charAt(i) !== '"' && input.charAt(i) !== "'") return;
var str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/);
if (str) {
return new tree.Quoted(true, str[1] || str[2]);
return new tree.Quoted(str[1] || str[2]);
}
},
@ -513,7 +513,7 @@ carto.Parser = function Parser(env) {
return new tree.Invalid(value, memo, 'Missing closing ) in URL.');
} else {
return new tree.URL((value.value || value instanceof tree.Variable) ?
value : new tree.Quoted(true, value), imports.paths);
value : new tree.Quoted(value), imports.paths);
}
},

View File

@ -4,6 +4,7 @@ tree.Comment = function Comment(value, silent) {
this.value = value;
this.silent = !!silent;
};
tree.Comment.prototype = {
toString: function(env) {
return '<!--' + this.value + '-->';

View File

@ -35,12 +35,8 @@ tree.Dimension.prototype = {
// conversions such that `100cm + 10mm` would yield
// `101cm`.
operate: function(op, other) {
if (other.is === 'field') {
return new tree.Quoted('', this.value + op + other.toString());
} else {
return new tree.Dimension(tree.operate(op, this.value, other.value),
this.unit || other.unit);
}
return new tree.Dimension(tree.operate(op, this.value, other.value),
this.unit || other.unit);
}
};

View File

@ -11,10 +11,6 @@ tree.Field.prototype = {
},
'eval': function() {
return this;
},
operate: function(op, other) {
return new tree.Quoted(false,
this.toString() + op + other.toString(true));
}
};

17
lib/carto/tree/literal.js Normal file
View File

@ -0,0 +1,17 @@
(function(tree) {
tree.Literal = function Field(content) {
this.value = content || '';
this.is = 'field';
};
tree.Literal.prototype = {
toString: function() {
return this.value;
},
'eval': function() {
return this;
}
};
})(require('../tree'));

View File

@ -1,11 +1,12 @@
(function(tree) {
tree.Operation = function Operation(op, operands, index) {
this.op = op.trim();
this.operands = operands;
this.index = index;
this.is = 'operation';
};
tree.Operation.prototype.eval = function(env) {
var a = this.operands[0].eval(env),
b = this.operands[1].eval(env),
@ -32,19 +33,22 @@ tree.Operation.prototype.eval = function(env) {
// Only concatenate plain strings, because this is easily
// pre-processed
if (a instanceof tree.Quoted && b instanceof tree.Quoted) {
if (this.op !== '+') {
env.error({
message: "Can't subtract, divide, or multiply strings.",
index: this.index,
type: 'runtime',
filename: this.filename
});
return {
is: 'undefined',
value: 'undefined'
};
}
if (a instanceof tree.Quoted && b instanceof tree.Quoted && this.op !== '+') {
env.error({
message: "Can't subtract, divide, or multiply strings.",
index: this.index,
type: 'runtime',
filename: this.filename
});
return {
is: 'undefined',
value: 'undefined'
};
}
if (a instanceof tree.Field || b instanceof tree.Field ||
a instanceof tree.Literal || b instanceof tree.Literal) {
return new tree.Literal(a.eval(env).toString(true) + this.op + b.eval(env).toString(true));
}
return a.operate(this.op, b);

View File

@ -1,18 +1,14 @@
(function(tree) {
tree.Quoted = function Quoted(ever_quote, content) {
tree.Quoted = function Quoted(content) {
this.value = content || '';
// ever_quote is basicaly a shutoff switch for this quoted string
// being a real expression. you can pass `false` as the first parameter
// to make sure that this never gets double-quoted. This is used with fields.
this.ever_quote = ever_quote;
this.is = 'string';
};
tree.Quoted.prototype = {
toString: function(quotes) {
var xmlvalue = this.value.replace(/\'/g, '&apos;');
return (this.ever_quote && quotes === true) ? "'" + xmlvalue + "'" : this.value;
return (quotes === true) ? "'" + xmlvalue + "'" : this.value;
},
'eval': function() {
@ -20,13 +16,8 @@ tree.Quoted.prototype = {
},
operate: function(op, other) {
if (other.is !== 'string') {
return new tree.Quoted(false,
this.toString(true) + op + other.toString());
} else {
return new tree.Quoted(true,
tree.operate(op, this.toString(), other.toString()));
}
return new tree.Quoted(true,
tree.operate(op, this.toString(), other.toString(this.contains_field)));
}
};

View File

@ -1,5 +1,5 @@
#world {
text-name: "hello " + [NAME] + ' hello';
text-name: "hello " + [NAME] + " hello";
text-size: 11;
text-face-name: "Georgia Regular", "Arial Italic";
}

View File

@ -8,7 +8,7 @@
</FontSet>
<Style name="world" filter-mode="first" >
<Rule>
<TextSymbolizer size="11" fontset-name="fontset-0" ><![CDATA[hello +[NAME]]]></TextSymbolizer>
<TextSymbolizer size="11" fontset-name="fontset-0" ><![CDATA['hello '+[NAME]+' hello']]></TextSymbolizer>
</Rule>
</Style>
<Layer name="world"

View File

@ -0,0 +1,14 @@
{
"srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
"Stylesheet": [
"transforms_field.mss"
],
"Layer": [{
"name": "world",
"srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
"Datasource": {
"file": "http://tilemill-data.s3.amazonaws.com/test_data/shape_demo.zip",
"type": "shape"
}
}]
}

View File

@ -0,0 +1,4 @@
#world {
point-file:url(foo.png);
point-transform: scale(2 * 5 * [POP2005], [POP2005]);
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]>
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" maximum-extent="-20037508.34,-20037508.34,20037508.34,20037508.34">
<Style name="world" filter-mode="first" >
<Rule>
<PointSymbolizer file="foo.png" image-transform="scale(10*[POP2005],[POP2005])" />
</Rule>
</Style>
<Layer name="world"
srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
<StyleName>world</StyleName>
<Datasource>
<Parameter name="file"><![CDATA[[absolute path]]]></Parameter>
<Parameter name="type"><![CDATA[shape]]></Parameter>
</Datasource>
</Layer>
</Map>