This repository has been archived on 2024-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
Bebop/bebop/rendering.py

77 lines
2.7 KiB
Python

"""Rendering Gemtext in curses."""
import curses
from bebop.colors import A_ITALIC, ColorPair
from bebop.metalines import LineType
def render_lines(metalines, window, max_width):
"""Write a list of metalines in window.
As this function does not know about the window/pad previous size, it
expects a cleared window, especially if the new content is shorter than the
previous one: merely clearing after the resize will not remove artefacts.
Arguments:
- metalines: list of metalines to render, must have at least one element.
- window: window that will be resized and filled with rendered lines.
- max_width: line length limit for the pad.
Returns:
The tuple of integers (height, width), the new dimensions of the resized
window.
"""
num_lines = len(metalines)
new_dimensions = max(num_lines, 1), max_width
window.resize(*new_dimensions)
for line_index, metaline in enumerate(metalines):
try:
render_line(metaline, window, max_width)
except ValueError:
return new_dimensions
if line_index < num_lines - 1:
window.addstr("\n")
return new_dimensions
def render_line(metaline, window, max_width):
"""Write a single line to the window."""
meta, line = metaline
line_type = meta["type"]
attributes = get_base_line_attributes(line_type)
line = line[:max_width - 1]
window.addstr(line, attributes)
if meta["type"] == LineType.LINK and "url" in meta:
url_text = f' {meta["url"]}'
attributes = (
curses.color_pair(ColorPair.LINK_PREVIEW)
| curses.A_DIM
| A_ITALIC
)
window.addstr(url_text, attributes)
def get_base_line_attributes(line_type) -> int:
"""Return the base attributes for this line type.
Other attributes may be freely used later for this line type but this is
what is used at the start of most lines of the given type.
"""
if line_type == LineType.TITLE_1:
return curses.color_pair(ColorPair.TITLE_1) | curses.A_BOLD
elif line_type == LineType.TITLE_2:
return curses.color_pair(ColorPair.TITLE_2) | curses.A_BOLD
elif line_type == LineType.TITLE_3:
return curses.color_pair(ColorPair.TITLE_3)
elif line_type == LineType.LINK:
return curses.color_pair(ColorPair.LINK)
elif line_type == LineType.PREFORMATTED:
return curses.color_pair(ColorPair.PREFORMATTED)
elif line_type == LineType.BLOCKQUOTE:
return curses.color_pair(ColorPair.BLOCKQUOTE) | A_ITALIC
elif line_type == LineType.ERROR:
return curses.color_pair(ColorPair.ERROR) | curses.A_BOLD
else: # includes LineType.PARAGRAPH
return curses.color_pair(ColorPair.NORMAL)