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
56 changes: 35 additions & 21 deletions src/textual/markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,32 +408,46 @@ def process_text(template_text: str, /) -> str:

elif token_name == "open_closing_tag":
tag_text = []

eof = False
for token in iter_tokens:
if token.name == "end_tag":
break
elif token.name == "eof":
eof = True
tag_text.append(token.value)
closing_tag = "".join(tag_text).strip()
normalized_closing_tag = normalize_markup_tag(closing_tag)
if normalized_closing_tag:
for index, (tag_position, tag_body, normalized_tag_body) in enumerate(
reversed(style_stack), 1
):
if normalized_tag_body == normalized_closing_tag:
style_stack.pop(-index)
if tag_position != position:
spans.append(Span(tag_position, position, tag_body))
break
else:
raise MarkupError(
f"closing tag '[/{closing_tag}]' does not match any open tag"
)

if eof:
# "tag" was unparsable
text_content = f"[/{''.join(tag_text)}"
text_append(text_content)
position += len(text_content)
else:
if not style_stack:
raise MarkupError("auto closing tag ('[/]') has nothing to close")
open_position, tag_body, _ = style_stack.pop()
if open_position != position:
spans.append(Span(open_position, position, tag_body))
closing_tag = "".join(tag_text).strip()
normalized_closing_tag = normalize_markup_tag(closing_tag)
if normalized_closing_tag:
for index, (
tag_position,
tag_body,
normalized_tag_body,
) in enumerate(reversed(style_stack), 1):
if normalized_tag_body == normalized_closing_tag:
style_stack.pop(-index)
if tag_position != position:
spans.append(Span(tag_position, position, tag_body))
break
else:
raise MarkupError(
f"closing tag '[/{closing_tag}]' does not match any open tag"
)

else:
if not style_stack:
raise MarkupError(
"auto closing tag ('[/]') has nothing to close"
)
open_position, tag_body, _ = style_stack.pop()
if open_position != position:
spans.append(Span(open_position, position, tag_body))

content_text = "".join(text)
text_length = len(content_text)
Expand Down
1 change: 1 addition & 0 deletions tests/test_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ def test_assemble():
("\\[/foo]", "[/foo]"),
("\\[]", "[]"),
("\\[0]", "[0]"),
("\\[/", "[/"),
],
)
def test_escape(markup: str, plain: str) -> None:
Expand Down
2 changes: 2 additions & 0 deletions tests/test_markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
("[0]", Content("[0]")),
("[red", Content("[red")),
("[red]", Content("")),
("[/", Content("[/")),
("[/red", Content("[/red")),
("foo", Content("foo")),
("foo\n", Content("foo\n")),
("foo\nbar", Content("foo\nbar")),
Expand Down
Loading