diff --git a/HISTORY.md b/HISTORY.md index 4e0dc5c..f7d6ede 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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) diff --git a/zpretty/attributes.py b/zpretty/attributes.py index 05ec795..3801c96 100644 --- a/zpretty/attributes.py +++ b/zpretty/attributes.py @@ -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 `&&` 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 `&&` split + _value = _value.replace("&&", "&&><") + # 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:"): @@ -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: diff --git a/zpretty/tests/test_attributes.py b/zpretty/tests/test_attributes.py index bcc40a4..57c4816 100644 --- a/zpretty/tests/test_attributes.py +++ b/zpretty/tests/test_attributes.py @@ -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 && d 4"}, + "\n".join( + ( + 'data-pat-testpattern="', + " a 1;", + " b 2 &&", + " c;;3 &&", + " 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" + )