Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jinja formatting issues #715

Merged
merged 7 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion src/djlint/formatter/indent.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nunjucks is pretty much identical to jinja, and anyone else using quotes can benefit from this :) Do you mind to remove the the profile check?

image

aren't cases like this still going to confuse vs code?

The other odd case is where there is a line break:

image

I think if we move this down to where we do the set tag formatting, it will be able to work w/ wrapping.

At the same time it might be good to add a flag --single-quote-templatetags, vs a --single-quote tag we can add later on for just html attributes.

Thanks for starting this, if you don't wanna invest more time you can leave as is and I can pick it up sometime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take a look at it to see if I can improve it further in the ways you suggested.

Specifically by set tag formatting are you referring to?
image

In reference to this photo
image
I'm not 100% how we could remedy this yet.

I'll think on some things and take a look at this tomorrow.

Copy link
Contributor Author

@jessielw jessielw Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you must be referring to for the set tag
image

If this is not correct please point me where you think i should impliment thr changes

I'll look into this and see if I can improve it further.

As far as the linter for
<a href='{{ url("fo\"o") }}'></a>
what would you suggest to improve this?

.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey sorry for the delay, yep I think this is the place- it is where the contents of functions are updated.

I'm free to discord call early afternoon today if it's good for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to add me on discord jlw_4049 so we can talk quicker

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
in_set_tag = False
is_raw_first_line = False
is_block_raw = False
jinja_replace_list = []

slt_html = config.indent_html_tags

Expand Down Expand Up @@ -320,6 +321,19 @@
if ignored_level == 0:
is_block_raw = False

# detect the outer quotes for jinja
if config.profile == "jinja":
matches = re.findall(
r"=([\"'])(\{\{[\s\S]*?\}\})\1", tmp, flags=re.MULTILINE
)

for match in matches:
outer_quotes = match[0]
inner_content = match[1]
jinja_replace_list.append(

Check warning on line 333 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L331-L333

Added lines #L331 - L333 were not covered by tests
{"outer_quote": outer_quotes, "content": inner_content}
)

beautified_code = beautified_code + tmp

# try to fix internal formatting of set tag
Expand Down Expand Up @@ -396,7 +410,41 @@
leading_space,
)

return f"{leading_space}{open_bracket} {tag}({contents}){index} {close_bracket}"
# # define cleaned match with both quote styles
cleaned_match = (
f"{leading_space}{open_bracket} {tag}({contents}){index} {close_bracket}"
)

if config.profile == "jinja":
outer_quotes = None
inner_quotes = None

# Determine user quote type
for jinja_content in jinja_replace_list:
content = cleaned_match.replace('"', "'") # Replace double quotes

Check warning on line 424 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L424

Added line #L424 was not covered by tests
if content == jinja_content.get("content"):
outer_quotes = jinja_content.get("outer_quote")
inner_quotes = "'" if outer_quotes == '"' else '"'
break
content = cleaned_match.replace("'", '"') # Replace single quotes

Check warning on line 429 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L426-L429

Added lines #L426 - L429 were not covered by tests
if content == jinja_content.get("content"):
outer_quotes = jinja_content.get("outer_quote")
inner_quotes = '"' if outer_quotes == "'" else "'"
break

Check warning on line 433 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L431-L433

Added lines #L431 - L433 were not covered by tests

if outer_quotes is not None and inner_quotes is not None:
# Replace all content inner quotes and remove trailing/leading spaces
cleaned_contents = re.sub(

Check warning on line 437 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L437

Added line #L437 was not covered by tests
rf"(?<=\{re.escape(outer_quotes)})\s+|\s+(?=\{re.escape(outer_quotes)})",
"",
contents.replace(outer_quotes, inner_quotes),
)

# Update cleaned match
cleaned_match = f"{leading_space}{open_bracket} {tag}({cleaned_contents}){index} {close_bracket}"
cleaned_match = cleaned_match.strip()

Check warning on line 445 in src/djlint/formatter/indent.py

View check run for this annotation

Codecov / codecov/patch

src/djlint/formatter/indent.py#L444-L445

Added lines #L444 - L445 were not covered by tests

return cleaned_match

if config.no_set_formatting is False:
func = partial(format_set, config, beautified_code)
Expand Down
20 changes: 13 additions & 7 deletions tests/test_jinja/test_parenthesis.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, instead of changing the test here, can you just do 2 tests?

Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@

test_data = [
pytest.param(
("{{ url('foo')}}"),
('{{ url("foo") }}\n'),
"{{ url('foo') }}",
"{{ url('foo') }}\n",
'{{ url("foo") }}\n',
id="parenthesis_tag",
),
)
]


@pytest.mark.parametrize(("source", "expected"), test_data)
def test_base(source, expected, jinja_config):
@pytest.mark.parametrize(("source", "expected1", "expected2"), test_data)
def test_base(source, expected1, expected2, jinja_config):
output = formatter(jinja_config, source)

printer(expected, source, output)
assert expected == output
printer(expected1, source, output)
assert expected1 == output or expected2 == output

output = formatter(jinja_config, source)

printer(expected2, source, output)
assert expected1 == output or expected2 == output
Loading