Update control handling
This commit is contained in:
@@ -533,78 +533,9 @@ def render_micron(content: str, ascii_art_scale: float = 0.75) -> ft.Control:
|
||||
parser = MicronParser(ascii_art_scale=ascii_art_scale)
|
||||
controls = parser.convert_micron_to_controls(content)
|
||||
|
||||
merged_controls = []
|
||||
current_text_parts = []
|
||||
current_style = None
|
||||
|
||||
def flush_text_parts():
|
||||
"""Merge and flush the current text parts into a single Flet Text control,
|
||||
if any, and append to merged_controls.
|
||||
"""
|
||||
nonlocal current_text_parts, current_style
|
||||
if current_text_parts:
|
||||
combined_text = "\n".join(current_text_parts)
|
||||
if current_style:
|
||||
color, bgcolor, weight, decoration, italic, size, text_align = current_style
|
||||
style = ft.TextStyle(
|
||||
color=color,
|
||||
bgcolor=bgcolor,
|
||||
weight=weight,
|
||||
decoration=decoration,
|
||||
italic=italic,
|
||||
size=size,
|
||||
)
|
||||
else:
|
||||
style = None
|
||||
|
||||
merged_controls.append(ft.Text(
|
||||
combined_text,
|
||||
style=style,
|
||||
text_align=text_align if current_style and text_align else "left",
|
||||
selectable=True,
|
||||
enable_interactive_selection=True,
|
||||
expand=True,
|
||||
font_family="monospace",
|
||||
))
|
||||
current_text_parts = []
|
||||
current_style = None
|
||||
|
||||
for control in controls:
|
||||
if isinstance(control, ft.Text) and not hasattr(control, "content"):
|
||||
style = control.style or ft.TextStyle()
|
||||
style_key = (
|
||||
getattr(style, "color", None),
|
||||
getattr(style, "bgcolor", None),
|
||||
getattr(style, "weight", None),
|
||||
getattr(style, "decoration", None),
|
||||
getattr(style, "italic", None),
|
||||
getattr(style, "size", None),
|
||||
getattr(control, "text_align", None),
|
||||
)
|
||||
|
||||
text_content = ""
|
||||
if hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
elif hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
else:
|
||||
text_content = ""
|
||||
|
||||
if style_key == current_style:
|
||||
current_text_parts.append(text_content)
|
||||
else:
|
||||
flush_text_parts()
|
||||
current_style = style_key
|
||||
current_text_parts = [text_content]
|
||||
else:
|
||||
flush_text_parts()
|
||||
merged_controls.append(control)
|
||||
|
||||
flush_text_parts()
|
||||
|
||||
return ft.Container(
|
||||
content=ft.ListView(
|
||||
controls=merged_controls,
|
||||
controls=controls,
|
||||
spacing=2,
|
||||
expand=True,
|
||||
),
|
||||
|
||||
@@ -96,16 +96,32 @@ class TestMicronRenderer:
|
||||
# Should return a Container
|
||||
assert isinstance(result, ft.Container)
|
||||
|
||||
# Should contain Text controls with the content
|
||||
# Should contain controls with the content
|
||||
assert len(result.content.controls) > 0
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
assert isinstance(control, ft.Text)
|
||||
# Extract text from the merged control
|
||||
if hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
# Extract text from the control
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
elif isinstance(control, ft.Container) and hasattr(control, "content"):
|
||||
# Handle indented text controls
|
||||
if isinstance(control.content, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control.content, "value") and control.content.value:
|
||||
text_content = control.content.value
|
||||
elif hasattr(control.content, "spans") and control.content.spans:
|
||||
text_content = "".join(span.text for span in control.content.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
# Should preserve the content
|
||||
# Remove trailing newline and should preserve the content
|
||||
all_text = all_text.rstrip("\n")
|
||||
assert content in all_text
|
||||
|
||||
def test_render_micron_headings(self):
|
||||
@@ -133,10 +149,16 @@ class TestMicronRenderer:
|
||||
# Should produce some text content
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
assert len(all_text) > 0 # Should have some processed content
|
||||
assert len(all_text.strip()) > 0 # Should have some processed content
|
||||
|
||||
def test_render_micron_colors(self):
|
||||
"""Test micron rendering with color codes."""
|
||||
@@ -149,10 +171,16 @@ class TestMicronRenderer:
|
||||
# Should produce some text content (color codes may consume characters)
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
assert len(all_text) > 0 # Should have some processed content
|
||||
assert len(all_text.strip()) > 0 # Should have some processed content
|
||||
|
||||
def test_render_micron_alignment(self):
|
||||
"""Test micron rendering with alignment."""
|
||||
@@ -165,10 +193,16 @@ class TestMicronRenderer:
|
||||
# Should have some text content
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
assert len(all_text) > 0
|
||||
assert len(all_text.strip()) > 0
|
||||
|
||||
def test_render_micron_comments(self):
|
||||
"""Test that comments are ignored."""
|
||||
@@ -179,9 +213,16 @@ class TestMicronRenderer:
|
||||
# Should only contain the visible text, not the comment
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if isinstance(control, ft.Text) and hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
all_text = all_text.strip()
|
||||
assert "Visible text" in all_text
|
||||
assert "This is a comment" not in all_text
|
||||
|
||||
@@ -212,13 +253,20 @@ class TestMicronRenderer:
|
||||
result = render_micron(content)
|
||||
|
||||
assert isinstance(result, ft.Container)
|
||||
# Text gets merged into single control due to text merging
|
||||
assert len(result.content.controls) >= 1
|
||||
# Each line is kept as separate control
|
||||
assert len(result.content.controls) >= 3
|
||||
# Should contain the ASCII art content
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if isinstance(control, ft.Text) and hasattr(control, "value"):
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
all_text = all_text.strip()
|
||||
assert "┌───┐" in all_text
|
||||
assert "Normal text" in all_text
|
||||
|
||||
@@ -231,8 +279,14 @@ class TestMicronRenderer:
|
||||
# Should contain the processed content (literal mode may not be fully implemented)
|
||||
all_text = ""
|
||||
for control in result.content.controls:
|
||||
if isinstance(control, ft.Text) and hasattr(control, "value") and control.value:
|
||||
all_text += control.value
|
||||
if isinstance(control, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
all_text += text_content + "\n"
|
||||
|
||||
# At minimum, should contain some text content
|
||||
assert len(all_text.strip()) > 0
|
||||
@@ -311,13 +365,28 @@ class TestRendererComparison:
|
||||
|
||||
assert plaintext_result.value == content
|
||||
|
||||
# For micron result (Container), extract text from merged controls
|
||||
# For micron result (Container), extract text from controls
|
||||
micron_text = ""
|
||||
for control in micron_result.content.controls:
|
||||
if isinstance(control, ft.Text):
|
||||
# Extract text from the merged control
|
||||
# Extract text from the control
|
||||
text_content = ""
|
||||
if hasattr(control, "value") and control.value:
|
||||
micron_text += control.value + "\n"
|
||||
text_content = control.value
|
||||
elif hasattr(control, "spans") and control.spans:
|
||||
text_content = "".join(span.text for span in control.spans)
|
||||
if text_content:
|
||||
micron_text += text_content + "\n"
|
||||
elif isinstance(control, ft.Container) and hasattr(control, "content"):
|
||||
# Handle indented text controls
|
||||
if isinstance(control.content, ft.Text):
|
||||
text_content = ""
|
||||
if hasattr(control.content, "value") and control.content.value:
|
||||
text_content = control.content.value
|
||||
elif hasattr(control.content, "spans") and control.content.spans:
|
||||
text_content = "".join(span.text for span in control.content.spans)
|
||||
if text_content:
|
||||
micron_text += text_content + "\n"
|
||||
|
||||
# Remove trailing newline and compare
|
||||
micron_text = micron_text.rstrip("\n")
|
||||
@@ -339,7 +408,7 @@ class TestRendererComparison:
|
||||
assert isinstance(micron_result.content, ft.ListView)
|
||||
assert micron_result.content.spacing == 2
|
||||
|
||||
# Check that all Text controls in the column have the expected properties
|
||||
# Check that all Text controls in the ListView have the expected properties
|
||||
for control in micron_result.content.controls:
|
||||
if isinstance(control, ft.Text):
|
||||
assert control.selectable is True
|
||||
|
||||
Reference in New Issue
Block a user