'Use data from the twitter API to turn links, mentions and media into A
tags. Also convert unicode emojis to images.
This works by using the urls, user_mentions and media data from
the twitter API and searching for unicode emojis in the text using
`unicode_emoji_regex`.
The first step is finding the locations of the URLs, mentions, media and
emoji in the text. For each match we build a dictionary with type, the start
location, end location, the URL to link to, and the text(codepoint and title
in case of emojis) to be used in the link(image in case of emojis).
Next we sort the matches by start location. And for each we add the
text from the end of the last link to the start of the current link to
the output. The text needs to added to the text attribute of the first
node (the P tag) or the tail the last link created.
Finally we add any remaining text to the last node.'

def twitter_text(self, text, urls, user_mentions, media):

    to_process = []
    for url_data in urls:
        short_url = url_data['url']
        full_url = url_data['expanded_url']
        for match in re.finditer(re.escape(short_url), text, re.IGNORECASE):
            to_process.append({'type': 'url', 'start': match.start(), 'end': match.end(), 'url': short_url, 'text': full_url})
    for user_mention in user_mentions:
        screen_name = user_mention['screen_name']
        mention_string = (u'@' + screen_name)
        for match in re.finditer(re.escape(mention_string), text, re.IGNORECASE):
            to_process.append({'type': 'mention', 'start': match.start(), 'end': match.end(), 'url': (u'https://twitter.com/' + force_text(urllib.parse.quote(force_str(screen_name)))), 'text': mention_string})
    for media_item in media:
        short_url = media_item['url']
        expanded_url = media_item['expanded_url']
        for match in re.finditer(re.escape(short_url), text, re.IGNORECASE):
            to_process.append({'type': 'media', 'start': match.start(), 'end': match.end(), 'url': short_url, 'text': expanded_url})
    for match in re.finditer(unicode_emoji_regex, text, re.IGNORECASE):
        orig_syntax = match.group('syntax')
        codepoint = unicode_emoji_to_codepoint(orig_syntax)
        if (codepoint in codepoint_to_name):
            display_string = ((':' + codepoint_to_name[codepoint]) + ':')
            to_process.append({'type': 'emoji', 'start': match.start(), 'end': match.end(), 'codepoint': codepoint, 'title': display_string})
    to_process.sort(key=(lambda x: x['start']))
    p = current_node = markdown.util.etree.Element('p')
    def set_text(text):
        '\n                                                Helper    to    set    the    text    or    the    tail    of    the    current_node\n                                                '
        if (current_node == p):
            current_node.text = text
        else:
            current_node.tail = text
    current_index = 0
    for item in to_process:
        if (item['start'] < current_index):
            continue
        set_text(text[current_index:item['start']])
        current_index = item['end']
        if (item['type'] != 'emoji'):
            current_node = elem = url_to_a(item['url'], item['text'])
        else:
            current_node = elem = make_emoji(item['codepoint'], item['title'])
        p.append(elem)
    set_text(text[current_index:])
    return p
