gemtext: handle list items

This commit is contained in:
dece 2021-02-16 20:23:44 +01:00
parent 4cb8ac11d6
commit 15f56289b9
2 changed files with 27 additions and 1 deletions

View file

@ -34,6 +34,12 @@ class Blockquote:
RE = re.compile(r">\s*(.*)")
@dataclass
class ListItem:
text: str
RE = re.compile(r"\*\s(.*)")
def parse_gemtext(data):
"""Parse UTF-8 encoded Gemtext as a list of elements."""
text = data.decode(encoding="utf8", errors="ignore")
@ -71,6 +77,12 @@ def parse_gemtext(data):
elements.append(Blockquote(text))
continue
match = ListItem.RE.match(line)
if match:
text = match.groups()[0]
elements.append(ListItem(text))
continue
if preformatted:
preformatted.lines.append(line)
else:

View file

@ -3,11 +3,13 @@ import string
from enum import IntEnum
from bebop.colors import ColorPair
from bebop.gemtext import Blockquote, Link, Paragraph, Preformatted, Title
from bebop.gemtext import (Blockquote, Link, ListItem, Paragraph, Preformatted,
Title)
SPLIT_CHARS = " \t-"
JOIN_CHAR = "-"
LIST_ITEM_MARK = ""
class LineType(IntEnum):
@ -24,6 +26,7 @@ class LineType(IntEnum):
LINK = 5
PREFORMATTED = 6
BLOCKQUOTE = 7
LIST_ITEM = 8
def format_elements(elements, width):
@ -60,6 +63,8 @@ def format_elements(elements, width):
elif isinstance(element, Blockquote):
element_metalines = format_blockquote(element, context)
has_margins = True
elif isinstance(element, ListItem):
element_metalines = format_list_item(element, context)
else:
continue
# If current element requires margins and is not the first elements,
@ -131,6 +136,15 @@ def format_blockquote(blockquote: Blockquote, context: dict):
return [({"type": LineType.BLOCKQUOTE}, line) for line in lines]
def format_list_item(item: ListItem, context: dict):
"""Return metalines for this list item."""
indent = len(LIST_ITEM_MARK)
lines = wrap_words(item.text, context["width"], indent=indent)
first_line = LIST_ITEM_MARK + lines[0][indent:]
lines[0] = first_line
return [({"type": LineType.LIST_ITEM}, line) for line in lines]
def wrap_words(text, width, indent=0):
"""Wrap a text in several lines according to the renderer's width."""
lines = []