Hashes ordered and unordered lists.

    re_list captures as many consecutive list items as possible and
    groups them into one list. Before hashing the lists, the items
    are recursively converted from Markdown to HTML. Upon unhashing,
    the lists will be ready in their final form.

    An attempt at list formatting is done by adding two spaces to
    each list item. Since list conversion is a recursive process,
    each nested list will add an additional two spaces to list items.
    The only exception is for pre blocks -- these are "pulled out" of
    indentation when the list is unhashed.

    A note on implementation: Markdown syntax for list items is
    essentially the same, except everything is shifted to the right by
    four spaces. This assumption is made when recursively converting
    list items.

    List items that consist of only a single paragraph of text are
    "pulled out" of the paragraph (that is, the <p> tag is removed).
    This differs slightly from original Markdown syntax, which encloses
    list items in <p> tags if list items are separated by one or more
    blank lines.

def hash_lists(text, hashes, markdown_obj):
    """Hashes ordered and unordered lists.

    re_list captures as many consecutive list items as possible and
    groups them into one list. Before hashing the lists, the items
    are recursively converted from Markdown to HTML. Upon unhashing,
    the lists will be ready in their final form.

    An attempt at list formatting is done by adding two spaces to
    each list item. Since list conversion is a recursive process,
    each nested list will add an additional two spaces to list items.
    The only exception is for pre blocks -- these are "pulled out" of
    indentation when the list is unhashed.

    A note on implementation: Markdown syntax for list items is
    essentially the same, except everything is shifted to the right by
    four spaces. This assumption is made when recursively converting
    list items.

    List items that consist of only a single paragraph of text are
    "pulled out" of the paragraph (that is, the <p> tag is removed).
    This differs slightly from original Markdown syntax, which encloses
    list items in <p> tags if list items are separated by one or more
    blank lines.
    """
    for style, marker in (('u', '[+*-]'), ('o', r'\d+\.')):
        list_re = re.compile(re_list % (marker, marker), re.S | re.X)
        # import pdb
        # pdb.set_trace()
        for match in list_re.finditer(text):
            if not match:
                continue
            lst = match.group(1)
            items = re.split(r'(?:\n|\A) {0,3}%s ' % marker, lst)[1:]
            whole_list = ''
            for item in items:
                item = re.sub(r'^ {1,4}', '', item, flags=re.M)
                item = markdown_obj.convert(item)
                par_match = re.match('<p>(.*?)</p>', item, flags=re.S)
                if par_match and par_match.group(0) == item.strip():
                    item = par_match.group(1)
                whole_list += '<li>{}</li>\n'.format(item)
            whole_list = '<{0}l>\n{1}\n</{0}l>'.format(
                    style,
                    re.sub('^', '  ', whole_list.strip(), flags=re.M))
            hashed = hash_text(whole_list, 'list')
            hashes[hashed] = whole_list
            start = text.index(match.group(0))
            end = start + len(match.group(0))
            text = text[:start] + '\n\n' + hashed + '\n\n' + text[end:]
    return text