Permalink
Browse files

macros... work? maybe?

  • Loading branch information...
1 parent bc00398 commit 58db4c9184dcb76dfe740cf5011f95458389c6b2 @paularmstrong committed Sep 24, 2011
Showing with 48 additions and 11 deletions.
  1. +35 −3 lib/parser.js
  2. +2 −0 lib/tags.js
  3. +4 −4 tests/parser.test.js
  4. +7 −4 tests/tags.test.js
View
@@ -23,7 +23,30 @@ function getMethod(input) {
}
function getArgs(input) {
- return JSON.parse('[' + input.replace(/^\w+\(|\)$/g, '').replace(/\\/g, '\\\\').replace(/'/g, '"') + ']');
+ var parts = input.replace(/^\w+\(|\)$/g, '').split(', '),
+ i = parts.length,
+ part = '',
+ partial = '',
+ out = [];
+
+ while (i) {
+ i -= 1;
+ part = parts[i];
+ if ((/^\'|^\"/).test(part) && !(/\"$|\'$/).test(part)) {
+ partial = part;
+ continue;
+ }
+
+ if (partial !== '') {
+ partial += part;
+ if (!(/\"$|\'$/).test(partial)) {
+ continue;
+ }
+ part = partial;
+ }
+ out.push(part);
+ }
+ return parts;
}
function parseVariable(token, escape) {
@@ -203,9 +226,18 @@ exports.compile = function compile(indent, parentBlock) {
}
if (token.type === VAR_TOKEN) {
- var name = token.name.replace(/\W/g, '_');
+ var name = token.name.replace(/\W/g, '_'), args;
code.push('if (typeof ' + name + ' === "function") {');
- code.push('__output.push(' + name + '.apply(null, ' + JSON.stringify(token.args) + '));');
+ if (token.args && token.args.length) {
+ _.each(token.args, function (value, key) {
+ if (helpers.isValidName(value)) {
+ code.push(helpers.setVar('__' + parseVariable(value).name.replace(/\W/g, '_'), parseVariable(value)))
+ token.args[key] = '__' + parseVariable(value).name.replace(/\W/g, '_');
+ }
+ });
+ args = '[' + token.args.join(',') + ']';
+ }
+ code.push('__output.push(' + name + '.apply(null, ' + args + '));');
code.push('} else {');
code.push(helpers.setVar('__' + name, token));
code.push('__output.push(__' + name + ');');
View
@@ -281,7 +281,9 @@ exports.macro = function (indent) {
}
out.push('var ' + macro + ' = function (' + args + ') {');
+ out.push(' var __output = [];');
out.push(parser.compile.call(this, indent + ' '));
+ out.push(' return __output.join("")');
out.push('};');
return out.join('\n' + indent);
View
@@ -99,7 +99,7 @@ exports.Variable = testCase({
test.deepEqual([{ type: parser.TOKEN_TYPES.VAR, name: 'foobar', escape: false, args: null, filters: [{ name: 'awesome', args: [] }] }], output, 'filter by name');
output = parser.parse('{{ foobar|awesome("param", 2) }}');
- test.deepEqual([{ type: parser.TOKEN_TYPES.VAR, name: 'foobar', escape: false, args: null, filters: [{ name: 'awesome', args: ['param', 2] }] }], output, 'filter with params');
+ test.deepEqual([{ type: parser.TOKEN_TYPES.VAR, name: 'foobar', escape: false, args: null, filters: [{ name: 'awesome', args: ['"param"', '2'] }] }], output, 'filter with params');
test.done();
},
@@ -109,7 +109,7 @@ exports.Variable = testCase({
test.deepEqual([{ type: parser.TOKEN_TYPES.VAR, name: 'foobar', escape: false, args: null, filters: [
{ name: 'baz', args: [1] },
{ name: 'rad', args: [] },
- { name: 'awesome', args: ['param', 2] }
+ { name: 'awesome', args: ['"param"', '2'] }
] }], output);
test.done();
@@ -127,15 +127,15 @@ exports.Variable = testCase({
'filters with all kinds of characters in params': function (test) {
var output = parser.parse("{{ foo|blah('01a,;?./¨œ∑´®†][{}]') }}");
test.deepEqual([
- { type: parser.TOKEN_TYPES.VAR, name: 'foo', filters: [{ name: 'blah', args: ["01a,;?./¨œ∑´®†][{}]"] }], escape: false, args: null }
+ { type: parser.TOKEN_TYPES.VAR, name: 'foo', filters: [{ name: 'blah', args: ['\'01a,;?./¨œ∑´®†][{}]\''] }], escape: false, args: null }
], output);
test.done();
},
'escapements carry over in filter args': function (test) {
var output = parser.parse('{{ foo|blah("\\s") }}');
test.deepEqual([
- { type: parser.TOKEN_TYPES.VAR, name: 'foo', filters: [{ name: 'blah', args: ["\\s"] }], escape: false, args: null }
+ { type: parser.TOKEN_TYPES.VAR, name: 'foo', filters: [{ name: 'blah', args: ['"\\s"'] }], escape: false, args: null }
], output);
test.done();
}
View
@@ -188,12 +188,15 @@ exports.macro = testCase({
complex: function (test) {
var tmpl8 = swig.fromString([
- '{% macro foo bar baz bop %}',
- '<input type="{{ bar }}" name="{{ baz }}" id="{{ baz }} value="{{ bop }}">',
+ '{% macro input type name id label value %}',
+ '<label for="{{ name }}">{{ label }}</label>',
+ '<input type="{{ type }}" name="{{ name }}" id="{{ id }}" value="{{ value }}">',
'{% endmacro %}',
- '{{ foo("text", "person", person.id, person.name) }}'
+ '{{ input("text", "person", person.id, "Your Name") }}'
].join(''));
- test.strictEqual(tmpl8.render({ person: { id: 'asdf', name: 'Paul' }}), '<input type="text" name="person" id="asdf" value="Paul">');
+ test.strictEqual(tmpl8.render({
+ person: { id: 'asdf', name: 'Paul' }
+ }), '<label for="person">Your Name</label><input type="text" name="person" id="asdf" value="">');
test.done();
}
});

0 comments on commit 58db4c9

Please sign in to comment.