Spaces:
Sleeping
Sleeping
File size: 3,365 Bytes
4b75840 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import html
from htbuilder import H, HtmlElement, styles
from htbuilder.units import unit
# Only works in 3.7+: from htbuilder import div, span
div = H.div
span = H.span
# Only works in 3.7+: from htbuilder.units import px, rem, em
px = unit.px
rem = unit.rem
em = unit.em
# Colors from the Streamlit palette.
# These are red-70, orange-70, ..., violet-70, gray-70.
PALETTE = [
"#ff4b4b",
"#ffa421",
"#ffe312",
"#21c354",
"#00d4b1",
"#00c0f2",
"#1c83e1",
"#803df5",
"#808495",
]
OPACITIES = [
"33", "66",
]
def annotation(body, label="", background=None, color=None, **style):
"""Build an HtmlElement span object with the given body and annotation label.
The end result will look something like this:
[body | label]
Parameters
----------
body : string
The string to put in the "body" part of the annotation.
label : string
The string to put in the "label" part of the annotation.
background : string or None
The color to use for the background "chip" containing this annotation.
If None, will use a random color based on the label.
color : string or None
The color to use for the body and label text.
If None, will use the document's default text color.
style : dict
Any CSS you want to apply to the containing "chip". This is useful for things like
Examples
--------
Produce a simple annotation with default colors:
# >>> annotation("apple", "fruit")
Produce an annotation with custom colors:
# >>> annotation("apple", "fruit", background="#FF0", color="black")
Produce an annotation with crazy CSS:
# >>> annotation("apple", "fruit", background="#FF0", border="1px dashed red")
"""
color_style = {}
if color:
color_style['color'] = color
if not background:
label_sum = sum(ord(c) for c in label)
background_color = PALETTE[label_sum % len(PALETTE)]
background_opacity = OPACITIES[label_sum % len(OPACITIES)]
background = background_color + background_opacity
return (
span(
style=styles(
background=background,
border_radius=rem(0.33),
padding=(rem(0.125), rem(0.5)),
overflow="hidden",
**color_style,
**style,
))(
html.escape(body),
span(
style=styles(
padding_left=rem(0.5),
text_transform="uppercase",
))(
span(
style=styles(
font_size=em(0.67),
opacity=0.5,
))(
html.escape(label),
),
),
)
)
def get_annotated_html(*args):
"""Writes text with annotations into an HTML string.
Parameters
----------
*args : see annotated_text()
Returns
-------
str
An HTML string.
"""
out = div()
for arg in args:
if isinstance(arg, str):
out(html.escape(arg))
elif isinstance(arg, HtmlElement):
out(arg)
elif isinstance(arg, tuple):
out(annotation(*arg))
else:
raise Exception("Bad input")
return str(out) |