From 9bf64aca03b26143e372f2085362ff4885a17cc7 Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Mon, 22 May 2023 09:51:02 -0500 Subject: [PATCH] feat(formatter): added option to disable newlines after yaml front matter closes #662 --- docs/src/_data/configuration.json | 23 +++++++++++++++++++++++ docs/src/docs/getting-started.md | 2 ++ docs/src/fr/docs/getting-started.md | 2 ++ docs/src/ru/docs/getting-started.md | 2 ++ src/djlint/__init__.py | 7 +++++++ src/djlint/formatter/condense.py | 19 ++++++++++--------- src/djlint/settings.py | 6 +++++- tests/test_html/test_yaml.py | 24 ++++++++++++++++++++---- 8 files changed, 71 insertions(+), 14 deletions(-) diff --git a/docs/src/_data/configuration.json b/docs/src/_data/configuration.json index 62eee6a7e..9200f6c27 100644 --- a/docs/src/_data/configuration.json +++ b/docs/src/_data/configuration.json @@ -1,4 +1,27 @@ [ + { + "name": "no_line_after_yaml", + "description": { + "en": "Do not add a blank line after yaml front matter.", + "ru": "Не добавляйте пустую строку после лицевой части yaml.", + "fr": "N'ajoutez pas de ligne vierge après la matière première yaml." + }, + "usage": [ + { + "name": "pyproject.toml", + "value": "no_line_after_yaml=true" + }, + { + "name": ".djlintrc", + "value": "\"no_line_after_yaml\": true" + }, + { + "name": "cli", + "value": "--no-line-after-yaml" + } + ], + "tags": ["formatter"] + }, { "name": "close_void_tags", "description": { diff --git a/docs/src/docs/getting-started.md b/docs/src/docs/getting-started.md index 9bf1b8690..638fbb7bb 100644 --- a/docs/src/docs/getting-started.md +++ b/docs/src/docs/getting-started.md @@ -79,6 +79,8 @@ Options: --indent-js INTEGER Set JS indent level. --close-void-tags Add closing mark on known void tags. Ex: becomse + --no-line-after-yaml Do not add a blank line after yaml front + matter. -h, --help Show this message and exit. ``` diff --git a/docs/src/fr/docs/getting-started.md b/docs/src/fr/docs/getting-started.md index e6cec4933..f067757a8 100644 --- a/docs/src/fr/docs/getting-started.md +++ b/docs/src/fr/docs/getting-started.md @@ -79,6 +79,8 @@ Options: --indent-js INTEGER Set JS indent level. --close-void-tags Add closing mark on known void tags. Ex: becomse + --no-line-after-yaml Do not add a blank line after yaml front + matter. -h, --help Show this message and exit. ``` diff --git a/docs/src/ru/docs/getting-started.md b/docs/src/ru/docs/getting-started.md index 0348101c0..cd3a843b6 100644 --- a/docs/src/ru/docs/getting-started.md +++ b/docs/src/ru/docs/getting-started.md @@ -79,6 +79,8 @@ Options: --indent-js INTEGER Set JS indent level. --close-void-tags Add closing mark on known void tags. Ex: becomse + --no-line-after-yaml Do not add a blank line after yaml front + matter. -h, --help Show this message and exit. ``` diff --git a/src/djlint/__init__.py b/src/djlint/__init__.py index 7d9daff38..f8b27b93e 100644 --- a/src/djlint/__init__.py +++ b/src/djlint/__init__.py @@ -232,6 +232,11 @@ is_flag=True, help="Add closing mark on known void tags. Ex: becomse ", ) +@click.option( + "--no-line-after-yaml", + is_flag=True, + help="Do not add a blank line after yaml front matter.", +) @colorama_text(autoreset=True) def main( src: List[str], @@ -270,6 +275,7 @@ def main( indent_css: Optional[int], indent_js: Optional[int], close_void_tags: bool, + no_line_after_yaml: bool, ) -> None: """djLint · HTML template linter and formatter.""" config = Config( @@ -309,6 +315,7 @@ def main( indent_css=indent_css, indent_js=indent_js, close_void_tags=close_void_tags, + no_line_after_yaml=no_line_after_yaml, ) temp_file = None diff --git a/src/djlint/formatter/condense.py b/src/djlint/formatter/condense.py index 1ba735808..a2af9e8f9 100644 --- a/src/djlint/formatter/condense.py +++ b/src/djlint/formatter/condense.py @@ -123,15 +123,16 @@ def yaml_add_blank_line_after(html: str, match: re.Match) -> str: return match.group() - func = partial(yaml_add_blank_line_after, html) - html = re.sub( - re.compile( - r"(^---.+?---)$", - re.MULTILINE | re.DOTALL, - ), - func, - html, - ) + if config.no_line_after_yaml is False: + func = partial(yaml_add_blank_line_after, html) + html = re.sub( + re.compile( + r"(^---.+?---)$", + re.MULTILINE | re.DOTALL, + ), + func, + html, + ) return html diff --git a/src/djlint/settings.py b/src/djlint/settings.py index 4bdb227b1..74ac04fde 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -188,7 +188,7 @@ def build_custom_blocks(custom_blocks: Union[str, None]) -> Optional[str]: open_tags = [x.strip() for x in custom_blocks.split(",")] close_tags = ["end" + x.strip() for x in custom_blocks.split(",")] # Group all tags together with a negative lookahead. - tags = set([tag + r"\b" for tag in open_tags + close_tags]) + tags = {tag + r"\b" for tag in open_tags + close_tags} return "|" + "|".join(sorted(tags)) return None @@ -251,6 +251,7 @@ def __init__( indent_css: Optional[int] = None, indent_js: Optional[int] = None, close_void_tags: bool = False, + no_line_after_yaml: bool = False, ): self.reformat = reformat self.check = check @@ -322,6 +323,9 @@ def __init__( self.close_void_tags: bool = close_void_tags or djlint_settings.get( "close_void_tags", False ) + self.no_line_after_yaml: bool = no_line_after_yaml or djlint_settings.get( + "no_line_after_yaml", False + ) # ignore is based on input and also profile self.ignore: str = str(ignore or djlint_settings.get("ignore", "")) diff --git a/tests/test_html/test_yaml.py b/tests/test_html/test_yaml.py index 6c83b4824..9fdcb6b20 100644 --- a/tests/test_html/test_yaml.py +++ b/tests/test_html/test_yaml.py @@ -5,7 +5,7 @@ import pytest from src.djlint.reformat import formatter -from tests.conftest import printer +from tests.conftest import config_builder, printer test_data = [ pytest.param( @@ -30,6 +30,7 @@ " \n" "\n" ), + ({}), id="invalid", ), pytest.param( @@ -49,11 +50,13 @@ " \n" "\n" ), + ({}), id="valid", ), pytest.param( ("---\n" "layout:
\n" "---\n" "
\n"), ("---\n" "layout:
\n" "---\n" "\n" "
\n"), + ({}), id="more", ), pytest.param( @@ -73,26 +76,31 @@ "\n" "

Hello world!

\n" ), + ({}), id="custom_parser", ), pytest.param( ("---\n" "---\n" "

\n" " Hello world!

\n"), ("---\n" "---\n" "\n" "

Hello world!

\n"), + ({}), id="empty", ), pytest.param( ("---\n" "---\n" "
\n" "---\n" "
\n"), ("---\n" "---\n" "\n" "
---
\n"), + ({}), id="empty_2", ), pytest.param( ("---\n" "---\n\n\n" "
\n" "---\n" "
\n"), ("---\n" "---\n" "\n" "
---
\n"), + ({}), id="blank_lines", ), pytest.param( ("---\n" "---\n\n\n\n" "{{ this }}\n"), ("---\n" "---\n" "\n" "{{ this }}\n"), + ({}), id="blank_lines_2", ), pytest.param( @@ -110,6 +118,7 @@ "\n" 'Test abc.\n' ), + ({}), id="issue_9042_no_empty_line", ), pytest.param( @@ -127,14 +136,21 @@ "\n" 'Test abc.\n' ), + ({}), id="issue_9042", ), + pytest.param( + ("---\n" "---\n\n\n\n" "{{ this }}\n"), + ("---\n" "---\n" "{{ this }}\n"), + ({"no_line_after_yaml": True}), + id="blank_lines_2", + ), ] -@pytest.mark.parametrize(("source", "expected"), test_data) -def test_base(source, expected, basic_config): - output = formatter(basic_config, source) +@pytest.mark.parametrize(("source", "expected", "args"), test_data) +def test_base(source, expected, args): + output = formatter(config_builder(args), source) printer(expected, source, output) assert expected == output