v2ex/babel/ext/bleach/__init__.py
def linkify(text, nofollow=True, target=None, filter_url=identity,
            filter_text=identity, skip_pre=False, parse_email=False):
    """Convert URL-like strings in an HTML fragment to links.

    linkify() converts strings that look like URLs or domain names in a
    blob of text that may be an HTML fragment to links, while preserving
    (a) links already in the string, (b) urls found in attributes, and
    (c) email addresses.

    If the nofollow argument is True (the default) then rel="nofollow"
    will be added to links created by linkify() as well as links already
    found in the text.

    The target argument will optionally add a target attribute with the
    given value to links created by linkify() as well as links already
    found in the text.

    linkify() uses up to two filters on each link. For links created by
    linkify(), the href attribute is passed through filter_url()
    and the text of the link is passed through filter_text(). For links
    already found in the document, the href attribute is passed through
    filter_url(), but the text is untouched.
    """
    text = force_unicode(text)

    if not text:
        return u''

    parser = html5lib.HTMLParser(tokenizer=HTMLSanitizer)

    forest = parser.parseFragment(text)

    if nofollow:
        rel = u'rel="nofollow"'
    else:
        rel = u''

    def replace_nodes(tree, new_frag, node):
        new_tree = parser.parseFragment(new_frag)
        for n in new_tree.childNodes:
            tree.insertBefore(n, node)
        tree.removeChild(node)

    def strip_wrapping_parentheses(fragment):
        """Strips wrapping parentheses.

        Returns a tuple of the following format::

            (string stripped from wrapping parentheses,
             count of stripped opening parentheses,
             count of stripped closing parentheses)
        """
        opening_parentheses = closing_parentheses = 0
        # Count consecutive opening parentheses
        # at the beginning of the fragment (string).
        for char in fragment:
            if char == '(':
                opening_parentheses += 1
            else:
                break

        if opening_parentheses:
            newer_frag = ''
            # Cut the consecutive opening brackets from the fragment.
            fragment = fragment[opening_parentheses:]
            # Reverse the fragment for easier detection of parentheses
            # inside the URL.
            reverse_fragment = fragment[::-1]
            skip = False
            for char in reverse_fragment:
                # Remove the closing parentheses if it has a matching
                # opening parentheses (they are balanced).
                if (char == ')' and
                        closing_parentheses < opening_parentheses and
                        not skip):
                    closing_parentheses += 1
                    continue
                # Do not remove ')' from the URL itself.
                elif char != ')':
                    skip = True
                newer_frag += char
            fragment = newer_frag[::-1]

        return fragment, opening_parentheses, closing_parentheses

    def linkify_nodes(tree, parse_text=True):
        for node in tree.childNodes:
            if node.type == NODE_TEXT and parse_text:
                new_frag = node.toxml()
                if parse_email:
                    new_frag = re.sub(email_re, email_repl, new_frag)
                    if new_frag != node.toxml():
                        replace_nodes(tree, new_frag, node)
                        linkify_nodes(tree, False)
                        continue
                new_frag = re.sub(url_re, link_repl, new_frag)
                replace_nodes(tree, new_frag, node)
            elif node.name == 'a':
                if 'href' in node.attributes:
                    if nofollow:
                        node.attributes['rel'] = 'nofollow'
                    if target is not None:
                        node.attributes['target'] = target
                    href = node.attributes['href']
                    node.attributes['href'] = filter_url(href)
            elif skip_pre and node.name == 'pre':
                linkify_nodes(node, False)
            else:
                linkify_nodes(node)

    def email_repl(match):
        repl = u'<a href="mailto:%(mail)s">%(mail)s</a>'
        return repl % {'mail': match.group(0).replace('"', '&quot;')}

    def link_repl(match):
        url = match.group(0)
        open_brackets = close_brackets = 0
        if url.startswith('('):
            url, open_brackets, close_brackets = (
                    strip_wrapping_parentheses(url)
            )
        end = u''
        m = re.search(punct_re, url)
        if m:
            end = m.group(0)
            url = url[0:m.start()]
        if re.search(proto_re, url):
            href = url
        else:
            href = u''.join([u'http://', url])

        repl = u'%s<a href="%s" %s>%s</a>%s%s'

        attribs = [rel]
        if target is not None:
            attribs.append('target="%s"' % target)

        return repl % ('(' * open_brackets,
                       filter_url(href), ' '.join(attribs), filter_text(url),
                       end, ')' * close_brackets)

    linkify_nodes(forest)

    return _render(forest)
Convert URL-like strings in an HTML fragment to links.

    linkify() converts strings that look like URLs or domain names in a
    blob of text that may be an HTML fragment to links, while preserving
    (a) links already in the string, (b) urls found in attributes, and
    (c) email addresses.

    If the nofollow argument is True (the default) then rel="nofollow"
    will be added to links created by linkify() as well as links already
    found in the text.

    The target argument will optionally add a target attribute with the
    given value to links created by linkify() as well as links already
    found in the text.

    linkify() uses up to two filters on each link. For links created by
    linkify(), the href attribute is passed through filter_url()
    and the text of the link is passed through filter_text(). For links
    already found in the document, the href attribute is passed through
    filter_url(), but the text is untouched.
    
Convert URL-like strings in an HTML fragment to links.
linkify() converts strings that look like URLs or domain names in a
blob of text that may be an HTML fragment to links, while preserving
(a) links already in the string, (b) urls found in attributes, and
(c) email addresses.

If the nofollow argument is True (the default) then rel="nofollow"
will be added to links created by linkify() as well as links already
found in the text.

The target argument will optionally add a target attribute with the
given value to links created by linkify() as well as links already
found in the text.

linkify() uses up to two filters on each link. For links created by
linkify(), the href attribute is passed through filter_url()
and the text of the link is passed through filter_text(). For links
already found in the document, the href attribute is passed through
filter_url(), but the text is untouched.
Convert URL - like strings in an HTML fragment to links . linkify () converts strings that look like URLs or domain names in a blob of text that may be an HTML fragment to links while preserving ( a ) links already in the string ( b ) urls found in attributes and ( c ) email addresses . If the nofollow argument is True ( the default ) then rel = " nofollow " will be added to links created by linkify () as well as links already found in the text . The target argument will optionally add a target attribute with the given value to links created by linkify () as well as links already found in the text . linkify () uses up to two filters on each link . For links created by linkify () the href attribute is passed through filter_url () and the text of the link is passed through filter_text () . For links already found in the document the href attribute is passed through filter_url () but the text is untouched .
def linkify(text, nofollow=True, target=None, filter_url=identity,
            filter_text=identity, skip_pre=False, parse_email=False):
    text = force_unicode(text)
    if not text:
        return u''
    parser = html5lib.HTMLParser(tokenizer=HTMLSanitizer)
    forest = parser.parseFragment(text)
    if nofollow:
        rel = u'rel="nofollow"'
    else:
        rel = u''
    def replace_nodes(tree, new_frag, node):
        new_tree = parser.parseFragment(new_frag)
        for n in new_tree.childNodes:
            tree.insertBefore(n, node)
        tree.removeChild(node)
    def strip_wrapping_parentheses(fragment):
        opening_parentheses = closing_parentheses = 0
        for char in fragment:
            if char == '(':
                opening_parentheses += 1
            else:
                break
        if opening_parentheses:
            newer_frag = ''
            fragment = fragment[opening_parentheses:]
            reverse_fragment = fragment[::-1]
            skip = False
            for char in reverse_fragment:
                if (char == ')' and
                        closing_parentheses < opening_parentheses and
                        not skip):
                    closing_parentheses += 1
                    continue
                elif char != ')':
                    skip = True
                newer_frag += char
            fragment = newer_frag[::-1]
        return fragment, opening_parentheses, closing_parentheses
    def linkify_nodes(tree, parse_text=True):
        for node in tree.childNodes:
            if node.type == NODE_TEXT and parse_text:
                new_frag = node.toxml()
                if parse_email:
                    new_frag = re.sub(email_re, email_repl, new_frag)
                    if new_frag != node.toxml():
                        replace_nodes(tree, new_frag, node)
                        linkify_nodes(tree, False)
                        continue
                new_frag = re.sub(url_re, link_repl, new_frag)
                replace_nodes(tree, new_frag, node)
            elif node.name == 'a':
                if 'href' in node.attributes:
                    if nofollow:
                        node.attributes['rel'] = 'nofollow'
                    if target is not None:
                        node.attributes['target'] = target
                    href = node.attributes['href']
                    node.attributes['href'] = filter_url(href)
            elif skip_pre and node.name == 'pre':
                linkify_nodes(node, False)
            else:
                linkify_nodes(node)
    def email_repl(match):
        repl = u'<a href="mailto:%(mail)s">%(mail)s</a>'
        return repl % {'mail': match.group(0).replace('"', '&quot;')}
    def link_repl(match):
        url = match.group(0)
        open_brackets = close_brackets = 0
        if url.startswith('('):
            url, open_brackets, close_brackets = (
                    strip_wrapping_parentheses(url)
            )
        end = u''
        m = re.search(punct_re, url)
        if m:
            end = m.group(0)
            url = url[0:m.start()]
        if re.search(proto_re, url):
            href = url
        else:
            href = u''.join([u'http://', url])
        repl = u'%s<a href="%s" %s>%s</a>%s%s'
        attribs = [rel]
        if target is not None:
            attribs.append('target="%s"' % target)
        return repl % ('(' * open_brackets,
                       filter_url(href), ' '.join(attribs), filter_text(url),
                       end, ')' * close_brackets)
    linkify_nodes(forest)
    return _render(forest)
def linkify ( text , nofollow = True , target = None , filter_url = identity , filter_text = identity , skip_pre = False , parse_email = False ) : text = force_unicode ( text ) if not text : return u'' parser = html5lib . HTMLParser ( tokenizer = HTMLSanitizer ) forest = parser . parseFragment ( text ) if nofollow : rel = u'rel="nofollow"' else : rel = u'' def replace_nodes ( tree , new_frag , node ) : new_tree = parser . parseFragment ( new_frag ) for n in new_tree . childNodes : tree . insertBefore ( n , node ) tree . removeChild ( node ) def strip_wrapping_parentheses ( fragment ) : """Strips wrapping parentheses.

        Returns a tuple of the following format::

            (string stripped from wrapping parentheses,
             count of stripped opening parentheses,
             count of stripped closing parentheses)
        """ opening_parentheses = closing_parentheses = 0 for char in fragment : if char == '(' : opening_parentheses += 1 else : break if opening_parentheses : newer_frag = '' fragment = fragment [ opening_parentheses : ] reverse_fragment = fragment [ : : - 1 ] skip = False for char in reverse_fragment : if ( char == ')' and closing_parentheses < opening_parentheses and not skip ) : closing_parentheses += 1 continue elif char != ')' : skip = True newer_frag += char fragment = newer_frag [ : : - 1 ] return fragment , opening_parentheses , closing_parentheses def linkify_nodes ( tree , parse_text = True ) : for node in tree . childNodes : if node . type == NODE_TEXT and parse_text : new_frag = node . toxml ( ) if parse_email : new_frag = re . sub ( email_re , email_repl , new_frag ) if new_frag != node . toxml ( ) : replace_nodes ( tree , new_frag , node ) linkify_nodes ( tree , False ) continue new_frag = re . sub ( url_re , link_repl , new_frag ) replace_nodes ( tree , new_frag , node ) elif node . name == 'a' : if 'href' in node . attributes : if nofollow : node . attributes [ 'rel' ] = 'nofollow' if target is not None : node . attributes [ 'target' ] = target href = node . attributes [ 'href' ] node . attributes [ 'href' ] = filter_url ( href ) elif skip_pre and node . name == 'pre' : linkify_nodes ( node , False ) else : linkify_nodes ( node ) def email_repl ( match ) : repl = u'<a href="mailto:%(mail)s">%(mail)s</a>' return repl % { 'mail' : match . group ( 0 ) . replace ( '"' , '&quot;' ) } def link_repl ( match ) : url = match . group ( 0 ) open_brackets = close_brackets = 0 if url . startswith ( '(' ) : url , open_brackets , close_brackets = ( strip_wrapping_parentheses ( url ) ) end = u'' m = re . search ( punct_re , url ) if m : end = m . group ( 0 ) url = url [ 0 : m . start ( ) ] if re . search ( proto_re , url ) : href = url else : href = u'' . join ( [ u'http://' , url ] ) repl = u'%s<a href="%s" %s>%s</a>%s%s' attribs = [ rel ] if target is not None : attribs . append ( 'target="%s"' % target ) return repl % ( '(' * open_brackets , filter_url ( href ) , ' ' . join ( attribs ) , filter_text ( url ) , end , ')' * close_brackets ) linkify_nodes ( forest ) return _render ( forest )
Convert URL-like strings in an HTML fragment to links.
Convert URL - like strings in an HTML fragment to links .
"""Convert URL-like strings in an HTML fragment to links.

    linkify() converts strings that look like URLs or domain names in a
    blob of text that may be an HTML fragment to links, while preserving
    (a) links already in the string, (b) urls found in attributes, and
    (c) email addresses.

    If the nofollow argument is True (the default) then rel="nofollow"
    will be added to links created by linkify() as well as links already
    found in the text.

    The target argument will optionally add a target attribute with the
    given value to links created by linkify() as well as links already
    found in the text.

    linkify() uses up to two filters on each link. For links created by
    linkify(), the href attribute is passed through filter_url()
    and the text of the link is passed through filter_text(). For links
    already found in the document, the href attribute is passed through
    filter_url(), but the text is untouched.
    """ """Strips wrapping parentheses.

        Returns a tuple of the following format::

            (string stripped from wrapping parentheses,
             count of stripped opening parentheses,
             count of stripped closing parentheses)
        """ # Count consecutive opening parentheses # at the beginning of the fragment (string). # Cut the consecutive opening brackets from the fragment. # Reverse the fragment for easier detection of parentheses # inside the URL. # Remove the closing parentheses if it has a matching # opening parentheses (they are balanced). # Do not remove ')' from the URL itself.
text
nofollow
target
filter_url
filter_text
skip_pre
parse_email