diff --git a/src/parser.js b/src/parser.js index b0ce1769..6aac3d79 100644 --- a/src/parser.js +++ b/src/parser.js @@ -1202,6 +1202,7 @@ var Parser = Object.extend({ data)])); } else if(tok.type === lexer.TOKEN_BLOCK_START) { + this.dropLeadingWhitespace = false; var n = this.parseStatement(); if(!n) { break; @@ -1211,12 +1212,16 @@ var Parser = Object.extend({ else if(tok.type === lexer.TOKEN_VARIABLE_START) { var e = this.parseExpression(); this.advanceAfterVariableEnd(); + this.dropLeadingWhitespace = false; buf.push(new nodes.Output(tok.lineno, tok.colno, [e])); } - else if(tok.type !== lexer.TOKEN_COMMENT) { + else if(tok.type === lexer.TOKEN_COMMENT) { + this.dropLeadingWhitespace = false; + } else { // Ignore comments, otherwise this should be an error this.fail('Unexpected token at top-level: ' + tok.type, tok.lineno, tok.colno); + } } diff --git a/tests/compiler.js b/tests/compiler.js index d3959e58..5f6b3d21 100644 --- a/tests/compiler.js +++ b/tests/compiler.js @@ -1223,5 +1223,25 @@ finish(done); }); + + it('should control whitespaces correctly', function(done) { + equal( + '{% if true -%}{{"hello"}} {{"world"}}{% endif %}', + 'hello world' + ); + + equal( + '{% if true -%}{% if true %} {{"hello"}} {{"world"}}' + + '{% endif %}{% endif %}', + ' hello world' + ); + + equal( + '{% if true -%}{# comment #} {{"hello"}}{% endif %}', + ' hello' + ); + + finish(done); + }); }); })(); diff --git a/tests/parser.js b/tests/parser.js index 0427902e..4bb9bf9e 100644 --- a/tests/parser.js +++ b/tests/parser.js @@ -583,6 +583,46 @@ [nodes.Symbol, 'y']]], [nodes.Output, [nodes.TemplateData, 'hi \n']]]); + + isAST(parser.parse('{% if x -%}{{y}} {{z}}{% endif %}'), + [nodes.Root, + [nodes.If, + [nodes.Symbol, 'x'], + [nodes.NodeList, + [nodes.Output, + [nodes.Symbol, 'y']], + [nodes.Output, + // the value of TemplateData should be ' ' instead of '' + [nodes.TemplateData, ' ']], + [nodes.Output, + [nodes.Symbol, 'z']]]]]); + + isAST(parser.parse('{% if x -%}{% if y %} {{z}}{% endif %}{% endif %}'), + [nodes.Root, + [nodes.If, + [nodes.Symbol, 'x'], + [nodes.NodeList, + [nodes.If, + [nodes.Symbol, 'y'], + [nodes.NodeList, + [nodes.Output, + // the value of TemplateData should be ' ' instead of '' + [nodes.TemplateData, ' ']], + [nodes.Output, + [nodes.Symbol, 'z']] + ]]]]]); + + isAST(parser.parse('{% if x -%}{# comment #} {{z}}{% endif %}'), + [nodes.Root, + [nodes.If, + [nodes.Symbol, 'x'], + [nodes.NodeList, + [nodes.Output, + // the value of TemplateData should be ' ' instead of '' + [nodes.TemplateData, ' ']], + [nodes.Output, + [nodes.Symbol, 'z']]]]]); + }); it('should throw errors', function() {