Strips text from the given html string, leaving only tags.
    This functionality requires BeautifulSoup, nothing will be
    done otherwise.

    This isn't perfect. Someone could put javascript in here:
        <a onClick="alert('hi');">test</a>

        So if you use valid_tags, you still need to trust your data entry.
        Or we could try:
          - only escape the non matching bits
          - use BeautifulSoup to understand the elements, escape everything
            else and remove potentially harmful attributes (onClick).
          - Remove this feature entirely. Half-escaping things securely is
            very difficult, developers should not be lured into a false
            sense of security.

def escape_tags(value, valid_tags):
    """
    Strips text from the given html string, leaving only tags.
    This functionality requires BeautifulSoup, nothing will be
    done otherwise.

    This isn't perfect. Someone could put javascript in here:
        <a onClick="alert('hi');">test</a>

        So if you use valid_tags, you still need to trust your data entry.
        Or we could try:
          - only escape the non matching bits
          - use BeautifulSoup to understand the elements, escape everything
            else and remove potentially harmful attributes (onClick).
          - Remove this feature entirely. Half-escaping things securely is
            very difficult, developers should not be lured into a false
            sense of security.
    """
    # 1. escape everything
    value = conditional_escape(value)

    # 2. Reenable certain tags
    if valid_tags:
        # TODO: precompile somewhere once?
        tag_re = re.compile(r'&lt;(\s*/?\s*(%s))(.*?\s*)&gt;' %
                            '|'.join(re.escape(tag) for tag in valid_tags))
        value = tag_re.sub(_replace_quot, value)

    # Allow comments to be hidden
    value = value.replace("&lt;!--", "<!--").replace("--&gt;", "-->")

    return mark_safe(value)