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, )