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

View file

@ -3,11 +3,13 @@ import string
from enum import IntEnum from enum import IntEnum
from bebop.colors import ColorPair 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-" SPLIT_CHARS = " \t-"
JOIN_CHAR = "-" JOIN_CHAR = "-"
LIST_ITEM_MARK = ""
class LineType(IntEnum): class LineType(IntEnum):
@ -24,6 +26,7 @@ class LineType(IntEnum):
LINK = 5 LINK = 5
PREFORMATTED = 6 PREFORMATTED = 6
BLOCKQUOTE = 7 BLOCKQUOTE = 7
LIST_ITEM = 8
def format_elements(elements, width): def format_elements(elements, width):
@ -60,6 +63,8 @@ def format_elements(elements, width):
elif isinstance(element, Blockquote): elif isinstance(element, Blockquote):
element_metalines = format_blockquote(element, context) element_metalines = format_blockquote(element, context)
has_margins = True has_margins = True
elif isinstance(element, ListItem):
element_metalines = format_list_item(element, context)
else: else:
continue continue
# If current element requires margins and is not the first elements, # 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] 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): def wrap_words(text, width, indent=0):
"""Wrap a text in several lines according to the renderer's width.""" """Wrap a text in several lines according to the renderer's width."""
lines = [] lines = []