Skip to content
Merged
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
14 changes: 11 additions & 3 deletions pytermgui/markup/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,21 @@ def tokenize_ansi( # pylint: disable=too-many-locals, too-many-branches, too-ma
csi = matchobj.groups()[0:2]
link_osc = matchobj.groups()[2:4]

if cursor < start:
yield PlainToken(text[cursor:start])

Comment on lines +204 to +206
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be that this being further up causes us to yield a non-plain link closer as if it was plain (though moving it back down didn't seem to fix things)

if link_osc != (None, None):
cursor = end
uri, label = link_osc

yield HLinkToken(uri)
yield PlainToken(label)
yield ClearToken("/~")

continue

full, content = csi

if cursor < start:
yield PlainToken(text[cursor:start])

cursor = end

code = ""
Expand Down Expand Up @@ -380,6 +381,9 @@ def parse_alias(
def parse_clear(token: ClearToken, _: ContextDict, get_full: Callable[[], str]) -> str:
"""Parses a clearer token."""

if token.value == "/~":
return "\x1b]8;;\x1b\\"

Comment on lines +384 to +386
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the sequence that shows up and AFAIK this is about the only place it's hard-coded, so it's a bit suspicious as well.

(though sometimes it comes up as the full form, other times only 8;;\x1b\\?)

index = CLEARERS.get(token.value)
if index is None:
raise MarkupSyntaxError(
Expand Down Expand Up @@ -513,6 +517,7 @@ def tokens_to_markup(tokens: list[Token]) -> str:
markup += f"[{' '.join(tag.markup for tag in tags)}]"

markup += token.value

tags = []

else:
Expand Down Expand Up @@ -704,6 +709,9 @@ def parse_tokens( # pylint: disable=too-many-branches, too-many-locals, too-man
if token.value in ("/", "/~"):
link = None

if token.value == "/~":
continue

found = False
for macro in macros.copy():
if token.targets(macro):
Expand Down
2 changes: 1 addition & 1 deletion pytermgui/regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import re
from functools import lru_cache

RE_LINK = re.compile(r"(?:\x1b\]8;;([^\\]*)\x1b\\([^\\]*)\x1b\]8;;\x1b\\)")
RE_LINK = re.compile(r"(?:\x1b\]8;;([^\\]*)\x1b\\([^\\]*?)\x1b\]8;;\x1b\\)")
RE_ANSI_NEW = re.compile(rf"(\x1b\[(.*?)[mH])|{RE_LINK.pattern}|(\x1b_G(.*?)\x1b\\)")
RE_ANSI = re.compile(r"(?:\x1b\[(.*?)[mH])|(?:\x1b\](.*?)\x1b\\)|(?:\x1b_G(.*?)\x1b\\)")
RE_MACRO = re.compile(r"(![a-z0-9_\-]+)(?:\(([\w\/\.?\-=:]+)\))?")
Expand Down
24 changes: 23 additions & 1 deletion tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@

import pytest

from pytermgui import StyledText, pretty, tim, tokenize_ansi, tokens_to_markup
from pytermgui import (
StyledText,
pretty,
tim,
tokenize_ansi,
tokens_to_markup,
tokenize_markup,
)
from pytermgui.colors import Color, str_to_color
from pytermgui.markup import StyledText, Token
from pytermgui.markup import tokens as tkns
from pytermgui.markup.parsing import parse_tokens
from pytermgui.markup.style_maps import CLEARERS, STYLES


Expand Down Expand Up @@ -98,6 +106,20 @@ def test_get_markup(self):
markup = tim.get_markup(ansi)
assert base == markup

def test_mutiline_markup(self):
base = "[141 @61 bold]Hello[/]\nWhat a beautifull day to look a this [~https://example.com]website[/~] !\nOh and this [~https://example.com]website also[/~]\nHave a nice day !"
opti_base = "[141 @61 bold]Hello[/]\nWhat a beautifull day to look a this [~https://example.com]website[/~] !\nOh and this [~https://example.com]website also[/~]\nHave a nice day ![/]"

tokens = tokenize_markup(base)
ansi = parse_tokens(list(tokens))
tokens2 = tokenize_ansi(ansi)
markup = tokens_to_markup(list(tokens2))
assert opti_base == markup

ansi = tim.parse(base)
markup = tim.get_markup(ansi)
assert opti_base == markup

def test_parse(self):
assert (
tim.parse("[141 @61 bold !upper]Hello")
Expand Down