Skip to content

Commit

Permalink
Relative multi-line HTML elements
Browse files Browse the repository at this point in the history
Reintroduces "relative multi-line" indentation to DjHTML:

    <long-html-tag
        attribute1="value"
        attribute2="value"
        attribute3="value"/>

However, this only happens when the tag name is followed by a newline.
Otherwise, "absolute multi-line" indentation will be used:

    <long-html-tag attribute1="value"
                   attribute2="value"
                   attribute3="value"/>

This is a good rule, but also the last rule I'm willing to add regarding
multi-line indentation. Our users deserve a stable set of indentation
principles, and this is it. No more bikeshedding.
  • Loading branch information
JaapJoris committed Feb 23, 2023
1 parent 041f3ac commit aee3d7d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 72 deletions.
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):
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"*\n", src):
# Use "relative" multi-line indendation instead
absolute = False
token.indents = True
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):
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:
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:
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

0 comments on commit aee3d7d

Please sign in to comment.