diff env/lib/python3.7/site-packages/mistune.py @ 5:9b1c78e6ba9c draft default tip

"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author shellac
date Mon, 01 Jun 2020 08:59:25 -0400
parents 79f47841a781
children
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/mistune.py	Thu May 14 16:47:39 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1184 +0,0 @@
-# coding: utf-8
-"""
-    mistune
-    ~~~~~~~
-
-    The fastest markdown parser in pure Python with renderer feature.
-
-    :copyright: (c) 2014 - 2018 by Hsiaoming Yang.
-"""
-
-import re
-import inspect
-
-__version__ = '0.8.4'
-__author__ = 'Hsiaoming Yang <me@lepture.com>'
-__all__ = [
-    'BlockGrammar', 'BlockLexer',
-    'InlineGrammar', 'InlineLexer',
-    'Renderer', 'Markdown',
-    'markdown', 'escape',
-]
-
-
-_key_pattern = re.compile(r'\s+')
-_nonalpha_pattern = re.compile(r'\W')
-_escape_pattern = re.compile(r'&(?!#?\w+;)')
-_newline_pattern = re.compile(r'\r\n|\r')
-_block_quote_leading_pattern = re.compile(r'^ *> ?', flags=re.M)
-_block_code_leading_pattern = re.compile(r'^ {4}', re.M)
-_inline_tags = [
-    'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data',
-    'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark',
-    'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr', 'ins', 'del',
-    'img', 'font',
-]
-_pre_tags = ['pre', 'script', 'style']
-_valid_end = r'(?!:/|[^\w\s@]*@)\b'
-_valid_attr = r'''\s*[a-zA-Z\-](?:\s*\=\s*(?:"[^"]*"|'[^']*'|[^\s'">]+))?'''
-_block_tag = r'(?!(?:%s)\b)\w+%s' % ('|'.join(_inline_tags), _valid_end)
-_scheme_blacklist = ('javascript:', 'vbscript:')
-
-
-def _pure_pattern(regex):
-    pattern = regex.pattern
-    if pattern.startswith('^'):
-        pattern = pattern[1:]
-    return pattern
-
-
-def _keyify(key):
-    key = escape(key.lower(), quote=True)
-    return _key_pattern.sub(' ', key)
-
-
-def escape(text, quote=False, smart_amp=True):
-    """Replace special characters "&", "<" and ">" to HTML-safe sequences.
-
-    The original cgi.escape will always escape "&", but you can control
-    this one for a smart escape amp.
-
-    :param quote: if set to True, " and ' will be escaped.
-    :param smart_amp: if set to False, & will always be escaped.
-    """
-    if smart_amp:
-        text = _escape_pattern.sub('&amp;', text)
-    else:
-        text = text.replace('&', '&amp;')
-    text = text.replace('<', '&lt;')
-    text = text.replace('>', '&gt;')
-    if quote:
-        text = text.replace('"', '&quot;')
-        text = text.replace("'", '&#39;')
-    return text
-
-
-def escape_link(url):
-    """Remove dangerous URL schemes like javascript: and escape afterwards."""
-    lower_url = url.lower().strip('\x00\x1a \n\r\t')
-
-    for scheme in _scheme_blacklist:
-        if re.sub(r'[^A-Za-z0-9\/:]+', '', lower_url).startswith(scheme):
-            return ''
-    return escape(url, quote=True, smart_amp=False)
-
-
-def preprocessing(text, tab=4):
-    text = _newline_pattern.sub('\n', text)
-    text = text.expandtabs(tab)
-    text = text.replace('\u2424', '\n')
-    pattern = re.compile(r'^ +$', re.M)
-    return pattern.sub('', text)
-
-
-class BlockGrammar(object):
-    """Grammars for block level tokens."""
-
-    def_links = re.compile(
-        r'^ *\[([^^\]]+)\]: *'  # [key]:
-        r'<?([^\s>]+)>?'  # <link> or link
-        r'(?: +["(]([^\n]+)[")])? *(?:\n+|$)'
-    )
-    def_footnotes = re.compile(
-        r'^\[\^([^\]]+)\]: *('
-        r'[^\n]*(?:\n+|$)'  # [^key]:
-        r'(?: {1,}[^\n]*(?:\n+|$))*'
-        r')'
-    )
-
-    newline = re.compile(r'^\n+')
-    block_code = re.compile(r'^( {4}[^\n]+\n*)+')
-    fences = re.compile(
-        r'^ *(`{3,}|~{3,}) *([^`\s]+)? *\n'  # ```lang
-        r'([\s\S]+?)\s*'
-        r'\1 *(?:\n+|$)'  # ```
-    )
-    hrule = re.compile(r'^ {0,3}[-*_](?: *[-*_]){2,} *(?:\n+|$)')
-    heading = re.compile(r'^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)')
-    lheading = re.compile(r'^([^\n]+)\n *(=|-)+ *(?:\n+|$)')
-    block_quote = re.compile(r'^( *>[^\n]+(\n[^\n]+)*\n*)+')
-    list_block = re.compile(
-        r'^( *)(?=[*+-]|\d+\.)(([*+-])?(?:\d+\.)?) [\s\S]+?'
-        r'(?:'
-        r'\n+(?=\1?(?:[-*_] *){3,}(?:\n+|$))'  # hrule
-        r'|\n+(?=%s)'  # def links
-        r'|\n+(?=%s)'  # def footnotes\
-        r'|\n+(?=\1(?(3)\d+\.|[*+-]) )'   # heterogeneous bullet
-        r'|\n{2,}'
-        r'(?! )'
-        r'(?!\1(?:[*+-]|\d+\.) )\n*'
-        r'|'
-        r'\s*$)' % (
-            _pure_pattern(def_links),
-            _pure_pattern(def_footnotes),
-        )
-    )
-    list_item = re.compile(
-        r'^(( *)(?:[*+-]|\d+\.) [^\n]*'
-        r'(?:\n(?!\2(?:[*+-]|\d+\.) )[^\n]*)*)',
-        flags=re.M
-    )
-    list_bullet = re.compile(r'^ *(?:[*+-]|\d+\.) +')
-    paragraph = re.compile(
-        r'^((?:[^\n]+\n?(?!'
-        r'%s|%s|%s|%s|%s|%s|%s|%s|%s'
-        r'))+)\n*' % (
-            _pure_pattern(fences).replace(r'\1', r'\2'),
-            _pure_pattern(list_block).replace(r'\1', r'\3'),
-            _pure_pattern(hrule),
-            _pure_pattern(heading),
-            _pure_pattern(lheading),
-            _pure_pattern(block_quote),
-            _pure_pattern(def_links),
-            _pure_pattern(def_footnotes),
-            '<' + _block_tag,
-        )
-    )
-    block_html = re.compile(
-        r'^ *(?:%s|%s|%s) *(?:\n{2,}|\s*$)' % (
-            r'<!--[\s\S]*?-->',
-            r'<(%s)((?:%s)*?)>([\s\S]*?)<\/\1>' % (_block_tag, _valid_attr),
-            r'<%s(?:%s)*?\s*\/?>' % (_block_tag, _valid_attr),
-        )
-    )
-    table = re.compile(
-        r'^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*'
-    )
-    nptable = re.compile(
-        r'^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*'
-    )
-    text = re.compile(r'^[^\n]+')
-
-
-class BlockLexer(object):
-    """Block level lexer for block grammars."""
-    grammar_class = BlockGrammar
-
-    default_rules = [
-        'newline', 'hrule', 'block_code', 'fences', 'heading',
-        'nptable', 'lheading', 'block_quote',
-        'list_block', 'block_html', 'def_links',
-        'def_footnotes', 'table', 'paragraph', 'text'
-    ]
-
-    list_rules = (
-        'newline', 'block_code', 'fences', 'lheading', 'hrule',
-        'block_quote', 'list_block', 'block_html', 'text',
-    )
-
-    footnote_rules = (
-        'newline', 'block_code', 'fences', 'heading',
-        'nptable', 'lheading', 'hrule', 'block_quote',
-        'list_block', 'block_html', 'table', 'paragraph', 'text'
-    )
-
-    def __init__(self, rules=None, **kwargs):
-        self.tokens = []
-        self.def_links = {}
-        self.def_footnotes = {}
-
-        if not rules:
-            rules = self.grammar_class()
-
-        self.rules = rules
-        self._max_recursive_depth = kwargs.get('max_recursive_depth', 6)
-        self._list_depth = 0
-        self._blockquote_depth = 0
-
-    def __call__(self, text, rules=None):
-        return self.parse(text, rules)
-
-    def parse(self, text, rules=None):
-        text = text.rstrip('\n')
-
-        if not rules:
-            rules = self.default_rules
-
-        def manipulate(text):
-            for key in rules:
-                rule = getattr(self.rules, key)
-                m = rule.match(text)
-                if not m:
-                    continue
-                getattr(self, 'parse_%s' % key)(m)
-                return m
-            return False  # pragma: no cover
-
-        while text:
-            m = manipulate(text)
-            if m is not False:
-                text = text[len(m.group(0)):]
-                continue
-            if text:  # pragma: no cover
-                raise RuntimeError('Infinite loop at: %s' % text)
-        return self.tokens
-
-    def parse_newline(self, m):
-        length = len(m.group(0))
-        if length > 1:
-            self.tokens.append({'type': 'newline'})
-
-    def parse_block_code(self, m):
-        # clean leading whitespace
-        code = _block_code_leading_pattern.sub('', m.group(0))
-        self.tokens.append({
-            'type': 'code',
-            'lang': None,
-            'text': code,
-        })
-
-    def parse_fences(self, m):
-        self.tokens.append({
-            'type': 'code',
-            'lang': m.group(2),
-            'text': m.group(3),
-        })
-
-    def parse_heading(self, m):
-        self.tokens.append({
-            'type': 'heading',
-            'level': len(m.group(1)),
-            'text': m.group(2),
-        })
-
-    def parse_lheading(self, m):
-        """Parse setext heading."""
-        self.tokens.append({
-            'type': 'heading',
-            'level': 1 if m.group(2) == '=' else 2,
-            'text': m.group(1),
-        })
-
-    def parse_hrule(self, m):
-        self.tokens.append({'type': 'hrule'})
-
-    def parse_list_block(self, m):
-        bull = m.group(2)
-        self.tokens.append({
-            'type': 'list_start',
-            'ordered': '.' in bull,
-        })
-        self._list_depth += 1
-        if self._list_depth > self._max_recursive_depth:
-            self.tokens.append({'type': 'list_item_start'})
-            self.parse_text(m)
-            self.tokens.append({'type': 'list_item_end'})
-        else:
-            cap = m.group(0)
-            self._process_list_item(cap, bull)
-        self.tokens.append({'type': 'list_end'})
-        self._list_depth -= 1
-
-    def _process_list_item(self, cap, bull):
-        cap = self.rules.list_item.findall(cap)
-
-        _next = False
-        length = len(cap)
-
-        for i in range(length):
-            item = cap[i][0]
-
-            # remove the bullet
-            space = len(item)
-            item = self.rules.list_bullet.sub('', item)
-
-            # outdent
-            if '\n ' in item:
-                space = space - len(item)
-                pattern = re.compile(r'^ {1,%d}' % space, flags=re.M)
-                item = pattern.sub('', item)
-
-            # determine whether item is loose or not
-            loose = _next
-            if not loose and re.search(r'\n\n(?!\s*$)', item):
-                loose = True
-
-            rest = len(item)
-            if i != length - 1 and rest:
-                _next = item[rest-1] == '\n'
-                if not loose:
-                    loose = _next
-
-            if loose:
-                t = 'loose_item_start'
-            else:
-                t = 'list_item_start'
-
-            self.tokens.append({'type': t})
-            # recurse
-            self.parse(item, self.list_rules)
-            self.tokens.append({'type': 'list_item_end'})
-
-    def parse_block_quote(self, m):
-        self.tokens.append({'type': 'block_quote_start'})
-        self._blockquote_depth += 1
-        if self._blockquote_depth > self._max_recursive_depth:
-            self.parse_text(m)
-        else:
-            # clean leading >
-            cap = _block_quote_leading_pattern.sub('', m.group(0))
-            self.parse(cap)
-        self.tokens.append({'type': 'block_quote_end'})
-        self._blockquote_depth -= 1
-
-    def parse_def_links(self, m):
-        key = _keyify(m.group(1))
-        self.def_links[key] = {
-            'link': m.group(2),
-            'title': m.group(3),
-        }
-
-    def parse_def_footnotes(self, m):
-        key = _keyify(m.group(1))
-        if key in self.def_footnotes:
-            # footnote is already defined
-            return
-
-        self.def_footnotes[key] = 0
-
-        self.tokens.append({
-            'type': 'footnote_start',
-            'key': key,
-        })
-
-        text = m.group(2)
-
-        if '\n' in text:
-            lines = text.split('\n')
-            whitespace = None
-            for line in lines[1:]:
-                space = len(line) - len(line.lstrip())
-                if space and (not whitespace or space < whitespace):
-                    whitespace = space
-            newlines = [lines[0]]
-            for line in lines[1:]:
-                newlines.append(line[whitespace:])
-            text = '\n'.join(newlines)
-
-        self.parse(text, self.footnote_rules)
-
-        self.tokens.append({
-            'type': 'footnote_end',
-            'key': key,
-        })
-
-    def parse_table(self, m):
-        item = self._process_table(m)
-
-        cells = re.sub(r'(?: *\| *)?\n$', '', m.group(3))
-        cells = cells.split('\n')
-        for i, v in enumerate(cells):
-            v = re.sub(r'^ *\| *| *\| *$', '', v)
-            cells[i] = re.split(r' *(?<!\\)\| *', v)
-
-        item['cells'] = self._process_cells(cells)
-        self.tokens.append(item)
-
-    def parse_nptable(self, m):
-        item = self._process_table(m)
-
-        cells = re.sub(r'\n$', '', m.group(3))
-        cells = cells.split('\n')
-        for i, v in enumerate(cells):
-            cells[i] = re.split(r' *(?<!\\)\| *', v)
-
-        item['cells'] = self._process_cells(cells)
-        self.tokens.append(item)
-
-    def _process_table(self, m):
-        header = re.sub(r'^ *| *\| *$', '', m.group(1))
-        header = re.split(r' *\| *', header)
-        align = re.sub(r' *|\| *$', '', m.group(2))
-        align = re.split(r' *\| *', align)
-
-        for i, v in enumerate(align):
-            if re.search(r'^ *-+: *$', v):
-                align[i] = 'right'
-            elif re.search(r'^ *:-+: *$', v):
-                align[i] = 'center'
-            elif re.search(r'^ *:-+ *$', v):
-                align[i] = 'left'
-            else:
-                align[i] = None
-
-        item = {
-            'type': 'table',
-            'header': header,
-            'align': align,
-        }
-        return item
-
-    def _process_cells(self, cells):
-        for i, line in enumerate(cells):
-            for c, cell in enumerate(line):
-                # de-escape any pipe inside the cell here
-                cells[i][c] = re.sub('\\\\\|', '|', cell)
-
-        return cells
-
-    def parse_block_html(self, m):
-        tag = m.group(1)
-        if not tag:
-            text = m.group(0)
-            self.tokens.append({
-                'type': 'close_html',
-                'text': text
-            })
-        else:
-            attr = m.group(2)
-            text = m.group(3)
-            self.tokens.append({
-                'type': 'open_html',
-                'tag': tag,
-                'extra': attr,
-                'text': text
-            })
-
-    def parse_paragraph(self, m):
-        text = m.group(1).rstrip('\n')
-        self.tokens.append({'type': 'paragraph', 'text': text})
-
-    def parse_text(self, m):
-        text = m.group(0)
-        self.tokens.append({'type': 'text', 'text': text})
-
-
-class InlineGrammar(object):
-    """Grammars for inline level tokens."""
-
-    escape = re.compile(r'^\\([\\`*{}\[\]()#+\-.!_>~|])')  # \* \+ \! ....
-    inline_html = re.compile(
-        r'^(?:%s|%s|%s)' % (
-            r'<!--[\s\S]*?-->',
-            r'<(\w+%s)((?:%s)*?)\s*>([\s\S]*?)<\/\1>' % (
-                _valid_end, _valid_attr),
-            r'<\w+%s(?:%s)*?\s*\/?>' % (_valid_end, _valid_attr),
-        )
-    )
-    autolink = re.compile(r'^<([^ >]+(@|:)[^ >]+)>')
-    link = re.compile(
-        r'^!?\[('
-        r'(?:\[[^^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*'
-        r')\]\('
-        r'''\s*(<)?([\s\S]*?)(?(2)>)(?:\s+['"]([\s\S]*?)['"])?\s*'''
-        r'\)'
-    )
-    reflink = re.compile(
-        r'^!?\[('
-        r'(?:\[[^^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*'
-        r')\]\s*\[([^^\]]*)\]'
-    )
-    nolink = re.compile(r'^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]')
-    url = re.compile(r'''^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])''')
-    double_emphasis = re.compile(
-        r'^_{2}([\s\S]+?)_{2}(?!_)'  # __word__
-        r'|'
-        r'^\*{2}([\s\S]+?)\*{2}(?!\*)'  # **word**
-    )
-    emphasis = re.compile(
-        r'^\b_((?:__|[^_])+?)_\b'  # _word_
-        r'|'
-        r'^\*((?:\*\*|[^\*])+?)\*(?!\*)'  # *word*
-    )
-    code = re.compile(r'^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)')  # `code`
-    linebreak = re.compile(r'^ {2,}\n(?!\s*$)')
-    strikethrough = re.compile(r'^~~(?=\S)([\s\S]*?\S)~~')  # ~~word~~
-    footnote = re.compile(r'^\[\^([^\]]+)\]')
-    text = re.compile(r'^[\s\S]+?(?=[\\<!\[_*`~]|https?://| {2,}\n|$)')
-
-    def hard_wrap(self):
-        """Grammar for hard wrap linebreak. You don't need to add two
-        spaces at the end of a line.
-        """
-        self.linebreak = re.compile(r'^ *\n(?!\s*$)')
-        self.text = re.compile(
-            r'^[\s\S]+?(?=[\\<!\[_*`~]|https?://| *\n|$)'
-        )
-
-
-class InlineLexer(object):
-    """Inline level lexer for inline grammars."""
-    grammar_class = InlineGrammar
-
-    default_rules = [
-        'escape', 'inline_html', 'autolink', 'url',
-        'footnote', 'link', 'reflink', 'nolink',
-        'double_emphasis', 'emphasis', 'code',
-        'linebreak', 'strikethrough', 'text',
-    ]
-    inline_html_rules = [
-        'escape', 'inline_html', 'autolink', 'url', 'link', 'reflink',
-        'nolink', 'double_emphasis', 'emphasis', 'code',
-        'linebreak', 'strikethrough', 'text',
-    ]
-
-    def __init__(self, renderer, rules=None, **kwargs):
-        self.renderer = renderer
-        self.links = {}
-        self.footnotes = {}
-        self.footnote_index = 0
-
-        if not rules:
-            rules = self.grammar_class()
-
-        kwargs.update(self.renderer.options)
-        if kwargs.get('hard_wrap'):
-            rules.hard_wrap()
-
-        self.rules = rules
-
-        self._in_link = False
-        self._in_footnote = False
-        self._parse_inline_html = kwargs.get('parse_inline_html')
-
-    def __call__(self, text, rules=None):
-        return self.output(text, rules)
-
-    def setup(self, links, footnotes):
-        self.footnote_index = 0
-        self.links = links or {}
-        self.footnotes = footnotes or {}
-
-    def output(self, text, rules=None):
-        text = text.rstrip('\n')
-        if not rules:
-            rules = list(self.default_rules)
-
-        if self._in_footnote and 'footnote' in rules:
-            rules.remove('footnote')
-
-        output = self.renderer.placeholder()
-
-        def manipulate(text):
-            for key in rules:
-                pattern = getattr(self.rules, key)
-                m = pattern.match(text)
-                if not m:
-                    continue
-                self.line_match = m
-                out = getattr(self, 'output_%s' % key)(m)
-                if out is not None:
-                    return m, out
-            return False  # pragma: no cover
-
-        while text:
-            ret = manipulate(text)
-            if ret is not False:
-                m, out = ret
-                output += out
-                text = text[len(m.group(0)):]
-                continue
-            if text:  # pragma: no cover
-                raise RuntimeError('Infinite loop at: %s' % text)
-
-        return output
-
-    def output_escape(self, m):
-        text = m.group(1)
-        return self.renderer.escape(text)
-
-    def output_autolink(self, m):
-        link = m.group(1)
-        if m.group(2) == '@':
-            is_email = True
-        else:
-            is_email = False
-        return self.renderer.autolink(link, is_email)
-
-    def output_url(self, m):
-        link = m.group(1)
-        if self._in_link:
-            return self.renderer.text(link)
-        return self.renderer.autolink(link, False)
-
-    def output_inline_html(self, m):
-        tag = m.group(1)
-        if self._parse_inline_html and tag in _inline_tags:
-            text = m.group(3)
-            if tag == 'a':
-                self._in_link = True
-                text = self.output(text, rules=self.inline_html_rules)
-                self._in_link = False
-            else:
-                text = self.output(text, rules=self.inline_html_rules)
-            extra = m.group(2) or ''
-            html = '<%s%s>%s</%s>' % (tag, extra, text, tag)
-        else:
-            html = m.group(0)
-        return self.renderer.inline_html(html)
-
-    def output_footnote(self, m):
-        key = _keyify(m.group(1))
-        if key not in self.footnotes:
-            return None
-        if self.footnotes[key]:
-            return None
-        self.footnote_index += 1
-        self.footnotes[key] = self.footnote_index
-        return self.renderer.footnote_ref(key, self.footnote_index)
-
-    def output_link(self, m):
-        return self._process_link(m, m.group(3), m.group(4))
-
-    def output_reflink(self, m):
-        key = _keyify(m.group(2) or m.group(1))
-        if key not in self.links:
-            return None
-        ret = self.links[key]
-        return self._process_link(m, ret['link'], ret['title'])
-
-    def output_nolink(self, m):
-        key = _keyify(m.group(1))
-        if key not in self.links:
-            return None
-        ret = self.links[key]
-        return self._process_link(m, ret['link'], ret['title'])
-
-    def _process_link(self, m, link, title=None):
-        line = m.group(0)
-        text = m.group(1)
-        if line[0] == '!':
-            return self.renderer.image(link, title, text)
-
-        self._in_link = True
-        text = self.output(text)
-        self._in_link = False
-        return self.renderer.link(link, title, text)
-
-    def output_double_emphasis(self, m):
-        text = m.group(2) or m.group(1)
-        text = self.output(text)
-        return self.renderer.double_emphasis(text)
-
-    def output_emphasis(self, m):
-        text = m.group(2) or m.group(1)
-        text = self.output(text)
-        return self.renderer.emphasis(text)
-
-    def output_code(self, m):
-        text = m.group(2)
-        return self.renderer.codespan(text)
-
-    def output_linebreak(self, m):
-        return self.renderer.linebreak()
-
-    def output_strikethrough(self, m):
-        text = self.output(m.group(1))
-        return self.renderer.strikethrough(text)
-
-    def output_text(self, m):
-        text = m.group(0)
-        return self.renderer.text(text)
-
-
-class Renderer(object):
-    """The default HTML renderer for rendering Markdown.
-    """
-
-    def __init__(self, **kwargs):
-        self.options = kwargs
-
-    def placeholder(self):
-        """Returns the default, empty output value for the renderer.
-
-        All renderer methods use the '+=' operator to append to this value.
-        Default is a string so rendering HTML can build up a result string with
-        the rendered Markdown.
-
-        Can be overridden by Renderer subclasses to be types like an empty
-        list, allowing the renderer to create a tree-like structure to
-        represent the document (which can then be reprocessed later into a
-        separate format like docx or pdf).
-        """
-        return ''
-
-    def block_code(self, code, lang=None):
-        """Rendering block level code. ``pre > code``.
-
-        :param code: text content of the code block.
-        :param lang: language of the given code.
-        """
-        code = code.rstrip('\n')
-        if not lang:
-            code = escape(code, smart_amp=False)
-            return '<pre><code>%s\n</code></pre>\n' % code
-        code = escape(code, quote=True, smart_amp=False)
-        return '<pre><code class="lang-%s">%s\n</code></pre>\n' % (lang, code)
-
-    def block_quote(self, text):
-        """Rendering <blockquote> with the given text.
-
-        :param text: text content of the blockquote.
-        """
-        return '<blockquote>%s\n</blockquote>\n' % text.rstrip('\n')
-
-    def block_html(self, html):
-        """Rendering block level pure html content.
-
-        :param html: text content of the html snippet.
-        """
-        if self.options.get('skip_style') and \
-           html.lower().startswith('<style'):
-            return ''
-        if self.options.get('escape'):
-            return escape(html)
-        return html
-
-    def header(self, text, level, raw=None):
-        """Rendering header/heading tags like ``<h1>`` ``<h2>``.
-
-        :param text: rendered text content for the header.
-        :param level: a number for the header level, for example: 1.
-        :param raw: raw text content of the header.
-        """
-        return '<h%d>%s</h%d>\n' % (level, text, level)
-
-    def hrule(self):
-        """Rendering method for ``<hr>`` tag."""
-        if self.options.get('use_xhtml'):
-            return '<hr />\n'
-        return '<hr>\n'
-
-    def list(self, body, ordered=True):
-        """Rendering list tags like ``<ul>`` and ``<ol>``.
-
-        :param body: body contents of the list.
-        :param ordered: whether this list is ordered or not.
-        """
-        tag = 'ul'
-        if ordered:
-            tag = 'ol'
-        return '<%s>\n%s</%s>\n' % (tag, body, tag)
-
-    def list_item(self, text):
-        """Rendering list item snippet. Like ``<li>``."""
-        return '<li>%s</li>\n' % text
-
-    def paragraph(self, text):
-        """Rendering paragraph tags. Like ``<p>``."""
-        return '<p>%s</p>\n' % text.strip(' ')
-
-    def table(self, header, body):
-        """Rendering table element. Wrap header and body in it.
-
-        :param header: header part of the table.
-        :param body: body part of the table.
-        """
-        return (
-            '<table>\n<thead>%s</thead>\n'
-            '<tbody>\n%s</tbody>\n</table>\n'
-        ) % (header, body)
-
-    def table_row(self, content):
-        """Rendering a table row. Like ``<tr>``.
-
-        :param content: content of current table row.
-        """
-        return '<tr>\n%s</tr>\n' % content
-
-    def table_cell(self, content, **flags):
-        """Rendering a table cell. Like ``<th>`` ``<td>``.
-
-        :param content: content of current table cell.
-        :param header: whether this is header or not.
-        :param align: align of current table cell.
-        """
-        if flags['header']:
-            tag = 'th'
-        else:
-            tag = 'td'
-        align = flags['align']
-        if not align:
-            return '<%s>%s</%s>\n' % (tag, content, tag)
-        return '<%s style="text-align:%s">%s</%s>\n' % (
-            tag, align, content, tag
-        )
-
-    def double_emphasis(self, text):
-        """Rendering **strong** text.
-
-        :param text: text content for emphasis.
-        """
-        return '<strong>%s</strong>' % text
-
-    def emphasis(self, text):
-        """Rendering *emphasis* text.
-
-        :param text: text content for emphasis.
-        """
-        return '<em>%s</em>' % text
-
-    def codespan(self, text):
-        """Rendering inline `code` text.
-
-        :param text: text content for inline code.
-        """
-        text = escape(text.rstrip(), smart_amp=False)
-        return '<code>%s</code>' % text
-
-    def linebreak(self):
-        """Rendering line break like ``<br>``."""
-        if self.options.get('use_xhtml'):
-            return '<br />\n'
-        return '<br>\n'
-
-    def strikethrough(self, text):
-        """Rendering ~~strikethrough~~ text.
-
-        :param text: text content for strikethrough.
-        """
-        return '<del>%s</del>' % text
-
-    def text(self, text):
-        """Rendering unformatted text.
-
-        :param text: text content.
-        """
-        if self.options.get('parse_block_html'):
-            return text
-        return escape(text)
-
-    def escape(self, text):
-        """Rendering escape sequence.
-
-        :param text: text content.
-        """
-        return escape(text)
-
-    def autolink(self, link, is_email=False):
-        """Rendering a given link or email address.
-
-        :param link: link content or email address.
-        :param is_email: whether this is an email or not.
-        """
-        text = link = escape_link(link)
-        if is_email:
-            link = 'mailto:%s' % link
-        return '<a href="%s">%s</a>' % (link, text)
-
-    def link(self, link, title, text):
-        """Rendering a given link with content and title.
-
-        :param link: href link for ``<a>`` tag.
-        :param title: title content for `title` attribute.
-        :param text: text content for description.
-        """
-        link = escape_link(link)
-        if not title:
-            return '<a href="%s">%s</a>' % (link, text)
-        title = escape(title, quote=True)
-        return '<a href="%s" title="%s">%s</a>' % (link, title, text)
-
-    def image(self, src, title, text):
-        """Rendering a image with title and text.
-
-        :param src: source link of the image.
-        :param title: title text of the image.
-        :param text: alt text of the image.
-        """
-        src = escape_link(src)
-        text = escape(text, quote=True)
-        if title:
-            title = escape(title, quote=True)
-            html = '<img src="%s" alt="%s" title="%s"' % (src, text, title)
-        else:
-            html = '<img src="%s" alt="%s"' % (src, text)
-        if self.options.get('use_xhtml'):
-            return '%s />' % html
-        return '%s>' % html
-
-    def inline_html(self, html):
-        """Rendering span level pure html content.
-
-        :param html: text content of the html snippet.
-        """
-        if self.options.get('escape'):
-            return escape(html)
-        return html
-
-    def newline(self):
-        """Rendering newline element."""
-        return ''
-
-    def footnote_ref(self, key, index):
-        """Rendering the ref anchor of a footnote.
-
-        :param key: identity key for the footnote.
-        :param index: the index count of current footnote.
-        """
-        html = (
-            '<sup class="footnote-ref" id="fnref-%s">'
-            '<a href="#fn-%s">%d</a></sup>'
-        ) % (escape(key), escape(key), index)
-        return html
-
-    def footnote_item(self, key, text):
-        """Rendering a footnote item.
-
-        :param key: identity key for the footnote.
-        :param text: text content of the footnote.
-        """
-        back = (
-            '<a href="#fnref-%s" class="footnote">&#8617;</a>'
-        ) % escape(key)
-        text = text.rstrip()
-        if text.endswith('</p>'):
-            text = re.sub(r'<\/p>$', r'%s</p>' % back, text)
-        else:
-            text = '%s<p>%s</p>' % (text, back)
-        html = '<li id="fn-%s">%s</li>\n' % (escape(key), text)
-        return html
-
-    def footnotes(self, text):
-        """Wrapper for all footnotes.
-
-        :param text: contents of all footnotes.
-        """
-        html = '<div class="footnotes">\n%s<ol>%s</ol>\n</div>\n'
-        return html % (self.hrule(), text)
-
-
-class Markdown(object):
-    """The Markdown parser.
-
-    :param renderer: An instance of ``Renderer``.
-    :param inline: An inline lexer class or instance.
-    :param block: A block lexer class or instance.
-    """
-    def __init__(self, renderer=None, inline=None, block=None, **kwargs):
-        if not renderer:
-            renderer = Renderer(**kwargs)
-        else:
-            kwargs.update(renderer.options)
-
-        self.renderer = renderer
-
-        if inline and inspect.isclass(inline):
-            inline = inline(renderer, **kwargs)
-        if block and inspect.isclass(block):
-            block = block(**kwargs)
-
-        if inline:
-            self.inline = inline
-        else:
-            self.inline = InlineLexer(renderer, **kwargs)
-
-        self.block = block or BlockLexer(BlockGrammar())
-        self.footnotes = []
-        self.tokens = []
-
-        # detect if it should parse text in block html
-        self._parse_block_html = kwargs.get('parse_block_html')
-
-    def __call__(self, text):
-        return self.parse(text)
-
-    def render(self, text):
-        """Render the Markdown text.
-
-        :param text: markdown formatted text content.
-        """
-        return self.parse(text)
-
-    def parse(self, text):
-        out = self.output(preprocessing(text))
-
-        keys = self.block.def_footnotes
-
-        # reset block
-        self.block.def_links = {}
-        self.block.def_footnotes = {}
-
-        # reset inline
-        self.inline.links = {}
-        self.inline.footnotes = {}
-
-        if not self.footnotes:
-            return out
-
-        footnotes = filter(lambda o: keys.get(o['key']), self.footnotes)
-        self.footnotes = sorted(
-            footnotes, key=lambda o: keys.get(o['key']), reverse=True
-        )
-
-        body = self.renderer.placeholder()
-        while self.footnotes:
-            note = self.footnotes.pop()
-            body += self.renderer.footnote_item(
-                note['key'], note['text']
-            )
-
-        out += self.renderer.footnotes(body)
-        return out
-
-    def pop(self):
-        if not self.tokens:
-            return None
-        self.token = self.tokens.pop()
-        return self.token
-
-    def peek(self):
-        if self.tokens:
-            return self.tokens[-1]
-        return None  # pragma: no cover
-
-    def output(self, text, rules=None):
-        self.tokens = self.block(text, rules)
-        self.tokens.reverse()
-
-        self.inline.setup(self.block.def_links, self.block.def_footnotes)
-
-        out = self.renderer.placeholder()
-        while self.pop():
-            out += self.tok()
-        return out
-
-    def tok(self):
-        t = self.token['type']
-
-        # sepcial cases
-        if t.endswith('_start'):
-            t = t[:-6]
-
-        return getattr(self, 'output_%s' % t)()
-
-    def tok_text(self):
-        text = self.token['text']
-        while self.peek()['type'] == 'text':
-            text += '\n' + self.pop()['text']
-        return self.inline(text)
-
-    def output_newline(self):
-        return self.renderer.newline()
-
-    def output_hrule(self):
-        return self.renderer.hrule()
-
-    def output_heading(self):
-        return self.renderer.header(
-            self.inline(self.token['text']),
-            self.token['level'],
-            self.token['text'],
-        )
-
-    def output_code(self):
-        return self.renderer.block_code(
-            self.token['text'], self.token['lang']
-        )
-
-    def output_table(self):
-        aligns = self.token['align']
-        aligns_length = len(aligns)
-        cell = self.renderer.placeholder()
-
-        # header part
-        header = self.renderer.placeholder()
-        for i, value in enumerate(self.token['header']):
-            align = aligns[i] if i < aligns_length else None
-            flags = {'header': True, 'align': align}
-            cell += self.renderer.table_cell(self.inline(value), **flags)
-
-        header += self.renderer.table_row(cell)
-
-        # body part
-        body = self.renderer.placeholder()
-        for i, row in enumerate(self.token['cells']):
-            cell = self.renderer.placeholder()
-            for j, value in enumerate(row):
-                align = aligns[j] if j < aligns_length else None
-                flags = {'header': False, 'align': align}
-                cell += self.renderer.table_cell(self.inline(value), **flags)
-            body += self.renderer.table_row(cell)
-
-        return self.renderer.table(header, body)
-
-    def output_block_quote(self):
-        body = self.renderer.placeholder()
-        while self.pop()['type'] != 'block_quote_end':
-            body += self.tok()
-        return self.renderer.block_quote(body)
-
-    def output_list(self):
-        ordered = self.token['ordered']
-        body = self.renderer.placeholder()
-        while self.pop()['type'] != 'list_end':
-            body += self.tok()
-        return self.renderer.list(body, ordered)
-
-    def output_list_item(self):
-        body = self.renderer.placeholder()
-        while self.pop()['type'] != 'list_item_end':
-            if self.token['type'] == 'text':
-                body += self.tok_text()
-            else:
-                body += self.tok()
-
-        return self.renderer.list_item(body)
-
-    def output_loose_item(self):
-        body = self.renderer.placeholder()
-        while self.pop()['type'] != 'list_item_end':
-            body += self.tok()
-        return self.renderer.list_item(body)
-
-    def output_footnote(self):
-        self.inline._in_footnote = True
-        body = self.renderer.placeholder()
-        key = self.token['key']
-        while self.pop()['type'] != 'footnote_end':
-            body += self.tok()
-        self.footnotes.append({'key': key, 'text': body})
-        self.inline._in_footnote = False
-        return self.renderer.placeholder()
-
-    def output_close_html(self):
-        text = self.token['text']
-        return self.renderer.block_html(text)
-
-    def output_open_html(self):
-        text = self.token['text']
-        tag = self.token['tag']
-        if self._parse_block_html and tag not in _pre_tags:
-            text = self.inline(text, rules=self.inline.inline_html_rules)
-        extra = self.token.get('extra') or ''
-        html = '<%s%s>%s</%s>' % (tag, extra, text, tag)
-        return self.renderer.block_html(html)
-
-    def output_paragraph(self):
-        return self.renderer.paragraph(self.inline(self.token['text']))
-
-    def output_text(self):
-        return self.renderer.paragraph(self.tok_text())
-
-
-def markdown(text, escape=True, **kwargs):
-    """Render markdown formatted text to html.
-
-    :param text: markdown formatted text content.
-    :param escape: if set to False, all html tags will not be escaped.
-    :param use_xhtml: output with xhtml tags.
-    :param hard_wrap: if set to True, it will use the GFM line breaks feature.
-    :param parse_block_html: parse text only in block level html.
-    :param parse_inline_html: parse text only in inline level html.
-    """
-    return Markdown(escape=escape, **kwargs)(text)