From 578c3810376f822ccb1c6968ee7d0f233f1f1d51 Mon Sep 17 00:00:00 2001 From: Mark Jeromin Date: Tue, 1 Oct 2024 23:42:35 -0400 Subject: [PATCH 1/4] Added linebreak option for indent filter. Fixes #2016 --- src/jinja2/filters.py | 13 ++++++++++--- tests/test_filters.py | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py index 14208770d..8862c262e 100644 --- a/src/jinja2/filters.py +++ b/src/jinja2/filters.py @@ -810,7 +810,11 @@ def do_urlize( def do_indent( - s: str, width: t.Union[int, str] = 4, first: bool = False, blank: bool = False + s: str, + width: t.Union[int, str] = 4, + first: bool = False, + blank: bool = False, + CRLF: bool = False, ) -> str: """Return a copy of the string with each line indented by 4 spaces. The first line and blank lines are not indented by default. @@ -818,6 +822,7 @@ def do_indent( :param width: Number of spaces, or a string, to indent by. :param first: Don't skip indenting the first line. :param blank: Don't skip indenting empty lines. + :param CRLF: Use CRLF line breaks. The default is LF line breaks. .. versionchanged:: 3.0 ``width`` can be a string. @@ -831,8 +836,10 @@ def do_indent( indention = width else: indention = " " * width - - newline = "\n" + if CRLF: + newline = "\r\n" + else: + newline = "\n" if isinstance(s, Markup): indention = Markup(indention) diff --git a/tests/test_filters.py b/tests/test_filters.py index d8e9114d0..f9364fb0c 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -161,14 +161,22 @@ def _test_indent_multiline_template(env, markup=False): text = "\n".join(["", "foo bar", '"baz"', ""]) if markup: text = Markup(text) - t = env.from_string("{{ foo|indent(2, false, false) }}") + t = env.from_string("{{ foo|indent(2, false, false, false) }}") assert t.render(foo=text) == '\n foo bar\n "baz"\n' - t = env.from_string("{{ foo|indent(2, false, true) }}") + t = env.from_string("{{ foo|indent(2, false, false, true) }}") + assert t.render(foo=text) == '\r\n foo bar\r\n "baz"\r\n' + t = env.from_string("{{ foo|indent(2, false, true, false) }}") assert t.render(foo=text) == '\n foo bar\n "baz"\n ' - t = env.from_string("{{ foo|indent(2, true, false) }}") + t = env.from_string("{{ foo|indent(2, false, true, true) }}") + assert t.render(foo=text) == '\r\n foo bar\r\n "baz"\r\n ' + t = env.from_string("{{ foo|indent(2, true, false, false) }}") assert t.render(foo=text) == ' \n foo bar\n "baz"\n' - t = env.from_string("{{ foo|indent(2, true, true) }}") + t = env.from_string("{{ foo|indent(2, true, false, true) }}") + assert t.render(foo=text) == ' \r\n foo bar\r\n "baz"\r\n' + t = env.from_string("{{ foo|indent(2, true, true, false) }}") assert t.render(foo=text) == ' \n foo bar\n "baz"\n ' + t = env.from_string("{{ foo|indent(2, true, true, true) }}") + assert t.render(foo=text) == ' \r\n foo bar\r\n "baz"\r\n ' def test_indent(self, env): self._test_indent_multiline_template(env) From f2777b943331e53d339cffcf408324c684cd0ff0 Mon Sep 17 00:00:00 2001 From: Mark Jeromin Date: Wed, 2 Oct 2024 17:21:49 -0400 Subject: [PATCH 2/4] Reverting changes --- src/jinja2/filters.py | 13 +++---------- tests/test_filters.py | 16 ++++------------ 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py index 8862c262e..14208770d 100644 --- a/src/jinja2/filters.py +++ b/src/jinja2/filters.py @@ -810,11 +810,7 @@ def do_urlize( def do_indent( - s: str, - width: t.Union[int, str] = 4, - first: bool = False, - blank: bool = False, - CRLF: bool = False, + s: str, width: t.Union[int, str] = 4, first: bool = False, blank: bool = False ) -> str: """Return a copy of the string with each line indented by 4 spaces. The first line and blank lines are not indented by default. @@ -822,7 +818,6 @@ def do_indent( :param width: Number of spaces, or a string, to indent by. :param first: Don't skip indenting the first line. :param blank: Don't skip indenting empty lines. - :param CRLF: Use CRLF line breaks. The default is LF line breaks. .. versionchanged:: 3.0 ``width`` can be a string. @@ -836,10 +831,8 @@ def do_indent( indention = width else: indention = " " * width - if CRLF: - newline = "\r\n" - else: - newline = "\n" + + newline = "\n" if isinstance(s, Markup): indention = Markup(indention) diff --git a/tests/test_filters.py b/tests/test_filters.py index f9364fb0c..d8e9114d0 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -161,22 +161,14 @@ def _test_indent_multiline_template(env, markup=False): text = "\n".join(["", "foo bar", '"baz"', ""]) if markup: text = Markup(text) - t = env.from_string("{{ foo|indent(2, false, false, false) }}") + t = env.from_string("{{ foo|indent(2, false, false) }}") assert t.render(foo=text) == '\n foo bar\n "baz"\n' - t = env.from_string("{{ foo|indent(2, false, false, true) }}") - assert t.render(foo=text) == '\r\n foo bar\r\n "baz"\r\n' - t = env.from_string("{{ foo|indent(2, false, true, false) }}") + t = env.from_string("{{ foo|indent(2, false, true) }}") assert t.render(foo=text) == '\n foo bar\n "baz"\n ' - t = env.from_string("{{ foo|indent(2, false, true, true) }}") - assert t.render(foo=text) == '\r\n foo bar\r\n "baz"\r\n ' - t = env.from_string("{{ foo|indent(2, true, false, false) }}") + t = env.from_string("{{ foo|indent(2, true, false) }}") assert t.render(foo=text) == ' \n foo bar\n "baz"\n' - t = env.from_string("{{ foo|indent(2, true, false, true) }}") - assert t.render(foo=text) == ' \r\n foo bar\r\n "baz"\r\n' - t = env.from_string("{{ foo|indent(2, true, true, false) }}") + t = env.from_string("{{ foo|indent(2, true, true) }}") assert t.render(foo=text) == ' \n foo bar\n "baz"\n ' - t = env.from_string("{{ foo|indent(2, true, true, true) }}") - assert t.render(foo=text) == ' \r\n foo bar\r\n "baz"\r\n ' def test_indent(self, env): self._test_indent_multiline_template(env) From 7c1b5c4e861d5be868dfb913e5dc5709410ef8d5 Mon Sep 17 00:00:00 2001 From: Mark Jeromin Date: Thu, 3 Oct 2024 17:06:56 -0400 Subject: [PATCH 3/4] Replaced hardcoded LF with newline_sequence in indent filter. --- src/jinja2/filters.py | 9 +++++++-- tests/test_filters.py | 11 ++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py index 14208770d..d2a753d31 100644 --- a/src/jinja2/filters.py +++ b/src/jinja2/filters.py @@ -809,8 +809,13 @@ def do_urlize( return rv +@pass_environment def do_indent( - s: str, width: t.Union[int, str] = 4, first: bool = False, blank: bool = False + environment: "Environment", + s: str, + width: t.Union[int, str] = 4, + first: bool = False, + blank: bool = False, ) -> str: """Return a copy of the string with each line indented by 4 spaces. The first line and blank lines are not indented by default. @@ -832,7 +837,7 @@ def do_indent( else: indention = " " * width - newline = "\n" + newline = environment.newline_sequence if isinstance(s, Markup): indention = Markup(indention) diff --git a/tests/test_filters.py b/tests/test_filters.py index d8e9114d0..762a037a2 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -158,17 +158,18 @@ def test_format(self, env): @staticmethod def _test_indent_multiline_template(env, markup=False): - text = "\n".join(["", "foo bar", '"baz"', ""]) + newline = env.newline_sequence + text = newline.join(["", "foo bar", '"baz"', ""]) if markup: text = Markup(text) t = env.from_string("{{ foo|indent(2, false, false) }}") - assert t.render(foo=text) == '\n foo bar\n "baz"\n' + assert t.render(foo=text) == f'{newline} foo bar{newline} "baz"{newline}' t = env.from_string("{{ foo|indent(2, false, true) }}") - assert t.render(foo=text) == '\n foo bar\n "baz"\n ' + assert t.render(foo=text) == f'{newline} foo bar{newline} "baz"{newline} ' t = env.from_string("{{ foo|indent(2, true, false) }}") - assert t.render(foo=text) == ' \n foo bar\n "baz"\n' + assert t.render(foo=text) == f' {newline} foo bar{newline} "baz"{newline}' t = env.from_string("{{ foo|indent(2, true, true) }}") - assert t.render(foo=text) == ' \n foo bar\n "baz"\n ' + assert t.render(foo=text) == f' {newline} foo bar{newline} "baz"{newline} ' def test_indent(self, env): self._test_indent_multiline_template(env) From 9899bdedd4b360d426c395528c9cb4255e1def88 Mon Sep 17 00:00:00 2001 From: Mark Jeromin Date: Thu, 3 Oct 2024 17:25:00 -0400 Subject: [PATCH 4/4] Fixed type mismatch error --- src/jinja2/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py index d2a753d31..be4869b55 100644 --- a/src/jinja2/filters.py +++ b/src/jinja2/filters.py @@ -837,7 +837,7 @@ def do_indent( else: indention = " " * width - newline = environment.newline_sequence + newline = str(environment.newline_sequence) if isinstance(s, Markup): indention = Markup(indention)