import posixpath
import re
from urllib.parse import urlparse
import bleach
from django.conf import settings
from markdown import markdown
ALLOWED_TAGS = [
"p",
"br",
"strong",
"em",
"ul",
"ol",
"li",
"table",
"thead",
"tbody",
"tr",
"th",
"td",
"h1",
"h2",
"h3",
"h4",
"a",
"code",
"pre",
"blockquote",
"hr",
"img",
"span",
"div",
]
ALLOWED_ATTRIBUTES = {
"a": ["href", "title"],
"img": ["src", "alt", "title"],
"th": ["align"],
"td": ["align"],
}
ALLOWED_PROTOCOLS = ["http", "https", "mailto"]
EXTENSIONS = ["tables", "fenced_code", "sane_lists"]
WIKI_IMAGE_PREFIXES = ("/buyer-guide/", "/ops-guide/")
_IMAGE_SRC_RE = re.compile(r'(
]*?\bsrc=")([^"]*)(")', re.IGNORECASE)
_ANCHOR_HREF_RE = re.compile(r'(]*?\bhref=")([^"]*)(")', re.IGNORECASE)
def _rewrite_anchor(match, base_folder, help_root):
prefix, href, suffix = match.groups()
parsed = urlparse(href)
if parsed.scheme or href.startswith(("#", "/")):
return match.group(0)
resolved = posixpath.normpath(posixpath.join(base_folder, href))
if resolved.startswith("user-guides/"):
suffix_path = resolved[len("user-guides/"):]
return f'{prefix}{help_root}{suffix_path}/{suffix}'
return match.group(0)
def _rewrite_image(match):
prefix, src, suffix = match.groups()
if src.startswith(WIKI_IMAGE_PREFIXES):
return f'{prefix}{settings.WIKI_PUBLIC_BASE}{src}{suffix}'
return match.group(0)
def render_markdown(content, page_path, help_root):
html = markdown(content or "", extensions=EXTENSIONS)
base_folder = posixpath.dirname(page_path)
html = _ANCHOR_HREF_RE.sub(lambda m: _rewrite_anchor(m, base_folder, help_root), html)
html = _IMAGE_SRC_RE.sub(_rewrite_image, html)
return bleach.clean(
html,
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
protocols=ALLOWED_PROTOCOLS,
)