Now have a 'when' (when the variable is true in *any* recent context) and 'if' (if the variable is true only in the *most* recent context). Added to the lexer a handler to determine if the block name is valid. This duplicates code from the parser, but it allows the lexer to tell the user when he's being dumb.
This commit is contained in:
parent
f65548f1c4
commit
2ff8172f33
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 1.6.1
|
||||
(function() {
|
||||
var exports, fromFile, fs, parse, render, tumble;
|
||||
var fromFile, fs, parse, render, tumble;
|
||||
|
||||
tumble = require('./lexer').parse;
|
||||
|
||||
|
@ -18,15 +18,21 @@
|
|||
|
||||
fromFile = function(path, options, callback) {
|
||||
return fs.readFile(path, 'utf8', function(err, str) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
if (callback) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
console.log(str, options);
|
||||
return callback(null, render(str, options, callback));
|
||||
}
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
return render(str, options, callback);
|
||||
});
|
||||
};
|
||||
|
||||
fromFile.render = render;
|
||||
|
||||
exports = fromFile;
|
||||
module.exports = fromFile;
|
||||
|
||||
}).call(this);
|
||||
|
|
191
lib/lexer.js
191
lib/lexer.js
|
@ -76,37 +76,38 @@ module.exports = (function() {
|
|||
peg$c3 = null,
|
||||
peg$c4 = ":",
|
||||
peg$c5 = "\":\"",
|
||||
peg$c6 = function(b, n) { return {type: b, name: n }; },
|
||||
peg$c7 = "/",
|
||||
peg$c8 = "\"/\"",
|
||||
peg$c9 = "tagname",
|
||||
peg$c10 = /^[a-zA-Z]/,
|
||||
peg$c11 = "[a-zA-Z]",
|
||||
peg$c12 = function(t) { return t.join(''); },
|
||||
peg$c13 = "",
|
||||
peg$c14 = /^[a-zA-Z:\/]/,
|
||||
peg$c15 = "[a-zA-Z:\\/]",
|
||||
peg$c16 = "{",
|
||||
peg$c17 = "\"{\"",
|
||||
peg$c18 = "}",
|
||||
peg$c19 = "\"}\"",
|
||||
peg$c20 = "\n",
|
||||
peg$c21 = "\"\\n\"",
|
||||
peg$c22 = "\r\n",
|
||||
peg$c23 = "\"\\r\\n\"",
|
||||
peg$c24 = "\r",
|
||||
peg$c25 = "\"\\r\"",
|
||||
peg$c26 = "\u2028",
|
||||
peg$c27 = "\"\\u2028\"",
|
||||
peg$c28 = "\u2029",
|
||||
peg$c29 = "\"\\u2029\"",
|
||||
peg$c30 = "any character",
|
||||
peg$c31 = function(c) {return c},
|
||||
peg$c32 = function(bs) { return { unit: 'text', content: bs.join('') } },
|
||||
peg$c33 = "variable",
|
||||
peg$c34 = function(t) { return { unit: 'variable', name: t }; },
|
||||
peg$c35 = function(t, ps, n) { return (t.type == n.type) && (t.name == n.name) },
|
||||
peg$c36 = function(t, ps, n) { return {unit: 'block', type:t.type, name:t.name, content: ps } },
|
||||
peg$c6 = function(b, n) { return is_valid_block_type(b); },
|
||||
peg$c7 = "",
|
||||
peg$c8 = function(b, n) { return {type: b, name: n }; },
|
||||
peg$c9 = "/",
|
||||
peg$c10 = "\"/\"",
|
||||
peg$c11 = "tagname",
|
||||
peg$c12 = /^[a-zA-Z]/,
|
||||
peg$c13 = "[a-zA-Z]",
|
||||
peg$c14 = function(t) { return t.join(''); },
|
||||
peg$c15 = /^[a-zA-Z:\/]/,
|
||||
peg$c16 = "[a-zA-Z:\\/]",
|
||||
peg$c17 = "{",
|
||||
peg$c18 = "\"{\"",
|
||||
peg$c19 = "}",
|
||||
peg$c20 = "\"}\"",
|
||||
peg$c21 = "\n",
|
||||
peg$c22 = "\"\\n\"",
|
||||
peg$c23 = "\r\n",
|
||||
peg$c24 = "\"\\r\\n\"",
|
||||
peg$c25 = "\r",
|
||||
peg$c26 = "\"\\r\"",
|
||||
peg$c27 = "\u2028",
|
||||
peg$c28 = "\"\\u2028\"",
|
||||
peg$c29 = "\u2029",
|
||||
peg$c30 = "\"\\u2029\"",
|
||||
peg$c31 = "any character",
|
||||
peg$c32 = function(c) {return c},
|
||||
peg$c33 = function(bs) { return { unit: 'text', content: bs.join('') } },
|
||||
peg$c34 = "variable",
|
||||
peg$c35 = function(t) { return { unit: 'variable', name: t }; },
|
||||
peg$c36 = function(t, ps, n) { return (t.type == n.type) && (t.name == n.name) },
|
||||
peg$c37 = function(t, ps, n) { return {unit: 'block', type:t.type, name:t.name, content: ps } },
|
||||
|
||||
peg$currPos = 0,
|
||||
peg$reportedPos = 0,
|
||||
|
@ -239,7 +240,7 @@ module.exports = (function() {
|
|||
}
|
||||
|
||||
function peg$parsetag_start() {
|
||||
var s0, s1, s2, s3, s4, s5;
|
||||
var s0, s1, s2, s3, s4, s5, s6;
|
||||
|
||||
peg$silentFails++;
|
||||
s0 = peg$currPos;
|
||||
|
@ -259,13 +260,25 @@ module.exports = (function() {
|
|||
if (s4 !== null) {
|
||||
s5 = peg$parserd();
|
||||
if (s5 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c6(s2,s4);
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
s0 = s1;
|
||||
peg$reportedPos = peg$currPos;
|
||||
s6 = peg$c6(s2,s4);
|
||||
if (s6) {
|
||||
s6 = peg$c7;
|
||||
} else {
|
||||
s0 = s1;
|
||||
s6 = peg$c3;
|
||||
}
|
||||
if (s6 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c8(s2,s4);
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
s0 = s1;
|
||||
} else {
|
||||
s0 = s1;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$c3;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
|
@ -303,11 +316,11 @@ module.exports = (function() {
|
|||
s1 = peg$parseld();
|
||||
if (s1 !== null) {
|
||||
if (input.charCodeAt(peg$currPos) === 47) {
|
||||
s2 = peg$c7;
|
||||
s2 = peg$c9;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c8); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c10); }
|
||||
}
|
||||
if (s2 !== null) {
|
||||
s3 = peg$parsetagname();
|
||||
|
@ -325,7 +338,7 @@ module.exports = (function() {
|
|||
s6 = peg$parserd();
|
||||
if (s6 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c6(s3,s5);
|
||||
s1 = peg$c8(s3,s5);
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
s0 = s1;
|
||||
|
@ -366,22 +379,22 @@ module.exports = (function() {
|
|||
peg$silentFails++;
|
||||
s0 = peg$currPos;
|
||||
s1 = [];
|
||||
if (peg$c10.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c12.test(input.charAt(peg$currPos))) {
|
||||
s2 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c11); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c13); }
|
||||
}
|
||||
if (s2 !== null) {
|
||||
while (s2 !== null) {
|
||||
s1.push(s2);
|
||||
if (peg$c10.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c12.test(input.charAt(peg$currPos))) {
|
||||
s2 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c11); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c13); }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -389,7 +402,7 @@ module.exports = (function() {
|
|||
}
|
||||
if (s1 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c12(s1);
|
||||
s1 = peg$c14(s1);
|
||||
}
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
|
@ -400,7 +413,7 @@ module.exports = (function() {
|
|||
peg$silentFails--;
|
||||
if (s0 === null) {
|
||||
s1 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c9); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c11); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -419,7 +432,7 @@ module.exports = (function() {
|
|||
s5 = peg$parserd();
|
||||
peg$silentFails--;
|
||||
if (s5 === null) {
|
||||
s4 = peg$c13;
|
||||
s4 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s4;
|
||||
s4 = peg$c3;
|
||||
|
@ -430,18 +443,18 @@ module.exports = (function() {
|
|||
s6 = peg$parseeol();
|
||||
peg$silentFails--;
|
||||
if (s6 === null) {
|
||||
s5 = peg$c13;
|
||||
s5 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$c3;
|
||||
}
|
||||
if (s5 !== null) {
|
||||
if (peg$c14.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c15.test(input.charAt(peg$currPos))) {
|
||||
s6 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s6 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c15); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c16); }
|
||||
}
|
||||
if (s6 !== null) {
|
||||
s4 = [s4, s5, s6];
|
||||
|
@ -467,7 +480,7 @@ module.exports = (function() {
|
|||
s5 = peg$parserd();
|
||||
peg$silentFails--;
|
||||
if (s5 === null) {
|
||||
s4 = peg$c13;
|
||||
s4 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s4;
|
||||
s4 = peg$c3;
|
||||
|
@ -478,18 +491,18 @@ module.exports = (function() {
|
|||
s6 = peg$parseeol();
|
||||
peg$silentFails--;
|
||||
if (s6 === null) {
|
||||
s5 = peg$c13;
|
||||
s5 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s5;
|
||||
s5 = peg$c3;
|
||||
}
|
||||
if (s5 !== null) {
|
||||
if (peg$c14.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c15.test(input.charAt(peg$currPos))) {
|
||||
s6 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s6 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c15); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c16); }
|
||||
}
|
||||
if (s6 !== null) {
|
||||
s4 = [s4, s5, s6];
|
||||
|
@ -535,11 +548,11 @@ module.exports = (function() {
|
|||
var s0;
|
||||
|
||||
if (input.charCodeAt(peg$currPos) === 123) {
|
||||
s0 = peg$c16;
|
||||
s0 = peg$c17;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c17); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c18); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -549,11 +562,11 @@ module.exports = (function() {
|
|||
var s0;
|
||||
|
||||
if (input.charCodeAt(peg$currPos) === 125) {
|
||||
s0 = peg$c18;
|
||||
s0 = peg$c19;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c19); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c20); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -563,43 +576,43 @@ module.exports = (function() {
|
|||
var s0;
|
||||
|
||||
if (input.charCodeAt(peg$currPos) === 10) {
|
||||
s0 = peg$c20;
|
||||
s0 = peg$c21;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c21); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c22); }
|
||||
}
|
||||
if (s0 === null) {
|
||||
if (input.substr(peg$currPos, 2) === peg$c22) {
|
||||
s0 = peg$c22;
|
||||
if (input.substr(peg$currPos, 2) === peg$c23) {
|
||||
s0 = peg$c23;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c23); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c24); }
|
||||
}
|
||||
if (s0 === null) {
|
||||
if (input.charCodeAt(peg$currPos) === 13) {
|
||||
s0 = peg$c24;
|
||||
s0 = peg$c25;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c25); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c26); }
|
||||
}
|
||||
if (s0 === null) {
|
||||
if (input.charCodeAt(peg$currPos) === 8232) {
|
||||
s0 = peg$c26;
|
||||
s0 = peg$c27;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c27); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c28); }
|
||||
}
|
||||
if (s0 === null) {
|
||||
if (input.charCodeAt(peg$currPos) === 8233) {
|
||||
s0 = peg$c28;
|
||||
s0 = peg$c29;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c29); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c30); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +633,7 @@ module.exports = (function() {
|
|||
s4 = peg$parsetag();
|
||||
peg$silentFails--;
|
||||
if (s4 === null) {
|
||||
s3 = peg$c13;
|
||||
s3 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s3;
|
||||
s3 = peg$c3;
|
||||
|
@ -631,11 +644,11 @@ module.exports = (function() {
|
|||
peg$currPos++;
|
||||
} else {
|
||||
s4 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c30); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c31); }
|
||||
}
|
||||
if (s4 !== null) {
|
||||
peg$reportedPos = s2;
|
||||
s3 = peg$c31(s4);
|
||||
s3 = peg$c32(s4);
|
||||
if (s3 === null) {
|
||||
peg$currPos = s2;
|
||||
s2 = s3;
|
||||
|
@ -659,7 +672,7 @@ module.exports = (function() {
|
|||
s4 = peg$parsetag();
|
||||
peg$silentFails--;
|
||||
if (s4 === null) {
|
||||
s3 = peg$c13;
|
||||
s3 = peg$c7;
|
||||
} else {
|
||||
peg$currPos = s3;
|
||||
s3 = peg$c3;
|
||||
|
@ -670,11 +683,11 @@ module.exports = (function() {
|
|||
peg$currPos++;
|
||||
} else {
|
||||
s4 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c30); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c31); }
|
||||
}
|
||||
if (s4 !== null) {
|
||||
peg$reportedPos = s2;
|
||||
s3 = peg$c31(s4);
|
||||
s3 = peg$c32(s4);
|
||||
if (s3 === null) {
|
||||
peg$currPos = s2;
|
||||
s2 = s3;
|
||||
|
@ -695,7 +708,7 @@ module.exports = (function() {
|
|||
}
|
||||
if (s1 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c32(s1);
|
||||
s1 = peg$c33(s1);
|
||||
}
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
|
@ -719,7 +732,7 @@ module.exports = (function() {
|
|||
s3 = peg$parserd();
|
||||
if (s3 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c34(s2);
|
||||
s1 = peg$c35(s2);
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
s0 = s1;
|
||||
|
@ -741,7 +754,7 @@ module.exports = (function() {
|
|||
peg$silentFails--;
|
||||
if (s0 === null) {
|
||||
s1 = null;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c33); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c34); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -763,15 +776,15 @@ module.exports = (function() {
|
|||
s3 = peg$parsetag_end();
|
||||
if (s3 !== null) {
|
||||
peg$reportedPos = peg$currPos;
|
||||
s4 = peg$c35(s1,s2,s3);
|
||||
s4 = peg$c36(s1,s2,s3);
|
||||
if (s4) {
|
||||
s4 = peg$c13;
|
||||
s4 = peg$c7;
|
||||
} else {
|
||||
s4 = peg$c3;
|
||||
}
|
||||
if (s4 !== null) {
|
||||
peg$reportedPos = s0;
|
||||
s1 = peg$c36(s1,s2,s3);
|
||||
s1 = peg$c37(s1,s2,s3);
|
||||
if (s1 === null) {
|
||||
peg$currPos = s0;
|
||||
s0 = s1;
|
||||
|
@ -798,6 +811,20 @@ module.exports = (function() {
|
|||
return s0;
|
||||
}
|
||||
|
||||
|
||||
var _VALID_BLOCK_TYPES = ['if', 'when', 'template', 'many', 'each', 'block'];
|
||||
var _VBT_LENGTH = _VALID_BLOCK_TYPES.length;
|
||||
|
||||
function is_valid_block_type(b) {
|
||||
for(i = 0; i < _VBT_LENGTH; i++) {
|
||||
if (_VALID_BLOCK_TYPES[i] == b) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
peg$result = peg$startRuleFunction();
|
||||
|
||||
if (peg$result !== null && peg$currPos === input.length) {
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
return r;
|
||||
};
|
||||
|
||||
Contexter.prototype["if"] = function(name, cb) {
|
||||
Contexter.prototype.when = function(name, cb) {
|
||||
var p;
|
||||
p = this.has_any_one(name);
|
||||
if (p) {
|
||||
|
@ -74,6 +74,16 @@
|
|||
}
|
||||
};
|
||||
|
||||
Contexter.prototype["if"] = function(name, cb) {
|
||||
var p;
|
||||
p = this.has(name);
|
||||
if (p) {
|
||||
return cb(this);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
Contexter.prototype.block = function(name, cb) {
|
||||
var p;
|
||||
p = this.has_any_one(name);
|
||||
|
|
|
@ -10,9 +10,12 @@ render = (str, options, callback) ->
|
|||
|
||||
fromFile = (path, options, callback) ->
|
||||
fs.readFile path, 'utf8', (err, str) ->
|
||||
return callback(err) if err
|
||||
render(str, options, callback)
|
||||
if callback
|
||||
return callback(err) if err
|
||||
console.log(str, options);
|
||||
return callback(null, render(str, options, callback))
|
||||
throw err if err
|
||||
|
||||
fromFile.render = render
|
||||
|
||||
exports = fromFile
|
||||
module.exports = fromFile
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
// -*- mode: javascript -*-
|
||||
{
|
||||
var _VALID_BLOCK_TYPES = ['if', 'when', 'template', 'many', 'each', 'block'];
|
||||
var _VBT_LENGTH = _VALID_BLOCK_TYPES.length;
|
||||
|
||||
function is_valid_block_type(b) {
|
||||
for(i = 0; i < _VBT_LENGTH; i++) {
|
||||
if (_VALID_BLOCK_TYPES[i] == b) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document
|
||||
= ps:part*
|
||||
|
@ -9,6 +23,7 @@ part
|
|||
|
||||
tag_start "tag_start"
|
||||
= ld b:tagname ":" n:tagname rd
|
||||
&{ return is_valid_block_type(b); }
|
||||
{ return {type: b, name: n }; }
|
||||
|
||||
tag_end
|
||||
|
|
|
@ -39,12 +39,18 @@ class Contexter
|
|||
@depth--
|
||||
r
|
||||
|
||||
if: (name, cb) ->
|
||||
# Execute and return this specifiecd block if and only if the
|
||||
when: (name, cb) ->
|
||||
# Execute and return this specified block if and only if the
|
||||
# requested context is valid.
|
||||
p = @has_any_one(name)
|
||||
if p then cb(@) else ''
|
||||
|
||||
if: (name, cb) ->
|
||||
# Execute and return this specifiecd block if and only if the
|
||||
# requested context is valid AND current
|
||||
p = @has(name)
|
||||
if p then cb(@) else ''
|
||||
|
||||
block: (name, cb) ->
|
||||
# Execute and return this specified block if and only if the
|
||||
# requested context is valid and entrant.
|
||||
|
|
Loading…
Reference in New Issue