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

Relative multi-line HTML elements #83

Merged
merged 3 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
29 changes: 20 additions & 9 deletions djhtml/modes.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,19 @@ def create_token(self, raw_token, src, line):

if raw_token == "<":
if tag := re.match(r"([\w\-\.:]+)", src):
JaapJoris marked this conversation as resolved.
Show resolved Hide resolved
token, mode = Token.Text(raw_token, mode=DjHTML), InsideHTMLTag(
tag[1], line, self
tagname = tag[1]
absolute = True
token = Token.Text(raw_token, mode=DjHTML)
offsets = dict(
relative=-1 if line.indents else 0,
absolute=len(line) + len(tagname) + 2,
)
if tag := re.match(tagname + r"[ \t]*\n", src):
JaapJoris marked this conversation as resolved.
Show resolved Hide resolved
JaapJoris marked this conversation as resolved.
Show resolved Hide resolved
# Use "relative" multi-line indendation instead
absolute = False
token.indents = True
Copy link
Member Author

Choose a reason for hiding this comment

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

Admittedly, this is "cheating" a bit because it changes an "internal" attribute of a token has already been created. It saves a whole bunch of if/else statements though, especially further down where the > token is created.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's avoidable too :).

Edit: after reviewing the handling of >, it still is avoidable here, just not there.

offsets = dict(relative=0, absolute=0)
mode = InsideHTMLTag(tagname, line, self, absolute, offsets)
else:
token = Token.Text(raw_token, mode=DjHTML)
elif raw_token == "<!--":
Expand Down Expand Up @@ -513,17 +523,14 @@ class InsideHTMLTag(DjTXT):

RAW_TOKENS = DjTXT.RAW_TOKENS + [r"/?>", r"[^ ='\">/\n]+=", r'"', r"'"]

def __init__(self, tagname, line, return_mode):
def __init__(self, tagname, line, return_mode, absolute, offsets):
JaapJoris marked this conversation as resolved.
Show resolved Hide resolved
self.tagname = tagname
self.return_mode = return_mode
self.absolute = absolute
self.offsets = offsets
self.token_re = compile_re(self.RAW_TOKENS)
self.inside_attr = False
self.offsets = dict(
relative=-1 if line.indents else 0, absolute=len(line) + len(tagname) + 2
)

# Pff...
self.additional_offset = -len(tagname) - 1
self.additional_offset = -len(tagname) - 1 if absolute else 0

def create_token(self, raw_token, src, line):
mode = self
Expand All @@ -549,6 +556,8 @@ def create_token(self, raw_token, src, line):
token = Token.Text(raw_token, mode=InsideHTMLTag, **self.offsets)
elif not self.inside_attr and raw_token == "/>":
token, mode = Token.Text(raw_token, mode=DjHTML), self.return_mode
if not self.absolute:
Copy link
Contributor

Choose a reason for hiding this comment

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

This is replaceable by an if that return Text or Close depending on self.absolute.

token.dedents = True
elif not self.inside_attr and raw_token == ">":
if self.tagname.lower() in DjHTML.IGNORE_TAGS:
token, mode = Token.Text(raw_token, mode=DjHTML), self.return_mode
Expand All @@ -565,6 +574,8 @@ def create_token(self, raw_token, src, line):
Token.Open(raw_token, mode=DjHTML),
self.return_mode,
)
if not self.absolute:
Copy link
Contributor

Choose a reason for hiding this comment

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

This particular case is indeed problematic without token.dedents. Solveable, but problematic.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't mind "cheating" with tokens this way. It's actually quite elegant, and if we did it everywhere we wouldn't need the separate Open, Close, and CloseAndOpen classes at all. So I'll leave it in just to remind my future self that this is also a possibility.

Thanks for reviewing!

token.dedents = True
else:
token, mode = super().create_token(raw_token, src, line)

Expand Down
63 changes: 37 additions & 26 deletions tests/suite/html.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,18 @@ <h1>Title</h1>
<!-- SVG with multi-line attribute values -->
<svg width="325" height="325" xmlns="http://www.w3.org/2000/svg">
<path
d="M 80 80
A 45 45, 0, 0, 0, 125 125
L 125 80 Z"
fill="green"
d="M 80 80
A 45 45, 0, 0, 0, 125 125
L 125 80 Z"
fill="green"
/>
<path
d="
M 80 80
A 45 45, 0, 0, 0, 125 125
L 125 80 Z
"
fill="green"
d="
M 80 80
A 45 45, 0, 0, 0, 125 125
L 125 80 Z
"
fill="green"
/>
<path d="M 80 80
A 45 45, 0, 0, 0, 125 125
Expand All @@ -161,20 +161,20 @@ <h1>Title</h1>

<!-- Block tags inside HTML elements -->
<div
{% block class %}
class="foo"
{% endblock %}
{% block class %}
class="foo"
{% endblock %}
>
text
</div>

<div
{% block classes %}
class="
foo
bar
"
{% endblock %}
{% block classes %}
class="
foo
bar
"
{% endblock %}
>
text
</div>
Expand Down Expand Up @@ -227,8 +227,8 @@ <h1>Title</h1>
text
</a>
<a
id="2" href=""
class="button">
id="2" href=""
class="button">
text
</a>
<a id="3" href=""
Expand All @@ -237,8 +237,8 @@ <h1>Title</h1>
text
</a>
<a
id="4" href=""
class="button"
id="4" href=""
class="button"
>
text
</a>
Expand Down Expand Up @@ -306,11 +306,11 @@ <h1>Title</h1>

<!-- Weird but legal element names -->
<my-component
hidden/>
hidden/>
<my.component
hidden/>
hidden/>
<my:component
hidden/>
hidden/>


<!-- Multi-line attribute value with additional elements/attributes -->
Expand Down Expand Up @@ -352,3 +352,14 @@ <h1>Title</h1>
class="baz'
"
/>


<!-- Absolute vs. relative mult-line elements -->
<long-html-tag attribute1="value"
attribute2="value"
attribute3="value"/>

<long-html-tag-followed-by-newline
attribute1="value"
attribute2="value"
attribute3="value"/>
Loading