mirror of
https://github.com/Hopiu/djLint.git
synced 2026-05-26 05:23:42 +00:00
parent
b8dec2ebfb
commit
569f9112ac
9 changed files with 248 additions and 228 deletions
|
|
@ -4,12 +4,16 @@ Changelog
|
|||
Next Release
|
||||
------------
|
||||
- Added rule H020 to find empty tag pairs
|
||||
- Added rule H021 to find inline styles
|
||||
- Added rule H022 to find http links
|
||||
- Added rule H023 to find entity references
|
||||
- Added rule H024 to find type on scripts and styles
|
||||
- Improved attribute formatting
|
||||
- Updated ``blank_line_after_tag`` option to add newline regardless of location
|
||||
- Fixed django ``trans`` tag formatting
|
||||
- Added linter rule H021 to check for inline styles
|
||||
- Added formatting for inline styles
|
||||
- Added formatting for template conditions inside attributes
|
||||
- Added srcset as possible url location in linter rules
|
||||
|
||||
0.5.3
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ Codes
|
|||
+--------+-------------------------------------------------------------------------+
|
||||
| H021 | Inline styles should be avoided. |
|
||||
+--------+-------------------------------------------------------------------------+
|
||||
| H022 | Use HTTPS for external links. |
|
||||
+--------+-------------------------------------------------------------------------+
|
||||
| H023 | Do not use entity references. |
|
||||
+--------+-------------------------------------------------------------------------+
|
||||
| H024 | Omit type on scripts and styles. |
|
||||
+--------+-------------------------------------------------------------------------+
|
||||
|
||||
Adding Rules
|
||||
------------
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@ def format_template_tags(config: Config, attributes: str) -> str:
|
|||
)
|
||||
)[-1]
|
||||
else:
|
||||
# if we don't know where we are, then return what we started with.
|
||||
if not re.findall(
|
||||
re.compile(r"^<\w+[^=\"']\s*", re.M), attributes[: match.start()]
|
||||
):
|
||||
return match.group()
|
||||
|
||||
attr_name = list(
|
||||
re.finditer(
|
||||
re.compile(r"^<\w+[^=\"']\s*", re.M), attributes[: match.start()]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ def indent_html(rawcode: str, config: Config) -> str:
|
|||
is_raw_first_line = False
|
||||
is_block_raw = False
|
||||
|
||||
slt_html = config.break_html_tags
|
||||
slt_html = config.indent_html_tags
|
||||
|
||||
# here using all tags cause we allow empty tags on one line
|
||||
always_slt_html = config.always_single_line_html_tags
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@
|
|||
flags: re.DOTALL
|
||||
# this should be using the static path from django settings
|
||||
patterns:
|
||||
- <(?:link|img|script)\s[^\>]*?(?:href|src)=[\"\']/?static/?
|
||||
- <(?:link|img|script|source)\s[^\>]*?(?:href|src|srcset)=[\"\']/?static/?
|
||||
- rule:
|
||||
name: J004
|
||||
message: (Jinja) Static urls should follow {{ url_for('static'..) }} pattern.
|
||||
flags: re.DOTALL
|
||||
# this should be using the static path from django settings
|
||||
patterns:
|
||||
- <(?:link|img|script)\s[^\>]*?(?:href|src)=[\"\']/?static/?
|
||||
- <(?:link|img|script|source)\s[^\>]*?(?:href|src|srcset)=[\"\']/?static/?
|
||||
- rule:
|
||||
name: H005
|
||||
message: Html tag should have lang attribute.
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
message: Attributes should be double quoted.
|
||||
flags: re.DOTALL|re.I
|
||||
patterns:
|
||||
- (?:class|id|src|width|height|alt|style|lang|title)=\'[^\']*'
|
||||
- (?:class|id|src|width|height|alt|style|lang|title|srcset|media)=\'[^\']*'
|
||||
- rule:
|
||||
name: H009
|
||||
message: Tag names should be lowercase.
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
message: Attribute names should be lowercase.
|
||||
flags: re.DOTALL
|
||||
patterns:
|
||||
- <\w+[^\>]+?(?:CLASS|ID|SRC|WIDTH|HEIGHT|ALT|STYLE|LANG|TITLE)=
|
||||
- <\w+[^\>]+?(?:CLASS|ID|SRC|WIDTH|HEIGHT|ALT|STYLE|LANG|TITLE|MEDIA|SRCSET)=
|
||||
- rule:
|
||||
name: H011
|
||||
message: Attribute values should be quoted.
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
| ul
|
||||
| var
|
||||
| video
|
||||
| wbr)\s+?[^>]*?(?:class|id|src|width|height|alt|style|lang|title|href|action|method|checked|required)=[a-zA-Z_-]+
|
||||
| wbr)\s+?[^>]*?(?:class|id|src|width|height|alt|style|lang|title|href|action|method|checked|required|srcset)=[a-zA-Z_-]+
|
||||
- <(?:meta)\s+?[^>]*?(?:class|id|src|alt|style|lang|title|href|action|method|name)=[a-zA-Z_-]+
|
||||
- rule:
|
||||
name: H012
|
||||
|
|
@ -281,3 +281,21 @@
|
|||
flags: re.I
|
||||
patterns:
|
||||
- <\w+\s[^>]*style(?=[^>]*>)
|
||||
- rule:
|
||||
name: H022
|
||||
message: Use HTTPS for external links.
|
||||
flags: re.I
|
||||
patterns:
|
||||
- <\w+\s[^>]*?(?:href|data-url|action|src|url|srcset)=[\"|']http://[^>]*?>
|
||||
- rule:
|
||||
name: H023
|
||||
message: Do not use entity references.
|
||||
flags: re.I
|
||||
patterns:
|
||||
- '&.{5};'
|
||||
- rule:
|
||||
name: H024
|
||||
message: Omit type on scripts and styles.
|
||||
flags: re.I
|
||||
patterns:
|
||||
- <(?:script|style)[^>]*?type=["|'][^>]*?>
|
||||
|
|
|
|||
|
|
@ -232,6 +232,132 @@ class Config:
|
|||
| {%[ ]djlint:on[ ]%}
|
||||
"""
|
||||
|
||||
# all html tags possible
|
||||
self.indent_html_tags: str = r"""
|
||||
a
|
||||
| abbr
|
||||
| acronym
|
||||
| address
|
||||
| applet
|
||||
| area
|
||||
| article
|
||||
| aside
|
||||
| audio
|
||||
| b
|
||||
| base
|
||||
| basefont
|
||||
| bdi
|
||||
| bdo
|
||||
| big
|
||||
| blockquote
|
||||
| body
|
||||
| br
|
||||
| button
|
||||
| canvas
|
||||
| caption
|
||||
| center
|
||||
| cite
|
||||
| code
|
||||
| col
|
||||
| colgroup
|
||||
| data
|
||||
| datalist
|
||||
| dd
|
||||
| del
|
||||
| details
|
||||
| dfn
|
||||
| dialog
|
||||
| dir
|
||||
| div
|
||||
| dl
|
||||
| dt
|
||||
| em
|
||||
| embed
|
||||
| fieldset
|
||||
| figcaption
|
||||
| figure
|
||||
| font
|
||||
| footer
|
||||
| form
|
||||
| frame
|
||||
| frameset
|
||||
| h1
|
||||
| h2
|
||||
| h3
|
||||
| h4
|
||||
| h5
|
||||
| h6
|
||||
| head
|
||||
| header
|
||||
| hr
|
||||
| html
|
||||
| i
|
||||
| iframe
|
||||
| icon
|
||||
| img
|
||||
| input
|
||||
| ins
|
||||
| kbd
|
||||
| label
|
||||
| legend
|
||||
| li
|
||||
| link
|
||||
| main
|
||||
| map
|
||||
| mark
|
||||
| meta
|
||||
| meter
|
||||
| nav
|
||||
| noframes
|
||||
| noscript
|
||||
| object
|
||||
| ol
|
||||
| optgroup
|
||||
| option
|
||||
| output
|
||||
| p
|
||||
| path
|
||||
| param
|
||||
| picture
|
||||
| progress
|
||||
| q
|
||||
| rp
|
||||
| rt
|
||||
| ruby
|
||||
| s
|
||||
| samp
|
||||
| script
|
||||
| section
|
||||
| select
|
||||
| small
|
||||
| source
|
||||
| span
|
||||
| strike
|
||||
| strong
|
||||
| style
|
||||
| sub
|
||||
| summary
|
||||
| sup
|
||||
| svg
|
||||
| table
|
||||
| tbody
|
||||
| td
|
||||
| template
|
||||
| tfoot
|
||||
| th
|
||||
| thead
|
||||
| time
|
||||
| title
|
||||
| tr
|
||||
| track
|
||||
| tt
|
||||
| u
|
||||
| ul
|
||||
| var
|
||||
| video
|
||||
| wbr
|
||||
"""
|
||||
|
||||
# the contents of these tag blocks will be indented, then unindented
|
||||
self.tag_indent: str = (
|
||||
r"""
|
||||
|
|
@ -258,117 +384,29 @@ class Config:
|
|||
)
|
||||
| (?:<
|
||||
(?:
|
||||
html
|
||||
| head
|
||||
| body
|
||||
| div
|
||||
| a
|
||||
| nav
|
||||
| ul
|
||||
| ol
|
||||
| dl
|
||||
| dd
|
||||
| dt
|
||||
| li
|
||||
| table
|
||||
| thead
|
||||
| tbody
|
||||
| tr
|
||||
| th
|
||||
| td
|
||||
| blockquote
|
||||
| select
|
||||
| i
|
||||
| form
|
||||
| option
|
||||
| cache
|
||||
| optgroup
|
||||
| fieldset
|
||||
| legend
|
||||
| label
|
||||
| header
|
||||
| main
|
||||
| section
|
||||
| aside
|
||||
| footer
|
||||
| figure
|
||||
| figcaption
|
||||
| video
|
||||
| span
|
||||
| p
|
||||
| g
|
||||
| svg
|
||||
| h\d
|
||||
| button
|
||||
| img
|
||||
| path
|
||||
| script
|
||||
| style
|
||||
| details
|
||||
| summary
|
||||
"""
|
||||
+ self.indent_html_tags
|
||||
+ """
|
||||
)
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
self.tag_unindent: str = r"""^
|
||||
self.tag_unindent: str = (
|
||||
r"""^
|
||||
(?:
|
||||
(?:\{\{\/)
|
||||
| (?:\{%-?[ ]*?end)
|
||||
)
|
||||
| (?:</
|
||||
(?:
|
||||
html
|
||||
| head
|
||||
| body
|
||||
| div
|
||||
| a
|
||||
| nav
|
||||
| ul
|
||||
| ol
|
||||
| dl
|
||||
| dd
|
||||
| dt
|
||||
| li
|
||||
| table
|
||||
| thead
|
||||
| tbody
|
||||
| tr
|
||||
| th
|
||||
| td
|
||||
| blockquote
|
||||
| select
|
||||
| form
|
||||
| i
|
||||
| option
|
||||
| optgroup
|
||||
| fieldset
|
||||
| legend
|
||||
| label
|
||||
| header
|
||||
| cache
|
||||
| main
|
||||
| section
|
||||
| aside
|
||||
| footer
|
||||
| figure
|
||||
| figcaption
|
||||
| video
|
||||
| span
|
||||
| p
|
||||
| g
|
||||
| svg
|
||||
| h\d
|
||||
| button
|
||||
| img
|
||||
| path
|
||||
| script
|
||||
| style
|
||||
| details
|
||||
| summary
|
||||
"""
|
||||
+ self.indent_html_tags
|
||||
+ """
|
||||
)
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
# these tags should be unindented and next line will be indented
|
||||
self.tag_unindent_line: str = r"""
|
||||
|
|
@ -540,126 +578,52 @@ class Config:
|
|||
"""
|
||||
|
||||
self.break_html_tags: str = r"""
|
||||
a
|
||||
# | abbr
|
||||
| acronym
|
||||
| address
|
||||
| applet
|
||||
| area
|
||||
| article
|
||||
| aside
|
||||
| audio
|
||||
| b
|
||||
| base
|
||||
| basefont
|
||||
| bdi
|
||||
| bdo
|
||||
| big
|
||||
| blockquote
|
||||
| body
|
||||
| br
|
||||
| button
|
||||
| canvas
|
||||
| caption
|
||||
| center
|
||||
| cite
|
||||
| code
|
||||
| col
|
||||
| colgroup
|
||||
| data
|
||||
| datalist
|
||||
| dd
|
||||
| del
|
||||
| details
|
||||
| dfn
|
||||
| dialog
|
||||
| dir
|
||||
| div
|
||||
| dl
|
||||
| dt
|
||||
# | em
|
||||
| embed
|
||||
| fieldset
|
||||
| figcaption
|
||||
| figure
|
||||
| font
|
||||
| footer
|
||||
| form
|
||||
| frame
|
||||
| frameset
|
||||
| h1
|
||||
| h2
|
||||
| h3
|
||||
| h4
|
||||
| h5
|
||||
| h6
|
||||
html
|
||||
| head
|
||||
| header
|
||||
| hr
|
||||
| html
|
||||
# | i
|
||||
| iframe
|
||||
# | icon
|
||||
| img
|
||||
| input
|
||||
| ins
|
||||
| kbd
|
||||
| label
|
||||
| legend
|
||||
| li
|
||||
| link
|
||||
| main
|
||||
| map
|
||||
| mark
|
||||
| meta
|
||||
| meter
|
||||
| body
|
||||
| div
|
||||
| a
|
||||
| nav
|
||||
| noframes
|
||||
| noscript
|
||||
| object
|
||||
| ol
|
||||
| optgroup
|
||||
| option
|
||||
| output
|
||||
| p
|
||||
| path
|
||||
| param
|
||||
| picture
|
||||
| progress
|
||||
| q
|
||||
| rp
|
||||
| rt
|
||||
| ruby
|
||||
| s
|
||||
| samp
|
||||
| script
|
||||
| section
|
||||
| select
|
||||
# | small
|
||||
| source
|
||||
# | span
|
||||
| strike
|
||||
# | strong
|
||||
| style
|
||||
| sub
|
||||
| summary
|
||||
| sup
|
||||
| svg
|
||||
| table
|
||||
| tbody
|
||||
| td
|
||||
| template
|
||||
| tfoot
|
||||
| th
|
||||
| thead
|
||||
| time
|
||||
| title
|
||||
| tr
|
||||
| track
|
||||
| tt
|
||||
| u
|
||||
| ul
|
||||
| var
|
||||
| ol
|
||||
| dl
|
||||
| dd
|
||||
| dt
|
||||
| li
|
||||
| table
|
||||
| thead
|
||||
| tbody
|
||||
| tr
|
||||
| th
|
||||
| td
|
||||
| blockquote
|
||||
| select
|
||||
| form
|
||||
| option
|
||||
| optgroup
|
||||
| fieldset
|
||||
| legend
|
||||
| label
|
||||
| header
|
||||
| cache
|
||||
| main
|
||||
| section
|
||||
| aside
|
||||
| footer
|
||||
| figure
|
||||
| figcaption
|
||||
| video
|
||||
| wbr
|
||||
| span
|
||||
| p
|
||||
| g
|
||||
| svg
|
||||
| h\d
|
||||
| button
|
||||
| img
|
||||
| path
|
||||
| picture
|
||||
| script
|
||||
| style
|
||||
| details
|
||||
| summary
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ run::
|
|||
|
||||
for a single test, run::
|
||||
|
||||
pytest tests/test_config.py::test_blank_lines_after_tag --cov=src/djlint \
|
||||
pytest tests/test_config.py::test_indent --cov=src/djlint \
|
||||
--cov-branch --cov-report xml:coverage.xml --cov-report term-missing
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -285,6 +285,27 @@ def test_H021(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
assert "H021 1:" in result.output
|
||||
|
||||
|
||||
def test_H022(runner: CliRunner, tmp_file: TextIO) -> None:
|
||||
write_to_file(tmp_file.name, b'<a href="http://">')
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 1
|
||||
assert "H022 1:" in result.output
|
||||
|
||||
|
||||
def test_H023(runner: CliRunner, tmp_file: TextIO) -> None:
|
||||
write_to_file(tmp_file.name, b"—")
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 1
|
||||
assert "H023 1:" in result.output
|
||||
|
||||
|
||||
def test_H024(runner: CliRunner, tmp_file: TextIO) -> None:
|
||||
write_to_file(tmp_file.name, b'<script type="hare">')
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 1
|
||||
assert "H024 1:" in result.output
|
||||
|
||||
|
||||
def test_rules_not_matched_in_ignored_block(
|
||||
runner: CliRunner, tmp_file: TextIO
|
||||
) -> None:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ run::
|
|||
pytest tests/test_nunjucks.py --cov=src/djlint --cov-branch \
|
||||
--cov-report xml:coverage.xml --cov-report term-missing
|
||||
|
||||
pytest tests/test_nunjucks.py::test_spaceless --cov=src/djlint --cov-branch \
|
||||
--cov-report xml:coverage.xml --cov-report term-missing
|
||||
|
||||
"""
|
||||
# pylint: disable=C0116
|
||||
from pathlib import Path
|
||||
|
|
@ -45,12 +48,10 @@ def test_spaceless(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
runner,
|
||||
b"""{%- if entry.children.length -%}<strong>{%- endif -%}""",
|
||||
)
|
||||
assert output["exit_code"] == 1
|
||||
print(output["text"])
|
||||
|
||||
assert output["exit_code"] == 0
|
||||
assert (
|
||||
output["text"]
|
||||
== r"""{%- if entry.children.length -%}
|
||||
<strong>
|
||||
{%- endif -%}
|
||||
== r"""{%- if entry.children.length -%}<strong>{%- endif -%}
|
||||
"""
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue