def test_nested_children(self): children = [range(2), tuple(range(3))] dom = div(id='container')(children) self.assertEqual(str(dom), '<div id="container">01012</div>') dom = div(children) self.assertEqual(str(dom), '<div>01012</div>')
def test_vararg_children(self): children = tuple(range(5)) dom = div(id='container')(*children) self.assertEqual(str(dom), '<div id="container">01234</div>') dom = div(*children) self.assertEqual(str(dom), '<div>01234</div>')
def test_iterable_children(self): children = range(5) dom = div(id='container')(children) self.assertEqual(str(dom), '<div id="container">01234</div>') dom = div(children) self.assertEqual(str(dom), '<div>01234</div>')
def hor_row_builder(horizontal_lines, color: int = 0): """creates the html of the horizontal lines for a row Parameters ---------- horizontal_lines : ndarray line states of the respective row of horizontal lines color : int,list, optional color to apply to the html objects, by default 0 Returns ------- html html object of the board row """ if type(color) is list: color1, color2, color3 = color else: color1, color2, color3 = color, color, color dot = div(_class="dot") lines = [ div(_class="horizContainer", style=styles(background_color=rgb(255, 255, 255) if i else rgb( color1, color2, color3))) for i in horizontal_lines ] l = [] for i in lines: l.append(dot) l.append(i) l.append(dot) row = div(_class="row")(l) return row
def layout(*args): style = """ <style> MainMenu {visibility: hidden;} footer {visibility: hidden;} .stApp { bottom: 60px; } </style> """ style_div = styles( position="fixed", left=0, bottom=0, margin=px(0, 15, 0, 0), text_align="center", opacity=0.5, ) body = p() foot = div(style=style_div)(body) st.markdown(style, unsafe_allow_html=True) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(str(foot), unsafe_allow_html=True)
def layout(*args): style = """ <style> #MainMenu {visibility: hidden;} footer {visibility: hidden;} </style> """ style_div = styles(left=0, bottom=0, margin=px(0, 0, 0, 0), width=percent(100), color="black", text_align="center", height="auto", opacity=1) style_hr = styles(margin=px(3, 3, 10, 3), border_style="inset", border_width=px(3)) body = p() foot = div(style=style_div)(hr(style=style_hr), body) st.markdown(style, unsafe_allow_html=True) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(str(foot), unsafe_allow_html=True)
def test_get_set_del_attr(self): dom = div(foo="bar", boz="boink") self.assertEqual(dom.foo, "bar") self.assertEqual(dom.boz, "boink") dom.foo = "bar2" self.assertEqual(dom.foo, "bar2") self.assertEqual(dom.boz, "boink") dom.boz = "boink2" self.assertEqual(dom.foo, "bar2") self.assertEqual(dom.boz, "boink2") del dom.boz self.assertEqual(dom.foo, "bar2") with self.assertRaises(AttributeError): getattr(dom, "boz") del dom.foo with self.assertRaises(AttributeError): getattr(dom, "foo") with self.assertRaises(AttributeError): getattr(dom, "boz")
def show(self, width=None, height=None, scrolling=True, **kwargs): out = div(style=styles(**kwargs))(self.html()) html = str(out) st.components.v1.html(html, width=width, height=height, scrolling=scrolling)
def annotated_text( df, text_column="text", value_column="vals", cmap_name="Blues", scale_values=True, **kwargs ): """Writes test with annotations into your Streamlit app. Parameters ---------- *df : pandas DataFrame """ style = styles(font_family="sans-serif", line_height="1.5", font_size=px(32),) out = div(_class="", style=style) cmap = get_cmap(cmap_name) for text, val in zip(df[text_column], df[value_column]): if scale_values: val = (val + 0.25) ** 2.5 color = (np.array(cmap(val)[:3]) * 255).astype(np.uint8) contrast = contrastColor(*color) hex_color = "#%02x%02x%02x" % (color[0], color[1], color[2]) contrast_color = "#%02x%02x%02x" % (contrast[0], contrast[1], contrast[2]) out(annotation(body=text + " ", color=contrast_color, background=hex_color)) streamlit.components.v1.html(str(out), **kwargs)
def annotated_text(*args, **kwargs): """Writes test with annotations into your Streamlit app. Parameters ---------- *args : str, tuple or htbuilder.HtmlElement Arguments can be: - strings, to draw the string as-is on the screen. - tuples of the form (main_text, annotation_text, background, color) where background and foreground colors are optional and should be an CSS-valid string such as "#aabbcc" or "rgb(10, 20, 30)" - HtmlElement objects in case you want to customize the annotations further. In particular, you can import the `annotation()` function from this module to easily produce annotations whose CSS you can customize via keyword arguments. """ out = div(style=styles( font_family="sans-serif", line_height="1.5", color="white", font_size=px(16), )) for arg in args: if isinstance(arg, str): out(arg) elif isinstance(arg, HtmlElement): out(arg) elif isinstance(arg, tuple): out(annotation(*arg)) else: raise Exception("Oh noes!") streamlit.components.v1.html(str(out), **kwargs)
def layout(*args): style = """ <style> # MainMenu {visibility: hidden;} footer {visibility: hidden;} .stApp { bottom: 70px; } </style> """ style_div = styles(position="fixed", left=0, bottom=0, margin=px(0, 0, 0, 0), width=percent(100), color="black", text_align="center", height="auto", opacity=1) body = p() foot = div(style=style_div)(body) st.markdown(style, unsafe_allow_html=True) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(str(foot), unsafe_allow_html=True)
def test_fragment_tag(self): dom = fragment( h1('hello'), div('world') ) self.assertEqual(str(dom), normalize_whitespace(''' <h1>hello</h1><div>world</div> '''))
def annotated_text(*args): """Writes test with annotations into your Streamlit app. Parameters ---------- *args : str, tuple or htbuilder.HtmlElement Arguments can be: - strings, to draw the string as-is on the screen. - tuples of the form (main_text, annotation_text, background, color) where background and foreground colors are optional and should be an CSS-valid string such as "#aabbcc" or "rgb(10, 20, 30)" - HtmlElement objects in case you want to customize the annotations further. In particular, you can import the `annotation()` function from this module to easily produce annotations whose CSS you can customize via keyword arguments. Examples -------- >>> annotated_text( ... "This ", ... ("is", "verb", "#8ef"), ... " some ", ... ("annotated", "adj", "#faa"), ... ("text", "noun", "#afa"), ... " for those of ", ... ("you", "pronoun", "#fea"), ... " who ", ... ("like", "verb", "#8ef"), ... " this sort of ", ... ("thing", "noun", "#afa"), ... ) >>> annotated_text( ... "Hello ", ... annotation("world!", "noun", color="#8ef", border="1px dashed red"), ... ) """ out = div(style=styles( font_family="sans-serif", line_height="1.5", font_size=px(16), )) for arg in args: if isinstance(arg, str): out(arg) elif isinstance(arg, HtmlElement): out(arg) elif isinstance(arg, tuple): out(annotation(*arg)) else: raise Exception("Oh noes!") streamlit.components.v1.html(str(out))
def board_builder(hor_state, ver_state, values, owners, color=0): """function to generate the html of the board Parameters ---------- hor_state : ndarray line states of the respective row of horizontal lines ver_state : ndarray line states of the respective row of vertical lines values : ndarray 2d array of the box values owners : ndarray 2d array of the box owners color : int,list, optional color to apply to the html objects, by default 0 Returns ------- html html object of the board """ global size ver_state = ver_state.T rows = [] for i in range(size): #hor_lines = hor_state[i*size:(i+1)*size] hor_lines = hor_state[i] #ver_lines = ver_state[i*(size+1):(i+1)*(size+1)] ver_lines = ver_state[i] #vals = values[i*size:(i+1)*size] vals = values[i] #own = owners[i*size:(i+1)*size] own = owners[i] rows.append(hor_row_builder(hor_lines, color)) rows.append(ver_row_builder(ver_lines, own, vals, color)) hor_lines = hor_state[-1] rows.append(hor_row_builder(hor_lines, color)) board = div(_id="board")(div(_id="game-board")(rows)) return board
def layout(*args): style = """ <style> # MainMenu {visibility: hidden;} footer {visibility: hidden;} .stApp { bottom: 105px; } </style> """ style_div = styles(position="fixed", left=0, bottom=0, margin=px(0, 0, 0, 0), width=percent(100), color="black", text_align="center", height="auto", opacity=1) style_hr = styles(display="block", margin=px(8, 8, "auto", "auto"), border_style="inset", border_width=px(2)) body = p() foot = div(style=style_div)(hr(style=style_hr), body) st.markdown(style, unsafe_allow_html=True) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(str(foot), unsafe_allow_html=True) # def footer(): # myargs = [ # "Made in ", # image('https://avatars3.githubusercontent.com/u/45109972?s=400&v=4', # width=px(25), height=px(25)), # " with ❤️ by Avinash Nair", # link("https://www.linkedin.com/in/avinash-nair-299b72157/", "@AvinashNair"), # br(), # ] # layout(*myargs) # if __name__ == "__main__": # footer()
def ver_row_builder(vertical_lines, owners, values, color: int = 0): """creates the html of the vertical lines for a row Parameters ---------- vertical_lines : ndarray line states of the respective row of vertical lines owners : ndarray 2d array of the box owners values : ndarray 2d array of the box values color : int,list, optional color to apply to the html objects, by default 0 Returns ------- html html object of the board row """ if type(color) is list: color1, color2, color3 = color else: color1, color2, color3 = color, color, color lines = [ div(_class="vertContainer", style=styles(background_color=rgb(255, 255, 255) if i else rgb( color1, color2, color3))) for i in vertical_lines ] boxes = [ div(_class="box", style=styles(background_color=rgba(255, 0, 0, 0.5) if o == 1 else ( rgba(0, 255, 0, 0.5) if o == 2 else rgb(255, 255, 255))))(v) for o, v in zip(owners, values) ] l = [j for i in zip(lines, boxes) for j in i] l.append(lines[-1]) row = div(_class="row")(l) return row
def layout(*args): style = """ <style> # MainMenu {visibility: hidden;} footer {visibility: hidden;} .stApp { bottom: 63px; } </style> """ style_div = styles( position="fixed", left=0, bottom=0, margin=px(0,0,0,0), width=percent(100), height="auto", color="black", background_color="#f5f7f8", text_align="left", opacity=1 ) style_hr = styles( position="fixed", left=0, bottom=px(75), display="block", margin=px(8, 8, "auto", "auto"), border_style="inset", border_width=px(2) ) body = p() foot = div( style=style_div )( #hr( # style=style_hr #), body ) st.markdown(style, unsafe_allow_html=True) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(str(foot), unsafe_allow_html=True)
def test_multiple_html_args(self): dom = ( div( id='container', _class='foo bar', style='color: red; border-radius: 10px;', )('hello') ) self.assertEqual( str(dom), normalize_whitespace(''' <div id="container" class="foo bar" style="color: red; border-radius: 10px;" >hello</div> '''), )
def layout(*args): hide_stuff = """ <style> #MainMenu {visibility: hidden;} footer {visibility: hidden;} .stApp { bottom: 105px; } </style> """ style_div = styles(position="fixed", left=0, bottom=0, margin=px(0, 0, 0, 0), width=percent(100), color="black", text_align="center", height="auto", opacity=1) style_hr = styles( #display="block", margin=px(0, 0, "auto", "auto"), #border_style="inset", border_width=px(3)) body = p() foot = div(style=style_div)(hr(style=style_hr), body) for arg in args: if isinstance(arg, str): body(arg) elif isinstance(arg, HtmlElement): body(arg) st.markdown(hide_stuff, unsafe_allow_html=True) st.markdown(str(foot), unsafe_allow_html=True)
def test_complex_tree(self): dom = ( div(id='container')( h1('Examples'), ul( li("Example 1"), li("Example 2"), li("Example 3"), ) ) ) self.assertEqual( str(dom), normalize_whitespace(''' <div id="container"> <h1>Examples</h1> <ul> <li>Example 1</li> <li>Example 2</li> <li>Example 3</li> </ul> </div> '''), )
def html(self): # Add document elements if self.document._.name == 'Document': document_name = 'Source Document' else: document_name = self.document._.name + ' summary' doc_header = div(id_="document-header")(document_name) doc_elements = [] # Add document content, which comprises multiple elements, one for each summary. Only the elment corresponding to # selected summary will be visible. mu = MultiUnderline() for summary_idx, summary in enumerate(self.summaries): token_idx_to_sent_idx = {} for sent_idx, sent in enumerate(summary.sents): for token in sent: token_idx_to_sent_idx[token.i] = sent_idx is_selected_summary = (summary_idx == 0 ) # By default, first summary is selected if self.semantic_alignments is not None: doc_token_idx_to_matches = defaultdict(list) semantic_alignment = self.semantic_alignments[summary_idx] for summary_token_idx, matches in semantic_alignment.items(): for doc_token_idx, sim in matches: doc_token_idx_to_matches[doc_token_idx].append( (summary_token_idx, sim)) else: doc_token_idx_to_matches = {} token_elements = [] for doc_token_idx, doc_token in enumerate(self.document): if doc_token.is_stop or doc_token.is_punct: classes = ["stopword"] if self.gray_out_stopwords: classes.append("grayed-out") el = span(_class=" ".join(classes))(doc_token.text) else: matches = doc_token_idx_to_matches.get(doc_token_idx) if matches: summary_token_idx, sim = max(matches, key=itemgetter(1)) sent_idx = token_idx_to_sent_idx[summary_token_idx] color_primary = get_color(sent_idx) highlight_color_primary = color_with_opacity( color_primary, sim) props = { 'data-highlight-id': str(doc_token_idx), 'data-primary-color': highlight_color_primary } match_classes = [] for summary_token_idx, sim in matches: sent_idx = token_idx_to_sent_idx[summary_token_idx] match_classes.append( f"summary-highlight-{summary_idx}-{summary_token_idx}" ) color = color_with_opacity(get_color(sent_idx), sim) props[ f"data-color-{summary_idx}-{summary_token_idx}"] = color props["data-match-classes"] = " ".join(match_classes) el = self._highlight( doc_token.text, highlight_color_primary, color_primary, match_classes + ["annotation-hidden"], **props) else: el = doc_token.text token_elements.append(el) spans = [] if self.lexical_alignments is not None: lexical_alignment = self.lexical_alignments[summary_idx] for summary_span, doc_spans in lexical_alignment.items(): summary_span_start, summary_span_end = summary_span span_id = f"{summary_idx}-{summary_span_start}-{summary_span_end}" sent_idx = token_idx_to_sent_idx[summary_span_start] for doc_span_start, doc_span_end in doc_spans: spans.append((doc_span_start, doc_span_end, sent_idx, get_color(sent_idx), span_id)) token_elements = mu.markup(token_elements, spans) classes = ["main-doc", "bordered"] if self.scroll: classes.append("scroll") main_doc = div(_class=" ".join(classes))(token_elements), classes = ["doc"] if is_selected_summary: classes.append("display") else: classes.append("nodisplay") doc_elements.append( div(**{ "class": " ".join(classes), "data-index": summary_idx })(main_doc, div(_class="proxy-doc"), div(_class="proxy-scroll"))) summary_title = "Summary" summary_header = div(id_="summary-header")( summary_title, div(id="summary-header-gap"), ) summary_items = [] for summary_idx, summary in enumerate(self.summaries): token_idx_to_sent_idx = {} for sent_idx, sent in enumerate(summary.sents): for token in sent: token_idx_to_sent_idx[token.i] = sent_idx spans = [] matches_ngram = [False] * len(list(summary)) if self.lexical_alignments is not None: lexical_alignment = self.lexical_alignments[summary_idx] for summary_span in lexical_alignment.keys(): start, end = summary_span matches_ngram[slice(start, end)] = [True] * (end - start) span_id = f"{summary_idx}-{start}-{end}" sent_idx = token_idx_to_sent_idx[start] spans.append( (start, end, sent_idx, get_color(sent_idx), span_id)) if self.semantic_alignments is not None: semantic_alignment = self.semantic_alignments[summary_idx] else: semantic_alignment = {} token_elements = [] for token_idx, token in enumerate(summary): if token.is_stop or token.is_punct: classes = ["stopword"] if self.gray_out_stopwords: classes.append("grayed-out") el = span(_class=" ".join(classes))(token.text) else: classes = [] if token.ent_iob_ in ('I', 'B'): classes.append("entity") if matches_ngram[token_idx]: classes.append("matches-ngram") matches = semantic_alignment.get(token_idx) if matches: top_match = max(matches, key=itemgetter(1)) top_sim = max(top_match[1], 0) top_doc_token_idx = top_match[0] props = { "data-highlight-id": f"{summary_idx}-{token_idx}", "data-top-doc-highlight-id": str(top_doc_token_idx), "data-top-doc-sim": f"{top_sim:.2f}", } classes.extend([ "annotation-hidden", f"summary-highlight-{summary_idx}-{token_idx}" ]) sent_idx = token_idx_to_sent_idx[token_idx] el = self._highlight( token.text, color_with_opacity(get_color(sent_idx), top_sim), color_with_opacity(get_color(sent_idx), 1), classes, **props) else: if classes: el = span(_class=" ".join(classes))(token.text) else: el = token.text token_elements.append(el) token_elements = mu.markup(token_elements, spans) classes = ["summary-item"] if summary_idx == 0: # Default is for first summary to be selected classes.append("selected") summary_items.append( div(**{ "class": ' '.join(classes), "data-index": summary_idx })(div(_class="name")(summary._.name), div(_class="content")(token_elements))) classes = ["summary-list", "bordered"] if self.scroll: classes.append("scroll") if self.lexical_alignments is not None: classes.append("has-lexical-alignment") if self.semantic_alignments is not None: classes.append("has-semantic-alignment") summary_list = div(_class=" ".join(classes))(summary_items) annotation_key = \ """ <ul class="annotation-key"> <li class="annotation-key-label">Annotations:</li> <li id="option-lexical" class="option selected"> <span class="annotation-key-ngram">N-Gram overlap</span> </li> <li id="option-semantic" class="option selected"> <span class="annotation-key-semantic">Semantic overlap</span> </li> <li id="option-novel" class="option selected"> <span class="annotation-key-novel">Novel words</span> </li> <li id="option-entity" class="option selected"> <span class="annotation-key-entity">Novel entities</span> </li> </ul> """ body = div( annotation_key, div(_class=f"vis-container {self.layout}-layout")( div(_class="doc-container")(doc_header, *doc_elements), div(_class="summary-container")(summary_header, summary_list)), ) return [ """<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">""", local_stylesheet( Path(__file__).parent / "resources" / "summvis.css"), """<link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">""", body, """<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>""", local_script( Path(__file__).parent / "resources" / "jquery.color-2.1.2.min.js"), local_script(Path(__file__).parent / "resources" / "summvis.js"), """<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>""" ]
def test_empty(self): dom = div() self.assertEqual( str(dom), normalize_whitespace('<div></div>'), )
padding_bottom=px(padding_bottom), ), **props)(element) # Return outermost nested span return element if __name__ == "__main__": from htbuilder import div # Test text = "The quick brown fox jumps" tokens = text.split() tokens = [ "The", htbuilder.span(style=styles(color="red"))("quick"), "brown", "fox", "jumps" ] spans = [ (0, 2, 0, "green", "green1"), (1, 3, 0, "orange", "orange1"), (3, 4, 0, "red", "red1"), (2, 4, 0, "blue", "blue1"), (1, 5, 0, "orange", "orange1"), ] mu = MultiUnderline() html = str(div(mu.markup(tokens, spans))) print(html)
def test_attr_understores_to_dashes_with_strip(self): dom = div(__foo_bar_="boz") self.assertEqual(str(dom), normalize_whitespace(''' <div foo-bar="boz"></div> '''))
def test_arg_order(self): dom = div("hello", foo="bar") self.assertEqual(str(dom), normalize_whitespace(''' <div foo="bar">hello</div> '''))
def test_basic_usage(self): dom = div('hello') self.assertEqual( str(dom), normalize_whitespace('<div>hello</div>'), )
def test_basic_usage_with_arg(self): dom = div(id='container')('hello') self.assertEqual( str(dom), normalize_whitespace('<div id="container">hello</div>'), )
def show_html(*elements, width=None, height=None, **kwargs): out = div(style=styles(**kwargs))(elements) html = str(out) st.components.v1.html(html, width=width, height=height, scrolling=True)
keyword_deacc = st.sidebar.checkbox("Remove Accentuation", value=False) kw = keywords(text, ratio=keyword_ratio, words=keyword_word_count, split=keyword_split_output, scores=keyword_scores, pos_filter=('NN', 'JJ'), lemmatize=keyword_lemmatize, deacc=keyword_deacc) if kw: result_col.header("Keywords") kw_expander = result_col.beta_expander("Expand keywords!") if kw_expander: kw_expander.write(HTML_WRAPPER.format(kw), unsafe_allow_html=True) if show_offsets: st.header("Offsets View") input_offset_col, result_offset_col = st.beta_columns(2) summary_out = div(style=styles( font_family="sans-serif", line_height="1.5", font_size=px(16), )) summaries = [] if isinstance(summary, list): summaries = summary elif isinstance(summary, str): summaries = summary.split("\n") summary_colors = {} for num, summary_item in enumerate(summaries): color = COLORS[num%len(COLORS)] summary_out(annotate(summary_item, "", color)) summary_colors[summary_item] = color
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from htbuilder import div, ul, li, img, styles, classes, fonts from htbuilder.units import px from htbuilder.funcs import rgba, rgb image_paths = [ "http://myimages.com/foo1.jpg", "http://myimages.com/foo2.jpg", "http://myimages.com/foo3.jpg", ] html_element = div(id="container")(ul(_class="image-list")([ li(img(src=image_path, _class="large-image")) for image_path in image_paths ])) print(html_element) bottom_margin = 10 s = styles( color="black", font_family=fonts("Comic Sans", "sans"), margin=px(0, 0, bottom_margin, 0), box_shadow=[ (0, 0, px(10), rgba(0, 0, 0, 0.1)), (0, 0, "2px", rgb(0, 0, 0)), ], )