Migrate mistune to markdown

This commit is contained in:
cuom1999 2022-10-24 23:59:04 -05:00
parent 412945626b
commit 77aaae6735
46 changed files with 5112 additions and 420 deletions

View file

@ -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

View file

@ -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 '<a href="%s"%s>%s</a>' % (link, self._link_rel(link), text)
def table(self, header, body):
return (
'<table class="table">\n<thead>%s</thead>\n'
"<tbody>\n%s</tbody>\n</table>\n"
) % (header, body)
def link(self, link, title, text):
link = mistune.escape_link(link)
if not title:
return '<a href="%s"%s>%s</a>' % (link, self._link_rel(link), text)
title = mistune.escape(title, quote=True)
return '<a href="%s" title="%s"%s>%s</a>' % (
link,
title,
self._link_rel(link),
text,
)
def block_code(self, code, lang=None):
if not lang:
return "\n<pre><code>%s</code></pre>\n" % mistune.escape(code).rstrip()
return highlight_code(code, lang)
def block_html(self, html):
if self.texoid and html.startswith("<latex"):
attr = html[6 : html.index(">")]
latex = html[html.index(">") + 1 : html.rindex("<")]
latex = self.parser.unescape(latex)
result = self.texoid.get_result(latex)
if not result:
return "<pre>%s</pre>" % mistune.escape(latex, smart_amp=False)
elif "error" not in result:
img = (
'''<img src="%(svg)s" onerror="this.src='%(png)s';this.onerror=null"'''
'width="%(width)s" height="%(height)s"%(tail)s>'
) % {
"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 "<pre>%s</pre>" % 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 = (
'<details><summary style="color: brown">'
+ '<span class="spoiler-summary">{summary}</span>'
+ "</summary>{detail}</details>"
)
for entire, summary, detail in matches:
detail = markdown(detail, style)
new_html = html.format(summary=summary, detail=detail)
value = value.replace(entire, new_html)
return value
ALLOWED_ATTRS = ["src", "width", "height", "href"]
@registry.filter
def markdown(value, style, math_engine=None, lazy_load=False, hard_wrap=False):
styles = settings.MARKDOWN_STYLES.get(style, settings.MARKDOWN_DEFAULT_STYLE)
escape = styles.get("safe_mode", True)
nofollow = styles.get("nofollow", True)
texoid = TEXOID_ENABLED and styles.get("texoid", False)
math = hasattr(settings, "MATHOID_URL") and styles.get("math", False)
value = create_spoiler(value, style)
post_processors = []
if styles.get("use_camo", False) and camo_client is not None:
post_processors.append(camo_client.update_tree)
if lazy_load:
post_processors.append(lazy_load_processor)
renderer = AwesomeRenderer(
escape=escape,
nofollow=nofollow,
texoid=texoid,
math=math and math_engine is not None,
math_engine=math_engine,
)
markdown = mistune.Markdown(
renderer=renderer,
inline=AwesomeInlineLexer,
parse_block_html=1,
parse_inline_html=1,
hard_wrap=hard_wrap,
)
result = markdown(value)
if post_processors:
try:
tree = html.fromstring(result, parser=html.HTMLParser(recover=True))
except (XMLSyntaxError, ParserError) as e:
if result and (
not isinstance(e, ParserError) or e.args[0] != "Document is empty"
):
logger.exception("Failed to parse HTML string")
tree = html.Element("div")
for processor in post_processors:
processor(tree)
result = html.tostring(tree, encoding="unicode")
return Markup(result)
def markdown(value, hard_wrap=False):
extensions = EXTENSIONS
if hard_wrap:
extensions = EXTENSIONS + ["nl2br"]
html = bleach.clean(value, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRS)
html = _markdown.markdown(html, extensions=extensions)
if not html:
html = escape(value)
return '<div class="md-typeset">%s</div>' % html

View file

@ -1,20 +0,0 @@
from copy import deepcopy
from django.templatetags.static import static
from lxml import html
def lazy_load(tree):
blank = static("blank.gif")
for img in tree.xpath(".//img"):
src = img.get("src", "")
if src.startswith("data") or "-math" in img.get("class", ""):
continue
noscript = html.Element("noscript")
copy = deepcopy(img)
copy.tail = ""
noscript.append(copy)
img.addprevious(noscript)
img.set("data-src", src)
img.set("src", blank)
img.set("class", img.get("class") + " unveil" if img.get("class") else "unveil")

View file

@ -1,69 +0,0 @@
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) or m.group(3))
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)

View file

@ -5,11 +5,11 @@ from judge.jinja2.markdown import markdown
from judge.jinja2.reference import reference
def generate_opengraph(cache_key, data, style):
def generate_opengraph(cache_key, data):
metadata = cache.get(cache_key)
if metadata is None:
description = None
tree = reference(markdown(data, style)).tree
tree = reference(markdown(data)).tree
for p in tree.iterfind(".//p"):
text = p.text_content().strip()
if text:

View file

@ -308,7 +308,6 @@ class ProblemDetail(ProblemMixin, SolvedProblemMixin, CommentedDetailView):
metadata = generate_opengraph(
"generated-meta-problem:%s:%d" % (context["language"], self.object.id),
context["description"],
"problem",
)
context["meta_description"] = self.object.summary or metadata[0]
context["og_image"] = self.object.og_image or metadata[1]

View file

@ -41,6 +41,7 @@ else:
css = {
"all": [
"pagedown_widget.css",
"markdown.css",
]
}
@ -50,6 +51,7 @@ else:
"all": [
"content-description.css",
"admin/css/pagedown.css",
"markdown.css",
]
}
js = ["admin/js/pagedown.js"]
@ -114,5 +116,6 @@ else:
"pygment-github.css",
"table.css",
"ranks.css",
"markdown.css",
]
}

View file

@ -11,7 +11,6 @@ django-impersonate
dmoj-wpadmin @ git+https://github.com/LQDJudge/dmoj-wpadmin.git
lxml
Pygments
mistune<2
social-auth-app-django
pytz
django-statici18n
@ -39,3 +38,5 @@ websocket-client
python-memcached
numpy
pandas
markdown
bleach

View file

@ -1,80 +1,15 @@
@import "vars";
.content-description {
line-height: 1.5em;
line-height: 1.6em;
font-size: 1em;
font-family: "Segoe UI", "Lucida Grande", Arial, sans-serif;
p {
margin: 1em 0 !important;
padding: 0 !important;
}
img {
max-width: 100%;
height: auto;
}
h1, h2, h3, h4, h5, h6 {
font-weight: normal;
color: #111;
margin-bottom: 0.75em;
padding: 0;
background: 0;
}
h3, h4, h5, h6 {
font-weight: bold;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 2em;
}
h3 {
font-size: 1.6em;
margin: 0;
padding: 0;
}
h4 {
font-size: 1.4em;
border-bottom: 1px solid #EEE;
line-height: 1.225;
padding-bottom: 0.3em;
padding-top: 0.5em;
}
h5 {
font-size: 1.15em;
margin-top: 0;
}
h6 {
font-size: 0.9em;
}
blockquote {
color: #666;
margin: 0;
padding-left: 1.5em;
border-left: 0.5em #EEE solid;
}
hr {
display: block;
height: 0;
border: 0;
font-style: italic;
border-bottom: 1px solid $border_gray;
margin: 25px 0 20px 0;
padding: 0;
}
pre, code, kbd, samp, span.code {
color: #000;
page-break-inside: avoid;

5032
resources/markdown.css Normal file

File diff suppressed because it is too large Load diff

View file

@ -26,14 +26,6 @@ td.user-name {
text-align: left;
}
tr {
padding-bottom: 96px;
&:target {
background: #fff897;
}
}
th.header.rank {
padding-left: 5px;
}
@ -84,6 +76,11 @@ th.header.rank {
&.highlight {
background: #fff897;
}
padding-bottom: 96px;
&:target {
background: #fff897;
}
}
}

View file

@ -57,6 +57,7 @@
<link rel="stylesheet" type="text/css" href="{{ static('libs/clipboard/tooltip.css') }}">
<link rel="stylesheet" type="text/css" href="{{ static('libs/select2/select2.css') }}">
<link rel="stylesheet" type="text/css" href="{{ static('icofont/icofont.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ static('markdown.css') }}">
{% endcompress %}
<link rel="canonical"
href="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">

View file

@ -36,7 +36,7 @@
</div>
<div class="body content-description">
{% cache 86400 'post_content' post.id MATH_ENGINE %}
{{ post.content|markdown('blog', MATH_ENGINE)|reference|str|safe}}
{{ post.content|markdown|reference|str|safe}}
{% endcache %}
</div>
</div>

View file

@ -38,7 +38,7 @@
</h2>
<div class="summary content-description blog-description">
{% cache 86400 'post_summary' post.id %}
{{ post.summary|default(post.content, true)|markdown('blog', 'svg', lazy_load=True)|reference|str|safe }}
{{ post.summary|default(post.content, true)|markdown|reference|str|safe }}
{% endcache %}
</div>
</section>

View file

@ -1 +1 @@
{{ preview_data|markdown('blog', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}

View file

@ -66,7 +66,6 @@ let META_HEADER = [
}
$('.body-block').slice(0, window.messages_per_page).each(function() {
resize_emoji($(this));
});
register_time($('.time-with-rel'));
@ -153,7 +152,6 @@ let META_HEADER = [
function add_message(data) {
var $data = $(data);
resize_emoji($data.find('.body-block'));
$('#chat-log').append($data);
$('#chat-box').scrollTop($('#chat-box')[0].scrollHeight);
@ -212,7 +210,6 @@ let META_HEADER = [
else {
add_new_message(message, room, true);
}
resize_emoji($body_block);
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
register_time($('.time-with-rel'));
remove_unread_current_user();
@ -439,10 +436,6 @@ let META_HEADER = [
});
{% endif %}
$('.body-block').each(function() {
resize_emoji($(this));
});
$("#chat-log").show();
$("#chat-log").change(function() {
$('#chat-log').scrollTop($('#chat-log')[0].scrollHeight);

View file

@ -21,7 +21,7 @@
</a>
{% endif %}
<div class="message-text message-text-other">
{{message.body | markdown('comment', MATH_ENGINE, hard_wrap=True)|reference|str|safe }}
{{message.body|markdown(hard_wrap=True)|reference|str|safe }}
</div>
</div>
</span>

View file

@ -1 +1 @@
{{ comment.body|markdown('comment', MATH_ENGINE)|reference|str|safe }}
{{ comment.body|markdown|reference|str|safe }}

View file

@ -13,6 +13,6 @@
{% endif %}
{% endwith %}
<div class='blog-description content-description'>
{{ comment.body |markdown("comment", MATH_ENGINE)|reference|str|safe }}
{{ comment.body |markdown|reference|str|safe }}
</div>
</div>

View file

@ -93,7 +93,7 @@
</div>
<div class="content content-description">
<div class="comment-body"{% if node.score <= vote_hide_threshold %} style="display:none"{% endif %}>
{{ node.body|markdown('comment', MATH_ENGINE, True)|reference|str|safe }}
{{ node.body|markdown|reference|str|safe }}
</div>
{% if node.score <= vote_hide_threshold %}
<div class="comment-body bad-comment-body">

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('comment', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -1,3 +1,3 @@
{% with node=revision.field_dict %}
<div class="comment-body">{{ node.body|markdown('comment', MATH_ENGINE)|reference|str|safe }}</div>
<div class="comment-body">{{ node.body|markdown|reference|str|safe }}</div>
{% endwith %}

View file

@ -69,7 +69,7 @@
<div class="content-description">
{% cache 3600 'contest_html' contest.id MATH_ENGINE %}
{{ contest.description|markdown('contest', MATH_ENGINE)|reference|str|safe }}
{{ contest.description|markdown|reference|str|safe }}
{% endcache %}
</div>

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('contest', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -4,4 +4,4 @@
<hr>
{% endif %}
{{ tag.description|markdown('contest_tag') }}
{{ tag.description|markdown }}

View file

@ -10,5 +10,5 @@
{% block header %}{% include "flatpages/admin_link.html" %}{% endblock %}
{% block body %}
<div class="content-description">{{ flatpage.content|markdown('solution')|reference|str|safe }}</div>
<div class="content-description">{{ flatpage.content|markdown|reference|str|safe }}</div>
{% endblock %}

View file

@ -1,7 +1,7 @@
{% extends "flatpages/markdown.html" %}
{% block body %}
<div class="content-description">{{ flatpage.content|markdown('solution', MATH_ENGINE)|reference }}</div>
<div class="content-description">{{ flatpage.content|markdown|reference }}</div>
{% endblock %}
{% block bodyend %}

View file

@ -1 +1 @@
{{ preview_data|markdown('license') }}
{{ preview_data|markdown }}

View file

@ -1,7 +1,7 @@
{% extends "common-content.html" %}
{% block description %}
{% cache 3600 'license_html' license.id %}
{{ license.text|markdown('license') }}
{{ license.text|markdown }}
{% endcache %}
{% endblock %}

View file

@ -39,7 +39,7 @@
<div class="sidebox-content">
<div style="margin: 0.3em;">
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
{{ organization.about|markdown('organization-about', MATH_ENGINE)|reference|str|safe }}
{{ organization.about|markdown|reference|str|safe }}
{% endcache %}
</div>
</div>

View file

@ -71,7 +71,7 @@
<div class="sidebox-content">
<div style="margin: 0.3em;">
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
{{ organization.about|markdown('organization-about', MATH_ENGINE)|reference|str|safe }}
{{ organization.about|markdown|reference|str|safe }}
{% endcache %}
</div>
</div>

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('organization-about', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -26,7 +26,7 @@
<p>Authors: {{ link_users(authors) }}</p>
{% endif %}
{% endwith %}
{{ solution.content|markdown('solution', MATH_ENGINE)|reference|str|safe }}
{{ solution.content|markdown|reference|str|safe }}
</div>
<hr>
{% include "comments/list.html" %}

View file

@ -54,7 +54,7 @@
{% endif %}
<div class='blog-description content-description'>
{% cache 86400 'problem_html' problem.id MATH_ENGINE LANGUAGE_CODE %}
{{ problem.description|markdown("problem", MATH_ENGINE)|reference|str|safe }}
{{ problem.description|markdown|reference|str|safe }}
{% endcache %}
{% if problem.pdf_description %}
<embed src="{{url('problem_pdf_description', problem.code)}}" width="100%" height="500" type="application/pdf" style="margin-top: 0.5em">

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('problem', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -376,7 +376,7 @@
{% endif %}
{% cache 86400 'problem_html' problem.id MATH_ENGINE LANGUAGE_CODE %}
{{ description|markdown("problem", MATH_ENGINE)|reference|str|safe }}
{{ description|markdown|reference|str|safe }}
{% endcache %}
{% if problem.pdf_description %}
@ -426,7 +426,7 @@
<div class="problem-clarification">
<div class="time">{{ relative_time(clarification.date) }}</div>
<span class="body">
{{ clarification.description|markdown('problem', MATH_ENGINE)|reference }}
{{ clarification.description|markdown|reference }}
</span>
</div>
{% endfor %}

View file

@ -3,8 +3,11 @@
<head>
<link rel="stylesheet" href="{{ static('style.css') }}">
<link rel="stylesheet" href="{{ static('pygment-github.css') }}" type="text/css">
<link rel="stylesheet" href="{{ static('markdown.css') }}">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="pygment-github.css" type="text/css">
<link rel="stylesheet" href="markdown.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
html {
@ -87,7 +90,7 @@
</div>
<hr style="clear: both;">
<div class="content-description printing">
{{ description|markdown('problem', 'tex')|reference|absolutify(url)|str|safe }}
{{ description|markdown|reference|absolutify(url)|str|safe }}
</div>
<script type="text/javascript" src="{{ static('mathjax_config.js') }}"></script>

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('solution', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -47,7 +47,7 @@
{% if language.description %}
<div class="content-description">
{% cache 86400 'language_html' language.id %}
{{ language.description|markdown('language') }}
{{ language.description|markdown }}
{% endcache %}
</div>
{% endif %}

View file

@ -20,6 +20,6 @@
{{link_user(ticket.messages.last().user)}} {{_(' replied')}}
</div>
<div class='blog-description content-description'>
{{ ticket.messages.last().body |markdown("ticket", MATH_ENGINE)|reference|str|safe }}
{{ ticket.messages.last().body |markdown|reference|str|safe }}
</div>
</div>

View file

@ -16,7 +16,7 @@
</div>
</div>
<div class="content content-description">
{{ message.body|markdown('ticket', MATH_ENGINE)|reference|str|safe }}
{{ message.body|markdown|reference|str|safe }}
</div>
</div>
</section>

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('ticket', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -1,4 +1,4 @@
{{ preview_data|markdown('self-description', MATH_ENGINE)|reference|str|safe }}
{{ preview_data|markdown|reference|str|safe }}
{% if REQUIRE_JAX %}
<div data-config="{{ static('mathjax_config.js') }}" class="require-mathjax-support"></div>
{% endif %}

View file

@ -82,7 +82,7 @@
{% if user.about %}
<h4>{{ _('About') }}</h4>
{% cache 86400 'user_about' user.id MATH_ENGINE %}
{{ user.about|markdown('self-description', MATH_ENGINE)|reference|str|safe }}
{{ user.about|markdown|reference|str|safe }}
{% endcache %}
{% else %}
<i>

View file

@ -38,7 +38,7 @@
<div class="about-td">
{% if user.about %}
{% cache 86400 'user_about' user.id MATH_ENGINE %}
{{ user.about|markdown('self-description', MATH_ENGINE)|reference|str|safe }}
{{ user.about|markdown|reference|str|safe }}
{% endcache %}
{% endif %}
</div>