diff --git a/dmoj/settings.py b/dmoj/settings.py index 8e3b27e..61d2aa4 100644 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -362,42 +362,6 @@ LANGUAGES = [ ("vi", _("Vietnamese")), ] -MARKDOWN_ADMIN_EDITABLE_STYLE = { - "safe_mode": False, - "use_camo": True, - "texoid": True, - "math": True, -} - -MARKDOWN_DEFAULT_STYLE = { - "safe_mode": True, - "nofollow": True, - "use_camo": True, - "math": True, -} - -MARKDOWN_USER_LARGE_STYLE = { - "safe_mode": True, - "nofollow": True, - "use_camo": True, - "math": True, -} - -MARKDOWN_STYLES = { - "comment": MARKDOWN_ADMIN_EDITABLE_STYLE, - "self-description": MARKDOWN_ADMIN_EDITABLE_STYLE, - "problem": MARKDOWN_ADMIN_EDITABLE_STYLE, - "contest": MARKDOWN_ADMIN_EDITABLE_STYLE, - "language": MARKDOWN_ADMIN_EDITABLE_STYLE, - "license": MARKDOWN_ADMIN_EDITABLE_STYLE, - "judge": MARKDOWN_ADMIN_EDITABLE_STYLE, - "blog": MARKDOWN_ADMIN_EDITABLE_STYLE, - "solution": MARKDOWN_ADMIN_EDITABLE_STYLE, - "contest_tag": MARKDOWN_ADMIN_EDITABLE_STYLE, - "organization-about": MARKDOWN_ADMIN_EDITABLE_STYLE, - "ticket": MARKDOWN_ADMIN_EDITABLE_STYLE, -} - # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases diff --git a/judge/jinja2/markdown/__init__.py b/judge/jinja2/markdown/__init__.py index e22ae61..3c01de2 100644 --- a/judge/jinja2/markdown/__init__.py +++ b/judge/jinja2/markdown/__init__.py @@ -1,183 +1,36 @@ -import logging -import re -from html.parser import HTMLParser -from urllib.parse import urlparse - -import mistune -from django.conf import settings -from markupsafe import Markup -from lxml import html -from lxml.etree import ParserError, XMLSyntaxError - -from judge.highlight_code import highlight_code -from judge.jinja2.markdown.lazy_load import lazy_load as lazy_load_processor -from judge.jinja2.markdown.math import MathInlineGrammar, MathInlineLexer, MathRenderer -from judge.utils.camo import client as camo_client -from judge.utils.texoid import TEXOID_ENABLED, TexoidRenderer from .. import registry - -logger = logging.getLogger("judge.html") - -NOFOLLOW_WHITELIST = settings.NOFOLLOW_EXCLUDED +import markdown as _markdown +import bleach +from django.utils.html import escape -class CodeSafeInlineGrammar(mistune.InlineGrammar): - double_emphasis = re.compile(r"^\*{2}([\s\S]+?)()\*{2}(?!\*)") # **word** - emphasis = re.compile(r"^\*((?:\*\*|[^\*])+?)()\*(?!\*)") # *word* +EXTENSIONS = [ + "pymdownx.magiclink", + "pymdownx.details", + "pymdownx.emoji", + "pymdownx.inlinehilite", + "pymdownx.superfences", + "pymdownx.tasklist", + "markdown.extensions.footnotes", + "markdown.extensions.attr_list", + "markdown.extensions.def_list", + "markdown.extensions.tables", + "markdown.extensions.admonition", + "pymdownx.arithmatex", +] +ALLOWED_TAGS = bleach.sanitizer.ALLOWED_TAGS + ["img", "center", "iframe"] -class AwesomeInlineGrammar(MathInlineGrammar, CodeSafeInlineGrammar): - pass - - -class AwesomeInlineLexer(MathInlineLexer, mistune.InlineLexer): - grammar_class = AwesomeInlineGrammar - - -class AwesomeRenderer(MathRenderer, mistune.Renderer): - def __init__(self, *args, **kwargs): - self.nofollow = kwargs.pop("nofollow", True) - self.texoid = TexoidRenderer() if kwargs.pop("texoid", False) else None - self.parser = HTMLParser() - super(AwesomeRenderer, self).__init__(*args, **kwargs) - - def _link_rel(self, href): - if href: - try: - url = urlparse(href) - except ValueError: - return ' rel="nofollow"' - else: - if url.netloc and url.netloc not in NOFOLLOW_WHITELIST: - return ' rel="nofollow"' - return "" - - def autolink(self, link, is_email=False): - text = link = mistune.escape(link) - if is_email: - link = "mailto:%s" % link - return '%s' % (link, self._link_rel(link), text) - - def table(self, header, body): - return ( - '
%s
\n" % mistune.escape(code).rstrip()
- return highlight_code(code, lang)
-
- def block_html(self, html):
- if self.texoid and html.startswith("%s" % mistune.escape(latex, smart_amp=False) - elif "error" not in result: - img = ( - '''' - ) % { - "svg": result["svg"], - "png": result["png"], - "width": result["meta"]["width"], - "height": result["meta"]["height"], - "tail": " /" if self.options.get("use_xhtml") else "", - } - style = [ - "max-width: 100%", - "height: %s" % result["meta"]["height"], - "max-height: %s" % result["meta"]["height"], - "width: %s" % result["meta"]["height"], - ] - if "inline" in attr: - tag = "span" - else: - tag = "div" - style += ["text-align: center"] - return '<%s style="%s">%s%s>' % (tag, ";".join(style), img, tag) - else: - return "
%s" % mistune.escape( - result["error"], smart_amp=False - ) - return super(AwesomeRenderer, self).block_html(html) - - def header(self, text, level, *args, **kwargs): - return super(AwesomeRenderer, self).header(text, level + 2, *args, **kwargs) - - -def create_spoiler(value, style): - respoiler = re.compile(r"(^\|\|(.+)\s+([\s\S]+?)\s*\|\|)", re.MULTILINE) - matches = re.findall(respoiler, value) - html = ( - '
Authors: {{ link_users(authors) }}
{% endif %} {% endwith %} - {{ solution.content|markdown('solution', MATH_ENGINE)|reference|str|safe }} + {{ solution.content|markdown|reference|str|safe }}