From a66fa6c462d4740b32329fb9162ea48c6546e477 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 26 Jun 2012 17:03:34 -0400 Subject: [PATCH] Fix quoting situation around fields --- lib/carto/parser.js | 8 +++++--- lib/carto/tree/field.js | 3 ++- lib/carto/tree/operation.js | 4 +++- lib/carto/tree/quoted.js | 14 +++++++++----- test/rendering/field.mss | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/carto/parser.js b/lib/carto/parser.js index a17dd38..6aaf961 100644 --- a/lib/carto/parser.js +++ b/lib/carto/parser.js @@ -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(str[0], str[1] || str[2]); + return new tree.Quoted(true, str[1] || str[2]); } }, @@ -481,13 +481,15 @@ carto.Parser = function Parser(env) { return new tree.Call(name, args, i); } }, - arguments: function() { + // Arguments are comma-separated expressions + 'arguments': function() { var args = [], arg; while (arg = $(this.expression)) { args.push(arg); if (! $(',')) { break; } } + return args; }, literal: function() { @@ -511,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('"', value), imports.paths); + value : new tree.Quoted(true, value), imports.paths); } }, diff --git a/lib/carto/tree/field.js b/lib/carto/tree/field.js index 0a8981b..249eaa4 100644 --- a/lib/carto/tree/field.js +++ b/lib/carto/tree/field.js @@ -13,7 +13,8 @@ tree.Field.prototype = { return this; }, operate: function(op, other) { - return new tree.Quoted('', this.toString() + op + other.toString(true)); + return new tree.Quoted(false, + this.toString() + op + other.toString(true)); } }; diff --git a/lib/carto/tree/operation.js b/lib/carto/tree/operation.js index 5406cc5..42b593d 100644 --- a/lib/carto/tree/operation.js +++ b/lib/carto/tree/operation.js @@ -30,7 +30,9 @@ tree.Operation.prototype.eval = function(env) { } } - if (a instanceof tree.Quoted || b instanceof tree.Quoted) { + // 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.", diff --git a/lib/carto/tree/quoted.js b/lib/carto/tree/quoted.js index 888a100..e5dfd46 100644 --- a/lib/carto/tree/quoted.js +++ b/lib/carto/tree/quoted.js @@ -1,14 +1,18 @@ (function(tree) { -tree.Quoted = function Quoted(str, content) { +tree.Quoted = function Quoted(ever_quote, content) { this.value = content || ''; - this.quote = str.charAt(0); + // 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, '''); - return (quotes === true) ? "'" + xmlvalue + "'" : this.value; + return (this.ever_quote && quotes === true) ? "'" + xmlvalue + "'" : this.value; }, 'eval': function() { @@ -17,10 +21,10 @@ tree.Quoted.prototype = { operate: function(op, other) { if (other.is !== 'string') { - return new tree.Quoted(this.quote, + return new tree.Quoted(false, this.toString(true) + op + other.toString()); } else { - return new tree.Quoted(this.quote, + return new tree.Quoted(true, tree.operate(op, this.toString(), other.toString())); } } diff --git a/test/rendering/field.mss b/test/rendering/field.mss index f5bb71f..28b8540 100644 --- a/test/rendering/field.mss +++ b/test/rendering/field.mss @@ -1,5 +1,5 @@ #world { - text-name: "hello " + [NAME]; + text-name: "hello " + [NAME] + ' hello'; text-size: 11; text-face-name: "Georgia Regular", "Arial Italic"; }