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:
Elf M. Sternberg 2013-06-11 09:05:32 -07:00
parent f65548f1c4
commit 2ff8172f33
6 changed files with 160 additions and 93 deletions

View File

@ -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 (callback) {
if (err) {
return callback(err);
}
return render(str, options, callback);
console.log(str, options);
return callback(null, render(str, options, callback));
}
if (err) {
throw err;
}
});
};
fromFile.render = render;
exports = fromFile;
module.exports = fromFile;
}).call(this);

View File

@ -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,8 +260,16 @@ module.exports = (function() {
if (s4 !== null) {
s5 = peg$parserd();
if (s5 !== null) {
peg$reportedPos = peg$currPos;
s6 = peg$c6(s2,s4);
if (s6) {
s6 = peg$c7;
} else {
s6 = peg$c3;
}
if (s6 !== null) {
peg$reportedPos = s0;
s1 = peg$c6(s2,s4);
s1 = peg$c8(s2,s4);
if (s1 === null) {
peg$currPos = s0;
s0 = s1;
@ -287,6 +296,10 @@ module.exports = (function() {
peg$currPos = s0;
s0 = peg$c3;
}
} else {
peg$currPos = s0;
s0 = peg$c3;
}
peg$silentFails--;
if (s0 === null) {
s1 = null;
@ -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) {

View File

@ -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);

View File

@ -10,9 +10,12 @@ render = (str, options, callback) ->
fromFile = (path, options, callback) ->
fs.readFile path, 'utf8', (err, str) ->
if callback
return callback(err) if err
render(str, options, callback)
console.log(str, options);
return callback(null, render(str, options, callback))
throw err if err
fromFile.render = render
exports = fromFile
module.exports = fromFile

View File

@ -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

View File

@ -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.