diff --git a/lib/compiler.js b/lib/compiler.js index 07550804..4b7e85a9 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -43,7 +43,9 @@ dust.optimizers = { key: noop, path: noop, literal: noop, - comment: nullify + comment: nullify, + line: nullify, + col: nullify }; dust.pragmas = { diff --git a/lib/parser.js b/lib/parser.js index 149b520f..d3ca968d 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -53,7 +53,7 @@ var parser = (function(){ "special": parse_special, "identifier": parse_identifier, "number": parse_number, - "frac": parse_frac, + "float": parse_float, "integer": parse_integer, "path": parse_path, "key": parse_key, @@ -169,7 +169,7 @@ var parser = (function(){ result1 = parse_part(); } if (result0 !== null) { - result0 = (function(offset, line, column, p) { return ["body"].concat(p) })(pos0.offset, pos0.line, pos0.column, result0); + result0 = (function(offset, line, column, p) { return ["body"].concat(p).concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0); } if (result0 === null) { pos = clone(pos0); @@ -303,7 +303,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, t) { t.push(["bodies"]); return t })(pos0.offset, pos0.line, pos0.column, result0[0]); + result0 = (function(offset, line, column, t) { t.push(["bodies"]); return t.concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[0]); } if (result0 === null) { pos = clone(pos0); @@ -785,7 +785,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, n, f) { return ["reference", n, f] })(pos0.offset, pos0.line, pos0.column, result0[1], result0[2]); + result0 = (function(offset, line, column, n, f) { return ["reference", n, f].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[1], result0[2]); } if (result0 === null) { pos = clone(pos0); @@ -907,7 +907,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, s, n, c, p) { var key = (s ===">")? "partial" : s; return [key, n, c, p] })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3], result0[4], result0[5]); + result0 = (function(offset, line, column, s, n, c, p) { var key = (s ===">")? "partial" : s; return [key, n, c, p].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3], result0[4], result0[5]); } if (result0 === null) { pos = clone(pos0); @@ -1041,7 +1041,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, k) { return ["special", k] })(pos0.offset, pos0.line, pos0.column, result0[2]); + result0 = (function(offset, line, column, k) { return ["special", k].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[2]); } if (result0 === null) { pos = clone(pos0); @@ -1089,7 +1089,7 @@ var parser = (function(){ reportFailures++; pos0 = clone(pos); - result0 = parse_frac(); + result0 = parse_float(); if (result0 === null) { result0 = parse_integer(); } @@ -1106,7 +1106,7 @@ var parser = (function(){ return result0; } - function parse_frac() { + function parse_float() { var result0, result1, result2, result3; var pos0, pos1; @@ -1157,7 +1157,7 @@ var parser = (function(){ } reportFailures--; if (reportFailures === 0 && result0 === null) { - matchFailed("frac"); + matchFailed("float"); } return result0; } @@ -1245,12 +1245,12 @@ var parser = (function(){ } if (result0 !== null) { result0 = (function(offset, line, column, k, d) { - d = d[0]; + d = d[0]; if (k && d) { d.unshift(k); - return [false, d]; + return [false, d].concat([['line', line], ['col', column]]); } - return [true, d]; + return [true, d].concat([['line', line], ['col', column]]); })(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]); } if (result0 === null) { @@ -1294,9 +1294,9 @@ var parser = (function(){ if (result0 !== null) { result0 = (function(offset, line, column, d) { if (d.length > 0) { - return [true, d[0]]; + return [true, d[0]].concat([['line', line], ['col', column]]); } - return [true, []] + return [true, []].concat([['line', line], ['col', column]]); })(pos0.offset, pos0.line, pos0.column, result0[1]); } if (result0 === null) { @@ -1603,7 +1603,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column) { return ["literal", ""] })(pos0.offset, pos0.line, pos0.column); + result0 = (function(offset, line, column) { return ["literal", ""].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column); } if (result0 === null) { pos = clone(pos0); @@ -1647,7 +1647,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, l) { return ["literal", l] })(pos0.offset, pos0.line, pos0.column, result0[1]); + result0 = (function(offset, line, column, l) { return ["literal", l].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[1]); } if (result0 === null) { pos = clone(pos0); @@ -1700,7 +1700,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, p) { return ["body"].concat(p) })(pos0.offset, pos0.line, pos0.column, result0[1]); + result0 = (function(offset, line, column, p) { return ["body"].concat(p).concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[1]); } if (result0 === null) { pos = clone(pos0); @@ -1725,7 +1725,7 @@ var parser = (function(){ pos0 = clone(pos); result0 = parse_literal(); if (result0 !== null) { - result0 = (function(offset, line, column, l) { return ["buffer", l] })(pos0.offset, pos0.line, pos0.column, result0); + result0 = (function(offset, line, column, l) { return ["buffer", l].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0); } if (result0 === null) { pos = clone(pos0); @@ -1913,7 +1913,7 @@ var parser = (function(){ result0 = null; } if (result0 !== null) { - result0 = (function(offset, line, column, b) { return ["buffer", b.join('')] })(pos0.offset, pos0.line, pos0.column, result0); + result0 = (function(offset, line, column, b) { return ["buffer", b.join('')].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0); } if (result0 === null) { pos = clone(pos0); @@ -2196,7 +2196,7 @@ var parser = (function(){ pos = clone(pos1); } if (result0 !== null) { - result0 = (function(offset, line, column, c) { return ["comment", c.join('')] })(pos0.offset, pos0.line, pos0.column, result0[1]); + result0 = (function(offset, line, column, c) { return ["comment", c.join('')].concat([['line', line], ['col', column]]) })(pos0.offset, pos0.line, pos0.column, result0[1]); } if (result0 === null) { pos = clone(pos0); diff --git a/package.json b/package.json index 2690559b..c02deed9 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,10 @@ { "name": "Richard Ragan", "email": "rragan@ebay.com" + }, + { + "name": "Steven Foote", + "email": "sfoote@linkedin.com" } ], "scripts": { @@ -32,10 +36,11 @@ "url": "https://github.com/linkedin/dustjs.git" }, "keywords": ["templates", "views"], - "devDependencies": { - "jasmine-node" : "1.9.x", - "cover" : "0.2.x", - "uglify-js" : "1.3.3" + "devDependencies": { + "jasmine-node" : "1.9.x", + "cover" : "0.2.x", + "uglify-js" : "1.3.3", + "pegjs" : "0.7.0" }, "license": "MIT", "engine": { diff --git a/src/dust.pegjs b/src/dust.pegjs index a6ef0cbd..4c2d1513 100644 --- a/src/dust.pegjs +++ b/src/dust.pegjs @@ -5,7 +5,7 @@ start body is defined as anything that matches with the part 0 or more times ---------------------------------------------------------------------------------------------------------------------------------------*/ body - = p:part* { return ["body"].concat(p) } + = p:part* { return ["body"].concat(p).concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- part is defined as anything that matches with comment or section or partial or special or reference or buffer @@ -19,9 +19,9 @@ part ---------------------------------------------------------------------------------------------------------------------------------------*/ section "section" = t:sec_tag_start ws* rd b:body e:bodies n:end_tag? &{if( (!n) || (t[1].text !== n.text) ) { throw new Error("Expected end tag for "+t[1].text+" but it was not found. At line : "+line+", column : " + column)} return true;} - { e.push(["param", ["literal", "block"], b]); t.push(e); return t } + { e.push(["param", ["literal", "block"], b]); t.push(e); return t.concat([['line', line], ['col', column]]) } / t:sec_tag_start ws* "/" rd - { t.push(["bodies"]); return t } + { t.push(["bodies"]); return t.concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- sec_tag_start is defined as matching an opening brace followed by one of #?^<+@% plus identifier plus context plus param @@ -65,7 +65,7 @@ bodies "bodies" ---------------------------------------------------------------------------------------------------------------------------------------*/ reference "reference" = ld n:identifier f:filters rd - { return ["reference", n, f] } + { return ["reference", n, f].concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- partial is defined as matching a opening brace followed by a > plus anything that matches with key or inline plus @@ -73,7 +73,7 @@ reference "reference" ---------------------------------------------------------------------------------------------------------------------------------------*/ partial "partial" = ld s:(">"/"+") ws* n:(k:key {return ["literal", k]} / inline) c:context p:params ws* "/" rd - { var key = (s ===">")? "partial" : s; return [key, n, c, p] } + { var key = (s ===">")? "partial" : s; return [key, n, c, p].concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- filters is defined as matching a pipe character followed by anything that matches the key @@ -87,7 +87,7 @@ filters "filters" ---------------------------------------------------------------------------------------------------------------------------------------*/ special "special" = ld "~" k:key rd - { return ["special", k] } + { return ["special", k].concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- identifier is defined as matching a path or key @@ -110,18 +110,18 @@ integer "integer" ---------------------------------------------------------------------------------------------------------------------------------------*/ path "path" = k:key? d:(array_part / array)+ { - d = d[0]; + d = d[0]; if (k && d) { d.unshift(k); - return [false, d]; + return [false, d].concat([['line', line], ['col', column]]); } - return [true, d]; + return [true, d].concat([['line', line], ['col', column]]); } / "." d:(array_part / array)* { if (d.length > 0) { - return [true, d[0]]; + return [true, d[0]].concat([['line', line], ['col', column]]); } - return [true, []] + return [true, []].concat([['line', line], ['col', column]]); } /*------------------------------------------------------------------------------------------------------------------------------------- @@ -142,9 +142,9 @@ array_part "array_part" double quotes plus inline_part followed by the closing double quotes ---------------------------------------------------------------------------------------------------------------------------------------*/ inline "inline" - = '"' '"' { return ["literal", ""] } - / '"' l:literal '"' { return ["literal", l] } - / '"' p:inline_part+ '"' { return ["body"].concat(p) } + = '"' '"' { return ["literal", ""].concat([['line', line], ['col', column]]) } + / '"' l:literal '"' { return ["literal", l].concat([['line', line], ['col', column]]) } + / '"' p:inline_part+ '"' { return ["body"].concat(p).concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- inline_part is defined as matching a special or reference or literal @@ -154,9 +154,9 @@ inline_part buffer "buffer" = e:eol w:ws* - { return ["format", e, w.join('')] } + { return ["format", e, w.join('')].concat([['line', line], ['col', column]]) } / b:(!tag !comment !eol c:. {return c})+ - { return ["buffer", b.join('')] } + { return ["buffer", b.join('')].concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- literal is defined as matching esc or any character except the double quotes and it cannot be a tag @@ -170,7 +170,7 @@ esc comment "comment" = "{!" c:(!"!}" c:. {return c})* "!}" - { return ["comment", c.join('')] } + { return ["comment", c.join('')].concat([['line', line], ['col', column]]) } /*------------------------------------------------------------------------------------------------------------------------------------- tag is defined as matching an opening brace plus any of #?^><+%:@/~% plus 0 or more whitespaces plus any character or characters that