Skip to content
This repository has been archived by the owner on Apr 11, 2018. It is now read-only.

Commit

Permalink
Allow variables, filters, arguments to span lines
Browse files Browse the repository at this point in the history
closes gh-122
  • Loading branch information
paularmstrong committed Oct 28, 2012
1 parent 73df080 commit 9b86dbe
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
9 changes: 5 additions & 4 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ exports.isValidBlockName = function (string) {
return (/^[A-Za-z]+[A-Za-z_0-9]*$/).test(string);
};


function stripWhitespace(input) {
return input.replace(/^\s+|\s+$/g, '');
}
exports.stripWhitespace = stripWhitespace;

// the varname is split on (/(\.|\[|\])/) but it may contain keys with dots,
// e.g. obj['hello.there']
Expand Down Expand Up @@ -248,9 +251,7 @@ exports.wrapMethod = function (variable, filter, context) {
args = filter.args.split(',');
args = _.map(args, function (value) {
var varname,
stripped = value.replace(/^\s+/, '');

stripped = stripped.replace(/\s+$/, '');
stripped = value.replace(/^\s+|\s+$/g, '');

try {
varname = '__' + parser.parseVariable(stripped).name.replace(/\W/g, '_');
Expand Down
31 changes: 12 additions & 19 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var helpers = require('./helpers'),
filters = require('./filters'),
_ = require('underscore');

var variableRegexp = /^\{\{.*?\}\}$/,
var variableRegexp = /^\{\{[^\r]*?\}\}$/,
logicRegexp = /^\{%[^\r]*?%\}$/,
commentRegexp = /^\{#[^\r]*?#\}$/,

Expand All @@ -17,15 +17,15 @@ exports.TOKEN_TYPES = {
};

function getMethod(input) {
return input.match(/^[\w\.]+/)[0];
return helpers.stripWhitespace(input).match(/^[\w\.]+/)[0];
}

function doubleEscape(input) {
return input.replace(/\\/g, '\\\\');
}

function getArgs(input) {
return doubleEscape(input.replace(/^[\w\.]+\(|\)$/g, ''));
return doubleEscape(helpers.stripWhitespace(input).replace(/^[\w\.]+\(|\)$/g, ''));
}

function getContextVar(varName, context) {
Expand Down Expand Up @@ -131,33 +131,26 @@ exports.parseVariable = function (token, escape) {
}

var filters = [],
parts = token.replace(/^\{\{ *| *\}\}$/g, '').split('|'),
parts = token.replace(/^\{\{\s*|\s*\}\}$/g, '').split('|'),
varname = parts.shift(),
i = 0,
l = parts.length,
args = null,
filter_name,
part;

if ((/\(/).test(varname)) {
args = getArgs(varname.replace(/^\w+\./, ''));
varname = getMethod(varname);
}

for (i; i < l; i += 1) {
part = parts[i];
_.each(parts, function (part, i) {
if (part && ((/^[\w\.]+\(/).test(part) || (/\)$/).test(part)) && !(/^[\w\.]+\([^\)]*\)$/).test(part)) {
parts[i] += '|' + parts[i + 1];
parts[i] += ((parts[i + 1]) ? '|' + parts[i + 1] : '');
parts[i + 1] = false;
}
}
});
parts = _.without(parts, false);

i = 0;
l = parts.length;
for (i; i < l; i += 1) {
part = parts[i];
filter_name = getMethod(part);
_.each(parts, function (part) {
var filter_name = getMethod(part);
if ((/\(/).test(part)) {
filters.push({
name: filter_name,
Expand All @@ -166,7 +159,7 @@ exports.parseVariable = function (token, escape) {
} else {
filters.push({ name: filter_name, args: '' });
}
}
});

return {
type: VAR_TOKEN,
Expand All @@ -178,7 +171,7 @@ exports.parseVariable = function (token, escape) {
};

exports.parse = function (data, tags, autoescape) {
var rawtokens = data.replace(/(^\s+)|(\s+$)/g, '').split(/(\{%[^\r]*?%\}|\{\{.*?\}\}|\{#[^\r]*?#\})/),
var rawtokens = helpers.stripWhitespace(data).split(/(\{%[^\r]*?%\}|\{\{.*?\}\}|\{#[^\r]*?#\})/),
escape = !!autoescape,
last_escape = escape,
stack = [[]],
Expand Down Expand Up @@ -221,7 +214,7 @@ exports.parse = function (data, tags, autoescape) {
// Ignore empty strings and comments
if (token.length === 0 || commentRegexp.test(token)) {
continue;
} else if (/^(\s|\n)+$/.test(token)) {
} else if (/^\s+$/.test(token)) {
token = token.replace(/ +/, ' ').replace(/\n+/, '\n');
} else if (variableRegexp.test(token)) {
token = exports.parseVariable(token, escape);
Expand Down
19 changes: 19 additions & 0 deletions tests/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ describe('Variables', function () {
expect(parser.parse('{{foobar}}')).to.eql(token);
});

it('can span lines', function () {
expect(parser.parse('{{\n foobar \n}}')).to.eql(token);
});

describe('accepts varying notation', function () {
it('can use dot notation', function () {
expect(swig.compile('{{ a.b.c }}')({ a: { b: { c: 'hi' }} }))
Expand Down Expand Up @@ -400,6 +404,21 @@ describe('Variables', function () {
args: null
}]);
});

it('can have arguments spanning multiple lines', function () {
swig.init({
filters: {
blah: function (value, a, b, c) {
expect(a).to.equal('a');
expect(b).to.equal('b');
expect(c).to.equal('c');
return [a, b, c].join('');
}
}
});
expect(swig.compile("{{ foo\n|\nblah(\n'a', \n'b',\n'c'\n) }}")({ foo: true }))
.to.equal('abc');
});
});
});

Expand Down

0 comments on commit 9b86dbe

Please sign in to comment.