| @@ -122,7 +122,7 @@ | |||
| function parseTemplate (template, tags) { | |||
| if (!template) | |||
| return []; | |||
| var firstNonSpace = true; | |||
| var sections = []; // Stack to hold section tokens | |||
| var tokens = []; // Buffer to hold the tokens | |||
| var spaces = []; // Indices of whitespace tokens on the current line | |||
| @@ -175,10 +175,11 @@ | |||
| if (isWhitespace(chr)) { | |||
| spaces.push(tokens.length); | |||
| if (!nonSpace) | |||
| indentation += chr; | |||
| indentation += chr; | |||
| } else { | |||
| nonSpace = true; | |||
| firstNonSpace = false; | |||
| indentation += ' '; | |||
| } | |||
| tokens.push([ 'text', chr, start, start + 1 ]); | |||
| @@ -189,6 +190,7 @@ | |||
| stripSpace(); | |||
| indentation = ''; | |||
| tagIndex = 0; | |||
| firstNonSpace = true; | |||
| } | |||
| } | |||
| } | |||
| @@ -222,7 +224,7 @@ | |||
| throw new Error('Unclosed tag at ' + scanner.pos); | |||
| if (type == '>') { | |||
| token = [ type, value, start, scanner.pos, indentation, tagIndex ]; | |||
| token = [ type, value, start, scanner.pos, indentation, tagIndex, firstNonSpace ]; | |||
| } else { | |||
| token = [ type, value, start, scanner.pos ]; | |||
| } | |||
| @@ -610,11 +612,11 @@ | |||
| return this.renderTokens(token[4], context, partials, originalTemplate); | |||
| }; | |||
| Writer.prototype.indentPartial = function indentPartial (partial, indentation) { | |||
| Writer.prototype.indentPartial = function indentPartial (partial, indentation, firstNonSpace) { | |||
| var filteredIndentation = indentation.replace(/[^ \t]/g, ''); | |||
| var partialByNl = partial.split('\n'); | |||
| for (var i = 0; i < partialByNl.length; i++) { | |||
| if (partialByNl[i].length) { | |||
| if (partialByNl[i].length && (i > 0 || firstNonSpace)) { | |||
| partialByNl[i] = filteredIndentation + partialByNl[i]; | |||
| } | |||
| } | |||
| @@ -626,11 +628,12 @@ | |||
| var value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; | |||
| if (value != null) { | |||
| var firstNonSpace = token[6]; | |||
| var tagIndex = token[5]; | |||
| var indentation = token[4]; | |||
| var indentedValue = value; | |||
| if (tagIndex == 0 && indentation) { | |||
| indentedValue = this.indentPartial(value, indentation); | |||
| indentedValue = this.indentPartial(value, indentation, firstNonSpace); | |||
| } | |||
| return this.renderTokens(this.parse(indentedValue, tags), context, partials, indentedValue); | |||
| } | |||
| @@ -40,12 +40,12 @@ var expectations = { | |||
| 'a\n{{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [ [ '#', 'b', 9, 15, [], 16 ] ], 23 ], [ 'text', 'b', 30, 31 ] ], | |||
| 'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 31, 32 ] ], | |||
| 'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 32, 33 ] ], | |||
| '{{>abc}}' : [ [ '>', 'abc', 0, 8, '', 0 ] ], | |||
| '{{> abc }}' : [ [ '>', 'abc', 0, 10, '', 0 ] ], | |||
| '{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0 ] ], | |||
| ' {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0 ] ], | |||
| ' {{> abc }} {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0 ], [ '>', 'abc', 13, 23, ' ', 1 ] ], | |||
| '{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0 ] ], | |||
| '{{>abc}}' : [ [ '>', 'abc', 0, 8, '', 0, true ] ], | |||
| '{{> abc }}' : [ [ '>', 'abc', 0, 10, '', 0, true ] ], | |||
| '{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0, true ] ], | |||
| ' {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, true ] ], | |||
| ' {{> abc }} {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, true ], [ '>', 'abc', 13, 23, ' ', 1, true ] ], | |||
| '{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0, true ] ], | |||
| '{{=<% %>=}}' : [ [ '=', '<% %>', 0, 11 ] ], | |||
| '{{= <% %> =}}' : [ [ '=', '<% %>', 0, 13 ] ], | |||
| '{{=<% %>=}}<%={{ }}=%>' : [ [ '=', '<% %>', 0, 11 ], [ '=', '{{ }}', 11, 22 ] ], | |||
| @@ -31,6 +31,24 @@ describe('Partials spec', function () { | |||
| var renderResult = Mustache.render(template, data, partials); | |||
| assert.equal(renderResult, expected); | |||
| }); | |||
| it('Inline partials should not be indented', function () { | |||
| var template = ' <div>{{> partial}}</div>'; | |||
| var data = {}; | |||
| var partials = {'partial':'This is a partial.'}; | |||
| var expected = ' <div>This is a partial.</div>'; | |||
| var renderResult = Mustache.render(template, data, partials); | |||
| assert.equal(renderResult, expected); | |||
| }); | |||
| it('Inline partials should not be indented (multiline)', function () { | |||
| var template = ' <div>{{> partial}}</div>'; | |||
| var data = {}; | |||
| var partials = {'partial':'This is a\npartial.'}; | |||
| var expected = ' <div>This is a\n partial.</div>'; | |||
| var renderResult = Mustache.render(template, data, partials); | |||
| assert.equal(renderResult, expected); | |||
| }); | |||
| it('The greater-than operator should properly recurse.', function () { | |||
| var template = '{{>node}}'; | |||
| var data = {'content':'X','nodes':[{'content':'Y','nodes':[]}]}; | |||