Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
9 changes: 5 additions & 4 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Changelog

## 4.0.1 (unreleased)


- Nothing changed yet.
## 4.1.0 (unreleased)

- Multiline values for Patternslib data attributes.
Split multiple Patternslib data attribute values into multiple lines. Keep it
single-lined, if there is only one value.
[thet]

## 4.0.0 (2026-04-10)

Expand Down
50 changes: 50 additions & 0 deletions zpretty/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,53 @@ def format_tal_multiline(self, value):
# restore ';;'
return new_value.replace("<>", ";;")

def format_pat_multiline(self, value):
"""Multiple values in Patternslib data-pat-PATTERNNAME attributes
should be formatted multiline.
The separator is `;`, `&&` or `&amp;&amp;` and same with the tal
attributes, a `;;` is a escaped semicolon.
"""

# Temporarily replace escaped semicolon `;;` as it should not be split
_value = value.replace(";;", "<>")
# Prepare for `&&` split
_value = _value.replace("&&", "&&><")
# Prepare for `&amp;&amp;` split
_value = _value.replace("&amp;&amp;", "&&><")
# Prepare for `;` split
_value = _value.replace(";", ";><")

# Split
lines = _value.split("><")

# Strip
lines = [line.strip() for line in lines]
# Filter for empty lines
lines = [line for line in lines if line]

# Don't split single-values
if len(lines) < 2:
return value

try:
line_prefix = self.element.prefix + self.prefix + self._multiline_prefix
except AttributeError:
line_prefix = self._multiline_prefix

# unindent at the end
line_prefix_end = line_prefix[:-2]

# Add line indents
new_value = line_prefix + f"\n{line_prefix}".join(lines)

# restore ';;'
new_value = new_value.replace("<>", ";;")

# Line break at start and end and add end indent.
new_value = f"\n{new_value}\n{line_prefix_end}"

return new_value

def is_tal_attribute(self, name):
"""Check if the attribute is a tal attribute"""
if name.startswith("tal:"):
Expand Down Expand Up @@ -217,6 +264,9 @@ def lines(self):
value = self.format_multiline(name, value)
elif name in self._tal_multiline_attributes:
value = self.format_tal_multiline(value)
# Split Patternslib data attributes.
elif name[:9] == "data-pat-":
value = self.format_pat_multiline(value)
if not value and self.can_be_valueless(name):
line = name
else:
Expand Down
28 changes: 28 additions & 0 deletions zpretty/tests/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,31 @@ def test_format_attributes_many_attribute(self):
)
),
)

def test_data_pat_multiline(self):
"""Patternslib attributes should be split."""
self.assertPrettifiedAttributes(
{"data-pat-testpattern": "a 1; b 2 && c;;3 &amp;&amp; d 4"},
"\n".join(
(
'data-pat-testpattern="',
" a 1;",
" b 2 &amp;&amp;",
" c;;3 &amp;&amp;",
" d 4",
'"',
)
),
)

def test_data_pat_singleline(self):
"""Patternslib data attributes with single values should not be split."""
self.assertPrettifiedAttributes(
{"data-pat-testpattern": "a 1;"}, 'data-pat-testpattern="a 1;"'
)

def test_data_pat_empty(self):
"""Empty Patternslib data attributes should not be split."""
self.assertPrettifiedAttributes(
{"data-pat-testpattern": ""}, "data-pat-testpattern"
)
Loading