Skip to content

Commit

Permalink
Added context passing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason LaPorte committed Aug 13, 2013
1 parent b76783b commit 2d192b3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 10 deletions.
39 changes: 29 additions & 10 deletions lib/template.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
module.exports = function(template) {
return function parse(expr) {
if(typeof expr === "number")
return expr.toString();
function parse(expr, stack) {
var result;

if(typeof expr === "number") {
stack.push(expr);

result = expr.toString();
}

else if(typeof expr === "string") {
stack.push(expr);

if(!template.hasOwnProperty(expr))
throw new Error("\"" + expr + "\" not found in language template.");

Expand All @@ -12,15 +19,15 @@ module.exports = function(template) {
throw new Error("\"" + expr + "\" was used in a value context, but is expected in a template context.");

else
return template[expr];
result = template[expr];
}

else if(typeof template[expr] === "function") {
if(template[expr].length !== 0)
throw new Error("\"" + expr + "\" was used in a value context, but is expected in a template context.");

else
return template[expr]();
result = template[expr].call(stack);
}

else
Expand All @@ -30,12 +37,14 @@ module.exports = function(template) {
else if(Array.isArray(expr) &&
expr.length &&
typeof expr[0] === "string") {
stack.push(expr[0]);

if(!template.hasOwnProperty(expr[0]))
throw new Error("\"" + expr[0] + "\" not found in language template.");

else if(typeof template[expr[0]] === "string")
return template[expr[0]].replace(/\$\d+/g, function(n) {
return parse(expr[n.slice(1)|0]);
result = template[expr[0]].replace(/\$\d+/g, function(n) {
return parse(expr[n.slice(1)|0], stack);
});

else if(typeof template[expr[0]] === "function") {
Expand All @@ -46,9 +55,12 @@ module.exports = function(template) {
throw new Error("Template \"" + expr[0] + "\" did not expect " + (expr.length - 1) + " arguments.");

else
return template[expr[0]].apply(null, expr.slice(1).map(function(arg) {
return parse(arg);
}));
result = template[expr[0]].apply(
stack,
expr.slice(1).map(function(arg) {
return parse(arg, stack);
})
);
}

else
Expand All @@ -57,5 +69,12 @@ module.exports = function(template) {

else
throw new Error("Invalid expression.");

stack.pop();
return result;
};

return function(expr) {
return parse(expr, []);
}
};
31 changes: 31 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,37 @@ describe("translation", function() {
it("should fail to apply a function template given a value", function() {
expect(function() { convert("baz"); }).to.throw();
});

it("should provide context to functions", function() {
var convert = template({
"foo": function(a, b, c) {
expect(this).to.deep.equal(["foo"]);
return "Moop.";
},
"bar": function() {
expect(this).to.deep.equal(["foo", "bar"]);
return "Boop.";
},
"baz": function(a) {
expect(this).to.deep.equal(["foo", "baz"]);
return "Soup.";
},
"quux": function() {
expect(this).to.deep.equal(["foo", "baz", "quux"]);
return "Floop.";
},
"neem": function(a) {
expect(this).to.deep.equal(["foo", "neem"]);
return "Bloop.";
},
"glorp": function(a) {
expect(this).to.deep.equal(["foo", "neem", "glorp"]);
return "Rope?";
}
});

convert(["foo", "bar", ["baz", "quux"], ["neem", ["glorp", 42]]]);
});
});

describe("language", function() {
Expand Down

0 comments on commit 2d192b3

Please sign in to comment.