Esempio n. 1
0
def close_html_doc(html_doc):
    with html_doc.body.children[-1]:
        assert html_doc.body.children[-1]['class'] == 'container-fluid'
        with tags.div(id="search_modal"):
            tags.attr(cls="modal fade")

    with html_doc:
        # add footnotes content of this section:
        with tags.ol(id="footnotes"):
            for (id) in html_doc.footnote_ids_of_this_html_doc:
                footnote = word_doc_footnotes.footnotes_part.notes[id + 1]
                assert footnote.id == id
                htmler.add_footnote_to_output(footnote.paragraphs)

        # add placeholder for searching
        tags.comment("search_placeholder")

    place_holder = "<!--search_placeholder-->"
    with open("input_web/stub_search.html", 'r') as file:
        search_html = file.read()

    html_doc_name = html_doc.index
    name = "debug_%s.html" % html_doc_name
    with open("output/" + name, 'w') as f:
        f.write(html_doc.render(inline=False).encode('utf8'))
    replace_in_file("output/" + name, place_holder, search_html)

    name = "%s.html" % html_doc_name
    with open("output/" + name, 'w') as f:
        f.write(html_doc.render(inline=True).encode('utf8'))
        print "Created ", name
    replace_in_file("output/" + name, place_holder, search_html)
Esempio n. 2
0
def close_html_doc(html_doc):
    with html_doc.body.children[-1]:
        assert html_doc.body.children[-1]['class'] == 'container-fluid'
        with tags.div(id="search_modal"):
            tags.attr(cls="modal fade")


    with html_doc:
        # add footnotes content of this section:
        with tags.ol(id="footnotes"):
            for (id) in html_doc.footnote_ids_of_this_html_doc:
                footnote = word_doc_footnotes.footnotes_part.notes[id + 1]
                assert footnote.id == id
                htmler.add_footnote_to_output(footnote.paragraphs)

        # add placeholder for searching
        tags.comment("search_placeholder")

    place_holder = "<!--search_placeholder-->"
    with open("input_web/stub_search.html", 'r') as file:
        search_html = file.read()

    html_doc_name = html_doc.index
    name = "debug_%s.html" % html_doc_name
    with open("output/" + name, 'w') as f:
        f.write(html_doc.render(pretty=True).encode('utf8'))
    replace_in_file("output/" + name, place_holder, search_html)

    name = "%s.html" % html_doc_name
    with open("output/" + name, 'w') as f:
        f.write(html_doc.render(pretty=False).encode('utf8'))
        print "Created ", name
    replace_in_file("output/" + name, place_holder, search_html)
Esempio n. 3
0
 def gen_fragments(self, fragments, classes=()):
     """Serialize a list of `fragments` to HTML."""
     with tags.pre(cls=" ".join(("alectryon-io", *classes))) as pre:
         tags.comment(" Generator: {} ".format(GENERATOR))
         fragments = transforms.group_whitespace_with_code(fragments)
         fragments = transforms.commit_io_annotations(fragments)
         for fr in fragments:
             self.gen_fragment(fr)
         return pre
Esempio n. 4
0
def create_mainpage_html(local, url_list, path, web_title):
    _html = dmtags.html(style="background-color:#fcfbeb;")
    _head, _body = _html.add(dmtags.head(dmtags.title(web_title)),
                             dmtags.body(cls="main_page"))
    with _head:
        dmtags.comment("The page is genarated on {} by Ein".format(
            time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        dmtags.meta(charset="utf-8",
                    name="viewport",
                    content="width=device-width, initial-scale=1")
        dmtags.link(
            href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:500",
            rel="stylesheet")
        dmtags.link(
            href=
            "https://cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.min.css",
            rel="stylesheet")
        dmtags.link(href="https://rawcdn.githack.com/c892836a/python_for_fun/"
                    "b2fa53022b0ae5a26d6f140c38b860a210c21040/css/custom.css",
                    rel="stylesheet")
        dmtags.link(
            href="https://lh3.googleusercontent.com/S__tM5EYqZDFLuv1uPG" +
            "mlZTTLLyNAbUvljzDH8-S0Pxq2nA9fnFF3SwU0w0wF8PlMu_hv3WhLMdlFodKbQ=s0",
            rel="shortcut icon",
            type="image/vnd.microsoft.icon")
    main_div = _body.add(
        dmtags.div(
            style=
            "text-align:center; font-family: 'Noto Sans JP', sans-serif; font-size:36px;"
        ))

    with main_div:
        _p1 = dmtags.p(style="color:#470000;")
        for url in url_list:
            _p2 = dmtags.p(style="font-size:20px;")
            with _p2:
                dmtags.a(url[0], href="{}".format(url[1]))
        with _p1:
            text("{}".format(web_title))

    # create html file
    if local:
        os.chdir(path)
        os.chdir(os.pardir)
        with open("{}.html".format(web_title), "w", encoding='utf8') as f:
            f.write("<!DOCTYPE html>\n")
            f.write(_html.render())

    else:
        with open("{}\\{}.html".format(path, web_title), "w",
                  encoding='utf8') as f:
            f.write("<!DOCTYPE html>\n")
            f.write(_html.render())
Esempio n. 5
0
def site():
    base = Path('website')
    with (base/'content'/'index.toml').open() as toml, \
         (base/'style'/'index.css').open() as css:
        data = loads(toml.read())

        with html(lang='en') as document:

            with head():
                meta(charset='utf-8')
                meta(name='description',
                     content=f'{SHARED.info.person_name} (engineer|designer)')
                meta(name='keywords', content=','.join(SHARED.meta.keywords))
                meta(name='author', content=f'{SHARED.info.person_name}')
                title(SHARED.info.person_name)
                link(rel='shortcut icon',
                     type='image/x-icon',
                     href='favicon.ico')
                link(rel='icon', type='image/x-icon', href='favicon.ico')
                style(raw(css.read()))
                script(src='website/js/anim.js')
                script(src='website/js/index.js')

            with body():
                _block('engineer', data['engineer'])
                _block('designer', data['designer'])
                with div(id='handler'):
                    div(raw('&laquo;&raquo;'))
                script('main();', type='text/javascript')

    copyright = comment(f'Copyright (C) 2015 - {datetime.now().year} '
                        f'{SHARED.info.person_name}. '
                        'All rights reserved.')
    return f'<!DOCTYPE html>{copyright}{document.render(pretty=False)}'
Esempio n. 6
0
def cv():
    base = Path('cv')
    with (base / 'content' / 'data.toml').open() as toml, \
         (base / 'style' / 'index.css').open() as css:
        data = loads(toml.read())
        with html(lang='en') as document:
            with head():
                meta(charset='utf-8')
                meta(name='description',
                     content=f'{SHARED.info.person_name} (engineer|designer)')
                meta(name='keywords', content=','.join(SHARED.meta.keywords))
                meta(name='author', content=f'{SHARED.info.person_name}')
                title(SHARED.info.person_name)
                style(raw(css.read()))
            with body():
                with table(id='content') as content:
                    with tr():
                        with td(id='image', colspan=4):
                            img(src='img/header.png', alt='...')
                            div('Curriculum Vitae')
                for row in chain(
                        Basic(data['basic']).as_rows(),
                        Skills(data['skills']).as_rows(),
                        Experience(data['experience']).as_rows(),
                        Education(data['education']).as_rows()):
                    content.add(row)

    copyright = comment(f'Copyright (C) 2015 - {datetime.now().year} '
                        f'{SHARED.info.person_name}. '
                        'All rights reserved.')
    return f'<!DOCTYPE html>{copyright}{document.render(pretty=False)}'
Esempio n. 7
0
    def __init__(self, *args, \
            bootstrap_url='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6', \
            jquery_url='https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js',
            static_folder=None,
            **kwargs):

        super().__init__(**kwargs)
        self.navbar = None

        self.meta = self.head.add(
            meta(
                name='viewport',
                content='width=device-width, initial-scale=1.0'
            )
        )
        self.head.add(comment('Latest compiled and minified CSS'))
        if static_folder is not None:
            bootstrap_url = static_folder

        self.head.add(
            link(
                rel='stylesheet',
                href=bootstrap_url + '/css/bootstrap.min.css'
            ),
        )
        self.content = self.body.add(Div(id='content'))
        self.scripts = self.body.add(Div(id='scripts'))
        self.scripts.add(comment('jQuery library'))

        if static_folder is not None:
            jquery_url = static_folder + '/js/jquery.min.js'

        self.scripts.add(
            script(src=jquery_url)
        )
        self.scripts.add(comment('Latest compiled JavaScript'))
        self.scripts.add(
            script(src=bootstrap_url + '/js/bootstrap.min.js')
        )

        self.add(*args)
Esempio n. 8
0
    def _get_wrap(self, node, classes='form-group'):
        # add required class, which strictly speaking isn't bootstrap, but
        # a common enough customization
        if node.flags.required:
            classes += ' required'

        div = tags.div(_class=classes)
        if current_app.debug:
            div.add(tags.comment(' Field: {} ({}) '.format(
                node.name, node.__class__.__name__)))

        return div
Esempio n. 9
0
    def _get_wrap(self, node, classes='form-group'):
        # add required class, which strictly speaking isn't bootstrap, but
        # a common enough customization
        if node.flags.required:
            classes += ' required'

        div = tags.div(_class=classes)
        if current_app.debug:
            div.add(tags.comment(' Field: {} ({}) '.format(
                node.name, node.__class__.__name__)))

        return div
Esempio n. 10
0
    def visit_object(self, node):
        """Fallback rendering for objects.

        If the current application is in debug-mode
        (``flask.current_app.debug`` is ``True``), an ``<!-- HTML comment
        -->`` will be rendered, indicating which class is missing a visitation
        function.
        Outside of debug-mode, returns an empty string.
        """
        if current_app.debug:
            return tags.comment('no implementation in {} to render {}'.format(
                self.__class__.__name__, node.__class__.__name__))

        return ''
Esempio n. 11
0
    def visit_object(self, node):
        """Fallback rendering for objects.

        If the current application is in debug-mode
        (``flask.current_app.debug`` is ``True``), an ``<!-- HTML comment
        -->`` will be rendered, indicating which class is missing a visitation
        function.

        Outside of debug-mode, returns an empty string.
        """
        if current_app.debug:
            return tags.comment('no implementation in {} to render {}'.format(
                self.__class__.__name__,
                node.__class__.__name__, ))
        return ''
Esempio n. 12
0
    def add(self, *items):
        items = parse_into_single_tuple(items)

        # store tabs and content that's been added
        tabs_added = []
        content_added = []

        # seperate :class: Tab, which is the preferred way to add content.
        tabs = tuple(item for item in items if isinstance(item, Tab))
        # seperate :class: TabbarTab (only has content relevent to the tab button, no content)
        tabbar_tabs = tuple(item for item in items if isinstance(item, TabbarTab))
        # this is what's left over
        panes = tuple(item for item in items if isinstance(item, TabPane))
        # catchall for everything left-over
        items = tuple(item for item in items if item not in tabs \
                and item not in tabbar_tabs and item not in panes)

        # add loosely passed tabbar_tabs and items that are :class: TabPane
        if len(tabbar_tabs) > 0:
            tabs_added = list(self.tabs.add(tabbar_tabs))
        if len(panes) > 0:
            content_added = list(self.content.add(panes))

        if len(tabs) > 0:
            for item in tabs:
                tabs_added.append(self.tabs.add(item.tab, active=item.active))
                content_added.append(self.content.add(item.content))

        if len(items) > 0:
            string = ' '.join(items)
            self.content.add(comment('These items are not of the correct class to add to the tabbar: ' + string))

        if len(tabs_added) > 0 and len(content_added) > 0:
            return (tuple(tabs_added), tuple(content_added))
        elif len(tabs_added) > 0:
            return (tuple(tabs_added), None)
        elif len(content_added) > 0:
            return (None, tuple(content_added))
        return
Esempio n. 13
0
    def add(self, *items, active=False):
        added = []
        items = parse_into_single_tuple(items)

        # seperate any tab elements from non-tab elements
        # hopefully all items are tab elements.
        tabs = tuple(item for item in items if isinstance(item, TabbarTab))
        items = tuple(item for item in items if item not in tabs)
        
        if len(items) > 0:
            string = ' '.join(items)
            super().add(comment('These items could not be added to TabbarUl because they are not of class TabbarTab: ' + string))
            
        # super().add() takes care of wrapping the element in an <li> tag
        _tabs = tuple(super().add(tabs, active=active))
        # combine all element we've added
        _tabs += tuple(added)
        if len(_tabs) == 1:
            return _tabs[0]
        elif len(tabs) > 1:
            return _tabs
        return
Esempio n. 14
0
def create_singlepage_html(local, is_mainpage, web_title, web_title_next,
                           web_title_pre, file_array, path):
    parent_web_title = ""
    if is_mainpage:
        os.chdir(path)
        os.chdir(os.pardir)
        parent_web_title = str(os.getcwd())[str(os.getcwd()).rindex("\\") + 1:]
    if local:
        web_title_next = special_character_encode(web_title_next)
        web_title_pre = special_character_encode(web_title_pre)
    _html = dmtags.html(style="background-color:black;")
    _head, _body = _html.add(dmtags.head(dmtags.title(web_title)),
                             dmtags.body())
    with _head:
        dmtags.comment("The page is genarated on {} by Ein".format(
            time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        dmtags.meta(charset="utf-8",
                    name="viewport",
                    content="width=device-width, initial-scale=1")
        dmtags.link(
            href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:500",
            rel="stylesheet")
        dmtags.link(
            href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.6/"
            "jquery.fancybox.min.css",
            rel="stylesheet")
        dmtags.link(
            href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/css/"
            "uikit.min.css",
            rel="stylesheet")
        dmtags.link(href="https://rawcdn.githack.com/c892836a/python_for_fun/"
                    "b2fa53022b0ae5a26d6f140c38b860a210c21040/css/custom.css",
                    rel="stylesheet")
        dmtags.link(
            href="https://lh3.googleusercontent.com/S__tM5EYqZDFLuv1uPG" +
            "mlZTTLLyNAbUvljzDH8-S0Pxq2nA9fnFF3SwU0w0wF8PlMu_hv3WhLMdlFodKbQ=s0",
            rel="shortcut icon",
            type="image/vnd.microsoft.icon")
        dmtags.script(
            src=
            "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js")
        dmtags.script(
            src=
            "https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.6/jquery.fancybox.min.js"
        )

    main_div = _body.add(
        dmtags.div(
            style=
            "text-align:center; font-family: 'Noto Sans JP', sans-serif; font-size:32px;"
        ))
    with main_div:
        _p1 = dmtags.p(style="color:#C2FFFC;padding-top: 20px;")
        if web_title_next == "" and web_title_pre == "":
            _button_top_div = dmtags.div(style="display: none;")
        else:
            _button_top_div = dmtags.div(style="padding-bottom: 30px;")
        if local:
            for pic in file_array:
                _a1 = dmtags.a(datafancybox="gallery",
                               href='./{}/{}'.format(
                                   urllib.parse.quote(web_title),
                                   urllib.parse.quote(pic)))
                with _a1:
                    dmtags.img(width="1200px",
                               src='./{}/{}'.format(
                                   urllib.parse.quote(web_title),
                                   urllib.parse.quote(pic)))
        else:
            web_title_temp = restrict_foldername(web_title)
            for pic in file_array:
                _a1 = dmtags.a(datafancybox="gallery",
                               href='./{}/{}'.format(
                                   urllib.parse.quote(web_title_temp),
                                   urllib.parse.quote(pic)))
                with _a1:
                    dmtags.img(width="1200px",
                               src='./{}/{}'.format(
                                   urllib.parse.quote(web_title_temp),
                                   urllib.parse.quote(pic)))
        with _p1:
            text("{} ({}P)".format(web_title, str(len(file_array))))
        _button_bottom_div = dmtags.div(
            style="padding-top: 20px; padding-bottom: 40px;")
        with _button_top_div:
            if web_title_pre != "":
                dmtags.a("Prev",
                         cls="uk-button uk-button-secondary n-bt",
                         href="./{}.html".format(web_title_pre))
            else:
                dmtags.a("Prev",
                         cls="uk-button uk-button-secondary h-bt",
                         href="./{}.html".format(web_title_pre))
            if is_mainpage:
                dmtags.a("Index",
                         cls="uk-button uk-button-secondary n-bt",
                         href="../{}.html".format(parent_web_title))
            if web_title_next != "":
                dmtags.a("Next",
                         cls="uk-button uk-button-secondary n-bt",
                         href="./{}.html".format(web_title_next))
            else:
                dmtags.a("Next",
                         cls="uk-button uk-button-secondary h-bt",
                         href="./{}.html".format(web_title_next))

        with _button_bottom_div:
            if web_title_pre != "":
                dmtags.a("Prev",
                         cls="uk-button uk-button-primary n-bt",
                         href="./{}.html".format(web_title_pre))
            else:
                dmtags.a("Prev",
                         cls="uk-button uk-button-primary h-bt",
                         href="./{}.html".format(web_title_pre))
            if is_mainpage:
                dmtags.a("Index",
                         cls="uk-button uk-button-primary n-bt",
                         href="../{}.html".format(parent_web_title))
            if web_title_next != "":
                dmtags.a("Next",
                         cls="uk-button uk-button-primary n-bt",
                         href="./{}.html".format(web_title_next))
            else:
                dmtags.a("Next",
                         cls="uk-button uk-button-primary h-bt",
                         href="./{}.html".format(web_title_next))

    # create html file
    with open("{}.html".format(special_character_encode(path)),
              "w",
              encoding='utf8') as f:
        f.write("<!DOCTYPE html>\n")
        f.write(_html.render().replace("datafancybox", "data-fancybox"))
Esempio n. 15
0
    def report_header(self,
                      theme='lux',
                      highlight_color='#f1c40f',
                      navbar_bg='primary',
                      custom_css='',
                      **kwargs):
        """
        Controls the link and script tags in the head. This method should always be called
        at the top

        :param str theme: Name of any bootswatch theme. Default is lux
        :param str highlight_color: any rgb color. default is #f1c40f
        :param str script: warg Pass additional JS/jquery to add to header
        :param str custom_css: Pass additional custom CSS. This is in the header, and controls style for the whole report
        :param str navbar_bg: Controls the color of the navbar.
        :param bool bootstrap: Set to True to get default bootstrap theme. Does not work with local files
        :return: The head tag for the report.

        Example showing how to change the default theme:
            >>> r = report.report_header(theme='flatly')
        """

        if len(self.report_name) > 40:
            logging.warning('A report_name greater than 40 characters can \
            can cause the navbar to expand and break some functionality.')

        with self.document.head as report_head:
            # link and script builder for bootstrap 4
            tag.comment('Created using reportng by securisec')
            tag.meta(charset="utf-8",
                     name="viewport",
                     content="width=device-width, initial-scale=1")
            # main style components
            tag.script(src=rng.JSCSS.jquery)
            tag.script(src=rng.JSCSS.popper_js)
            tag.script(src=rng.JSCSS.bs4_js)
            if not self.search == False:
                tag.script(src=rng.JSCSS.mark_js)

            # JS for tooltip
            tag.command('JS for tooltip')
            tag.script(raw(rng.JSCustom.tooltip_js))

            # JS for mark_js
            tag.comment('JS for mark.js')
            tag.script(raw(rng.JSCustom.markjs_script))

            # JS to populate the navbar dropdown
            tag.comment('JS to populate the navbar dropdown')
            tag.script(raw(rng.JSCustom.populate_navbar_onload))

            # script that allows for smooth scrolling and adds padding for navbar
            tag.comment(
                'script that allows for smooth scrolling and adds padding for navbar'
            )
            tag.script(raw(rng.JSCustom.smoothscroll_navbar_pad))

            # js to filter in the dropdown menu
            tag.comment('js to filter in the dropdown menu')
            tag.script(raw(rng.JSCustom.dropdown_filter))

            # user insterted JS
            if 'script' in kwargs:
                tag.comment('User inserted JS')
                tag.script(raw(kwargs.get('script')))

            # bootswatch style sheets
            tag.comment('style sheets')
            if 'bootstrap' in kwargs:
                if kwargs['bootstrap']:
                    bootswatch = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css'
            elif theme != 'lux':
                bootswatch = "https://bootswatch.com/4/%s/bootstrap.min.css" % theme
            else:
                bootswatch = rng.JSCSS.bootswatch
            tag.link(rel="stylesheet",
                     type="text/css",
                     href=bootswatch,
                     id='bootswatch')
            tag.link(href=rng.JSCSS.font_awesome, rel="stylesheet")

            # constructing this way to avoid loading un needed js and css
            # css for asciinema
            if self.asciinema == True:
                tag.comment('css for asciinema')
                tag.link(rel="stylesheet",
                         type="text/css",
                         href=rng.JSCSS.asciinema_css)

            # css and js for highlight.js
            if self.code == True:
                tag.comment('css and js for highlight.js')
                tag.link(rel="stylesheet", href=rng.JSCSS.highlightjs_css)
                tag.script(src=rng.JSCSS.highlightjs_js)
                tag.script(
                    raw("""
                    hljs.initHighlightingOnLoad();
                    """))

            # script for progress bar
            if self.pbar == True:
                tag.comment('js for progress bar')
                tag.script(src=rng.JSCSS.progressbar_js)
                tag.script(raw(rng.JSCustom.progress_bar))

            # search highlight color control
            tag.comment('search highlight color control')
            # tag.style('span.highlight{background:  %s;}' %
            #           highlight_color)
            tag.style(
                raw("""
                mark {background: %s;}
                mark.current {background: orangered;}
                """ % highlight_color))

            if custom_css != '':
                tag.comment('Custom CSS starts here')
                tag.style(raw(custom_css))

            # Navbar on top with 2 margin to seperate from first jumbotron. add class mb-2
            with tag.nav(
                    _class=
                    "navbar navbar-expand-lg navbar-dark bg-%s sticky-top" %
                    rng.HelperFunctions.color_to_tag(navbar_bg)):
                tag.a(self.brand, _class="navbar-brand", href="#")
                # sets the report title on the navbar
                tag.span(self.report_name, _class="navbar-text text-secondary")
                # theme previewer
                if self.theme_preview:
                    tag.comment('Theme previewer')
                    raw(rng.CustomHTML.themes_preview)
                # Button for responsive navbar
                with tag.button(_class="navbar-toggler",
                                type="button",
                                data_toggle="collapse",
                                data_target="#navbarid",
                                aria_controls="navbarColor01",
                                aria_expanded="false",
                                aria_label="Toggle navigation"):
                    tag.span(_class="navbar-toggler-icon")

                # Search box and button on navbar
                # make sure to include the word context to div/p tags to make it searchable
                with tag.div(_class=
                             "navbar-collapse collapse justify-content-md-end",
                             id="navbarid"):
                    # ul class to house the navbar navigation items
                    with tag.ul(_class="navbar-nav"):
                        with tag.li(_class="nav-item"):
                            # add dropdown menu to house h1 tags from sections
                            with tag.div(_class="dropdown"):
                                tag.button(
                                    'sections',
                                    _class=
                                    "btn btn-secondary btn-block dropdown-toggle",
                                    type="button",
                                    id="dropdownMenuButton",
                                    data_toggle="dropdown",
                                    aria_haspopup="true",
                                    aria_expanded="false")
                                with tag.ul(
                                        _class=
                                        "dropdown-menu dropdown-menu-right",
                                        aria_labelledby="dropdownMenuButton",
                                        id="ddmenu",
                                        style=
                                        "max-height: 300px; height: auto; overflow: scroll"
                                ):
                                    # input box for filtering dropdown
                                    tag.input(_class="form-control-sm",
                                              id="ddfilter",
                                              type="text",
                                              placeholder="Filter..")
                        # highlight box form starts here
                        # input for search box
                        if not self.search == False:
                            tag.input(_class="form-control mr-sm-2",
                                      type="search",
                                      placeholder="Search",
                                      data_toggle="tooltip",
                                      data_placement="bottom",
                                      title="Regex capable. Case sensitive.")
                            # Show search hit count
                            tag.span(
                                "0",
                                id="searchcount",
                                style=
                                "color:%s; font-size: initial; padding-right: 8; align-self: center;"
                                % highlight_color)
                            raw("""
                                <button data-search="next" class="btn btn-sm btn-secondary">&darr;</button>
                                <button data-search="prev" class="btn btn-sm btn-secondary">&uarr;</button>
                                """

                                # <button data-search="clear" class="btn btn-sm btn-secondary">✖</button>
                                )
            if self.theme_preview:
                # theme preview jquery
                tag.comment('theme preview jquery')
                tag.script(raw(rng.JSCustom.themes_preview))
        return str(report_head)