Source code for functui.io.html
"""Functions to convert layouts to html."""
from ..classes import Layout, Rect, StyleAttr, ComputedStyle, ResultCreatedWith, Screen, Result, Color4, Color24, hex, layout_to_result
from ..color_data import xterm256_to_hex
from typing import NamedTuple
HTML_ESCAPES = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
}
# def hex_int_to_string
def style_to_tag(style: ComputedStyle) -> HTMLTags:
tags_open = []
tags_closed = []
if StyleAttr.BOLD in style.attrs:
tags_open.append("b")
tags_closed.append("b")
if StyleAttr.ITALIC in style.attrs:
tags_open.append("i")
tags_closed.append("i")
if StyleAttr.STRIKE_THROUGH in style.attrs:
tags_open.append("strike")
tags_closed.append("strike")
if StyleAttr.UNDERLINE in style.attrs:
tags_open.append("u")
tags_closed.append("u")
style_attributes = []
if style.fg != Color4.RESET:
if isinstance(style.fg, int):
color = hex(xterm256_to_hex(style.fg))
else:
color = style.fg
style_attributes.append(f"color:{color.hex_str}")
if style.bg != Color4.RESET:
if isinstance(style.bg, int):
color = hex(xterm256_to_hex(style.bg))
else:
color = style.bg
style_attributes.append(f"background-color:{color.hex_str}")
if style_attributes:
tags_open.append(f"span style=\"{"; ".join(style_attributes)}\"")
tags_closed.append("span")
return HTMLTags(
open="".join(f"<{i}>" for i in tags_open),
closed="".join(f"</{i}>" for i in tags_closed)
)
[docs]
def result_to_html_str(result: Result):
"""Convert a result to an html string.
Returns:
Html representations of the result wrapped in a ``<pre>`` tag."""
data = result.try_data(ResultCreatedWith)
if data is None:
raise AssertionError("Result has no ResultCreatedWith data. If possible please use get_result() function to get a result.")
screen = Screen(data.screen_size.width, data.screen_size.height)
screen.apply_draw_commands(data.measure_text_func, result.get_commands())
curr_style = ComputedStyle()
curr_tags = style_to_tag(curr_style)
out = [curr_tags.open]
for line in screen.split_by_lines():
for pixel in line:
if pixel.style != curr_style:
out.append(curr_tags.closed)
curr_style = pixel.style
curr_tags = style_to_tag(curr_style)
out.append(curr_tags.open)
if pixel.char in HTML_ESCAPES:
out.append(HTML_ESCAPES[pixel.char])
else:
out.append(pixel.char)
out.append("\n")
out = out[:-1] # -1 to remove the \n on the end
out.append(curr_tags.closed)
return f"<pre style=\"font-family:monospace\">\n{"".join(out)}\n</pre>"
[docs]
def layout_to_html_str(layout: Layout, dimensions: Rect):
"""Convert a layout to an html string.
A shorthand for ``result_to_html_str(layout_to_result(...))``.
Returns:
Html representations of the result wrapped in a ``<pre>`` tag."""
return result_to_html_str(layout_to_result(layout, dimensions))