diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2013-05-19 11:09:19 +0100 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2013-05-19 11:09:19 +0100 |
commit | f3acf0b7b37876775a6f4d8bb3b9b8469c693ba9 (patch) | |
tree | 3871f4d32338b66d3c54f9de170c6c0bc554d498 /jinja2 | |
parent | 840e7e060e3537172c57a8a96cf5bc502f55b67f (diff) | |
parent | 7e912c6dfa7a17dd1334ecb1a8d57dd5722b633a (diff) | |
download | jinja2-f3acf0b7b37876775a6f4d8bb3b9b8469c693ba9.tar.gz |
Merge remote-tracking branch 'wking/keep-trailing-newline'
Diffstat (limited to 'jinja2')
-rw-r--r-- | jinja2/defaults.py | 1 | ||||
-rw-r--r-- | jinja2/environment.py | 17 | ||||
-rw-r--r-- | jinja2/ext.py | 4 | ||||
-rw-r--r-- | jinja2/lexer.py | 13 | ||||
-rw-r--r-- | jinja2/testsuite/lexnparse.py | 13 |
5 files changed, 42 insertions, 6 deletions
diff --git a/jinja2/defaults.py b/jinja2/defaults.py index 3201271..8216450 100644 --- a/jinja2/defaults.py +++ b/jinja2/defaults.py @@ -23,6 +23,7 @@ LINE_STATEMENT_PREFIX = None LINE_COMMENT_PREFIX = None TRIM_BLOCKS = False NEWLINE_SEQUENCE = '\n' +KEEP_TRAILING_NEWLINE = False # default filters, tests and namespace diff --git a/jinja2/environment.py b/jinja2/environment.py index 58573a2..23d00aa 100644 --- a/jinja2/environment.py +++ b/jinja2/environment.py @@ -15,7 +15,8 @@ from jinja2.defaults import BLOCK_START_STRING, \ BLOCK_END_STRING, VARIABLE_START_STRING, VARIABLE_END_STRING, \ COMMENT_START_STRING, COMMENT_END_STRING, LINE_STATEMENT_PREFIX, \ LINE_COMMENT_PREFIX, TRIM_BLOCKS, NEWLINE_SEQUENCE, \ - DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE + DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE, \ + KEEP_TRAILING_NEWLINE from jinja2.lexer import get_lexer, TokenStream from jinja2.parser import Parser from jinja2.optimizer import optimize @@ -147,6 +148,13 @@ class Environment(object): useful default for Linux and OS X systems as well as web applications. + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + `extensions` List of Jinja extensions to use. This can either be import paths as strings or extension classes. For more information have a @@ -232,6 +240,7 @@ class Environment(object): line_comment_prefix=LINE_COMMENT_PREFIX, trim_blocks=TRIM_BLOCKS, newline_sequence=NEWLINE_SEQUENCE, + keep_trailing_newline=KEEP_TRAILING_NEWLINE, extensions=(), optimized=True, undefined=Undefined, @@ -263,6 +272,7 @@ class Environment(object): self.line_comment_prefix = line_comment_prefix self.trim_blocks = trim_blocks self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline # runtime information self.undefined = undefined @@ -828,6 +838,7 @@ class Template(object): line_comment_prefix=LINE_COMMENT_PREFIX, trim_blocks=TRIM_BLOCKS, newline_sequence=NEWLINE_SEQUENCE, + keep_trailing_newline=KEEP_TRAILING_NEWLINE, extensions=(), optimized=True, undefined=Undefined, @@ -837,8 +848,8 @@ class Template(object): block_start_string, block_end_string, variable_start_string, variable_end_string, comment_start_string, comment_end_string, line_statement_prefix, line_comment_prefix, trim_blocks, - newline_sequence, frozenset(extensions), optimized, undefined, - finalize, autoescape, None, 0, False, None) + newline_sequence, keep_trailing_newline, frozenset(extensions), + optimized, undefined, finalize, autoescape, None, 0, False, None) return env.from_string(source, template_class=cls) @classmethod diff --git a/jinja2/ext.py b/jinja2/ext.py index 495e643..651ee98 100644 --- a/jinja2/ext.py +++ b/jinja2/ext.py @@ -589,7 +589,9 @@ def babel_extract(fileobj, keywords, comment_tags, options): options.get('line_statement_prefix') or LINE_STATEMENT_PREFIX, options.get('line_comment_prefix') or LINE_COMMENT_PREFIX, getbool(options, 'trim_blocks', TRIM_BLOCKS), - NEWLINE_SEQUENCE, frozenset(extensions), + NEWLINE_SEQUENCE, + getbool(options, 'keep_trailing_newline', KEEP_TRAILING_NEWLINE), + frozenset(extensions), cache_size=0, auto_reload=False ) diff --git a/jinja2/lexer.py b/jinja2/lexer.py index bd2e861..5594e0a 100644 --- a/jinja2/lexer.py +++ b/jinja2/lexer.py @@ -391,7 +391,8 @@ def get_lexer(environment): environment.line_statement_prefix, environment.line_comment_prefix, environment.trim_blocks, - environment.newline_sequence) + environment.newline_sequence, + environment.keep_trailing_newline) lexer = _lexer_cache.get(key) if lexer is None: lexer = Lexer(environment) @@ -434,6 +435,7 @@ class Lexer(object): block_suffix_re = environment.trim_blocks and '\\n?' or '' self.newline_sequence = environment.newline_sequence + self.keep_trailing_newline = environment.keep_trailing_newline # global lexing rules self.rules = { @@ -557,7 +559,14 @@ class Lexer(object): """This method tokenizes the text and returns the tokens in a generator. Use this method if you just want to tokenize a template. """ - source = '\n'.join(six.text_type(source).splitlines()) + source = six.text_type(source) + lines = source.splitlines() + if self.keep_trailing_newline and source: + for newline in ('\r\n', '\r', '\n'): + if source.endswith(newline): + lines.append('') + break + source = '\n'.join(lines) pos = 0 lineno = 1 stack = ['root'] diff --git a/jinja2/testsuite/lexnparse.py b/jinja2/testsuite/lexnparse.py index f05f601..7022e23 100644 --- a/jinja2/testsuite/lexnparse.py +++ b/jinja2/testsuite/lexnparse.py @@ -108,6 +108,19 @@ class LexerTestCase(JinjaTestCase): result = tmpl.render() assert result.replace(seq, 'X') == '1X2X3X4' + def test_trailing_newline(self): + for keep in [True, False]: + env = Environment(keep_trailing_newline=keep) + for template,expected in [ + ('', {}), + ('no\nnewline', {}), + ('with\nnewline\n', {False: 'with\nnewline'}), + ('with\nseveral\n\n\n', {False: 'with\nseveral\n\n'}), + ]: + tmpl = env.from_string(template) + expect = expected.get(keep, template) + result = tmpl.render() + assert result == expect, (keep, template, result, expect) class ParserTestCase(JinjaTestCase): |