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 // Generated by CoffeeScript 1.6.1
(function() { (function() {
var exports, fromFile, fs, parse, render, tumble; var fromFile, fs, parse, render, tumble;
tumble = require('./lexer').parse; tumble = require('./lexer').parse;
@ -18,15 +18,21 @@
fromFile = function(path, options, callback) { fromFile = function(path, options, callback) {
return fs.readFile(path, 'utf8', function(err, str) { return fs.readFile(path, 'utf8', function(err, str) {
if (callback) {
if (err) { if (err) {
return callback(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; fromFile.render = render;
exports = fromFile; module.exports = fromFile;
}).call(this); }).call(this);

View File

@ -76,37 +76,38 @@ module.exports = (function() {
peg$c3 = null, peg$c3 = null,
peg$c4 = ":", peg$c4 = ":",
peg$c5 = "\":\"", peg$c5 = "\":\"",
peg$c6 = function(b, n) { return {type: b, name: n }; }, peg$c6 = function(b, n) { return is_valid_block_type(b); },
peg$c7 = "/", peg$c7 = "",
peg$c8 = "\"/\"", peg$c8 = function(b, n) { return {type: b, name: n }; },
peg$c9 = "tagname", peg$c9 = "/",
peg$c10 = /^[a-zA-Z]/, peg$c10 = "\"/\"",
peg$c11 = "[a-zA-Z]", peg$c11 = "tagname",
peg$c12 = function(t) { return t.join(''); }, peg$c12 = /^[a-zA-Z]/,
peg$c13 = "", peg$c13 = "[a-zA-Z]",
peg$c14 = /^[a-zA-Z:\/]/, peg$c14 = function(t) { return t.join(''); },
peg$c15 = "[a-zA-Z:\\/]", peg$c15 = /^[a-zA-Z:\/]/,
peg$c16 = "{", peg$c16 = "[a-zA-Z:\\/]",
peg$c17 = "\"{\"", peg$c17 = "{",
peg$c18 = "}", peg$c18 = "\"{\"",
peg$c19 = "\"}\"", peg$c19 = "}",
peg$c20 = "\n", peg$c20 = "\"}\"",
peg$c21 = "\"\\n\"", peg$c21 = "\n",
peg$c22 = "\r\n", peg$c22 = "\"\\n\"",
peg$c23 = "\"\\r\\n\"", peg$c23 = "\r\n",
peg$c24 = "\r", peg$c24 = "\"\\r\\n\"",
peg$c25 = "\"\\r\"", peg$c25 = "\r",
peg$c26 = "\u2028", peg$c26 = "\"\\r\"",
peg$c27 = "\"\\u2028\"", peg$c27 = "\u2028",
peg$c28 = "\u2029", peg$c28 = "\"\\u2028\"",
peg$c29 = "\"\\u2029\"", peg$c29 = "\u2029",
peg$c30 = "any character", peg$c30 = "\"\\u2029\"",
peg$c31 = function(c) {return c}, peg$c31 = "any character",
peg$c32 = function(bs) { return { unit: 'text', content: bs.join('') } }, peg$c32 = function(c) {return c},
peg$c33 = "variable", peg$c33 = function(bs) { return { unit: 'text', content: bs.join('') } },
peg$c34 = function(t) { return { unit: 'variable', name: t }; }, peg$c34 = "variable",
peg$c35 = function(t, ps, n) { return (t.type == n.type) && (t.name == n.name) }, peg$c35 = function(t) { return { unit: 'variable', name: t }; },
peg$c36 = function(t, ps, n) { return {unit: 'block', type:t.type, name:t.name, content: ps } }, 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$currPos = 0,
peg$reportedPos = 0, peg$reportedPos = 0,
@ -239,7 +240,7 @@ module.exports = (function() {
} }
function peg$parsetag_start() { function peg$parsetag_start() {
var s0, s1, s2, s3, s4, s5; var s0, s1, s2, s3, s4, s5, s6;
peg$silentFails++; peg$silentFails++;
s0 = peg$currPos; s0 = peg$currPos;
@ -259,8 +260,16 @@ module.exports = (function() {
if (s4 !== null) { if (s4 !== null) {
s5 = peg$parserd(); s5 = peg$parserd();
if (s5 !== null) { 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; peg$reportedPos = s0;
s1 = peg$c6(s2,s4); s1 = peg$c8(s2,s4);
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
s0 = s1; s0 = s1;
@ -287,6 +296,10 @@ module.exports = (function() {
peg$currPos = s0; peg$currPos = s0;
s0 = peg$c3; s0 = peg$c3;
} }
} else {
peg$currPos = s0;
s0 = peg$c3;
}
peg$silentFails--; peg$silentFails--;
if (s0 === null) { if (s0 === null) {
s1 = null; s1 = null;
@ -303,11 +316,11 @@ module.exports = (function() {
s1 = peg$parseld(); s1 = peg$parseld();
if (s1 !== null) { if (s1 !== null) {
if (input.charCodeAt(peg$currPos) === 47) { if (input.charCodeAt(peg$currPos) === 47) {
s2 = peg$c7; s2 = peg$c9;
peg$currPos++; peg$currPos++;
} else { } else {
s2 = null; s2 = null;
if (peg$silentFails === 0) { peg$fail(peg$c8); } if (peg$silentFails === 0) { peg$fail(peg$c10); }
} }
if (s2 !== null) { if (s2 !== null) {
s3 = peg$parsetagname(); s3 = peg$parsetagname();
@ -325,7 +338,7 @@ module.exports = (function() {
s6 = peg$parserd(); s6 = peg$parserd();
if (s6 !== null) { if (s6 !== null) {
peg$reportedPos = s0; peg$reportedPos = s0;
s1 = peg$c6(s3,s5); s1 = peg$c8(s3,s5);
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
s0 = s1; s0 = s1;
@ -366,22 +379,22 @@ module.exports = (function() {
peg$silentFails++; peg$silentFails++;
s0 = peg$currPos; s0 = peg$currPos;
s1 = []; s1 = [];
if (peg$c10.test(input.charAt(peg$currPos))) { if (peg$c12.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos); s2 = input.charAt(peg$currPos);
peg$currPos++; peg$currPos++;
} else { } else {
s2 = null; s2 = null;
if (peg$silentFails === 0) { peg$fail(peg$c11); } if (peg$silentFails === 0) { peg$fail(peg$c13); }
} }
if (s2 !== null) { if (s2 !== null) {
while (s2 !== null) { while (s2 !== null) {
s1.push(s2); s1.push(s2);
if (peg$c10.test(input.charAt(peg$currPos))) { if (peg$c12.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos); s2 = input.charAt(peg$currPos);
peg$currPos++; peg$currPos++;
} else { } else {
s2 = null; s2 = null;
if (peg$silentFails === 0) { peg$fail(peg$c11); } if (peg$silentFails === 0) { peg$fail(peg$c13); }
} }
} }
} else { } else {
@ -389,7 +402,7 @@ module.exports = (function() {
} }
if (s1 !== null) { if (s1 !== null) {
peg$reportedPos = s0; peg$reportedPos = s0;
s1 = peg$c12(s1); s1 = peg$c14(s1);
} }
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
@ -400,7 +413,7 @@ module.exports = (function() {
peg$silentFails--; peg$silentFails--;
if (s0 === null) { if (s0 === null) {
s1 = null; s1 = null;
if (peg$silentFails === 0) { peg$fail(peg$c9); } if (peg$silentFails === 0) { peg$fail(peg$c11); }
} }
return s0; return s0;
@ -419,7 +432,7 @@ module.exports = (function() {
s5 = peg$parserd(); s5 = peg$parserd();
peg$silentFails--; peg$silentFails--;
if (s5 === null) { if (s5 === null) {
s4 = peg$c13; s4 = peg$c7;
} else { } else {
peg$currPos = s4; peg$currPos = s4;
s4 = peg$c3; s4 = peg$c3;
@ -430,18 +443,18 @@ module.exports = (function() {
s6 = peg$parseeol(); s6 = peg$parseeol();
peg$silentFails--; peg$silentFails--;
if (s6 === null) { if (s6 === null) {
s5 = peg$c13; s5 = peg$c7;
} else { } else {
peg$currPos = s5; peg$currPos = s5;
s5 = peg$c3; s5 = peg$c3;
} }
if (s5 !== null) { if (s5 !== null) {
if (peg$c14.test(input.charAt(peg$currPos))) { if (peg$c15.test(input.charAt(peg$currPos))) {
s6 = input.charAt(peg$currPos); s6 = input.charAt(peg$currPos);
peg$currPos++; peg$currPos++;
} else { } else {
s6 = null; s6 = null;
if (peg$silentFails === 0) { peg$fail(peg$c15); } if (peg$silentFails === 0) { peg$fail(peg$c16); }
} }
if (s6 !== null) { if (s6 !== null) {
s4 = [s4, s5, s6]; s4 = [s4, s5, s6];
@ -467,7 +480,7 @@ module.exports = (function() {
s5 = peg$parserd(); s5 = peg$parserd();
peg$silentFails--; peg$silentFails--;
if (s5 === null) { if (s5 === null) {
s4 = peg$c13; s4 = peg$c7;
} else { } else {
peg$currPos = s4; peg$currPos = s4;
s4 = peg$c3; s4 = peg$c3;
@ -478,18 +491,18 @@ module.exports = (function() {
s6 = peg$parseeol(); s6 = peg$parseeol();
peg$silentFails--; peg$silentFails--;
if (s6 === null) { if (s6 === null) {
s5 = peg$c13; s5 = peg$c7;
} else { } else {
peg$currPos = s5; peg$currPos = s5;
s5 = peg$c3; s5 = peg$c3;
} }
if (s5 !== null) { if (s5 !== null) {
if (peg$c14.test(input.charAt(peg$currPos))) { if (peg$c15.test(input.charAt(peg$currPos))) {
s6 = input.charAt(peg$currPos); s6 = input.charAt(peg$currPos);
peg$currPos++; peg$currPos++;
} else { } else {
s6 = null; s6 = null;
if (peg$silentFails === 0) { peg$fail(peg$c15); } if (peg$silentFails === 0) { peg$fail(peg$c16); }
} }
if (s6 !== null) { if (s6 !== null) {
s4 = [s4, s5, s6]; s4 = [s4, s5, s6];
@ -535,11 +548,11 @@ module.exports = (function() {
var s0; var s0;
if (input.charCodeAt(peg$currPos) === 123) { if (input.charCodeAt(peg$currPos) === 123) {
s0 = peg$c16; s0 = peg$c17;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c17); } if (peg$silentFails === 0) { peg$fail(peg$c18); }
} }
return s0; return s0;
@ -549,11 +562,11 @@ module.exports = (function() {
var s0; var s0;
if (input.charCodeAt(peg$currPos) === 125) { if (input.charCodeAt(peg$currPos) === 125) {
s0 = peg$c18; s0 = peg$c19;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c19); } if (peg$silentFails === 0) { peg$fail(peg$c20); }
} }
return s0; return s0;
@ -563,43 +576,43 @@ module.exports = (function() {
var s0; var s0;
if (input.charCodeAt(peg$currPos) === 10) { if (input.charCodeAt(peg$currPos) === 10) {
s0 = peg$c20; s0 = peg$c21;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c21); } if (peg$silentFails === 0) { peg$fail(peg$c22); }
} }
if (s0 === null) { if (s0 === null) {
if (input.substr(peg$currPos, 2) === peg$c22) { if (input.substr(peg$currPos, 2) === peg$c23) {
s0 = peg$c22; s0 = peg$c23;
peg$currPos += 2; peg$currPos += 2;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c23); } if (peg$silentFails === 0) { peg$fail(peg$c24); }
} }
if (s0 === null) { if (s0 === null) {
if (input.charCodeAt(peg$currPos) === 13) { if (input.charCodeAt(peg$currPos) === 13) {
s0 = peg$c24; s0 = peg$c25;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c25); } if (peg$silentFails === 0) { peg$fail(peg$c26); }
} }
if (s0 === null) { if (s0 === null) {
if (input.charCodeAt(peg$currPos) === 8232) { if (input.charCodeAt(peg$currPos) === 8232) {
s0 = peg$c26; s0 = peg$c27;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; s0 = null;
if (peg$silentFails === 0) { peg$fail(peg$c27); } if (peg$silentFails === 0) { peg$fail(peg$c28); }
} }
if (s0 === null) { if (s0 === null) {
if (input.charCodeAt(peg$currPos) === 8233) { if (input.charCodeAt(peg$currPos) === 8233) {
s0 = peg$c28; s0 = peg$c29;
peg$currPos++; peg$currPos++;
} else { } else {
s0 = null; 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(); s4 = peg$parsetag();
peg$silentFails--; peg$silentFails--;
if (s4 === null) { if (s4 === null) {
s3 = peg$c13; s3 = peg$c7;
} else { } else {
peg$currPos = s3; peg$currPos = s3;
s3 = peg$c3; s3 = peg$c3;
@ -631,11 +644,11 @@ module.exports = (function() {
peg$currPos++; peg$currPos++;
} else { } else {
s4 = null; s4 = null;
if (peg$silentFails === 0) { peg$fail(peg$c30); } if (peg$silentFails === 0) { peg$fail(peg$c31); }
} }
if (s4 !== null) { if (s4 !== null) {
peg$reportedPos = s2; peg$reportedPos = s2;
s3 = peg$c31(s4); s3 = peg$c32(s4);
if (s3 === null) { if (s3 === null) {
peg$currPos = s2; peg$currPos = s2;
s2 = s3; s2 = s3;
@ -659,7 +672,7 @@ module.exports = (function() {
s4 = peg$parsetag(); s4 = peg$parsetag();
peg$silentFails--; peg$silentFails--;
if (s4 === null) { if (s4 === null) {
s3 = peg$c13; s3 = peg$c7;
} else { } else {
peg$currPos = s3; peg$currPos = s3;
s3 = peg$c3; s3 = peg$c3;
@ -670,11 +683,11 @@ module.exports = (function() {
peg$currPos++; peg$currPos++;
} else { } else {
s4 = null; s4 = null;
if (peg$silentFails === 0) { peg$fail(peg$c30); } if (peg$silentFails === 0) { peg$fail(peg$c31); }
} }
if (s4 !== null) { if (s4 !== null) {
peg$reportedPos = s2; peg$reportedPos = s2;
s3 = peg$c31(s4); s3 = peg$c32(s4);
if (s3 === null) { if (s3 === null) {
peg$currPos = s2; peg$currPos = s2;
s2 = s3; s2 = s3;
@ -695,7 +708,7 @@ module.exports = (function() {
} }
if (s1 !== null) { if (s1 !== null) {
peg$reportedPos = s0; peg$reportedPos = s0;
s1 = peg$c32(s1); s1 = peg$c33(s1);
} }
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
@ -719,7 +732,7 @@ module.exports = (function() {
s3 = peg$parserd(); s3 = peg$parserd();
if (s3 !== null) { if (s3 !== null) {
peg$reportedPos = s0; peg$reportedPos = s0;
s1 = peg$c34(s2); s1 = peg$c35(s2);
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
s0 = s1; s0 = s1;
@ -741,7 +754,7 @@ module.exports = (function() {
peg$silentFails--; peg$silentFails--;
if (s0 === null) { if (s0 === null) {
s1 = null; s1 = null;
if (peg$silentFails === 0) { peg$fail(peg$c33); } if (peg$silentFails === 0) { peg$fail(peg$c34); }
} }
return s0; return s0;
@ -763,15 +776,15 @@ module.exports = (function() {
s3 = peg$parsetag_end(); s3 = peg$parsetag_end();
if (s3 !== null) { if (s3 !== null) {
peg$reportedPos = peg$currPos; peg$reportedPos = peg$currPos;
s4 = peg$c35(s1,s2,s3); s4 = peg$c36(s1,s2,s3);
if (s4) { if (s4) {
s4 = peg$c13; s4 = peg$c7;
} else { } else {
s4 = peg$c3; s4 = peg$c3;
} }
if (s4 !== null) { if (s4 !== null) {
peg$reportedPos = s0; peg$reportedPos = s0;
s1 = peg$c36(s1,s2,s3); s1 = peg$c37(s1,s2,s3);
if (s1 === null) { if (s1 === null) {
peg$currPos = s0; peg$currPos = s0;
s0 = s1; s0 = s1;
@ -798,6 +811,20 @@ module.exports = (function() {
return s0; 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(); peg$result = peg$startRuleFunction();
if (peg$result !== null && peg$currPos === input.length) { if (peg$result !== null && peg$currPos === input.length) {

View File

@ -64,7 +64,7 @@
return r; return r;
}; };
Contexter.prototype["if"] = function(name, cb) { Contexter.prototype.when = function(name, cb) {
var p; var p;
p = this.has_any_one(name); p = this.has_any_one(name);
if (p) { 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) { Contexter.prototype.block = function(name, cb) {
var p; var p;
p = this.has_any_one(name); p = this.has_any_one(name);

View File

@ -10,9 +10,12 @@ render = (str, options, callback) ->
fromFile = (path, options, callback) -> fromFile = (path, options, callback) ->
fs.readFile path, 'utf8', (err, str) -> fs.readFile path, 'utf8', (err, str) ->
if callback
return callback(err) if err 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 fromFile.render = render
exports = fromFile module.exports = fromFile

View File

@ -1,4 +1,18 @@
// -*- mode: javascript -*- // -*- 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 document
= ps:part* = ps:part*
@ -9,6 +23,7 @@ part
tag_start "tag_start" tag_start "tag_start"
= ld b:tagname ":" n:tagname rd = ld b:tagname ":" n:tagname rd
&{ return is_valid_block_type(b); }
{ return {type: b, name: n }; } { return {type: b, name: n }; }
tag_end tag_end

View File

@ -39,12 +39,18 @@ class Contexter
@depth-- @depth--
r r
if: (name, cb) -> when: (name, cb) ->
# Execute and return this specifiecd block if and only if the # Execute and return this specified block if and only if the
# requested context is valid. # requested context is valid.
p = @has_any_one(name) p = @has_any_one(name)
if p then cb(@) else '' 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) -> block: (name, cb) ->
# Execute and return this specified block if and only if the # Execute and return this specified block if and only if the
# requested context is valid and entrant. # requested context is valid and entrant.