diff --git a/zerver/lib/markdown/priorities.py b/zerver/lib/markdown/priorities.py index 6ac58ea158..f761f09601 100644 --- a/zerver/lib/markdown/priorities.py +++ b/zerver/lib/markdown/priorities.py @@ -17,6 +17,7 @@ PREPROCESSOR_PRIORITES = { "tabbed_sections": -500, "nested_code_blocks": -500, "emoticon_translations": -505, + "static_images": -510, } BLOCK_PROCESSOR_PRIORITIES = { diff --git a/zerver/lib/markdown/static.py b/zerver/lib/markdown/static.py new file mode 100644 index 0000000000..f2d2a98eb2 --- /dev/null +++ b/zerver/lib/markdown/static.py @@ -0,0 +1,33 @@ +from typing import Any +from xml.etree.ElementTree import Element + +import markdown +from django.contrib.staticfiles.storage import staticfiles_storage +from markdown.extensions import Extension + +from zerver.lib.markdown.priorities import PREPROCESSOR_PRIORITES + + +class MarkdownStaticImagesGenerator(Extension): + def extendMarkdown(self, md: markdown.Markdown) -> None: + md.treeprocessors.register( + StaticImageProcessor(md), + "static_images", + PREPROCESSOR_PRIORITES["static_images"], + ) + + +class StaticImageProcessor(markdown.treeprocessors.Treeprocessor): + """ + Rewrite img tags which refer to /static/ to use staticfiles + """ + + def run(self, root: Element) -> None: + for img in root.iter("img"): + url = img.get("src") + if url is not None and url.startswith("/static/"): + img.set("src", staticfiles_storage.url(url[len("/static/") :])) + + +def makeExtension(*args: Any, **kwargs: str) -> MarkdownStaticImagesGenerator: + return MarkdownStaticImagesGenerator(*args, **kwargs) diff --git a/zerver/lib/templates.py b/zerver/lib/templates.py index 5a3e9f45de..5028770b3b 100644 --- a/zerver/lib/templates.py +++ b/zerver/lib/templates.py @@ -22,6 +22,7 @@ import zerver.lib.markdown.help_relative_links import zerver.lib.markdown.help_settings_links import zerver.lib.markdown.include import zerver.lib.markdown.nested_code_blocks +import zerver.lib.markdown.static import zerver.lib.markdown.tabbed_sections import zerver.openapi.markdown_extension from zerver.lib.cache import dict_to_items_tuple, ignore_unhashable_lru_cache, items_tuple_to_dict @@ -127,6 +128,7 @@ def render_markdown_path( zerver.lib.markdown.help_settings_links.makeExtension(), zerver.lib.markdown.help_relative_links.makeExtension(), zerver.lib.markdown.help_emoticon_translations_table.makeExtension(), + zerver.lib.markdown.static.makeExtension(), ] if "api_url" in context: # We need to generate the API code examples extension each