diff --git a/docs/src/_data/configuration.json b/docs/src/_data/configuration.json index ebb08f0c0..62eee6a7e 100644 --- a/docs/src/_data/configuration.json +++ b/docs/src/_data/configuration.json @@ -275,6 +275,29 @@ } ] }, + { + "name": "line_break_after_multiline_tag", + "tags": ["formatter"], + "description": { + "en": "Do not condense the content of multi-line tags into the line of the last attribute.", + "ru": "Не сжимайте содержимое многострочных тегов в строку последнего атрибута.", + "fr": "Ne pas condenser le contenu des balises multilignes dans la ligne du dernier attribut." + }, + "usage": [ + { + "name": "pyproject.toml", + "value": "line_break_after_multiline_tag=true" + }, + { + "name": ".djlintrc", + "value": "\"line_break_after_multiline_tag\": \"true\"" + }, + { + "name": "cli", + "value": "--line-break-after-multiline-tag" + } + ] + }, { "name": "profile", "tags": ["linter", "formatter"], diff --git a/src/djlint/__init__.py b/src/djlint/__init__.py index 5e454cafd..7d9daff38 100644 --- a/src/djlint/__init__.py +++ b/src/djlint/__init__.py @@ -157,6 +157,11 @@ default="", help="Add an additional blank line before {% ... %} tag groups.", ) +@click.option( + "--line-break-after-multiline-tag", + is_flag=True, + help="Do not condense the content of multi-line tags into the line of the last attribute.", +) @click.option( "--custom-blocks", type=str, @@ -252,6 +257,7 @@ def main( ignore_blocks: str, blank_line_after_tag: str, blank_line_before_tag: str, + line_break_after_multiline_tag: bool, custom_blocks: str, custom_html: str, exclude: str, @@ -290,6 +296,7 @@ def main( ignore_blocks=ignore_blocks, blank_line_after_tag=blank_line_after_tag, blank_line_before_tag=blank_line_before_tag, + line_break_after_multiline_tag=line_break_after_multiline_tag, custom_blocks=custom_blocks, custom_html=custom_html, exclude=exclude, diff --git a/src/djlint/formatter/condense.py b/src/djlint/formatter/condense.py index eaf4b6cdf..1ba735808 100644 --- a/src/djlint/formatter/condense.py +++ b/src/djlint/formatter/condense.py @@ -145,12 +145,17 @@ def condense_html(html, config): def condense_line(config: Config, html: str, match: re.Match) -> str: """Put contents on a single line if below max line length.""" + # match.group(1) contains the opening tag, which may be split over multiple lines + if config.line_break_after_multiline_tag: + combined_length = len(match.group(1) + match.group(3) + match.group(4)) + else: + combined_length = len( + match.group(1).splitlines()[-1] + match.group(3) + match.group(4) + ) + if ( not inside_ignored_block(config, html, match) - and ( - len(match.group(1).splitlines()[-1] + match.group(3) + match.group(4)) - < config.max_line_length - ) + and combined_length < config.max_line_length and if_blank_line_after_match(config, match.group(3)) and if_blank_line_before_match(config, match.group(3)) ): diff --git a/src/djlint/formatter/expand.py b/src/djlint/formatter/expand.py index d661dcfcd..f435143f3 100644 --- a/src/djlint/formatter/expand.py +++ b/src/djlint/formatter/expand.py @@ -20,7 +20,7 @@ def add_html_line(out_format: str, match: re.Match) -> str: Do not add whitespace if the tag is in a non indent block. - Do not add whiatespace if the tag is a in a template block + Do not add whitespace if the tag is a in a template block """ if inside_ignored_block(config, html, match): return match.group(1) diff --git a/src/djlint/rules.yaml b/src/djlint/rules.yaml index ad12c3cf8..790356596 100644 --- a/src/djlint/rules.yaml +++ b/src/djlint/rules.yaml @@ -276,4 +276,4 @@ message: Duplicate attribute found. flags: re.I patterns: - - <\w[^>]*?\s([a-z][a-z-]*?)(?==.+?\1=[^>]*?>) + - <\w[^>]*?\s\K([a-z][a-z-]*?)(?==[^>]+?\1=[^>]*?>) diff --git a/src/djlint/settings.py b/src/djlint/settings.py index e7a250618..4d4dec80d 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -237,6 +237,7 @@ def __init__( custom_blocks: str = "", blank_line_after_tag: str = "", blank_line_before_tag: str = "", + line_break_after_multiline_tag: bool = False, custom_html: str = "", exclude: str = "", extend_exclude: str = "", @@ -435,6 +436,12 @@ def __init__( str ] = blank_line_before_tag or djlint_settings.get("blank_line_before_tag", None) + # add line break after multi-line tags + self.line_break_after_multiline_tag: bool = ( + line_break_after_multiline_tag + or djlint_settings.get("line_break_after_multiline_tag", False) + ) + # contents of tags will not be formatted self.ignored_block_opening: str = r"""