Fix pretty printing
This commit is contained in:
56
sia/util.py
56
sia/util.py
@@ -1,5 +1,6 @@
|
||||
from typing import Iterator
|
||||
import xml.dom.minidom
|
||||
import xml.etree.ElementTree as ET
|
||||
from typing import Iterator, Optional
|
||||
|
||||
def stop_before_value(iterator: Iterator[str], stop_value: str) -> Iterator[str]:
|
||||
"""
|
||||
@@ -22,6 +23,57 @@ def stop_before_value(iterator: Iterator[str], stop_value: str) -> Iterator[str]
|
||||
break
|
||||
yield item
|
||||
|
||||
def escape_text_for_xml(text: str) -> str:
|
||||
"""Convert any value to string representation for XML storage."""
|
||||
if text is None:
|
||||
return ''
|
||||
return str(text)
|
||||
|
||||
def pretty_print_element(elem: ET.Element, level: int = 0, max_line: int = 80) -> str:
|
||||
"""Convert ElementTree element to pretty-printed string with custom formatting."""
|
||||
indent = ' ' * level
|
||||
|
||||
# Handle empty elements
|
||||
if not elem.text and not elem.tail and not elem.attrib and len(elem) == 0:
|
||||
return f'{indent}<{elem.tag}/>'
|
||||
|
||||
# Build opening tag with attributes
|
||||
tag = elem.tag
|
||||
attrs = elem.attrib
|
||||
if attrs:
|
||||
attr_strings = [f'{k}="{v}"' for k, v in sorted(attrs.items())]
|
||||
attr_str = ' ' + ' '.join(attr_strings)
|
||||
|
||||
if len(indent) + len(tag) + len(attr_str) + 2 > max_line:
|
||||
attr_indent = indent + ' '
|
||||
attr_str = '\n' + '\n'.join(f'{attr_indent}{a}' for a in attr_strings)
|
||||
else:
|
||||
attr_str = ''
|
||||
|
||||
parts = [f'{indent}<{tag}{attr_str}>']
|
||||
|
||||
# Handle text content
|
||||
if elem.text and elem.text.strip():
|
||||
text = elem.text
|
||||
if ']]>' in text:
|
||||
escaped = text.replace('&', '&') \
|
||||
.replace('<', '<') \
|
||||
.replace('>', '>') \
|
||||
.replace('"', '"') \
|
||||
.replace("'", ''')
|
||||
parts.append(f'{indent} {escaped}')
|
||||
else:
|
||||
parts.append(f'{indent} <![CDATA[{text}]]>')
|
||||
|
||||
# Handle children
|
||||
for child in elem:
|
||||
parts.append(pretty_print_element(child, level + 1, max_line))
|
||||
if child.tail and child.tail.strip():
|
||||
parts.append(f'{indent} {child.tail}')
|
||||
|
||||
parts.append(f'{indent}</{tag}>')
|
||||
return '\n'.join(parts)
|
||||
|
||||
def escape_text_for_xml(text: str) -> str:
|
||||
"""
|
||||
Convert any text value to a properly escaped XML string.
|
||||
@@ -47,4 +99,4 @@ def escape_text_for_xml(text: str) -> str:
|
||||
.replace("'", ''')
|
||||
|
||||
# Otherwise wrap in CDATA
|
||||
return f'<![CDATA[{text_str}]]>'
|
||||
return f'<![CDATA[{text_str}]]>'
|
||||
|
||||
Reference in New Issue
Block a user