diff --git a/docs/djlint/usage.rst b/docs/djlint/usage.rst
index 63b1fb4..291b7b6 100644
--- a/docs/djlint/usage.rst
+++ b/docs/djlint/usage.rst
@@ -19,7 +19,7 @@ Linter Usage
djlint src -e html.dj
Formatter Usage
------------------
+---------------
Foramtting is a beta tool. ``--check`` the output before applying changes.
@@ -37,6 +37,17 @@ To format code run:
djlint . --reformat --indent=3
+Ignoring Code
+-------------
+
+Code can be skipped by the linter and formatter by wrapping in djlint tags:
+
+.. code:: html
+
+ {% djlint:off %}
+
+ {% djlint:on %}
+
Stdin vs Path
-------------
diff --git a/src/djlint/formatter/expand_html.py b/src/djlint/formatter/expand_html.py
index b773abd..c9b52cf 100644
--- a/src/djlint/formatter/expand_html.py
+++ b/src/djlint/formatter/expand_html.py
@@ -26,9 +26,8 @@ def _should_ignore(config: Config, html: str, match: re.Match) -> bool:
return any(
ignored_match.start() < match.start(1) and ignored_match.end() > match.end(1)
for ignored_match in re.finditer(
- config.ignored_blocks,
+ re.compile(config.ignored_blocks, re.DOTALL | re.IGNORECASE | re.VERBOSE),
html,
- re.DOTALL | re.IGNORECASE | re.VERBOSE,
)
)
diff --git a/src/djlint/lint.py b/src/djlint/lint.py
index 44edcaa..c1f36c5 100644
--- a/src/djlint/lint.py
+++ b/src/djlint/lint.py
@@ -45,6 +45,18 @@ def get_line(start: int, line_ends: List) -> str:
return "%d:%d" % (line_ends.index(line) + 1, start - line["start"])
+# filter out matches that are inside ignored blocks
+def _should_ignore(config: Config, html: str, match: re.Match) -> bool:
+ """Do not add whitespace if the tag is in a non indent block."""
+ return any(
+ ignored_match.start() < match.start() and ignored_match.end() > match.end()
+ for ignored_match in re.finditer(
+ re.compile(config.ignored_blocks, re.DOTALL | re.IGNORECASE | re.VERBOSE),
+ html,
+ )
+ )
+
+
def lint_file(config: Config, this_file: Path) -> Dict:
"""Check file for formatting errors."""
file_name = str(this_file)
@@ -73,14 +85,16 @@ def lint_file(config: Config, this_file: Path) -> Dict:
re.compile(pattern, flags=build_flags(rule.get("flags", "re.DOTALL"))),
html,
):
- errors[file_name].append(
- {
- "code": rule["name"],
- "line": get_line(match.start(), line_ends),
- "match": match.group().strip()[:20],
- "message": rule["message"],
- }
- )
+
+ if _should_ignore(config, html, match) is False:
+ errors[file_name].append(
+ {
+ "code": rule["name"],
+ "line": get_line(match.start(), line_ends),
+ "match": match.group().strip()[:20],
+ "message": rule["message"],
+ }
+ )
# remove duplicate matches
for file_name, error_dict in errors.items():
diff --git a/src/djlint/settings.py b/src/djlint/settings.py
index 8aa2329..7ef1931 100644
--- a/src/djlint/settings.py
+++ b/src/djlint/settings.py
@@ -147,6 +147,7 @@ class Config:
| [^\{]{\#
|
+ | {%[ ]djlint:off[ ]%}.*?{%[ ]djlint:on[ ]%}
|
| {\*.*?\*}
| {\#.*?\#}
diff --git a/tests/test_html.py b/tests/test_html.py
index fcb1048..3679602 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -240,5 +240,45 @@ def test_ignored_block(runner: CliRunner, tmp_file: TextIO) -> None:
+"""
+ )
+
+ # check custom ignore tag {# djlint:off #} {# djlint:on #}
+ output = reformat(
+ tmp_file,
+ runner,
+ b"""{% djlint:off %}
+
+ {% djlint:on %}
+""",
+ )
+
+ assert output["exit_code"] == 0
+
+ assert (
+ output["text"]
+ == """{% djlint:off %}
+
+ {% djlint:on %}
+"""
+ )
+
+ # check script tag
+ output = reformat(
+ tmp_file,
+ runner,
+ b"""
+""",
+ )
+
+ assert output["exit_code"] == 0
+
+ assert (
+ output["text"]
+ == """
"""
)
diff --git a/tests/test_linter.py b/tests/test_linter.py
index e5d711e..bdc8394 100644
--- a/tests/test_linter.py
+++ b/tests/test_linter.py
@@ -5,6 +5,11 @@ run::
pytest tests/test_linter.py --cov=src/djlint --cov-branch \
--cov-report xml:coverage.xml --cov-report term-missing
+ # for a single test
+
+ pytest tests/test_linter.py::test_rules_not_matched_in_ignored_block --cov=src/djlint --cov-branch \
+ --cov-report xml:coverage.xml --cov-report term-missing
+
"""
# pylint: disable=C0116,C0103
@@ -187,3 +192,13 @@ def test_DJ018(runner: CliRunner, tmp_file: TextIO) -> None:
assert result.exit_code == 1
assert "D018 1:" in result.output
assert "J018 1:" in result.output
+
+
+def test_rules_not_matched_in_ignored_block(
+ runner: CliRunner, tmp_file: TextIO
+) -> None:
+ write_to_file(tmp_file.name, b"")
+ result = runner.invoke(djlint, [tmp_file.name])
+ print(result.output)
+ assert result.exit_code == 0
+ assert "H011 1:" not in result.output