import re import mistune from django.conf import settings from judge.utils.mathoid import MathoidMathParser mistune._pre_tags.append("latex") class MathInlineGrammar(mistune.InlineGrammar): block_math = re.compile(r"^\$\$(.*?)\$\$|^\\\[(.*?)\\\]", re.DOTALL) math = re.compile(r"^~(.*?)~|^\\\((.*?)\\\)", re.DOTALL) text = re.compile(r"^[\s\S]+?(?=[\\<!\[_*`~$]|\\[\[(]|https?://| {2,}\n|$)") class MathInlineLexer(mistune.InlineLexer): grammar_class = MathInlineGrammar def __init__(self, *args, **kwargs): self.default_rules = self.default_rules[:] self.inline_html_rules = self.default_rules self.default_rules.insert(self.default_rules.index("strikethrough") + 1, "math") self.default_rules.insert( self.default_rules.index("strikethrough") + 1, "block_math" ) super(MathInlineLexer, self).__init__(*args, **kwargs) def output_block_math(self, m): return self.renderer.block_math(m.group(1) or m.group(2)) def output_math(self, m): return self.renderer.math(m.group(1) or m.group(2)) def output_inline_html(self, m): tag = m.group(1) text = m.group(3) if self._parse_inline_html and text: if tag == "a": self._in_link = True text = self.output(text) self._in_link = False else: text = self.output(text) 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) class MathRenderer(mistune.Renderer): def __init__(self, *args, **kwargs): if kwargs.pop("math", False) and settings.MATHOID_URL != False: self.mathoid = MathoidMathParser(kwargs.pop("math_engine", None) or "svg") else: self.mathoid = None super(MathRenderer, self).__init__(*args, **kwargs) def block_math(self, math): if self.mathoid is None or not math: return r"\[%s\]" % mistune.escape(str(math)) return self.mathoid.display_math(math) def math(self, math): if self.mathoid is None or not math: return r"\(%s\)" % mistune.escape(str(math)) return self.mathoid.inline_math(math)