From 66fa71a8f11b6ce5e8471b533f67cc3a1fdb85a8 Mon Sep 17 00:00:00 2001 From: Arturs Artamonovs Date: Sun, 29 Jan 2023 10:30:54 +0000 Subject: Update to new mistune, removed old mistune, rewrite to python3 --- src/mistune/renderers/html.py | 151 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/mistune/renderers/html.py (limited to 'src/mistune/renderers/html.py') diff --git a/src/mistune/renderers/html.py b/src/mistune/renderers/html.py new file mode 100644 index 0000000..c458a4a --- /dev/null +++ b/src/mistune/renderers/html.py @@ -0,0 +1,151 @@ +from ..core import BaseRenderer +from ..util import escape as escape_text, striptags, safe_entity + + +class HTMLRenderer(BaseRenderer): + """A renderer for converting Markdown to HTML.""" + NAME = 'html' + HARMFUL_PROTOCOLS = ( + 'javascript:', + 'vbscript:', + 'file:', + 'data:', + ) + GOOD_DATA_PROTOCOLS = ( + 'data:image/gif;', + 'data:image/png;', + 'data:image/jpeg;', + 'data:image/webp;', + ) + + def __init__(self, escape=True, allow_harmful_protocols=None): + super(HTMLRenderer, self).__init__() + self._allow_harmful_protocols = allow_harmful_protocols + self._escape = escape + + def render_token(self, token, state): + # backward compitable with v2 + func = self._get_method(token['type']) + attrs = token.get('attrs') + + if 'raw' in token: + text = token['raw'] + elif 'children' in token: + text = self.render_tokens(token['children'], state) + else: + if attrs: + return func(**attrs) + else: + return func() + if attrs: + return func(text, **attrs) + else: + return func(text) + + def safe_url(self, url: str) -> str: + """Ensure the given URL is safe. This method is used for rendering + links, images, and etc. + """ + if self._allow_harmful_protocols is True: + return url + + _url = url.lower() + if self._allow_harmful_protocols and \ + _url.startswith(tuple(self._allow_harmful_protocols)): + return url + + if _url.startswith(self.HARMFUL_PROTOCOLS) and \ + not _url.startswith(self.GOOD_DATA_PROTOCOLS): + return '#harmful-link' + return url + + def text(self, text: str) -> str: + if self._escape: + return escape_text(text) + return safe_entity(text) + + def emphasis(self, text: str) -> str: + return '' + text + '' + + def strong(self, text: str) -> str: + return '' + text + '' + + def link(self, text: str, url: str, title=None) -> str: + s = '' + text + '' + + def image(self, text: str, url: str, title=None) -> str: + src = self.safe_url(url) + alt = escape_text(striptags(text)) + s = '' + alt + '' + + def codespan(self, text: str) -> str: + return '' + text + '' + + def linebreak(self) -> str: + return '
\n' + + def softbreak(self) -> str: + return '\n' + + def inline_html(self, html: str) -> str: + if self._escape: + return escape_text(html) + return html + + def paragraph(self, text: str) -> str: + return '

' + text + '

\n' + + def heading(self, text: str, level: int, **attrs) -> str: + tag = 'h' + str(level) + html = '<' + tag + _id = attrs.get('id') + if _id: + html += ' id="' + _id + '"' + return html + '>' + text + '\n' + + def blank_line(self) -> str: + return '' + + def thematic_break(self) -> str: + return '
\n' + + def block_text(self, text: str) -> str: + return text + + def block_code(self, code: str, info=None) -> str: + html = '
' + escape_text(code) + '
\n' + + def block_quote(self, text: str) -> str: + return '
\n' + text + '
\n' + + def block_html(self, html: str) -> str: + if self._escape: + return '

' + escape_text(html) + '

\n' + return html + '\n' + + def block_error(self, text: str) -> str: + return '
' + text + '
\n' + + def list(self, text: str, ordered: bool, **attrs) -> str: + if ordered: + html = '\n' + text + '\n' + return '\n' + + def list_item(self, text: str) -> str: + return '
  • ' + text + '
  • \n' -- cgit v1.2.3