Skip to content

Commit

Permalink
Added support for li value attribute, ol start and reverse attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
danschwarz committed May 16, 2023
1 parent fe88a40 commit b3c654b
Showing 1 changed file with 61 additions and 19 deletions.
80 changes: 61 additions & 19 deletions toot/tui/richtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def html_to_widgets(self, html, recovery_attempt=False) -> List[urwid.Widget]:
"h4",
"h5",
"h6",
)
) # NOTE: update this list if Mastodon starts supporting more block tags
):
return self.html_to_widgets(f"<p>{html}</p>", recovery_attempt=True)

Expand Down Expand Up @@ -113,6 +113,7 @@ def text_to_widget(self, attr, markup) -> TextEmbed:
for run in markup:
if isinstance(run, tuple):
txt, attr_list = decompose_tagmarkup(run)
# find anchor titles with an ETX separator followed by href
m = re.match(r"(^.+)\x03(.+$)", txt)
if m:
anchor_attr = self.get_best_anchor_attr(attr_list)
Expand Down Expand Up @@ -220,6 +221,8 @@ def get_best_anchor_attr(self, attrib_list) -> str:
return "a"

def _a(self, tag) -> Tuple:
"""anchor tag handler"""

markups = self.process_inline_tag_children(tag)
if not markups:
return (tag.name, "")
Expand All @@ -229,6 +232,8 @@ def _a(self, tag) -> Tuple:
if not attrib_list:
attrib_list = [tag]
if href:
# use ASCII ETX (end of record) as a
# delimiter between the title and the HREF
title += f"\x03{href}"

attr = self.get_best_anchor_attr(attrib_list)
Expand Down Expand Up @@ -282,7 +287,46 @@ def _em(self, tag) -> Tuple:
return ("i", markups)

def _ol(self, tag) -> urwid.Widget:
return self.list_widget(tag, ordered=True)
"""ordered list tag handler"""

widgets = []
list_item_num = 1
increment = -1 if tag.has_attr("reversed") else 1

# get ol start= attribute if present
if tag.has_attr("start") and len(tag.attrs["start"]) > 0:
try:
list_item_num = int(tag.attrs["start"])
except ValueError:
pass

for li in tag.find_all("li", recursive=False):
method = getattr(self, "_li", self.inline_tag_to_text)
markup = method(li)

# li value= attribute will change the item number
# it also overrides any ol start= attribute

if li.has_attr("value") and len(li.attrs["value"]) > 0:
try:
list_item_num = int(li.attrs["value"])
except ValueError:
pass

if not isinstance(markup, urwid.Widget):
txt = self.text_to_widget("li", [str(list_item_num), ". ", markup])
# 1. foo, 2. bar, etc.
widgets.append(txt)
else:
txt = self.text_to_widget("li", [str(list_item_num), ". "])
columns = urwid.Columns(
[txt, ("weight", 9999, markup)], dividechars=1, min_width=3
)
widgets.append(columns)

list_item_num += increment

return urwid.Pile(widgets)

def _pre(self, tag) -> urwid.Widget:
# <PRE> tag spec says that text should not wrap,
Expand Down Expand Up @@ -314,7 +358,17 @@ def _span(self, tag) -> Tuple:
# of its own

if "class" in tag.attrs:
# uncomment the following code to hide all HTML marked
# invisible (generally, the http:// prefix of URLs)
# could be a user preference, it's only advisable if
# the terminal supports OCS 8 hyperlinks (and that's not
# automatically detectable)

# if "invisible" in tag.attrs["class"]:
# return (tag.name, "")

style_name = self.get_urwid_attr_name(tag)

if style_name != "span":
# unique class name matches an entry in our palette
return (style_name, markups)
Expand All @@ -340,36 +394,24 @@ def _strong(self, tag) -> Tuple:
return ("b", markups)

def _ul(self, tag) -> urwid.Widget:
return self.list_widget(tag, ordered=False)
"""unordered list tag handler"""

def list_widget(self, tag, ordered=False) -> urwid.Widget:
"""common logic for ordered and unordered list rendering
as urwid widgets"""
widgets = []
i = 1

for li in tag.find_all("li", recursive=False):
method = getattr(self, "_li", self.inline_tag_to_text)
markup = method(li)

if not isinstance(markup, urwid.Widget):
if ordered:
txt = self.text_to_widget("li", [str(i), ". ", markup])
# 1. foo, 2. bar, etc.
else:
txt = self.text_to_widget("li", ["\N{bullet} ", markup])
# * foo, * bar, etc.
txt = self.text_to_widget("li", ["\N{bullet} ", markup])
# * foo, * bar, etc.
widgets.append(txt)
else:
if ordered:
txt = self.text_to_widget("li", [str(i), ". "])
else:
txt = self.text_to_widget("li", ["\N{bullet} "])

txt = self.text_to_widget("li", ["\N{bullet} "])
columns = urwid.Columns(
[txt, ("weight", 9999, markup)], dividechars=1, min_width=3
)
widgets.append(columns)
i += 1

return urwid.Pile(widgets)

Expand Down

0 comments on commit b3c654b

Please sign in to comment.